Tekton Triggersによるwebhook構築

Tekton Triggersは、Tekton Pipelinesにwebhookを追加する機能です。
CronJobからwebhookを呼ぶことで定時バッチの実行も可能です。

前提条件

まず、 Tekton Pipelinesをセットアップし、tknコマンドでタスク実行可能な状態を作っておく必要があります。
TriggerはPipelineを呼び出す構造になっています。

TriggersとInterceptorのアドオンは、以下のようにkubectl applyでインストールできます。
基礎的なwebhookはIntercepterなしでも動作しますが、 ルーティングにInterceptorが必要になります。

$ kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
$ kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yaml

また、TriggerはクラスタリソースにアクセスするためのServiceAccountを必要とします。
Examplesのrbac.yamlにミニマム権限を設定したmanifest例があるので、流用すると良いでしょう。サービスアカウントを含むRBACはkubernetesの標準機能を用いて実装します。

Tekton Triggersの構成

Triggerの主要リソースは、EventListener, TriggerTemplate, TriggerBindingの3つです。

  • EventListenerは、ServiceとDeploymentを生成しデーモンプロセスとして動作します。port8080でHTTPリクエストをlistenします
  • TriggerTemplateは、実行対象のPipelineを参照します
  • TriggerBindingは、リクエストbodyのJSONデータなどをparamsにマップします

これらを組み合わせて、HTTPリクエストをPipelinesのリソースに変換します。

EventListenerの概要

Triggersは、EventListenerの性質を把握すると理解が進みます。ドキュメントされていない特徴として、以下のような実装になっています。

  • tkn eventlistenerコマンドで操作できます。
    • 起動ログやリクエストの処理状況はlogsサブコマンドで確認可能
    • セットアップ時にconfigMapを読めないなどの権限エラーが出ている場合には、概ねServiceAccountの設定不良
  • httpリクエストのエンドポイントはel-<listener_name>という名前のServiceです。
    • クラスタ内部からhttp://el-<listener_name>.<namespace>.svc.cluster.local:8080にリクエストするとTriggerを実行可能
    • curlなどのプリミティブなhttpクライアントからリクエスト可能
    • サービスをクラスタ外に公開するには、認証を考慮のうえk8sの標準的な方法で追加セットアップが必要
  • EventListenerは1インスタンスではなく、TriggerTemplateの数だけ立ち上がります

paramsの挙動

Tektonはparamsのうちdefaultを設定したパラメータが全般的に省略可能ですが、TriggersへのhttpリクエストではTriggerTemplateにdefault設定したパラメータのみ省略可能です。

ほかにPipelineTaskのレイヤでもdefault設定可能ですが、これらは参照されません。

動作不良への対応。paramsの更新

一度設定したTriggerTemplateやTriggerBindingは更新可能ですが、kubectl applyで差分更新が効かないケースがあります。
その場合、kubectl delete -> kubectl createすると反映できるでしょう。

パラメータの不調については、tekton-cliをインストールのうえtkn triggerbinding describetkn triggertemplate describeを実行すると、現在受け付けているパラメータ一覧を確認できます。

EventListenerのQoS強化

EventListenerはDeploymentを作成します。デフォルトでは QoSがBestEffortであり、リソースが逼迫してくると優先的に停止されることで、タスクを実行できないケースがあります。

QoSを変更するには、以下のようにリソース要求を設定します。limitsを利用してGuaranteedも指定可能でしょう。

apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
spec:
  resources:
    kubernetesResource:
      spec:
        template:
          spec:
            containers:
            - resources:
                requests:
                  cpu: 50m
  triggers:

kubernetesResourceについては、 EventListernerのdocに説明がありますが、API仕様が厳密ではない点に注意が必要です。

TriggerTemplate

TriggerTemplatesは、spec.resourcetemplatesにPipelineRunを記述することでタスクを起動するリソースです。spec.pipelineRefでターゲットのPipelineを指定し、主にspec.paramsspec.workspacesといったTektonの基礎的なリソースを割り当てます。

他にもPipelineRunスペックの項目を設定できます。たとえば実行時のServiceAccountを割当てるには、バージョンv1の場合spec.taskRunTemplate.serviceAccountNameに指定します。タスク内でkubectlを実行したいケースではRoleを用いた適切な権限が必要になるでしょう。

また、affinityなどのpodSpecはtaskRunTemplate.podTemplateに記述できます。

Tekton Triggersのメリット

Triggersを実装することで、tknコマンドの実行環境をセットアップすることなく一般的なhttpクライアントからPipelineを実行できます。

また、Cronについてはk8s標準の CronJosを用いたTriggerリクエスト実装パターンがコミュニティの暫定ベストプラクティスになっているようです。

ログレベルを一時的に変更

Configuring debug logging for EventListenersの解説のとおり、configmap/config-logging-triggersを変更するとログレベルを変えられます。kubectl patchのほかkubectl editで編集することも可能です。

ただしConfigMapはtektonをバージョンアップすると上書きされ、恒久的な設定方法はありません。Triggersはログが冗長で抑止する手段がないため、実運用にはフィルタツールが不可欠であると思います。

証明書エラー

interceptorにリクエストを送ってもタスクが起動しない場合、TLS証明書のエラーが起きているケースがあります。
triggers-webhook-cert expired after a yearで失効ケースの報告がありますが、アップグレード後に証明書の更新が失敗することもあります。

イベントリスナーやinterceptorのログを確認するとTLS証明書エラーを確認できます。

$ kubectl logs deploy/<EventListener name>
$ kubectl logs -ntekton-pipelines deploy/tekton-triggers-core-interceptors

証明書の再作成で対処できます。証明書はコンテナ起動時に作成する挙動のようです。

$ kubectl delete -ntekton-pipelines secret triggers-webhook-certs
$ kubectl delete -ntekton-pipelines secret tekton-triggers-core-interceptors-certs
$ kubectl rollout restart -ntekton-pipelines deploy tekton-triggers-core-interceptors

なお、このエラーは膨大な量のエラーログを出力するため、放置するとロギング課金を食いつぶすことがあり得ます。

⁋ 2021/07/06↻ 2024/11/07
中馬崇尋
Chuma Takahiro