[Tekton Pipelines] Tekton Pipelineのパイプライン機能を使ってみよう

Tekton Pipelinesは、Kuernetes上で実行するCI/CD形式のパイプラインツールです。Kubernetes Nativeなオープンソースとして開発されています。 TektonはThe Continuous Delivery Foundation(CDF)のプロジェクトとして採用されています。

前回の記事では、Tekton PipelinesのインストールとTaskの実行例を紹介しました。本記事では複数のTaskを組み合わせて実行順番を制御するPipelineの実行例を紹介します。

対象読者

  • Kubernetes-nativeなCI/CDツールを探している人
  • Cloud Delivery Foundation(CDF)に興味がある人
  • Cloud Nativeの思想に興味がある人

もくじ

  1. 検証環境
  2. 検証前の準備
  3. 検証のながれ
  4. PipelineResourceの定義
  5. Taskの定義
  6. Pipelineの定義
  7. Docker Hub認証情報の作成
  8. ServiceAccountの定義
  9. PipelineRunの定義
  10. Pipelineの実行
  11. 実行結果の確認
  12. さいごに

検証環境

GKE環境で検証を行いました。検証に利用したKubernetesのクライアントおよびサーバのバージョンは以下の通りです。

$ kubectl version --short
Client Version: v1.14.1
Server Version: v1.12.8-gke.10

検証前の準備

以降の実行例は、Kubernetesクラスタ上にTekton Pipelinesがインストール済みの環境で実行しています。Kubernetesクラスタの構築とTekton Pipelinesのインストール方法は、前回の記事を参照してください。

検証のながれ

今回の実行例では、以下の処理を行います。

  1. Git Hubからアプリケーションソースをクローン
  2. アプリケーションソースを含めたDockerイメージをビルド
  3. 作成したDockerイメージをプッシュ
  4. 作成したDockerイメージをKubernetes上にデプロイ

1.~3.の処理は、前回の記事で作成したマニフェストファイルを利用します。処理の詳細は前回の記事を参照してください。

PipelineResourceの定義

Git HubのリポジトリおよびDocker Hubのレジストリを指定したPipelineResourceを定義します。

前回の記事と同じファイルを利用します。ファイル内容の説明は、前回の記事を参照してください。

# gitResource.yaml
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: easydoggie-git
  namespace: default
spec:
  type: git
  params:
    - name: url
      value: https://github.com/sumomo-99/TektonSample.git
    - name: revision
      value: master
# imageResource.yaml
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: easydoggie-test-image
  namespace: default
spec:
  type: image
  params:
    - name: url
      value: easydoggie/testapp

Taskの定義

処理の流れに従ってTaskを定義します。

1.~3.の処理は、前回の記事で作成したTaskを利用します。

  1. Git Hubからアプリケーションソースをクローン
  2. アプリケーションソースを含めたDockerイメージをビルド
  3. 作成したDockerイメージをプッシュ
# task.yaml
apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
  name: test-doker-image
spec:
  inputs:
    resources:
      - name: app
        type: git
    params:
      - name: dockerfile
        default: /workspace/app/Dockerfile
      - name: context
        default: /workspace/app
  outputs:
    resources:
      - name: builtImage
        type: image
  steps:
    - name: build-and-push
      image: gcr.io/kaniko-project/executor
      command:
        - /kaniko/executor
      args:
        - --dockerfile=${inputs.params.dockerfile}
        - --destination=${outputs.resources.builtImage.url}
        - --context=${inputs.params.context}

今回は追加で4.のTaskを作成します。

  1. 作成したDockerイメージをKubernetes上にデプロイ
# task1.yaml
apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
  name: test-deploy
