TEKTONとArgoを比較してみた
はじめに
この記事は NTTコミュニケーションズ Advent Calendar 2020の24日目の記事です。
Kubernetesで、CI/CDツールを選定するときに選択肢が多すぎて、何を選定したらいいかわからない!!
多くの担当者が抱えているあるあるだと思います。
ある程度トレンドを抑え、導入する環境の要件に相応しいCI/CDを選定していきたいものです。
その中でも、TEKTONとArgoが有名なCI/CDツールである。ということは何となくわかっていますが、
よくよく違いについてあまり理解していなかったので、調査してきました。
実はプロジェクトのこと
TEKTONとArgoをCI/CDツールと思っている人は少なくないと思いますが、
実は、プロジェクトであるということです。
実際、我々がTEKTONとArgoと省略して呼んでいるのはどうやら、大抵は以下のことを指していることが多いです。
- TEKTON = TEKTON Pipeline
- Argo = Argo CD
TEKTONとは
TektonはGoogleのKnativeのプロジェクトにいたが、
現在、CD FOUNDATIONのプロジェクトとして位置しているということです。
代表されるプロジェクトとしては以下のグループがあります。
グループ | 説明 |
---|---|
Pipelines | CI/CDのパイプラインを構成する。Tektonと言ったらこれを指すと言ってもよい、コアな機能といえる。 |
Triggers | GithubやGitlabなどからリクエストを受け取って、Tektonパイプラインを動作させるためのWEBサービス |
CLI | TektonPipelines用のCLIを提供 |
Dashboard | TektonPipelinesのWEB-UIを提供 |
これらのグループを一式提供するoperatorも開発が進められているようです!
Argoとは
Argoは Cloud Native Computing Foundationのプロジェクトとして位置しているということです。
代表されるプロジェクトとしては以下のグループがあります。
グループ | 説明 |
---|---|
Argo Workflow | CI/CDのパイプラインを構成する。 |
Argo CD | CD機能を提供する。Gitリポジトリの変更検知を行い、helm/kustomizeなどにも対応している。Argoといえばこの機能を指すといってもよい |
Argo Rollouts | Blue/Greenデプロイ カナリアリリースなどのデプロイを実現でき、デプロイ分析も行うことができる。 |
Argo Events | 様々なイベント(webhookなど)を受け取り、トリガーするためのWEBサービス |
Gitopsを考えると
さきほど説明したグループを使って、TEKTONとArgoのそれぞれでGitopsをすることを考えてみます。
Applicatonリポジトリへのソースをcommitし、Build/PushするCIと、
Applicatonリポジトリへの変更を契機に、kubernetesマニフェストをデプロイするCDを想定すると、
以下のような区分けができそうです。
TEKTONでCD機能を実装することはあまり有用ではないかもしれない
TEKTONはパイプラインとトリガーの機能しか備わっていないため、CDをしようとなるとTektonPipelinesのパイプライン内で実現しなくてはなりません。
またTEKTONは、ArgoCDのような差分検知は難しく、デプロイ手法や分析も乏しいです。
実際に、TEKTON pipelinesとArgoCDを併用することもできるため、CDの手段にはArgoCDを使うのが良さそうです。
TEKTONとArgoでは被っていそうなグループもある
図をみてみると、役割としては以下が役割として被っていそうです。
- TEKTON pipelineとArgoWorkflow
- TEKTON TriggerとArgoEvents
被ってそうなところを見てみる
TEKTON pipelineとArgoWorkflow
CIのパイプライン部分を司る役割ではどちらも同じ機能と言えそうです。
実際の概念をそれぞれ確認してみます。
TEKTON pipeline
主なコンポーネント
TEKTONのパイプラインにおける、主なコンポーネントは以下のような感じです。
用語 | 説明 |
---|---|
Step | 実行処理の最小単位。Task内に記載する。 |
Task | Stepの集合体。CRDで定義されている。 |
Pipeline | TASKの集合体。並列もしくは直列にTaskを設定できる。CRDで定義されている。 |
TaskRun | Taskの実行インスタンス。CRDで定義されている。 |
PipelineRun | Pipelineの実行インスタンス。CRDで定義されている。 |
PipelineResource | Pipelineが参照するアーティファクトの定義。CRDで定義されている。 |
それぞれの実行単位がこんな感じで定義できるのがわかると思います。
Pipeline > Task > Step
また、それらを実行するためのインスタンス定義としてこうある感じでしょうか。
PipelineRun > TaskRun
Kubernetesの概念と非常に近しいから、コンセプトが非常にわかりやすい!!
Task ≒ Pods
Step ≒ Container
という概念であり、Step/TASKを組み立ててパイプラインを立てていくというイメージが湧きやすいです。
Pipeline/Taskの作成したyamlサンプルとしてはこんな感じで、以下を確認することができると思います。
- pipelineにTaskが書かれていること
- PipelineRunから呼び出すためのパラメータ類が定義されていること
- TaskにStepが書かれており、複数のステップを記載できること。(sampleでは1つしか記載していない)
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: build-and-deploy-pipeline
spec:
workspaces:
- name: git-source
description: The git repo
# パラメータセクション 実行時に PipelineRun から変数を与える。
params:
- name: gitUrl
description: Git repository url
- name: gitRevision
description: Git revision to check out
default: master
- name: pathToContext
description: The path to the build context, used by Kaniko - within the workspace
default: src
- name: imageUrl
description: Image name including repository
- name: imageTag
description: Image tag
default: "latest"
- name: GIT_USER_NAME
type: string
description: |
Git user name for performing git operation.
default: ""
- name: GIT_USER_EMAIL
type: string
description: |
Git user email for performing git operation.
default: ""
- name: GIT_SCRIPT
description: The git script to run.
type: string
default: |
git help
tasks:
# タスク #1
# GitHubからソースコードをワークスペースにクローン(取得)する
- name: clone-repo
taskRef:
name: git-clone
workspaces:
- name: output
workspace: git-source
params:
- name: url
value: "$(params.gitUrl)"
- name: revision
value: "$(params.gitRevision)"
- name: subdirectory
value: "."
- name: deleteExisting
value: "true"
# タスク #2
# コンテナのビルドとレジストリへ登録 Kanikoタスクにパラメータを渡してビルド実行、イメージをレジストリへ登録
- name: source-to-image
taskRef:
name: kaniko
runAfter:
- clone-repo
workspaces:
- name: source
workspace: git-source
params:
- name: CONTEXT
value: $(params.pathToContext)
- name: IMAGE
value: $(params.imageUrl):$(params.imageTag)
# タスク #3
# Gitのクローンし、Imageタグを置換、新しいブランチを作成し、GithubへPushする。
- name: git-etc
taskRef:
name: git-cli
runAfter:
- source-to-image
workspaces:
- name: source
workspace: git-source
- name: input
workspace: git-source
params:
- name: GIT_USER_NAME
value: $(params.GIT_USER_NAME)
- name: GIT_USER_EMAIL
value: $(params.GIT_USER_EMAIL)
- name: GIT_SCRIPT
value: $(params.GIT_SCRIPT)
Taskのyaml(タスク #3)としてはこんな感じ
※TEKTONでは、Tekton catalogからTaskのyamlを収集できるのが良い!!
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: git-cli
labels:
app.kubernetes.io/version: "0.1"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/tags: git
tekton.dev/displayName: "git cli"
spec:
description: >-
This task can be used to perform git operations.
Git command that needs to be run can be passed as a script to
the task.This task needs authentication to git in order to push
after the git operation.
workspaces:
- name: source
description: A workspace that contains the fetched git repository.
- name: input
description: A workspace that contains file that needs to be added to git.
params:
- name: BASE_IMAGE
description: |
The base image for the task.
type: string
default: alpine/git:latest
- name: GIT_USER_NAME
type: string
description: |
Git user name for performing git operation.
default: ""
- name: GIT_USER_EMAIL
type: string
description: |
Git user email for performing git operation.
default: ""
- name: GIT_SCRIPT
description: The git script to run.
type: string
default: |
git help
results:
- name: commit
description: The precise commit SHA after the git operation.
steps:
- name: git
image: $(params.BASE_IMAGE)
workingDir: $(workspaces.source.path)
script: |
# Setting up the config for the git.
git config --global user.email "$(params.GIT_USER_EMAIL)"
git config --global user.name "$(params.GIT_USER_NAME)"
$(params.GIT_SCRIPT)
RESULT_SHA="$(git rev-parse HEAD | tr -d '\n')"
EXIT_CODE="$?"
if [ "$EXIT_CODE" != 0 ]
then
exit $EXIT_CODE
fi
# Make sure we don't add a trailing newline to the result!
echo -n "$RESULT_SHA" > $(results.commit.path)
図にするとこんな感じ
PipelineRunの実行時に異なる実行パラメータを与えることで、PipelineがTemplateとして機能することがわかります。
ArgoWorkflow
主なコンポーネント
ArgoWorkflowは主なコンポーネントはこんな感じ。
用語 | 説明 |
---|---|
workflow | 1つ以上のテンプレートの実行を定義する。CRDで定義される |
workflow template | workflowを再利用するための定義。CRDで定義される。 |
Steps/Step | workflowでの実行最小単位 およびそれを束ねたList |
DAG(Directed Acyclic Graph) | Stepと同レベルの実行単位。Stepと違い、依存関係を定義し、複雑なワークフローを実施できる |
TEKTONと違い、workflowリソースのみを定義していくいこととなります。
それぞれの実行単位がこんな感じで定義できます。
workflow > Step or DAG
作成したサンプルのWorkflowのyaml例としてはこんな感じで、以下を確認することができると思います。
- workflowのyaml内にStepが全て定義されていること
template配下の部分は、CRDで定義されている workflow templateで外出しし、
再利用することもできるようです。
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
name: sample-workflow
namespace: sample-workflow
generateName: sample-workflow-
spec:
# select main path
entrypoint: main
# work-dir temp PVC
volumeClaimTemplates: # define volume, same syntax as k8s Pod spec
- metadata:
name: workdir # name of volume claim
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi # Gi => 1024 * 1024 * 1024
# select mount secrets or exsistence volume
volumes:
- name: git-aaa-secrets
secret:
secretName: git-aaa-secrets
defaultMode: 256
- name: git-bbb-secrets
secret:
secretName: git-bbb-secrets
defaultMode: 256
# main process
templates:
- name: main
steps:
# clone aaa-argo-source
- - name: git-clone-aaa
template: git-clone
arguments:
parameters: [{name: git-name, value: aaa}]
# clone bbb-argo-manifests
- - name: git-clone-bbb
template: git-clone
arguments:
parameters: [{name: git-name, value: bbb}]
# git-clone template
- name: git-clone
inputs:
parameters:
- name: git-name
container:
image: alpine/git
command: ["/bin/sh","-c"]
args:
- >
git clone git@github.com:sample-git/argo-{{inputs.parameters.git-name}}.git /tmp/{{inputs.parameters.git-name}}
volumeMounts:
- name: workdir
mountPath: /tmp/
図にするとこんな感じ
(公式サイト引用:https://argoproj.github.io/argo/architecture/)
作り方に違いがありそう
インテグレーション方法として、イメージするなら、Tektonは実行タスクごとに部品を作っていき中からPipelineを組み立てるような作り方で、Argoはworkflow単位で外側から組み立てていくような作り方です。
ただ実際、どちらもTemplate化することはできるので、作りやすさに違いはないだろうと言えます。
そのほかの比較
そのほか、主要な機能について比較して纏めてみましたが、大きな違いはなさそうです。
機能 | 説明 | Tekton pipelines | Argo workflow |
---|---|---|---|
Template機能 | 再利用可能な部品 | ○(Task/pipelines) | ○(workflow template) |
Cron機能 | 定期実行可能なワークフロー | ○ | ○ |
リトライ指定 | ワークフローに対するリトライ | ○ | ○ |
DAG | 有向非巡回グラフ的順序の設定 | ○ | ○ |
Prometheus | Prometheusでメトリックスが取得できるか | △(実験的) | ○ |
kubernetesCluster-Version | 求められるK8sクラスタのバージョン | ver1.15~ | 指定無し |
TEKTONTriggerとArgoEvents
どちらも役割としては同じ、Gitなどをcommit/pushしたあとのWebhookを受け取る、トリガーとなる役割を司るようです。
TEKTON Trigger
TEKTON TRIGGERの基本的なコンポーネントは以下となるようです。
コンポーネント | 説明 |
---|---|
EventListener | 外部からのイベントを定義するコンポーネント |
TriggerBinding | イベント/トリガーに対してバインドするコンポーネント |
TriggerTemplate | 実際にトリガーするTriggerのコンポーネント(TektonPipelinesのPipelineなどをトリガーする) |
ArgoEvents
ArgoEventsの基本的なコンポーネントは以下となるようです。
コンポーネント | 説明 |
---|---|
Event Source | 外部からのイベントを定義するコンポーネント |
Sensor | イベント入力とトリガー出力の依存関係を定義 |
Trigger | センサーによって実行されるリソース/ワークロード |
機能比較
これらの機能は、入力と出力の指定種類が機能の違いだと思うので、羅列して整理してみます。
入力
TEKTON
TEKTONではインセプターを利用して指定ができるようです。
- Webhookインターセプター
- GitHubインターセプター
- GitLabインターセプター
- Bitbucketインターセプター
- CELインターセプター
Argo
- AMQP
- AWS SNS
- AWS SQS
- Cron Schedules
- GCP PubSub
- GitHub
- GitLab
- HDFS
- File Based Events
- Kafka
- Minio
- NATS
- MQTT
- K8s Resources
- Slack
- NetApp StorageGrid
- Webhooks
- Stripe
- NSQ
- Emitter
- Redis
- Azure Events Hub
出力
TEKTON
- TEKTON pipelines
Argo
- Argo Workflows
- Standard K8s Objects
- HTTP Requests / Serverless Workloads (OpenFaas, Kubeless, KNative etc.)
- AWS Lambda
- NATS Messages
- Kafka Messages
- Slack Notifications
- Argo Rollouts
- Custom Trigger / Build Your Own Trigger
- Apache OpenWhisk
上記から、ArgoEventsは豊富なOutを用意しているのに対し、
TEKTON triggerはTEKTON pipelinesだけで使用する設計となっているようです。
まとめ
Pipelines機能に大きな違いはないものの、Trigger機能を実装する場合は、
以下のような掛け合わせはできないとわかります。
- TEKTON Trigger --- Argoworkflow
- ArgoEvents --- TEKTON pipelines
大きな違いは、やはりCD機能(ArgoCD,ArgoRollout)の有無であると言えます。
TEKTON pipelinesで実装するには限界があるので、高度なCDを実現する場合は、ArgoCD、ArgoRolloutを併用して使ってみるのが良いと思います。
最後に
疑問、質問、ご指摘などがあればコメントなどでぜひお願いいたします。
それでは、NTTコミュニケーションズ Advent Calendar 2020の24日目の記事はここまでとさせていただきます。
Discussion