こんにちは、Red Hatでソリューションアーキテクトをしている石川です。
OpenShiftではクラウドネイティブなCI/CDを実現する手段として、OpenShift Pipelines という機能を提供しています。 以前はTech Previewだったのですが、今年の5月にGAとなったため、今回から2回に分けてOpenShift Pipelinesを使ってCI/CDパイプラインを構築する方法についてご紹介していきたいと思います。
OpenShift Pipelinesの概要
OpenShift PipelinesはTektonというOSSがベースになっています。
TektonはLinux Foundationが母体となるContinuous Delivery Foundation(CDF)にて開発が進められているプロジェクトです。元々はKubernetes上でサーバーレスを提供するKnativeの一部として開発されていましたが、現在は独立したプロジェクトとなっており、Kuberenetes上でCI/CDを提供するための様々な機能を提供しています。
Tektonは複数のコンポーネントで構成されており、CI/CDを実施する際に主に利用されるTekton PipelinesやTekton Triggersといったメインのコンポーネントに加え、CLIを提供するTekton CLI、後述するTaskのカタログを提供するTekton Catalogなどがあります。
Tekton Pipelines、Tekton TriggersはそれぞれKubernetesのCRD、Custom Controllerとして実装されています。OpenShiftではOpenShift Pipelines Operatorをインストールすることで簡単にTektonを使い始めることが可能となります。
ユースケース
今回の記事ではTekton Pipelinesについて説明をしていきますが、その前にCI/CDパイプラインのユースケースについて考えてみましょう。 例えば、以下のように開発者が自身の作業用ブランチからメインブランチに対しプルリクエストを行い、それが承認されたタイミング(merge commitが作成されたタイミング)で、アプリケーションの静的診断、コンテナイメージの作成、レジストリへのプッシュなどを自動的に実施するパターンを考えてみます。 本記事ではこのパイプライン作成部分をTekton Pipelinesにて実施したいと思います。
Tekton Pipelinesで登場する概念
Tekton PipelinesではCI/CDで実行したいアクションをTask、Taskの組み合わせや実行順序などをPipelineという形で表現します。 ユースケースの図の例だと、"Git Clone"や"SAST"などが一つ一つのTaskとなり、PipelineではそれらのTaskを参照し、実行順序を定義します。これらのTaskやPipelineはKubernetesのカスタムリソースとして作成します。
Pipelineは、PipelineRunという別のカスタムリソースを作成することにより実行されます。
PipelineRunが作成されると、内部的にはPipelineに含まれる一つ一つのTaskに対しTaskRunというカスタムリソースが作成され、それにより個々のTaskが実行されます。PipelineRunを使う場合は指定した順序でTaskRunが自動で作成されますが、Pipelineの構築時など、ある特定のTaskの動作を確認したい場合などでは、TaskRunを手動で作成し、一つのTaskだけを実行することも可能です。TaskRunが作成されるとTask実行のためのPodが作成され、Taskの中で指定されたコンテナイメージを使って処理を実施していきます。
Pipelineを実行するにはこれらのカスタムリソースを作成する必要があるわけですが、Gitリポジトリからのソースコードのクローンや、コンテナイメージのビルド、など一般的によく使われるようなTaskについては、Tekton CatalogというTaskがまとめられたカタログ集や、Tekton Hubというページで公開されているTaskを使用することが出来ます。 OpenShift Pipelinesではインストールの際にTekton Catalogの一部がClusterTask(クラスタ全体で共通利用可能なTask)として登録されるためそれらをすぐに利用することが出来ます。
Pipelineの作成と実行
本記事ではOpenShiftに登録済みのCluster Taskと、Tekton Catalogで公開されているTaskを使いPipelineを作成していきたいと思います。 Tekton CatalogからTaskをインストールするには利用したいyamlをダウンロードし、CICDを実行するNameSpace上で実行します。今回はアプリケーションの静的診断を行うため、SonarQubeのTaskをインストールします。それ以外はデフォルトのClusterTaskを使用します。
# SonarQube実行のためのyamlの取得 curl https://raw.githubusercontent.com/tektoncd/catalog/main/task/sonarqube-scanner/0.1/sonarqube-scanner.yaml -o sonarqube-scanner.yaml # Taskインストール oc apply -f sonarqube-scanner.yaml # 確認 oc get task --- NAME AGE sonarqube-scanner 4s
続いてPipelineのためのマニフェストファイルを作成していきます。 Pipelineに含むTaskはspec.tasks以下にリスト形式で記述します。
apiVersion: tekton.dev/v1beta1 kind: Pipeline metadata: name: test-pipeline spec: # Task間のデータの受け渡しはworkspaceにて実施 workspaces: - name: shared-workspace - name: sonar-settings # 各Taskで利用されるパラメータを定義 params: - name: url type: string - name: SONAR_HOST_URL type: string - name: SONAR_PROJECT_KEY type: string - name: IMAGE type: string tasks: - name: git-clone # Pipelineで実行するTaskの参照先 taskRef: kind: ClusterTask name: git-clone params: - name: url value: $(params.url) - name: subdirectory value: "" - name: deleteExisting value: "true" workspaces: - name: output workspace: shared-workspace - name: sonarqube-scanner taskRef: name: sonarqube-scanner # あるTaskが実行された後に本Taskが実行されるよう順番を制御 runAfter: - git-clone params: - name: SONAR_HOST_URL value: $(params.SONAR_HOST_URL) - name: SONAR_PROJECT_KEY value: $(params.SONAR_PROJECT_KEY) workspaces: - name: source-dir workspace: shared-workspace - name: sonar-settings workspace: sonar-settings - name: buildah taskRef: kind: ClusterTask name: buildah runAfter: - sonarqube-scanner params: - name: IMAGE value: $(params.IMAGE) workspaces: - name: source workspace: shared-workspace
このマニフェストをoc apply -f test-pipeline.yaml
で適用するとPipelineが作成されます。
OpenShiftのコンソールでは以下のような形で作成したPipelineを確認することが出来ます。
Pipelineを作成することが出来たので、このPipelineを実行してみたいと思います。Pipeline実行に必要なPipelineRunを以下の通り作成します。PipelineRunでは、Pipelineに渡すパラメータの値や、Task間のデータの受け渡しで使用されるWorkspaceのPVC情報などを記載します。
apiVersion: tekton.dev/v1beta1 kind: PipelineRun metadata: generateName: test-run- spec: pipelineRef: name: test-pipeline params: - name: url value: 'https://[git cloneしたいリポジトリのURL]' - name: SONAR_HOST_URL value: 'http://sonarqube:9000' - name: SONAR_PROJECT_KEY value: 'test-project' - name: IMAGE value: '[作成するコンテナイメージ名:タグ名]' workspaces: - name: shared-workspace volumeClaimTemplate: spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi - name: sonar-settings emptyDir: {}
PipelineRunを作成し適用するとPipelineが実行されます。 コンソールからはPipelineの実行状況や、Taskごとのログ情報をリアルタイムに確認することが出来ます。
無事Pipelineが実行され、各Taskが成功していることを確認することが出来ました。
まとめ
本記事ではOpenShift Pipelinesの概要と、Tekton Pipelinesの仕組み、実行方法についてご紹介させて頂きました。
もしOpenShift Pipelinesを自分で触ってみたいという方は、こちらのサイトから簡単にハンズオンを実施することが可能ですので是非やってみて下さい。 さて、実際に開発におけるCI/CDのパイプラインとしてこれらを利用するには、Gitのイベント(pushやPRなど)を契機として、PipelineRunの作成を自動化していく必要があります。この部分を実施するTektonのもう一つのコンポーネント、Tekton Triggersについては次回の記事でご紹介していきたいと思います。