【KubernetesでCI/CD】Tekton Pipelineでビルドからデプロイまでやってみる
はじめに
Tekton PipelineでJGithubからソースを取得して、ビルドしてデプロイするまでを試してみたいと思います。
Tekton Pipelineを簡単な例で動かしてみるのは下記の記事でやってみましたが、今回はもう少し実例に近いような形で動かしてみます。
【KubernetesでCI/CD】Tekton動かしてみる
はじめに 簡単な例を使って、Tekton Pipelineを動かしてみたいと思います。 Tek
また、Tekton Pipelineの基本的な概念も上記の記事で解説しています。
流れと全体像
今回構築するパイプラインは下記のようなイメージになります。
流れとしては、
- Githubからソースを取得
- ソースからイメージをビルド
- イメージをDockerHubにプッシュ
- DockerHubのイメージとGithubからマニフェストを取得
- Kubernetesにデプロイ
となります。
作成するリソースは以下の通りです
- GithubのPipelineResource
- DockerHubのPipelineResource
- ビルドのTask
- デプロイのTask
- ServiceAccount
- Pipeline
- PipelineRun
2つのTaskからなるPipelineを作成しています。
ビルドするソース
今回ビルドするのはGoで書かれたWebサーバになります。内容としては下記のDockerのドキュメントで紹介されているものになります。
Build images
Learn how to build your first Docker image by writing a Dockerfile
リポジトリは下記になります。
GitHub - monda00/go-server
Contribute to monda00/go-server development by creating an account on GitHub.
PipelineResourceの作成
まずはTaskの処理の中でインプットとアウトプットになるGithubとDockerHubのPipelineResourceを作成します。
まずはGithubのPipelineResouceのマニフェストgoserver-source-github.yaml
です。
1apiVersion: tekton.dev/v1alpha1
2kind: PipelineResource
3metadata:
4 name: goserver-source-github
5spec:
6 type: git
7 params:
8 - name: revision
9 value: main
10 - name: url
11 value: https://github.com/monda00/go-server
DockerHubのマニフェストgoserver-image-dockerhub.yaml
です。
1apiVersion: tekton.dev/v1alpha1
2kind: PipelineResource
3metadata:
4 name: goserver-image-dockerhub
5spec:
6 type: image
7 params:
8 - name: url
9 value: monda00/go-server:v0.1 # 自分のリポジトリに変更
それぞれのマニフェストを反映します。
1❯ kubectl apply -f goserver-source-github.yaml
2pipelineresource.tekton.dev/goserver-source-github created
3
4❯ kubectl apply -f goserver-image-dockerhub.yaml
5pipelineresource.tekton.dev/goserver-image-dockerhub created
ビルドのTaskの作成
次にビルドするTaskを作成します。
内容としては、Githubからソースを取得し、kanikoを使ってビルドし、DockerHubにイメージをプッシュしています。
マニフェストbuild-docker-image-from-git-source.yaml
は以下のようになります。
1apiVersion: tekton.dev/v1beta1
2kind: Task
3metadata:
4 name: build-docker-image-from-git-source
5spec:
6 params:
7 - name: pathToDockerFile
8 type: string
9 description: The path to the dockerfile to build
10 default: $(resources.inputs.docker-source.path)/Dockerfile
11 - name: pathToContext
12 type: string
13 description: |
14 The build context used by Kaniko
15 (https://github.com/GoogleContainerTools/kaniko#kaniko-build-contexts)
16 default: $(resources.inputs.docker-source.path)
17 resources:
18 inputs:
19 - name: docker-source
20 type: git
21 outputs:
22 - name: builtImage
23 type: image
24 steps:
25 - name: build-and-push
26 image: gcr.io/kaniko-project/executor
27 env:
28 - name: "DOCKER_CONFIG"
29 value: "/tekton/home/.docker/"
30 command:
31 - /kaniko/executor
32 args:
33 - --dockerfile=$(params.pathToDockerFile)
34 - --destination=$(resources.outputs.builtImage.url)
35 - --context=$(params.pathToContext)
GitHub - GoogleContainerTools/kaniko: Build Container Images In Kubernetes
Build Container Images In Kubernetes. Contribute to GoogleContainerTools/kaniko development by creating an account on GitHub.
マニフェストを反映します。
1❯ kubectl apply -f build-docker-image-from-git-source.yaml
2task.tekton.dev/build-docker-image-from-git-source created
Taskで利用するServiceAccountの作成
ここでTaskの処理の中で利用するServiceAccountを作成します。
まずServiceAccountが利用するSecretを作成しておきます。こちらはDockerHubへアクセスするための情報になります。
1kubectl create secret docker-registry regcred \
2 --docker-server=https://index.docker.io/v1/ \
3 --docker-username=<DockerHubのアカウント名> \
4 --docker-password=<DockerHubのパスワード> \
5 --docker-email=<DockerHubのメールアドレス>
下記のtutorial-service.yaml
からServiceAccountを作成します。
1apiVersion: v1
2kind: ServiceAccount
3metadata:
4 name: tutorial-service
5secrets:
6 - name: regcred
1❯ kubectl apply -f tutorial-service.yaml
2serviceaccount/tutorial-service created
デプロイのTaskの作成
デプロイするTaskを作成します。
内容としては、DockerHubからビルドしたイメージとGithubからマニフェストを取得し、yq
コマンドでマニフェストのタグ名を書き換え、kubectl
でデプロイしています。
マニフェストdeploy-using-kubectl.yaml
は以下のようになります。
1apiVersion: tekton.dev/v1beta1
2kind: Task
3metadata:
4 name: deploy-using-kubectl
5spec:
6 params:
7 - name: path
8 type: string
9 description: Path to the manifest to apply
10 - name: yamlPathToImage
11 type: string
12 description: |
13 The path to the image to replace in the yaml manifest (arg to yq)
14 resources:
15 inputs:
16 - name: source
17 type: git
18 - name: image
19 type: image
20 steps:
21 - name: replace-image
22 image: mikefarah/yq:3.4.1
23 command: ["yq"]
24 args:
25 - "w"
26 - "-i"
27 - "$(params.path)"
28 - "$(params.yamlPathToImage)"
29 - "$(resources.inputs.image.url)"
30 - name: run-kubectl
31 image: lachlanevenson/k8s-kubectl
32 command: ["kubectl"]
33 args:
34 - "apply"
35 - "-f"
36 - "$(params.path)"
マニフェストを反映します。
1❯ kubectl apply -f deploy-using-kubectl.yaml
2task.tekton.dev/deploy-using-kubectl created
ServiceAccountにRoleを付与
デプロイができるように先ほど作成したServiceAccountにRoleを付与します。
1❯ kubectl create clusterrole tutorial-role \
2 --verb=* \
3 --resource=deployments,deployments.apps
4
5clusterrole.rbac.authorization.k8s.io/tutorial-role created
6
7❯ kubectl create clusterrolebinding tutorial-binding \
8 --clusterrole=tutorial-role \
9 --serviceaccount=default:tutorial-service
10
11clusterrolebinding.rbac.authorization.k8s.io/tutorial-binding created
Pipelineの作成
TaskをまとめたPipelineを作成します。
マニフェストtutorial-pipeline.yaml
は下記の通りです。params
で設定した値がTaskの中で利用されています。
1apiVersion: tekton.dev/v1beta1
2kind: Pipeline
3metadata:
4 name: tutorial-pipeline
5spec:
6 resources:
7 - name: source-repo
8 type: git
9 - name: go-server-image
10 type: image
11 tasks:
12 - name: build-go-server
13 taskRef:
14 name: build-docker-image-from-git-source
15 params:
16 - name: pathToDockerFile
17 value: Dockerfile
18 - name: pathToContext
19 value: /workspace/docker-source
20 resources:
21 inputs:
22 - name: docker-source
23 resource: source-repo
24 outputs:
25 - name: builtImage
26 resource: go-server-image
27 - name: deploy-go-server
28 taskRef:
29 name: deploy-using-kubectl
30 resources:
31 inputs:
32 - name: source
33 resource: source-repo
34 - name: image
35 resource: go-server-image
36 from:
37 - build-go-server
38 params:
39 - name: path
40 value: /workspace/source/kubernetes/go-server.yaml
41 - name: yamlPathToImage
42 value: "spec.template.spec.containers[0].image"
マニフェストを反映します。
1❯ kubectl apply -f tutorial-pipeline.yaml
2pipeline.tekton.dev/tutorial-pipeline created
PipelineRunの作成
Pipelineを実行するためのPipelineRunを作成します。
マニフェストtutorial-pipeline-run-1.yaml
は下記になります。リソースの取得場所として利用するPipelineResourceをここで指定しています。
1apiVersion: tekton.dev/v1beta1
2kind: PipelineRun
3metadata:
4 name: tutorial-pipeline-run-1
5spec:
6 serviceAccountName: tutorial-service
7 pipelineRef:
8 name: tutorial-pipeline
9 resources:
10 - name: source-repo
11 resourceRef:
12 name: goserver-source-github
13 - name: go-server-image
14 resourceRef:
15 name: goserver-image-dockerhub
マニフェストを反映します。
1❯ kubectl apply -f tutorial-pipeline-run-1.yaml
2pipelinerun.tekton.dev/tutorial-pipeline-run-1 created
実行したログを確認
下記のコマンドで実行したPipelineのログが確認できます。
1❯ tkn pipelinerun logs tutorial-pipeline-run-1 -f
PipelineRunの詳細も下記で確認できます。
1❯ tkn pipelinerun describe tutorial-pipeline-run-1
2
3Name: tutorial-pipeline-run-1
4Namespace: default
5Pipeline Ref: tutorial-pipeline
6Service Account: tutorial-service
7Timeout: 1h0m0s
8Labels:
9 tekton.dev/pipeline=tutorial-pipeline
10
11🌡️ Status
12
13STARTED DURATION STATUS
1420 minutes ago 1 minute Succeeded
15
16📦 Resources
17
18 NAME RESOURCE REF
19 ∙ source-repo goserver-source-github
20 ∙ go-server-image goserver-image-dockerhub
21
22⚓ Params
23
24 No params
25
26📝 Results
27
28 No results
29
30📂 Workspaces
31
32 No workspaces
33
34🗂 Taskruns
35
36 NAME TASK NAME STARTED DURATION STATUS
37 ∙ tutorial-pipeline-run-1-deploy-go-server-l8df5 deploy-go-server 19 minutes ago 13 seconds Succeeded
38 ∙ tutorial-pipeline-run-1-build-go-server-jxpzd build-go-server 20 minutes ago 1 minute Succeeded
39
40⏭️ Skipped Tasks
41
42 No Skipped Tasks
デプロイしたアプリの確認
Pipelineが成功したらDeploymentとServiceを確認してみます。
1❮ kubectl get deployment
2
3NAME READY UP-TO-DATE AVAILABLE AGE
4go-server 1/1 1 1 6m34s
5
6❯ kubectl get deployment
7
8NAME READY UP-TO-DATE AVAILABLE AGE
9go-server 1/1 1 1 4m3s
動作確認するためにポートフォワードします。
1❯ kubectl port-forward service/go-server 8080:8080
2
3Forwarding from 127.0.0.1:8080 -> 8080
4Forwarding from [::1]:8080 -> 8080
以下のように実行しているアプリを確認できます。
1❯ curl localhost:8080
2Hello, Docker! <3%
参考
- pipeline/tutorial.md at main · tektoncd/pipeline
- Build your Go image | Docker Documentation
- Pull an Image from a Private Registry | Kubernetes
- mikefarah/yq: yq is a portable command-line YAML processor