Tektonでパイプラインを動かす


Tektonをさわってみた のつづき

簡単なパイプラインをくんで動かしてみた。

作るもの

Goで作ったシンプルなWebサーバのアプリ。8080ポートでListenしてて、アクセスするとホスト名を返してくれるだけのやつ。

これを、githubからpullしてきて、ビルドしてイメージ化してpushするだけのシンプルなパイプラインを作る。

以下の通り、ソースコードとパイプライン含め、githubに配置している。

https://github.com/grugrut/go-web-hello

タスクを作る

パイプラインは、複数のタスクを順番に実行していくものなので、パイプラインの前にタスクを作る必要がある。

もちろんタスクを前回のように、自分で定義するのもよいが、TektonではCatalogというリポジトリに いろいろな人が作ったTaskが公開されているので、これを使うのが簡単。

https://github.com/tektoncd/catalog/

この中から、githubからソースコードを取得するのに git-clone 、 goのビルドをするのに golang-build 、コンテナイメージを作成してDockerHubにpushするのに buildah を利用してみた。

パイプラインを定義する

パイプラインも他のリソースと同様に、yamlで定義する。

apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: go-web-hello-pipeline
spec:
  workspaces:
    - name: shared-data
  tasks:
    - name: fetch-repo
      taskRef:
        name: git-clone
      workspaces:
        - name: output
          workspace: shared-data
      params:
        - name: url
          value: https://github.com/grugrut/go-web-hello.git
    - name: build
      taskRef:
        name: golang-build
      runAfter:
        - fetch-repo
      params:
        - name: package
          value: github.com/grugrut/go-web-hello
        - name: packages
          value: ./...
      workspaces:
        - name: source
          workspace: shared-data
    - name: docker-build
      taskRef:
        name: buildah
      runAfter:
        - build
      params:
        - name: IMAGE
          value: grugrut/go-web-hello
      workspaces:
        - name: source
          workspace: shared-data

パイプラインのspecには大きくふたつの定義をおこなう。

  • workspaces 各タスクでの作業領域。同じ名前のワークスペースを使うことでタスク間で中間成果物を受け渡すことができる。 実体としては、Podにvolumeがマウントされる。具体的なvolumeの定義は実行時におこなう。
  • tasks 具体的なタスク群を記載していく。 今回は3つのタスクを実行するが、具体的な定義内容は以下の通り。

GitHubからソースコードをクローン

- name: fetch-repo
  taskRef:
    name: git-clone
  workspaces:
    - name: output
      workspace: shared-data
  params:
    - name: url
      value: https://github.com/grugrut/go-web-hello.git

git-clone タスクを利用した。outputのワークスペースにソースコードをcloneして、次のタスクに渡すことができる。 今回はリポジトリのurlしか指定していないが、ブランチ名を指定することなどももちろんできる。

Goのソースをビルド

- name: build
  taskRef:
    name: golang-build
  runAfter:
    - fetch-repo
  params:
    - name: package
      value: github.com/grugrut/go-web-hello
    - name: packages
      value: ./...
  workspaces:
    - name: source
      workspace: shared-data

golang-build タスクを利用した。sourceのワークスペースに対して、 go build -v $(packages) をしてくれる。 また、ソースコードのcloneがおこなわれてから実行されるように、 runAfterで指定している。 これがないと並列にタスクが実行されてしまい、うまくいかないはず。

昔に、Jenkinsでgoのビルドをしたことがある(http://grugrut.hatenablog.jp/entry/2017/04/10/201607)が、 GOPATH のあつかいが面倒で、withEnvとか駆使しないといけなかった。 Tektonの場合、それぞれのタスクごとにPodがわかれていて、 GOPATH も設定ずみのところにソースが配置されるように あらかじめ設定されているので、まったく気にすることなくビルドできて便利だと思った。

コンテナイメージのビルドとPush

- name: docker-build
  taskRef:
    name: buildah
  runAfter:
    - build
  params:
    - name: IMAGE
      value: grugrut/go-web-hello
  workspaces:
    - name: source
      workspace: shared-data

buildah タスクを利用した。何も指定しないと、workspace直下のDockerfileでビルドして、 イメージ名にもとづき、イメージのpushまでをおこなってくれる。

そのため、たとえばDockerHubのような認証が必要な場合は、事前に認証情報を作成しておく。

kubectl create secret generic basic-user-pass --type kubernetes.io/basic-auth --from-literal username=user --from-literal password=pass
kubectl annotate secrets basic-user-pass tekton.dev/docker-0=https://docker.io

tekton.dev/docker-0 のアノテーションをつけておくことで、docker pushするときの認証として使われるようになる。

あとは、これがパイプラインが動作する際に利用されるように、ServiceAccountを作成しておく。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: build-bot
secrets:
  - name: basic-user-pass

パイプラインを実行する

パイプラインを実行する場合は、 PipelineRun のリソースを作成する。またこの際に実行するパイプラインの情報をいろいろとつける。

cat <<EOF | kubectl create -f -
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  generateName: go-web-hello-pipeline-
spec:
  pipelineRef:
    name: go-web-hello-pipeline
  serviceAccountName: build-bot
  workspaces:
    - name: shared-data
      volumeClaimTemplate:
        spec:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 1Gi
          storageClassName: nfs-client
EOF

今回はgenerateNameを使っているので、 apply ではなく、 create していることに注意。 PipelineRunでは、どのパイプラインを実行するかとserviceAccountとworkspaceとして利用するvolumeの情報を書いている。

パイプラインの結果を見る

パイプラインのタスクはPodとして動くが、 tkn コマンドでよりわかりやすく見ることができる。

  • パイプラインの実行結果の一覧を見る

    tkn pipelinerun list

    $ tkn pr list
    NAME                              STARTED       DURATION     STATUS
    go-web-hello-pipeline-c9dhn       3 hours ago   59 seconds   Succeeded
    go-web-hello-pipeline-xx5qb       1 day ago     55 seconds   Failed
    
  • パイプラインの実行結果の詳細を見る

    tkn pipelinerun describe xxxx

    $ tkn pr describe go-web-hello-pipeline-c9dhn
    Name:              go-web-hello-pipeline-c9dhn
    Namespace:         default
    Pipeline Ref:      go-web-hello-pipeline
    Service Account:   build-bot
    
    ??  Status
    
    STARTED       DURATION     STATUS
    3 hours ago   59 seconds   Succeeded
    
    ? Resources
    
     No resources
    
    ? Params
    
     No params
    
    ?  Taskruns
    
     NAME                                               TASK NAME      STARTED       DURATION     STATUS
     ・ go-web-hello-pipeline-c9dhn-docker-build-mpht6   docker-build   3 hours ago   40 seconds   Succeeded
     ・ go-web-hello-pipeline-c9dhn-build-x72xl          build          3 hours ago   11 seconds   Succeeded
     ・ go-web-hello-pipeline-c9dhn-fetch-repo-nmkx7     fetch-repo     3 hours ago   8 seconds    Succeeded
    
  • パイプラインの実行時のログを見る(-f オプションをつけることで実行中でも見れる)

    tkn pipeline log xxxxx

まとめ

Tektonを使ってパイプラインを実行することができた。CI/CDというには、実行のトリガーのところとか、デプロイのところができてないので、 次はそのへんを見ていく予定。(コンテナイメージもlatestタグになってて、超微妙だし。。。)


See also

comments powered by Disqus