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

はじめに

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

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

【KubernetesでCI/CD】Tekton動かしてみる
はじめに簡単な例を使って、Tekton Pipelineを動かしてみたいと思います。Tektonについては下記を参考にしてください。また、Tekton Pipeline使うまでの準備も紹介しています。本記事では、Tekton Pip...

また、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 your Go image
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です。

apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: goserver-source-github
spec:
  type: git
  params:
    - name: revision
      value: main
    - name: url
      value: https://github.com/monda00/go-server

DockerHubのマニフェストgoserver-image-dockerhub.yamlです。

DockerHubのリポジトリは自分のものに書き換えてください。

apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: goserver-image-dockerhub
spec:
  type: image
  params:
    - name: url
      value: monda00/go-server:v0.1 # 自分のリポジトリに変更

それぞれのマニフェストを反映します。

❯ kubectl apply -f goserver-source-github.yaml
pipelineresource.tekton.dev/goserver-source-github created

❯ kubectl apply -f goserver-image-dockerhub.yaml
pipelineresource.tekton.dev/goserver-image-dockerhub created

ビルドのTaskの作成

次にビルドするTaskを作成します。

内容としては、Githubからソースを取得し、kanikoを使ってビルドし、DockerHubにイメージをプッシュしています。

マニフェストbuild-docker-image-from-git-source.yamlは以下のようになります。

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: build-docker-image-from-git-source
spec:
  params:
    - name: pathToDockerFile
      type: string
      description: The path to the dockerfile to build
      default: $(resources.inputs.docker-source.path)/Dockerfile
    - name: pathToContext
      type: string
      description: |
        The build context used by Kaniko
        (https://github.com/GoogleContainerTools/kaniko#kaniko-build-contexts)
      default: $(resources.inputs.docker-source.path)
  resources:
    inputs:
      - name: docker-source
        type: git
    outputs:
      - name: builtImage
        type: image
  steps:
    - name: build-and-push
      image: gcr.io/kaniko-project/executor
      env:
        - name: "DOCKER_CONFIG"
          value: "/tekton/home/.docker/"
      command:
        - /kaniko/executor
      args:
        - --dockerfile=$(params.pathToDockerFile)
        - --destination=$(resources.outputs.builtImage.url)
        - --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.

マニフェストを反映します。

❯ kubectl apply -f build-docker-image-from-git-source.yaml
task.tekton.dev/build-docker-image-from-git-source created

Taskで利用するServiceAccountの作成

ここでTaskの処理の中で利用するServiceAccountを作成します。

まずServiceAccountが利用するSecretを作成しておきます。こちらはDockerHubへアクセスするための情報になります。

kubectl create secret docker-registry regcred \
                    --docker-server=https://index.docker.io/v1/ \
                    --docker-username=<DockerHubのアカウント名> \
                    --docker-password=<DockerHubのパスワード> \
                    --docker-email=<DockerHubのメールアドレス>

下記のtutorial-service.yamlからServiceAccountを作成します。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: tutorial-service
secrets:
  - name: regcred
❯ kubectl apply -f tutorial-service.yaml
serviceaccount/tutorial-service created

デプロイのTaskの作成

デプロイするTaskを作成します。

内容としては、DockerHubからビルドしたイメージとGithubからマニフェストを取得し、yqコマンドでマニフェストのタグ名を書き換え、kubectlでデプロイしています。

マニフェストdeploy-using-kubectl.yamlは以下のようになります。

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: deploy-using-kubectl
spec:
  params:
    - name: path
      type: string
      description: Path to the manifest to apply
    - name: yamlPathToImage
      type: string
      description: |
        The path to the image to replace in the yaml manifest (arg to yq)
  resources:
    inputs:
      - name: source
        type: git
      - name: image
        type: image
  steps:
    - name: replace-image
      image: mikefarah/yq:3.4.1
      command: ["yq"]
      args:
        - "w"
        - "-i"
        - "$(params.path)"
        - "$(params.yamlPathToImage)"
        - "$(resources.inputs.image.url)"
    - name: run-kubectl
      image: lachlanevenson/k8s-kubectl
      command: ["kubectl"]
      args:
        - "apply"
        - "-f"
        - "$(params.path)"

マニフェストを反映します。

❯ kubectl apply -f deploy-using-kubectl.yaml
task.tekton.dev/deploy-using-kubectl created

ServiceAccountにRoleを付与

デプロイができるように先ほど作成したServiceAccountにRoleを付与します。

❯ kubectl create clusterrole tutorial-role \
               --verb=* \
               --resource=deployments,deployments.apps

clusterrole.rbac.authorization.k8s.io/tutorial-role created

❯ kubectl create clusterrolebinding tutorial-binding \
             --clusterrole=tutorial-role \
             --serviceaccount=default:tutorial-service

clusterrolebinding.rbac.authorization.k8s.io/tutorial-binding created

Pipelineの作成

TaskをまとめたPipelineを作成します。

マニフェストtutorial-pipeline.yamlは下記の通りです。paramsで設定した値がTaskの中で利用されています。

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: tutorial-pipeline
spec:
  resources:
    - name: source-repo
      type: git
    - name: go-server-image
      type: image
  tasks:
    - name: build-go-server
      taskRef:
        name: build-docker-image-from-git-source
      params:
        - name: pathToDockerFile
          value: Dockerfile
        - name: pathToContext
          value: /workspace/docker-source
      resources:
        inputs:
          - name: docker-source
            resource: source-repo
        outputs:
          - name: builtImage
            resource: go-server-image
    - name: deploy-go-server
      taskRef:
        name: deploy-using-kubectl
      resources:
        inputs:
          - name: source
            resource: source-repo
          - name: image
            resource: go-server-image
            from:
              - build-go-server
      params:
        - name: path
          value: /workspace/source/kubernetes/go-server.yaml
        - name: yamlPathToImage
          value: "spec.template.spec.containers[0].image"

マニフェストを反映します。

❯ kubectl apply -f tutorial-pipeline.yaml
pipeline.tekton.dev/tutorial-pipeline created

PipelineRunの作成

Pipelineを実行するためのPipelineRunを作成します。

マニフェストtutorial-pipeline-run-1.yamlは下記になります。リソースの取得場所として利用するPipelineResourceをここで指定しています。

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  name: tutorial-pipeline-run-1
spec:
  serviceAccountName: tutorial-service
  pipelineRef:
    name: tutorial-pipeline
  resources:
    - name: source-repo
      resourceRef:
        name: goserver-source-github
    - name: go-server-image
      resourceRef:
        name: goserver-image-dockerhub

マニフェストを反映します。

❯ kubectl apply -f tutorial-pipeline-run-1.yaml
pipelinerun.tekton.dev/tutorial-pipeline-run-1 created

実行したログを確認

下記のコマンドで実行したPipelineのログが確認できます。

❯ tkn pipelinerun logs tutorial-pipeline-run-1 -f

PipelineRunの詳細も下記で確認できます。

❯ tkn pipelinerun describe tutorial-pipeline-run-1

Name:              tutorial-pipeline-run-1
Namespace:         default
Pipeline Ref:      tutorial-pipeline
Service Account:   tutorial-service
Timeout:           1h0m0s
Labels:
 tekton.dev/pipeline=tutorial-pipeline

🌡️  Status

STARTED          DURATION   STATUS
20 minutes ago   1 minute   Succeeded

📦 Resources

 NAME                RESOURCE REF
 ∙ source-repo       goserver-source-github
 ∙ go-server-image   goserver-image-dockerhub

⚓ Params

 No params

📝 Results

 No results

📂 Workspaces

 No workspaces

🗂  Taskruns

 NAME                                               TASK NAME          STARTED          DURATION     STATUS
 ∙ tutorial-pipeline-run-1-deploy-go-server-l8df5   deploy-go-server   19 minutes ago   13 seconds   Succeeded
 ∙ tutorial-pipeline-run-1-build-go-server-jxpzd    build-go-server    20 minutes ago   1 minute     Succeeded

⏭️  Skipped Tasks

 No Skipped Tasks

デプロイしたアプリの確認

Pipelineが成功したらDeploymentとServiceを確認してみます。

❮ kubectl get deployment

NAME         READY   UP-TO-DATE   AVAILABLE   AGE
go-server    1/1     1            1           6m34s

❯ kubectl get deployment

NAME         READY   UP-TO-DATE   AVAILABLE   AGE
go-server    1/1     1            1           4m3s

動作確認するためにポートフォワードします。

❯ kubectl port-forward service/go-server 8080:8080

Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

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

❯ curl localhost:8080
Hello, Docker! <3%

参考

タイトルとURLをコピーしました