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