Tekton Pipelineをインストール時のエラーの対処

はじめに

Tekton Pipelineをインストールしてタスクをデプロイしようとした際に上手に動かず、ハマったため解決策を記載する。

環境

  • AWS EC2
  • Ubuntu22.04.3
  • Kubernetes v1.28.3
  • cri-o 1.28.1
  • Tekton Pipelines v0.59.0

現象

Taskのデプロイに失敗する。

$ kubectl apply -f git-clone_rev.yaml
Error from server (InternalError): error when creating "git-clone_rev.yaml": Internal error occurred: failed calling webhook "webhook.pipeline.tekton.dev": failed to call webhook: P
ost "https://tekton-pipelines-webhook.tekton-pipelines.svc:443/defaulting?timeout=10s": context deadline exceeded

Pipelinesのリソースのログを確認するとエラーを出力していた。

$ kubectl -n tekton-pipelines get pod
NAME                                           READY   STATUS    RESTARTS   AGE
tekton-events-controller-7688d89cd8-vr2rj      1/1     Running   0          5h55m
tekton-pipelines-controller-5656b8bdb5-rsssd   1/1     Running   0          5h55m
tekton-pipelines-webhook-9d8675984-t5zb7       1/1     Running   0          2m54s

$ kubectl -n tekton-pipelines logs tekton-pipelines-webhook-9d8675984-t5zb7
{"severity":"error","timestamp":"2024-05-14T23:15:09.740Z","logger":"tekton-pipelines-webhook.DefaultingWebhook","caller":"controller/controller.go:566","message":"Reconcile error",
"commit":"34d8c0f","knative.dev/traceid":"12c64009-6b0d-4c3f-b216-3f77e34b6704","knative.dev/key":"webhook.pipeline.tekton.dev","duration":0.08037835,"error":"failed to update webho
ok: Operation cannot be fulfilled on mutatingwebhookconfigurations.admissionregistration.k8s.io \"webhook.pipeline.tekton.dev\": the object has been modified; please apply your chan
ges to the latest version and try again","stacktrace":"knative.dev/pkg/controller.(*Impl).handleErr\n\tknative.dev/pkg@v0.0.0-20240116073220-b488e7be5902/controller/controller.go:56
6\nknative.dev/pkg/controller.(*Impl).processNextWorkItem\n\tknative.dev/pkg@v0.0.0-20240116073220-b488e7be5902/controller/controller.go:543\nknative.dev/pkg/controller.(*Impl).RunC
ontext.func3\n\tknative.dev/pkg@v0.0.0-20240116073220-b488e7be5902/controller/controller.go:491"}

解決策

一度、 tekton-pipelines-webhookのpodを削除し、レプリカセットにより再起動させた。

$ kubectl -n tekton-pipelines delete tekton-pipelines-webhook-9d8675984-t5zb7
$ kubectl -n tekton-pipelines get pod
NAME                                           READY   STATUS    RESTARTS   AGE
tekton-events-controller-7688d89cd8-vr2rj      1/1     Running   0          5h55m
tekton-pipelines-controller-5656b8bdb5-rsssd   1/1     Running   0          5h55m
tekton-pipelines-webhook-9d8675984-t5zb7       1/1     Running   0          2m54s


# 確認
$ kubectl apply -f git-clone_rev.yaml
$ kubectl get task
NAME        AGE
git-clone   9s

VM上のゲストOSのディスク容量拡張

はじめに

VM上のゲストOSのディスク容量が足りなくなったため、拡張する方法を記載する。

環境

  • Ubuntu 20.04.6 LTS(ホストOS)
  • Ubuntu 22.04.2 LTS(ゲストOS)

操作手順

ゲストOSが使用しているディスクサイズの拡張

ゲストOSが使用しているディスクサイズの拡張する。今回は50GBから100GBにディスク拡張する場合を記載する。

##ドメインを停止する
$ virsh shutdown <domain_name>

##rootユーザに変更
$ sudo -i
$ whoami
root

##ゲストOSが使用しているディスクのフォルダに移動
# cd /var/lib/libvirt/images

##ゲストOSの名前を定義
# VMNAME=test

##ゲストOSの確認
# qemu-img info $VMNAME.qcow2
image: test.qcow2
file format: qcow2
virtual size: 50 GiB (53687091200 bytes)
disk size: 48.1 GiB
cluster_size: 65536
backing file: jammy-server-cloudimg-amd64.img
backing file format: qcow2
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false

##ディスクサイズの拡張
# qemu-img resize  $VMNAME.qcow2 100G

##ディスクサイズの拡張を確認
# qemu-img info $VMNAME.qcow2
image: test.qcow2
file format: qcow2
virtual size: 100 GiB (107374182400 bytes)
disk size: 48.1 GiB
cluster_size: 65536
backing file: jammy-server-cloudimg-amd64.img
backing file format: qcow2
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false

##rootユーザの終了
# exit
$ 

ゲストOSへ変更を反映

ゲストOSへディスクサイズ拡張を反映させる。次の例ではvda1というパーティションに対し、拡張を行った。 拡張にはgrowpartを使用する。growpart は、パーティションテーブルのエントリを変更することなく、パーティションのサイズを拡張するために使用される。

#ドメインを起動する
$ virsh start <domain_name>

#ドメインにアクセス
 $ virsh console<domain_name>

#確認
$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        49G   29G   21G  59% /

#確認
$ sudo sfdisk -Vl /dev/vda1
Disk /dev/vda1: 49.89 GiB, 53570682368 bytes, 104630239 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

#ディスクを最大限拡張
$ sudo growpart /dev/vda 1
CHANGED: partition=1 start=227328 old: size=104630239 end=104857567 new: size=209487839 end=209715167

#確認
$ sudo sfdisk -Vl /dev/vda1
Disk /dev/vda1: 99.89 GiB, 107257773568 bytes, 209487839 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

#コマンド実行後に一旦リブートを行います。
$ sudo reboot

次に、resize2fsコマンドの実行する。resize2fs コマンドは、ファイルシステムのサイズを変更するために使用される。

$ sudo resize2fs /dev/vda1
resize2fs 1.46.5 (30-Dec-2021)
Filesystem at /dev/vda1 is mounted on /; on-line resizing required
old_desc_blocks = 7, new_desc_blocks = 13
The filesystem on /dev/vda1 is now 26185979 (4k) blocks long.

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        97G   29G   69G  30% /

これにより拡張できたことを確認した。

参考

knowledge.sakura.ad.jp

WireGuardを使ったVPNの構築

はじめに

次のVM上のサーバ間でWireGuardを使ってVPN接続ができるように構築する。

$ virsh net-dhcp-leases default
 Expiry Time           MAC address         Protocol   IP address           Hostname   Client ID or DUID
------------------------------------------------------------------------------------------------------------------------------------------------
 2023-12-22 02:27:45   52:54:00:70:0f:14   ipv4       192.168.123.123/24   vpn1       ff:56:50:4d:98:00:02:00:00:ab:11:21:77:3b:5b:4c:12:bc:c2
 2023-12-22 02:40:08   52:54:00:cc:d7:ca   ipv4       192.168.123.192/24   vpn2       ff:56:50:4d:98:00:02:00:00:ab:11:43:f1:be:a3:9d:05:4e:e9

環境

  • Ubuntu 20.04.6 LTS(ホストOS)
  • Ubuntu 22.04.2 LTS(ゲストOS)

構築

VPNサーバの構築

#ホストからVMにログイン
$ ssh 192.168.123.123

#VM上で操作
$ sudo apt update;sudo apt upgrade -y
wireguardパッケージのインストール
$ sudo apt install wireguard -y

サーバー用鍵ペアの作成する。

#秘密鍵の作成と保存
$ wg genkey | sudo tee /etc/wireguard/server.key
$ sudo chmod 600 /etc/wireguard/server.key
$ sudo ls -la /etc/wireguard/server.key
-rw------- 1 root root 45 Dec 22 01:48 /etc/wireguard/server.key

#作成したサーバーの秘密鍵の確認
$ sudo cat /etc/wireguard/server.key
oLXg+zI+hFbWqWg5abKZsCOpu0HDG8XJX5xGFT4CoGw=

#秘密鍵から公開鍵を作成する
$ sudo cat /etc/wireguard/server.key | wg pubkey | sudo tee /etc/wireguard/server.pub
$ sudo chmod 600 /etc/wireguard/server.pub
$ sudo ls -la /etc/wireguard/server.pub
-rw------- 1 root root 45 Dec 22 01:49 /etc/wireguard/server.pub

#作成したサーバーの公開鍵の確認
$ sudo cat /etc/wireguard/server.pub
dzLJmkwcJ5D4hgfxj3hD5H5qMxjxzep3VzXRhipa/3o=

IPアドレスの確認
$ ip a
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:70:0f:14 brd ff:ff:ff:ff:ff:ff
    inet 192.168.123.123/24 metric 100 brd 192.168.123.255 scope global dynamic enp1s0
       valid_lft 3266sec preferred_lft 3266sec
    inet6 fe80::5054:ff:fe70:f14/64 scope link
       valid_lft forever preferred_lft forever

VPNクライアントの構築

クライアント用鍵ペアの作成する。

#ホストからVMにログイン
$ ssh 192.168.123.192

#VM上で操作
$ sudo apt install wireguard -y
$ wg genkey | sudo tee /etc/wireguard/client.key
$ sudo cat /etc/wireguard/client.key | wg pubkey | sudo tee /etc/wireguard/client.pub
$ sudo chmod 600 /etc/wireguard/client.key /etc/wireguard/client.pub
$ sudo ls -la /etc/wireguard/client.key /etc/wireguard/client.pub
-rw------- 1 root root 45 Dec 22 01:52 /etc/wireguard/client.key
-rw------- 1 root root 45 Dec 22 01:52 /etc/wireguard/client.pub

# 作成したクライアントの秘密鍵の確認
$ sudo cat /etc/wireguard/client.key
KO1zn3Qq0HQDrvFaYfs8z9iuARl9VOghfBAXOpxBCHk=
# 作成したクライアントの公開鍵の確認
$ sudo cat /etc/wireguard/client.pub
j9SRypHMiQ3AshaL/VITyyEVqaJxW22kWXyUIwQNiA4=

VPNサーバの設定

WireGuardの設定ファイルは、「⁠/etc/wireguard/作成するインターフェイス名.conf」という名前で作成する必要がある。今回はインターフェイス名を「wg0」とするので、「⁠/etc/wireguard/wg0.conf」というファイルを作成し、以下の内容を記述する。 VPNサーバのプライベートキー、VPNクライアントのパブリックキーを使用することに留意する。

$ sudo vim /etc/wireguard/wg0.conf
[Interface]
PrivateKey = oLXg+zI+hFbWqWg5abKZsCOpu0HDG8XJX5xGFT4CoGw=
Address = 10.0.0.1 (サーバーのインターフェイスに割り当てるIPアドレス)
ListenPort = 51820

[Peer]
PublicKey = j9SRypHMiQ3AshaL/VITyyEVqaJxW22kWXyUIwQNiA4=
AllowedIPs = 10.0.0.2/32 (クライアントに割り当てたIPアドレス)

VPNクライアントの設定

クライアント側にも設定ファイルが必要である。以下の内容で「/etc/wireguard/wg0.conf」を作成する。 VPNクライアントのプライベートキー、VPNサーバのパブリックキーを使用することに留意する。

$ sudo vim /etc/wireguard/wg0.conf
[Interface]
PrivateKey = KO1zn3Qq0HQDrvFaYfs8z9iuARl9VOghfBAXOpxBCHk=
Address = 10.0.0.2 (クライアントのIPアドレス)

[Peer]
PublicKey = dzLJmkwcJ5D4hgfxj3hD5H5qMxjxzep3VzXRhipa/3o=
EndPoint = 192.168.123.123:51820(サーバーのIPアドレス:51820)
AllowedIPs = 10.0.0.0/24 (WireGuardを経由して通信する先のIPアドレス)
WireGuardの起動(VPNサーバでの作業)

VPNサーバのサービス起動

VPNサーバで、WireGuardのサービスを起動する。

$ sudo wg-quick down wg0
$ sudo wg-quick up wg0

$ ip a show wg0
4: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none
    inet 10.0.0.1/32 scope global wg0
       valid_lft forever preferred_lft forever

VPNクライアントのサービス起動と接続

VPBクライアントからVPNサーバへの接続する。

$ sudo wg-quick up wg0
$  ip a show wg0
3: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none
    inet 10.0.0.2/32 scope global wg0
       valid_lft forever preferred_lft forever

接続を確認できた。

Ingress、Nginx-Ingressコントローラの動作確認

はじめに

Kubernetesのリソースの一つであるIngressの動作を確認し、Kubernetesクラスタネットワーク外部からアクセスを待ち受けられるようにする。

環境

  • Windows11(ホストOS)
  • Ubuntu22.04.3(ゲストOS、WSL2)
  • k3s v1.29.4+k3s1

Ingressについて

IngressIngressのリソースそのものに加えて、Ingressを提供するためにはIngressコントローラーが必要である。 Ingressコントローラーとして以下のようなものがある。

今回はNginxのIngressコントローラーを使用する。

構築と動作確認

構築イメージ

Ingressコントローラー

kubernetes.github.io

上記を参考にNginx-Ingressをインストールする。

$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.10.1/deploy/static/provider/cloud/deploy.yaml

#確認
$ kubectl get all -n ingress-nginx
NAME                                            READY   STATUS      RESTARTS   AGE
pod/ingress-nginx-admission-create-xmst5        0/1     Completed   0          87s
pod/ingress-nginx-admission-patch-cgtwl         0/1     Completed   1          87s
pod/ingress-nginx-controller-57b7568757-fpn5s   1/1     Running     0          87s

NAME                                         TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                      AGE
service/ingress-nginx-controller-admission   ClusterIP      10.43.145.184   <none>          443/TCP                      87s
service/ingress-nginx-controller             LoadBalancer   10.43.35.137    172.23.13.179   80:32720/TCP,443:30940/TCP   88s
                                                                                                                                                                                   NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ingress-nginx-controller   1/1     1            1           87s
                                                                                                                                                                                   NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/ingress-nginx-controller-57b7568757   1         1         1       87s
                                                                                                                                                                                   NAME                                       COMPLETIONS   DURATION   AGE
job.batch/ingress-nginx-admission-create   1/1           19s        87s
job.batch/ingress-nginx-admission-patch    1/1           19s        87s

Ingress

Ingressが接続するService, Podを作成する。

$ cat > nginx-pod-svc.yaml << "EOF"
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 80
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
EOF

Ingressを作成する。

$ cat > ingress.yaml << "EOF"
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: nginx-ingress.test
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-svc
            port:
              number: 80
EOF

それぞれのマニフェストファイルを適用してデプロイする。

$ kubectl apply -f nginx-pod-svc.yaml
$ kubectl apply -f ingress.yaml

#確認
$ kubectl get pod,svc,ingress
NAME                                              READY   STATUS    RESTARTS   AGE
pod/nginx                                         1/1     Running   0          70s

NAME                                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
service/nginx-svc                    ClusterIP   10.43.255.87    <none>        80/TCP              70s

NAME                                      CLASS   HOSTS                ADDRESS         PORTS   AGE
ingress.networking.k8s.io/nginx-ingress   nginx   nginx-ingress.test   172.23.13.179   80      56s

ingressで定義したホスト名を解決できるように、/etc/hostsに設定を追記する。

$ sudo vim /etc/hosts
(省略)
172.23.13.179 nginx-ingress.test
(省略)

最後に、IngressコントローラーとIngressを通してアクセスできることを確認する。

#portの確認
$ kubectl get svc -n ingress-nginx
NAME                                         TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.43.35.137    172.23.13.179   80:32720/TCP,443:30940/TCP   88s

#アクセス確認
$ curl http://nginx-ingress.test:32720
(省略)
<h1>Welcome to nginx!</h1>
(省略)

#これでもアクセス確認ができた。なぜ?
$ curl http://nginx-ingress.test
(省略)
<h1>Welcome to nginx!</h1>
(省略)

ソースコード

使用したソースコードを以下に格納する。

test/kubernetes/ingress at main · InoueReo0406/test · GitHub

その他

Istioをコントローラとして使用するなら以下を参考にしたらできそうである。Ingressを通してgRPCも試してみたい。

istio.io

参考

christina04.hatenablog.com

Tekton Triggersを使ったTaskを実行

はじめに

Tekton Triggersを使って、Taskを実行した。その方法を記載する。

環境

  • Windows11(ホストOS)
  • Ubuntu22.04.3(ゲストOS、WSL2)
  • k3s v1.29.4+k3s1
  • Tekton Pipelines v0.59.0
  • Tekton Triggers v0.25.2

前提条件

Tekton Pipelinesはインストールされているものとする。

構築と実行

Tekton Triggersのインストール

最新バージョンだと動作しなかったため、TektonのTriggerのバージョンを下げてインストールを行った。なお記事執筆時の最新バージョンはv0.26.2 である。

$ VERSION_NUMBER=v0.25.2
$ kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/previous/$VERSION_NUMBER/release.yaml
$ kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/previous/$VERSION_NUMBER/interceptors.yaml

TektonのTask, Pipeline, Pipelinerunの作成

inorio.hatenablog.com

上記のTask, Pipeline, Pipelinerunを流用して作成する。

TriggerTemplate/TriggerBinding/EventListenerの作成

EventListenerを担うPodに紐づくServiceに対して、APIが実行された際、パイプラインが起動する。

処理の流れとしては、EventListenerが受け取った情報はTriggerBindingに記載された構文に従う必要があり、その情報をTriggerTemplateにわたすことでPilelineRun相当の処理が実行される。

以下の図がイメージがしやすい。

https://blog.mosuke.tech/entry/2021/04/06/tekton-trigger/ より引用

TriggerTemplateを作成する。

$ cat > triggertemp-clone-read.yaml << "EOF"
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerTemplate
metadata:
  name: clone-read-run-template
spec:
  params:
    - name: repo-url
  resourcetemplates:
    - apiVersion: tekton.dev/v1beta1
      kind: PipelineRun
      metadata:
        name: clone-read-run
      spec:
        pipelineRef:
          name: clone-read
        podTemplate:
          securityContext:
            fsGroup: 65532
        workspaces:
        - name: shared-data
          volumeClaimTemplate:
            spec:
              accessModes:
              - ReadWriteOnce
              resources:
                requests:
                  storage: 1Gi
        params:
        - name: repo-url
          value: $(tt.params.repo-url)
        serviceAccountName: clone-read-run-sa
EOF

TriggerBindingを作成する。

$ cat > triggerbinding-clone-read.yaml << "EOF"
apiVersion: triggers.tekton.dev/v1alpha1
kind: TriggerBinding
metadata:
  name: clone-read-run-binding
spec:
  params:
    - name: repo-url
      value: $(body.git.url)
EOF

tekton.dev

上記を参考に、EventListener Podが使用するが利用するService Accountの作成する。なお、Role/RoleBindingで作成すると権限によるエラー(参考:https://www.mtioutput.com/entry/k8s-sa-permissionerror )を確認したため、ClusterRole/ClusterRoleBindingで作成した。

$ cat > clone-read-run-sa.yaml << "EOF"
apiVersion: v1
kind: ServiceAccount
metadata:
  name: clone-read-run-sa
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: trigger-role
rules:
# Permissions for every EventListener deployment to function
- apiGroups: ["triggers.tekton.dev"]
  resources: ["clustertriggerbindings", "eventlisteners", "triggerbindings", "triggertemplates", "triggers", "interceptors", "clusterinterceptors"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  # secrets are only needed for Github/Gitlab interceptors
  resources: ["configmaps", "secrets"]
  verbs: ["get", "list", "watch"]
# Permissions to create resources in associated TriggerTemplates
- apiGroups: ["tekton.dev"]
  resources: ["pipelineruns", "pipelineresources", "taskruns"]
  verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: triggers-role-binding
subjects:
  - kind: ServiceAccount
    name: clone-read-run-sa
    namespace: default
roleRef:
  kind: ClusterRole
  apiGroup: rbac.authorization.k8s.io
  name: trigger-role
EOF

EventListenerを作成する。

$ cat > eventlistener-clone-read.yaml << "EOF"
apiVersion: triggers.tekton.dev/v1alpha1
kind: EventListener
metadata:
  name: clone-read-run-listener
spec:
  serviceAccountName: clone-read-run-sa
  triggers:
    - name: clone-read-run-el
      bindings:
        - ref: clone-read-run-binding
      template:
        ref: clone-read-run-template
EOF

それぞれのマニフェストファイルを適用してデプロイする。加えて、EventListenerのPod/Serviceを確認する。

#デプロイ
$ kubectl apply -f triggertemp-clone-read.yaml
$ kubectl apply -f triggerbinding-clone-read.yaml
$ kubectl apply -f clone-read-run-sa.yaml
$ kubectl apply -f eventlistener-clone-read.yaml

#EventListenerのPod/Serviceを確認
$ kubectl get pod,deploy,svc
NAME                                              READY   STATUS    RESTARTS   AGE
pod/el-clone-read-run-listener-84bd976fc7-p6pg8   1/1     Running   0          58s

NAME                                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/el-clone-read-run-listener   1/1     1            1           58s

NAME                                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)             AGE
service/kubernetes                   ClusterIP   10.43.0.1      <none>        443/TCP             2d
service/el-clone-read-run-listener   ClusterIP   10.43.45.162   <none>        8080/TCP,9000/TCP   59s

APIの実行

通常はWebhookからAPIを実行するが、今回は簡略化してcurlコマンドで動作を確認する。 EventListener Pod/Serviceはネットワークはホスト側に公開していないので、port-fowardを使って転送を行う。 curlの-dオプションでTriggerBindingに渡すデータ(data)を定義している。

$ kubectl port-forward service/el-clone-read-run-listener 8080:8080
Forwarding from 127.0.0.1:8080 -> 8000
Forwarding from [::1]:8080 -> 8000

#別ターミナルでcurlの実行
$ curl -X POST -H 'Content-Type: application/json' http://localhost:8080 -d '{"git":{"url": "https://github.com/InoueReo0406/test.git"}}'
{"eventListener":"clone-read-run-listener","namespace":"default","eventListenerUID":"fe1bb963-da21-4d1c-8600-58cd8b9bf8b1","eventID":"54c5e031-66b7-480c-bc6f-7f2806f17d68"}

$ kubectl get pipelinerun,taskrun,pod
NAME                                    SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
pipelinerun.tekton.dev/clone-read-run   True        Succeeded   41s         12s

NAME                                             SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
taskrun.tekton.dev/clone-read-run-fetch-source   True        Succeeded   41s         22s
taskrun.tekton.dev/clone-read-run-show-readme    True        Succeeded   22s         12s

NAME                                              READY   STATUS      RESTARTS   AGE
pod/el-clone-read-run-listener-84bd976fc7-6f2mx   1/1     Running     0          46m
pod/clone-read-run-fetch-source-pod               0/1     Completed   0          41s
pod/clone-read-run-show-readme-pod                0/1     Completed   0          22s

無事に実行していることを確認した。

トラブルシューティング

EventListenerを作成時、以下のエラーの回避方法がわからなかった。

$ kubectl get eventlistener
NAME                      ADDRESS                                                            AVAILABLE   REASON                     READY   REASON
clone-read-run-listener   http://el-clone-read-run-listener.default.svc.cluster.local:8080   True        MinimumReplicasAvailable   True

$ kubectl get pod,svc
NAME                                          READY   STATUS    RESTARTS   AGE
el-clone-read-run-listener-84bd976fc7-c5gbf   1/1     Running   0          14s

そのため、TektonのTriggerのバージョンを下げることで対応を行った。なお記事執筆時の最新バージョンはv0.26.2 である。

#アンインストール
$ kubectl delete --filename https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
$ kubectl delete --filename https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yaml

#インストール
$ VERSION_NUMBER=v0.25.2
$ kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/previous/$VERSION_NUMBER/release.yaml
$ kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/previous/$VERSION_NUMBER/interceptors.yaml

https://issues.redhat.com/browse/OCPBUGS-19318 でcaBundleに関するバグ修正が報告されているので、バグなのかもしれない。

その他

EventListener Pod/Serviceのネットワークの公開は、port-fowardよりもIngressのほうが、スマートだと思われる。 EventListener Pod/Serviceはネットワークはホスト側に公開していないので、Ingressを使って転送を行うことができる。 Ingressを使うことで、クラスター外からクラスター内ServiceへのHTTPとHTTPSのルートを公開することができる。

引用:https://kubernetes.io/ja/docs/concepts/services-networking/ingress/

ソースコード

使用したソースコードを以下に格納する。

test/kubernetes/tekton/webhook at main · InoueReo0406/test · GitHub

参考

blog.mosuke.tech

github.com

Cloudflare Tunnelを利用したサービスの公開

はじめに

Cloudflare Tunnelを利用して、Kubernetes上のアプリをオープンネットワークに公開する。 AWSKubernetesを構築している場合、アプリをオープンネットワークへ公開するにはAWS から提供される load balancerを使うことが一般的である。ただし、今回は確認用にアプリを公開したいため、 無償のCloudflare Tunnelを使用してオープンネットワークへ公開する。

環境

  • Windows11(ホストOS)
  • Ubuntu22.04.3(ゲストOS、WSL2)
  • k3s v1.29.4+k3s1

Cloudflare Tunnelについて

Cloudflare TunnelはCloudflare社が提供するTunnelを構築できるサービスである。ngrokなども同様のことを実施することができる。

Cloudflare Tunnelのインストール

developers.cloudflare.com

上記を参考に、CLIを用いてインストールを行う。

$ sudo mkdir -p --mode=0755 /usr/share/keyrings
$ curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null

$ echo "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflared.list

$ sudo apt-get update && sudo apt-get install cloudflared

Quick Tunnelsを用いた簡易的なトンネルの作成

developers.cloudflare.com

上記を参考に簡易的なトンネルの作成してサービスをアプリをオープンネットワークへ公開する。 まず、公開するアプリを作成する。

python3 -m http.server 8080

次に、トンネルを作成してアプリを公開する。表示されるURLにアクセスして、アプリが公開されていることを確認した。

$ cloudflared tunnel --url http://localhost:8080
(省略)
INF +--------------------------------------------------------------------------------------------+
INF |  Your quick Tunnel has been created! Visit it at (it may take some time to be reachable):  |
INF |  https://*************************************************************                              |
INF +--------------------------------------------------------------------------------------------+
(省略)

なお、URLは起動のたびに毎回変更される。 これを利用すれば、urlの指定をKubernetes上のサービスのURLを指定することで、公開できそうである。

アカウント情報を用いたトンネルの作成(失敗)

次にcloudflareへ認証を行う。なお事前にcloudflareへのアカウントの登録を済ませておく。

$ cloudflared tunnel login
Please open the following URL and log in with your Cloudflare account:

https://dash.cloudflare.com/argotunnel?aud=&callback=https*** ←ここにログインして、GUIでDNSの登録を行う。

Leave cloudflared running to download the cert automatically.

次にTunnelの作成を行う。

zenn.dev

上記を参考にTunnelのサービスを作成し、Tunnel name, Tunnel IDを取得した。

ただし、ログインが成功せず、cert.pemを作成できなかったため断念した。

補足

ドメインの登録が最大24時間かかるらしいので、そのあとにログインを実施すれば成功するかもしれない。確認する。

参考

developers.cloudflare.com

qiita.com

qiita.com

TektonをHelm化する際のpipelineとpipelinerunの起動順序を制御

はじめに

TektonをHelm化するにあたり、pipelineとpipelinerunの起動順序を制御できず、起動に失敗することがあった。その解決方法を模索した。

helmのリソースの起動順序

次のソースでHelm適用時のKubernetesのリソースの起動順序が記載されている。

github.com

var InstallOrder KindSortOrder = []string{
    "PriorityClass",
    "Namespace",
    "NetworkPolicy",
    "ResourceQuota",
    "LimitRange",
    "PodSecurityPolicy",
    "PodDisruptionBudget",
    "ServiceAccount",
    "Secret",
    "SecretList",
    "ConfigMap",
    "StorageClass",
    "PersistentVolume",
    "PersistentVolumeClaim",
    "CustomResourceDefinition",
    "ClusterRole",
    "ClusterRoleList",
    "ClusterRoleBinding",
    "ClusterRoleBindingList",
    "Role",
    "RoleList",
    "RoleBinding",
    "RoleBindingList",
    "Service",
    "DaemonSet",
    "Pod",
    "ReplicationController",
    "ReplicaSet",
    "Deployment",
    "HorizontalPodAutoscaler",
    "StatefulSet",
    "Job",
    "CronJob",
    "IngressClass",
    "Ingress",
    "APIService",
}

ここに記載が行われていない、カスタムリソースのTektonのpipelineとpipelinerunは特に制御されていないようである。実際にHelmで起動した際、5回中2回はpipelinerunがpipelineより先に起動し、pipelinerunがうまく動かなかった。

対策

helm.sh

上記のChart Hooksを使用して制御する。こちらを使うことでリリースのライフサイクルを操作することができる。 Chart Hooksのpost-installをpipelinerunに適用する。通常で動作するpipelineより。pipelinerunの起動順序が後段になるように設定する。

https://gitlab.com/InoueRio/public/-/blob/main/kubernetes/helm/clone-read/templates/piplinerun-clone-read.yaml#L8

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  name: clone-read-run
  annotations:
    # This is what defines this resource as a hook. Without this line, the
    # job is considered part of the release.
    "helm.sh/hook": post-install
(省略)

これでpipelineとpipelinerunの順序で起動し、pipelinerunが起動に失敗しなくなった(5回中5回は成功)。

#install
$ helm install clone-read-v1 ../clone-read/

#動作確認
$ kubectl get pod,taskrun,pipelinerun
NAME                                    READY   STATUS      RESTARTS   AGE
pod/clone-read-run-fetch-source-pod     0/1     Completed   0          41s
pod/clone-read-run-show-readme-pod      0/1     Completed   0          23s

NAME                                             SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
taskrun.tekton.dev/clone-read-run-fetch-source   True        Succeeded   41s         23s
taskrun.tekton.dev/clone-read-run-show-readme    True        Succeeded   23s         6s

NAME                                    SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
pipelinerun.tekton.dev/clone-read-run   True        Succeeded   42s         6s

$ kubectl logs pod/clone-read-run-show-readme-pod
Defaulted container "step-read" out of: step-read, prepare (init), place-scripts (init)
# Tekton Catalog
(省略)

参考

qiita.com

inorio.hatenablog.com