【KubernetesでCI/CD】Tekton Pipelineでビルドからデプロイまでやってみる

2021.11.16
2024.03.24
CI/CD
GoTektonTekton Pipeline

はじめに

Tekton PipelineでJGithubからソースを取得して、ビルドしてデプロイするまでを試してみたいと思います。

Tekton Pipelineを簡単な例で動かしてみるのは下記の記事でやってみましたが、今回はもう少し実例に近いような形で動かしてみます。

【KubernetesでCI/CD】Tekton動かしてみる

【KubernetesでCI/CD】Tekton動かしてみる

はじめに 簡単な例を使って、Tekton Pipelineを動かしてみたいと思います。 Tek

また、Tekton Pipelineの基本的な概念も上記の記事で解説しています。

流れと全体像

今回構築するパイプラインは下記のようなイメージになります。

流れとしては、

  1. Githubからソースを取得
  2. ソースからイメージをビルド
  3. イメージをDockerHubにプッシュ
  4. DockerHubのイメージとGithubからマニフェストを取得
  5. Kubernetesにデプロイ

となります。

作成するリソースは以下の通りです

  • GithubのPipelineResource
  • DockerHubのPipelineResource
  • ビルドのTask
  • デプロイのTask
  • ServiceAccount
  • Pipeline
  • PipelineRun

2つのTaskからなるPipelineを作成しています。

ビルドするソース

今回ビルドするのはGoで書かれたWebサーバになります。内容としては下記のDockerのドキュメントで紹介されているものになります。

Build images

Build images

Learn how to build your first Docker image by writing a Dockerfile

リポジトリは下記になります。

GitHub - monda00/go-server

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です。

DockerHubのリポジトリは自分のものに書き換えてください。
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

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

以下のように実行しているアプリを確認できます。

1curl localhost:8080
2Hello, Docker! <3%

参考

Support

\ この記事が役に立ったと思ったら、サポートお願いします! /

buy me a coffee
Share

Profile

author

Masa

都内のIT企業で働くエンジニア
自分が学んだことをブログでわかりやすく発信していきながらスキルアップを目指していきます!

buy me a coffee