spec:
  inputs:
    resources:
      - name: source
        type: git
      - name: image
        type: image
    params:
      - name: manifestPath
      - name: yqArg
      - name: yamlPathToImage
  steps:
    - name: replace-image
      image: mikefarah/yq
      command: ["yq"]
      args:
        - w
        - -i
        - ${inputs.params.yqArg}
        - ${inputs.params.manifestPath}
        - ${inputs.params.yamlPathToImage}
        - ${inputs.resources.image.url}
    - name: run-kubectl
      image: bitnami/kubectl
      command: ["kubectl"]
      args:
        - apply
        - -f
        - ${inputs.params.manifestPath}

このTaskでは、はじめにビルドしたイメージのタグでマニフェストファイルの書き換えを行います。マニフェストファイル(yaml)の書き換えに、Yamlのコマンドラインパースツールであるyqを利用します。-iオプション(in-place)を利用することで、マニフェストファイルを直接に書き換えを行っています。
次に、書き換えを行ったマニフェストファイルをkubectl applyコマンドで適用することで、Kubernetesへのデプロイを行っています。

Pipelineの定義

Taskをまとめて順番を制御するPipelineを作成します。

# pipeline.yaml
apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
  name: test-pipeline
spec:
  resources:
    - name: gitSource
      type: git
    - name: dockerImage
      type: image
  tasks:
    - name: build-image
      taskRef:
        name: test-doker-image
      resources:
        inputs:
          - name: app
            resource: gitSource
        outputs:
          - name: builtImage
            resource: dockerImage
    - name: deploy-kubernetes
      taskRef:
        name: test-deploy
      resources:
        inputs:
          - name: source
            resource: gitSource
          - name: image
            resource: dockerImage
            from:
              - build-image
      params:
        - name: manifestPath
          value: /workspace/source/deployment.yaml
        - name: yqArg
          value: "-d0"
        - name: yamlPathToImage
          value: "spec.template.spec.containers[0].image"

後続TaskのInputに先行TaskのOutputを渡したい場合は、fromフィールドを利用することで、受け渡しを行うことができます。上記のPipelineの例では、先行Taskで作成したビルドイメージのリソース情報を後続TaskのInputに引き渡しています。

  - name: image
    resource: dockerImage
    from: # fromフィールドで先行TaskのOutputを渡す
      - build-image

先行TaskのOutputとの紐づけが必要ない場合は、fromの代わりにrunAfterフィールドを利用します。またTaskの実行に失敗した場合の再実行回数をretriesフィールドで指定することができます。

フィールド名 説明
from 先行TaskのOutputをInputに利用する後続Taskに設定する
runAfter 先行TaskのOutputとの紐づけが必要ない後続Taskに設定する
retries Taskの実行に失敗したときの再実行回数

paramsにはTaskに引き渡すパラメータを指定します。用意したマニフェストファイルの配置場所やimageの指定位置に従って、設定を書き換えてください。

  params:
    - name: manifestPath #Gitからcloneされたマニフェストファイルのパス
      value: /workspace/source/deployment.yaml
    - name: yqArg #yqコマンドのオプション。マニフェストファイルに複数のリソースを設定している場合は、書き換えるリソースの位置を変えてください。0が基準でデフォルトは0です。
      value: "-d0"
    - name: yamlPathToImage #マニフェストファイル(yaml)のコンテナイメージのパス
      value: "spec.template.spec.containers[0].image"

今回の実行例では、以下のようなマニフェストファイルを用意しました。

#deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: testapp-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: easydoggie
  template:
    metadata:
      labels:
        app: easydoggie
    spec:
      containers:
      - name: testapp
        image: easydoggie/testapp:latest
        ports:
        - containerPort: 80

Taskが実行されることで、easydoggie/testapp:latestのイメージ名の書き換えが行われます。

Docker Hub認証情報の作成

Docker Hubへイメージをプッシュするために、Docker Hubの認証情報をKubernetesのSecretに定義します。

前回の記事と同じファイルを利用します。ファイル内容の説明は、前回の記事を参照してください。

# secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: basic-user-pass
  annotations:
    tekton.dev/docker-0: https://index.docker.io/v1/
