はじめに
2019年3月に CI/CD の普及とエコシステムの促進を目的に "Continuous Delivery Foundation" が発足されました。
この "Continuous Delivery Foundation" がホストしているプロジェクトは以下の4つですが、Jenkins や Spinnaker を知っている人は多いと思いますが、一番右の "Tekton" について知っている人は少ないと思います。
しかし、Tekton はクラウドプラットフォームに依存しない CI/CD パイプラインの標準化を目指しており、今後注目されるオープンソースのフレームワークであると考えています。
本記事では、Tekton の概要と簡単なパイプラインの設定方法について説明したいと思います。
Tekton 概要
Tekton とは、Kubernetes ネイティブな CI/CD パイプラインを作るオープンソースのフレームワークです。
コンテナを実行ブロックの単位として利用することができることや、Kubernetes で書き慣れたYAMLファイルと同じ書き方で CI/CD パイプラインを定義することができます。
インストール方法
インストール手順は以下のURLに記載されています。
kubectl apply
コマンドの実行前に、ユーザに cluster-admin 権限を付与する必要がありますが、以下のコマンドでインストールすることができます。
$ kubectl apply --filename https://storage.googleapis.com/tekton-releases/latest/release.yaml
上記の release.yaml ファイルでは、カスタムコントローラのデプロイと CRD (Custom Resource Definition) の作成を行なっています。
デプロイが完了すると controller と webhook の2つの Pod が作成されます。
Custom Resource Definition 種別
作成される CRD (Custom Resource Definition) の種別は以下の通りです。
- PipelineResource: Task で利用するインプット/アウトプットを指定するリソース
- Task: 最小の実行単位、複数の Step から構成されたリソース
- TaskRun: Task を実行するためのリソース
- Pipeline: 複数の Task から構成されたリソース
- PipelineRun: Pipeline を実行するためのリソース
Pipeline は、CI/CD パイプラインを定義しており、複数の Task から構成されています。
Task は複数の Step から構成されており、Step では一つのコンテナイメージを利用して処理を実行しています。
以下ではそれぞれの CRD (Custome Resource Definition) について説明をしたいと考えております。
PipelineResource 設定例
Task で利用するインプット/アウトプットを定義します。PipelineResource の設定例は以下の通りです。
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
name: skaffold-git
spec:
type: git
params:
- name: revision
value: master
- name: url
value: https://github.com/GoogleContainerTools/skaffold
- type: インプット/アウトプットのタイプを指定
上記のYAMLファイルは Git をインプットする場合の設定例ですが、2019年5月時点でサポート対象のタイプは以下の通りです。
- Git Resource
- Image Resource: インプット/アウトプットにコンテナレジストリを指定
- Cluster Resource: 他の Kubernetes クラスタへのアプリケーションのデプロイなどに利用
- Storage Resource: ストレージ上のファイル/ディレクトリをインプット/アウトプットに利用。GCS(Google Cloud Storage)のみサポート対象。
Task 設定例
パイプラインを構成するタスクを定義します。Task の設定例は以下の通りですが、複数の Step から構成することも可能です。
apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
name: build-docker-image-from-git-source
spec:
inputs:
resources:
- name: docker-source
type: git
params:
- name: pathToDockerFile
description: The path to the dockerfile to build
default: /workspace/docker-source/Dockerfile
- name: pathToContext
description:
The build context used by Kaniko
(https://github.com/GoogleContainerTools/kaniko#kaniko-build-contexts)
default: /workspace/docker-source
outputs:
resources:
- name: builtImage
type: image
steps:
- name: build-and-push
image: gcr.io/kaniko-project/executor:v0.9.0
# specifying DOCKER_CONFIG is required to allow kaniko to detect docker credential
env:
- name: "DOCKER_CONFIG"
value: "/builder/home/.docker/"
command:
- /kaniko/executor
args:
- --dockerfile=${inputs.params.pathToDockerFile}
- --destination=${outputs.resources.builtImage.url}
- --context=${inputs.params.pathToContext}
- inputs: インプットに必要な PipelineResource とパラメータを指定
- outputs: Task によって作成される PipelineResource を指定
- steps: 実行したいコンテナイメージを指定、コンテナが実行ブロックの単位となります
上記の設定例からも分かるように、Kubernetes のYAMLファイルの書き方に非常に似ており、Kubernetes を利用している開発者がパイプラインの定義も書きやすいようになっています。
TaskRun 設定例
Task を実行するためのリソースです。実行したい Task やインプット/アウトプットとなる PipelineResource を指定します。TaskRun の設定例は以下の通りです。
apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
name: build-docker-image-from-git-source-task-run
spec:
taskRef:
name: build-docker-image-from-git-source
inputs:
resources:
- name: docker-source
resourceRef:
name: skaffold-git
params:
- name: pathToDockerFile
value: Dockerfile
- name: pathToContext
value: /workspace/docker-source/examples/microservices/leeroy-web #configure: may change according to your source
outputs:
resources:
- name: builtImage
resourceRef:
name: skaffold-image-leeroy-web
- taskRef: 実行したい Task を指定
- resources: インプット/アウトプットとなる PipelineResource を指定
また、上記の設定例では記載されておりませんが、Pod などの設定と同様に以下を設定することも可能です。
- serviceAccount: Task を実行するサービスアカウントを指定
- nodeSelector / tolerations / affinity: Pod と同様に Task を実行するノードを制御可能
Pipeline 設定例
パイプラインを定義します。Pipeline の設定例は以下の通りです。
apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
name: tutorial-pipeline
spec:
resources:
- name: source-repo
type: git
- name: web-image
type: image
tasks:
- name: build-skaffold-web
taskRef:
name: build-docker-image-from-git-source
params:
- name: pathToDockerFile
value: Dockerfile
- name: pathToContext
value: /workspace/docker-source/examples/microservices/leeroy-web #configure: may change according to your source
resources:
inputs:
- name: docker-source
resource: source-repo
outputs:
- name: builtImage
resource: web-image
- name: deploy-web
taskRef:
name: deploy-using-kubectl
resources:
inputs:
- name: source
resource: source-repo
- name: image
resource: web-image
from:
- build-skaffold-web
params:
- name: path
value: /workspace/source/examples/microservices/leeroy-web/kubernetes/deployment.yaml #configure: may change according to your source
- name: yqArg
value: "-d1"
- name: yamlPathToImage
value: "spec.template.spec.containers[0].image"
- tasks: 実行する一連の Task を指定
- from: 先行する Task のアウトプットの PipelineResource がある場合に指定
また、上記の設定例には記載されておりませんが、以下の設定によりパイプラインの実行順を制御することもできます。
- runAfter: 別の Task の完了後に実行する場合に指定、アウトプットを連携する必要はない
- retries: Task の実行に失敗した際にリトライしたい場合に指定
PipelineRun 設定例
パイプラインを実行するためのリソースです。実行したい Pipeline やインプット/アウトプットとなる PipelineResource を指定します。PipelineRun の設定例は以下の通りです。
apiVersion: tekton.dev/v1alpha1
kind: PipelineRun
metadata:
name: tutorial-pipeline-run-1
spec:
pipelineRef:
name: tutorial-pipeline
resources:
- name: source-repo
resourceRef:
name: skaffold-git
- name: web-image
resourceRef:
name: skaffold-image-leeroy-web
- pipelineRef: 実行したい Pipeline を指定
- resources: インプット/アウトプットとなる PipelineResource を指定
また、上記の設定例は記載されておりませんが、Pod などの設定と同様に以下を設定することも可能です。
- serviceAccount: Task を実行するサービスアカウントを指定
- nodeSelector / tolerations / affinity: Pod と同様に Task を実行するノードを制御可能
パイプライン実行方法
パイプラインを実行する方法は、これまで説明してきたリソースを以下のコマンドにより作成するだけです。
$ kubectl apply -f <name-of-file.yaml>
実行結果は以下のコマンド例のように確認することができます。
$ kubectl get pipelineruns/tutorial-pipeline-run-1 -o yaml
apiVersion: tekton.dev/v1alpha1
kind: PipelineRun
metadata:
annotations:
creationTimestamp: 2018-12-11T20:30:19Z
generation: 1
name: tutorial-pipeline-run-1
namespace: default
resourceVersion: "6760151"
selfLink: /apis/tekton.dev/v1alpha1/namespaces/default/pipelineruns/tutorial-pipeline-run-1
uid: 93acb0ea-fd83-11e8-9129-42010a8a0fdc
spec:
generation: 1
pipelineRef:
name: tutorial-pipeline
resources:
- name: source-repo
paths: null
resourceRef:
name: skaffold-git
- name: web-image
paths: null
resourceRef:
name: skaffold-image-leeroy-web
serviceAccount: ""
status:
conditions:
- lastTransitionTime: 2018-12-11T20:32:41Z
message: All Tasks have completed executing
reason: Succeeded
status: "True"
type: Succeeded
taskRuns:
tutorial-pipeline-run-1-build-skaffold-web:
conditions:
- lastTransitionTime: 2018-12-11T20:31:41Z
status: "True"
type: Succeeded
podName: tutorial-pipeline-run-1-build-skaffold-web-pod-21ddf0
startTime: 2018-12-11T20:30:19Z
steps:
- terminated:
containerID: docker://c699fcba94....f96108ac9f4db22b94e0c
exitCode: 0
finishedAt: 2018-12-11T20:30:36Z
reason: Completed
startedAt: 2018-12-11T20:30:36Z
- terminated:
containerID: docker://f5f752d....824262ad6ce7675
exitCode: 0
finishedAt: 2018-12-11T20:31:17Z
reason: Completed
startedAt: 2018-12-11T20:30:37Z
tutorial-pipeline-run-1-deploy-web:
conditions:
- lastTransitionTime: 2018-12-11T20:32:41Z
status: "True"
type: Succeeded
podName: tutorial-pipeline-run-1-deploy-web-pod-7a796b
startTime: 2018-12-11T20:32:11Z
steps:
- terminated:
containerID: docker://eaefb7b6d685....f001f895430f71374
exitCode: 0
finishedAt: 2018-12-11T20:32:28Z
reason: Completed
startedAt: 2018-12-11T20:32:28Z
- terminated:
containerID: docker://4cfc6eba47a7a....dcaef1e9b1eee3661b8a85f
exitCode: 0
finishedAt: 2018-12-11T20:32:31Z
reason: Completed
startedAt: 2018-12-11T20:32:31Z
- terminated:
containerID: docker://01b376b92....dce4ccec9641d77
exitCode: 0
finishedAt: 2018-12-11T20:32:35Z
reason: Completed
startedAt: 2018-12-11T20:32:34Z
さいごに
本記事では、Tekton の概要と簡単なパイプラインの設定方法について説明してきました。
また、最後にこっそりネタバレになりますが、本記事は 2019/5/28 に開催された Red Hat Tech Night でLT発表したネタの流用となります。
LTだと時間が短く説明できなかった箇所もあったため、Qiitaに記事を書かせてもらいました。
個人的には、インストールが非常に簡単であり、各リソースのYAMLファイルも非常に読みやすく理解し易かったので、今後も注目が必要なオープンソースのフレームワークであると考えています。