tekton pipelineの概要と触ってみた感想！（プライベートリポジトリからのPullを題材に）

OpenStandia 事業部のumanetesといいます。今回アドベントカレンダーとしてKubernetesを中心として、CICDを実現するOSSであるTektonについて調べましたので書いてみます。


## Tektonとは

> Tekton（テクトン）は、元々Knativeのプロジェクトの一部として始まり、現在はTekton PiplinesとしてCDF（Continuous Delivery Foundation）というCI/CD（継続的インテグレーションと継続的デリバリー）を標準化する組織で開発が行われているツールの一つです。
TektonはCI/CDシステムを作成するための強力かつ柔軟なKubernetesネイティブのオープンソースフレームワークです。基盤となる実装の詳細を抽象化することにより、複数のクラウドプロバイダーまたはオンプレミスシステムを横断してビルド、テスト、デプロイができます。
(引用: https://openstandia.jp/oss_info/tekton/)

Kubernetesを前提としたオープンソースのCICDフレームワークであり、他のCICDのフレームワークとは異なり、Kubernetes上に展開しているため、AWSやGCP、Azureなど場所を選ばないこと、またgithubやgitlabなどバージョン管理システムにも依存しないことがメリットかと思います。
個人的なポイントとしては、**設定と実行環境情報の分離**かと思います

## 特徴
Tektonは主に4種類のコンポーネントからなります
- Pipeline: cicdを構成する基本的な要素
- Trigger: cicdをキックするイベントトリガ
- CLI: CICD Workflowを管理するCLI
- Dashboard: パイプラインとかを可視化するダッシュボード

とくに重要なPipelineコンポーネントは、Step,Task,Pipelineのリソースに分割され、それぞれを実行するTaskRun、PipelineRunリソースが存在します。

Step: CICDのワークフローで指定するコマンド
Task: 順番に実行されるStepのかたまり。Taskで利用するシークレット情報やアーティファクトの管理などをここで設定できる
Pipelilne: Taskのかたまり。taskの依存関係などを定義できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142319/a1348dba-3eb3-be1e-b4b2-be09b6e6eb51.png)
(引用: https://tekton.dev/docs/concepts/)

このTaskリソースと、PipelineリソースはKubernetesのカスタムリソースとして作成され、マニフェストによる宣言的管理がされます。
そして重要な**設定と実行環境情報の分離**を実現するのは、この作成されたリソースを実行するTaskRunリソースとPipelineRunリソースになります。
TaskRunとPipelineRunは実行環境情報を入れることができます。例えば、開発環境用のImage　RegistoryにImageをPushしたい場合と本番環境用にPushしたいときは、このPushするところを環境変数化しておいて、それぞれPipeline　RunやTaskRunリソースでその値を入れるといった感じになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142319/fb14d0f8-96a0-98ef-44b6-e6991f9095cd.png)
(引用: https://tekton.dev/docs/concepts/)

## 触ってみる
まずはこのコマンドでTektonをKubernetesにインストールする

```
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
```

タスクを定義。今回はGitからPullするタスクをTektonHubから流用します。
https://hub.tekton.dev/tekton/task/git-clone

```
$ tkn hub install task git-clone --version 0.5
```
```bash
$ tkn task list
NAME        DESCRIPTION              AGE
git-clone   These Tasks are Git...   6 days ago
``` 

github のプライベートリポジトリからCloneするには認証情報を取得する必要があるので、そのSecretと対応するServiceAccountを事前に作っておきます  

```yaml
apiVersion: v1
kind: Secret
metadata:
  name: ssh-key
  annotations:
    tekton.dev/git-0: github.com
type: kubernetes.io/ssh-auth
data:
  ssh-privatekey: <githubに登録した公開鍵に対する秘密鍵>
  known_hosts: <githubの公開鍵>
  config: <sshするときの設定>

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: tekton-admin
secrets:
  - name: ssh-key
```
そしてTaskRunを定義してGitCloneを走らせます。Taskの定義と実行情報の設定（今回だとSecret情報）が分離されています。

```yaml
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  generateName: git-clone-run-
spec:
  serviceAccountName: tekton-admin
  taskRef:
    name: git-clone
  workspaces:
    - name: output
      persistentVolumeClaim:
        claimName: example
    - name: ssh-directory
      secret:
        secretName: ssh-key
  params:
    - name: url
      value: git@github.com:<GITHUB_USERNAME>/<GITHUB_REPONAME>.git
    - name: revision
      value: main
```

```
[clone] + '[' false '=' true ]
[clone] + '[' true '=' true ]
[clone] + cp -R /workspace/ssh-directory /tekton/home/.ssh
[clone] + chmod 700 /tekton/home/.ssh
[clone] + chmod -R 400 /tekton/home/.ssh/config /tekton/home/.ssh/id_my-ssh-credential /tekton/home/.ssh/id_ssh-key /tekton/home/.ssh/known_hosts /tekton/home/.ssh/ssh-directory
[clone] + '[' false '=' true ]
[clone] + CHECKOUT_DIR=/workspace/output/
[clone] + '[' true '=' true ]
[clone] + cleandir
[clone] + '[' -d /workspace/output/ ]
[clone] + rm -rf /workspace/output//LICENSE /workspace/output//README.md /workspace/output//argo /workspace/output//deploy /workspace/output//sample /workspace/output//tekton
[clone] + rm -rf /workspace/output//.git /workspace/output//.gitignore
[clone] + rm -rf '/workspace/output//..?*'
[clone] + test -z 
[clone] + test -z 
[clone] + test -z 
[clone] + /ko-app/git-init '-url=git@github.com:<YOUR_GITHUB_REPO>.git' '-revision=main' '-refspec=' '-path=/workspace/output/' '-sslVerify=true' '-submodules=true' '-depth=1' '-sparseCheckoutDirectories='
[clone] {"level":"info","ts":1638700453.298347,"caller":"git/git.go:169","msg":"Successfully cloned git@github.com:<YOUR_GITHUB_REPO>.git @ xxxxxxxxxxxxxxxxxxxxxxxx (grafted, HEAD, origin/main) in path /workspace/output/"}
[clone] {"level":"info","ts":1638700453.323792,"caller":"git/git.go:207","msg":"Successfully initialized and updated submodules in path /workspace/output/"}
[clone] + cd /workspace/output/
[clone] + git rev-parse HEAD
[clone] + RESULT_SHA=
[clone] + EXIT_CODE=0
[clone] + '[' 0 '!=' 0 ]
[clone] + printf '%s' 
[clone] + printf '%s' git@github.com:<YOUR_GITHUB_REPO>.git
```



## CICDツールのとの比較
Tektonが強みを発揮できるのは、Taskの再利用性にメリットがあるのではと思っています。
サービスと環境ごとにパイプラインを持つケースもしくは、パイプラインの実行条件を書いて複雑なパイプラインにしているケースが多いと思っています。Tekton Triggerなどで複雑なパイプラインを環境毎で生成するPipelineRunリソースを作成し、すべて外部のパラメータで利用することで処理の記載の量を減らすことができると思います。SREチームどの横断的な組織がTaskとパイプラインを定義して、アプリチームがPipeline Runを作成してあげるようにするのが良いのかなとおもいます。

一方Tektonにも弱みがあり、Tekton用のKubernetesのリソースの管理などをしないといけなくなることが最大のポイントかなと思います。GitHubActionやCircleCIなどはSaaSとして使用する場合がほとんどで管理することはないというのがとても便利です。

## 感想
Tektonはパイプライン設計を共通チームで管理したいときに使用できるのかなと思います。0からパイプラインを作成することは結構大変だと思うので、共通チームがある程度パイプラインを作成してあげることで、生産性は向上するのかなと思いました。 
しかしTektonのリソースの管理なども求められ、GitHubActionなどのSaaSを前提としているものがCICDツールには多く、この管理負荷を超えるメリットを得られるような使い方はまだないのかなと感じています
またTektonにはTektonTriggerなどのリソースも残っているので今後調査してみたいと考えます。