Kubernetesネイティブなパイプラインへの移行
CI/CDの管理は、しばしば「シャドウ・インフラ」という税金を払っているように感じられます。私は、スタンドアロンのJenkinsノードにパッチを当てたり、クラスターの内部サービスを認識できない外部ランナーのデバッグをしたりして、あまりにも多くの週末を費やしてきました。摩擦は現実的です。アプリケーションはKubernetes上で動作しているのに、それをビルドするエンジンは外部から覗き見ている見知らぬ人のようです。この不一致は、認証のハードル、ネットワークの遅延、そして高価なリソースのアイドル状態を生み出します。
従来のCI/CDツールは、Kubernetesを単なるデプロイ先として扱います。それらは同じ「言語」を話しません。トラフィックが急増し、50ノードにスケールアップしたとき、静的なランナーはしばしば大きなボトルネックになります。結局、2つの異なる世界を、2つの異なるスケーリングロジックで管理することになってしまいます。
Tektonは、パイプラインをクラスター自体の一部にすることで、この問題を解決します。これは単なる統合ではなく、カスタムリソース定義(CRD)の集合体です。私の経験では、Tektonに移行したことで、個別のランナーVMを管理する必要がなくなったため、構成オーバーヘッドが約40%削減されました。すべてのビルドステップはコンテナであり、すべてのパイプラインはネイティブオブジェクトです。アプリですでに使用しているものと同じYAMLパターンを使用する、よりクリーンなスタックです。
Tektonエンジンのデプロイ
Tektonはモジュール式です。肥大化した巨大なスイートをインストールする必要はありません。ワークフローが実際に必要とするコンポーネントだけを取得します。
1. Tekton Pipelinesのインストール
コアとなる Pipelineコンポーネントから始めましょう。これにより、ビルド指示を監視し、Podとして実行するコントローラーがセットアップされます。
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
ステータスを確認して、コントローラーの準備ができていることを確認します:
kubectl get pods -n tekton-pipelines
2. Tekton Triggers의 추가
GitHub에 코드가 푸시되었을 때 클러스터가 반응하게 하고 싶다면 Triggers 컴포넌트가 필요합니다.
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
3. CLI (tkn) 를 마스터하기
kubectl을 사용할 수도 있지만, 그것은 포크로 스프를 먹는 것과 같습니다. tkn CLI는 이 워크플로우를 위해 특별히 제작되었습니다. 표준 도구보다 여러 컨테이너에 걸친 로그 스트리밍을 훨씬 더 잘 처리합니다.
curl -LO https://github.com/tektoncd/cli/releases/download/v0.32.0/tkn_0.32.0_Linux_x86_64.tar.gz
tar xvzf tkn_0.32.0_Linux_x86_64.tar.gz -C /usr/local/bin tkn
構成要素:TasksとPipelines
Tektonはレゴのように機能します。Taskは最小のレンガであり、1つのPod内で実行される一連のステップです。Pipelineは、それらを順番に組み合わせるための設計図です。
ビルドTaskの定義
リポジトリをクローンし、ファイルを監査するTaskを見てみましょう。ここでの各ステップは、同じPod内のコンテナとして実行されます。デフォルトでローカルファイルシステムを共有するため、効率的です。
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: source-check
spec:
steps:
- name: list-files
image: alpine
script: |
#!/bin/sh
ls -R $(workspaces.source.path)
workspacesフィールドは架け橋となります。ステップをPersistent Volumeに接続し、データの損失なしにクローンステップからビルドやテストのステップにデータを渡すことができます。
Pipelineの構築
Pipelineはフローを規定します。Taskを並列に実行したり、厳格な依存関係を設定したりできます。
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: simple-deploy-pipeline
spec:
workspaces:
- name: shared-data
tasks:
- name: fetch-source
taskRef:
name: git-clone
params:
- name: url
value: $(params.repo-url)
workspaces:
- name: output
workspace: shared-data
- name: verify-source
runAfter: ["fetch-source"]
taskRef:
name: source-check
workspaces:
- name: source
workspace: shared-data
Triggersによる自動化
デバッグのためにパイプラインを手動で実行するのは良いですが、自動化が目標です。Tekton Triggersは3部構成のシステムを使用します。Webhookデータを取得するTriggerBinding、実行を定義するTriggerTemplate、そしてトラフィックをキャッチするEventListenerです。
TriggerTemplate
これはビルドの再利用可能なテンプレートと考えてください。Webhookが届くと、Tektonはこの設計図にコミットIDとリポジトリURLを注入します。
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
name: app-trigger-template
spec:
params:
- name: git-repo-url
- name: git-revision
resourcetemplates:
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: app-run-
spec:
pipelineRef:
name: simple-deploy-pipeline
params:
- name: repo-url
value: $(tt.params.git-repo-url)
workspaces:
- name: shared-data
volumeClaimTemplate:
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
小規模なマイクロサービスでは1Giが標準的ですが、大規模なモノリポジトリの場合は、重いビルド中のディスク圧迫を避けるために、通常は50Giに増やします。
可視化とモニタリング
どのようにして動作を確認するのでしょうか?ここでtknがその価値を発揮します。ビルドが失敗した理由を確認するために、わざわざ一時的なPod名を探し回る必要はありません。
ログのストリーミング
1つのコマンドで最新の実行を確認できます:
tkn pipelinerun list
ビルドをライブで監視するには、logsコマンドを使用します。すべてのコンテナとステップの実行を自動的に追跡します:
tkn pipelinerun logs <name> -f
Dashboard GUI
Taskを視覚的なグラフで確認したい場合は、Tekton Dashboardが複雑なTriggersのデバッグに最適です。
kubectl apply --filename https://storage.googleapis.com/tekton-releases/dashboard/latest/tekton-dashboard-release.yaml
kubectl port-forward svc/tekton-dashboard 9097:9097 -n tekton-pipelines
ブラウザでlocalhost:9097にアクセスしてください。すべてのビルドのクリーンな履歴と、リアルタイムのコンテナログが表示されます。TriggerBindingが特定のGitHubシークレットの受け渡しに失敗している理由を特定する最も速い方法です。
このようにCI/CDを構築することは、ネイティブであるため非常に自然に感じられます。プラットフォームと戦うのではなく、プラットフォームを活用しているのです。ビルドが完了するとPodは消滅します。クラスターはクリーンな状態を保ちます。リソースはアイドリング状態のビルドランナーではなく、ユーザーのために集中させることができます。