type: kubernetes.io/basic-auth
stringData:
  username: <username>
  password: <password>

ServiceAccountの定義

パイプラインを実行するアカウント(build-bot)を作成します。先ほど作成したSecretsを紐づけておきます。

# serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: build-bot
secrets:
  - name: basic-user-pass

このアカウントでKunernetesにデプロイを実行するので、cluster-adminの権限を与えておきます。

# buildAccount.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: build-cluster-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: build-bot
  namespace: default

PipelineRunの定義

PipelineRunでPipelineResourcesとして定義したリソースをPipelineのInputとOutputに紐づけます。

# pipelinerun.yaml
apiVersion: tekton.dev/v1alpha1
kind: PipelineRun
metadata:
  name: test-pipelinerun
spec:
  serviceAccount: build-bot
  pipelineRef:
    name: test-pipeline
  resources:
    - name: gitSource
      resourceRef:
        name: easydoggie-git
    - name: dockerImage
      resourceRef:
        name: easydoggie-test-image

Pipelineの実行

以上ですべてのKubernetesマニフェストファイルの準備ができました。マニフェストファイルをkubectl applyコマンドで適用してみましょう。

$ kubectl apply -f gitResource.yaml -f imageResource.yaml -f task.yaml -f task1.yaml -f secret.yaml -f serviceaccount.yaml -f buildAccount.yaml -f pipeline.yaml -f pipelinerun.yaml
pipelineresource.tekton.dev/easydoggie-git created
pipelineresource.tekton.dev/easydoggie-test-image created
task.tekton.dev/test-doker-image created
task.tekton.dev/test-deploy created
secret/basic-user-pass created
serviceaccount/build-bot created
pipeline.tekton.dev/test-pipeline created
pipelinerun.tekton.dev/test-pipelinerun created

実行結果の確認

$ kubectl get pods
NAME                                                  READY   STATUS      RESTARTS   AGE
test-pipelinerun-build-image-9d5r5-pod-84ab40         0/3     Completed   0          43s
test-pipelinerun-deploy-kubernetes-q2jfj-pod-4456e7   0/3     Completed   0          16s
testapp-deployment-cdcf6bdb8-5b2s9                    1/1     Running     0          10s

パイプラインに設定した2つのタスクが実行され、デプロイされたコンテナが起動しました!
PipelineRunの実行結果は、以下のコマンドで確認することができます。

※PipelineRunの名前は(下記の例ではtest-pipelinesrun)、確認するリソースに合わせて変更してください。

$ kubectl get pipelineruns/test-pipelinerun -o yaml

タスクごとの実行時間やエラーの発生個所を調べる場合などに利用できます。

さいごに

本記事ではKubernetes-nativeなCI/CDツールである、Tekton Pipelinesのパイプラインの実行例を紹介しました。前回紹介したTaskの実行例を理解できれば、今回のパイプラインの仕組みは簡単に理解できたのではないでしょうか。
前回および今回の記事はCLIでタスク、パイプラインの実行と確認を行いました。次回はTektonのWebベースUIである、Tekton Dashboardの紹介を行う予定です。

スカイアーチ ファンタジー研究室

スカイアーチ ファンタジー研究室

EasyDoggie

投稿者プロフィール

石川 淳
スカイアーチネットワークスで、新しいサービスの企画を行っています。
元SIer、元スマフォ向けゲームインフラの経験を生かして、新しいサービスをリリースしていきます。現在企画中のサービスはこちら。
https://github.com/easydoggie
コメントを頂けると嬉しいです。

ABOUTこの記事をかいた人

スカイアーチネットワークスで、新しいサービスの企画を行っています。 元SIer、元スマフォ向けゲームインフラの経験を生かして、新しいサービスをリリースしていきます。現在企画中のサービスはこちら。 https://github.com/easydoggie コメントを頂けると嬉しいです。