0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Concourse・Harbor・Argo CD・OpenShiftの関係を整理する

0
Posted at

はじめに

CI/CD環境を触っていると、Concourse、Harbor、Argo CD、Red Hat OpenShiftという名前が同じ構成図に登場することがあります。

最初は「すべてデプロイに関係するツールなのでは」と混乱しやすいですが、担当する対象は異なります。

Concourse = 作る
Harbor    = 置く
Argo CD   = 反映する
OpenShift = 動かす

この覚え方は入口として便利です。ただし、HarborからArgo CDを経由してOpenShiftへコンテナイメージが運ばれるわけではありません。

この記事では、4つの役割を「制御の流れ」と「成果物の流れ」に分け、ソースコードの変更からOpenShift上でPodが起動するまでを整理します。

先に全体像

4つの関係を正確に捉えるには、Gitの変更を反映する制御の流れと、コンテナイメージを受け渡す成果物の流れを分けます。

ここで重要なのは、次の2経路です。

経路 流れるもの 主な担当
制御の流れ Gitのコミット、Kubernetesマニフェスト、同期命令 Concourse、Argo CD
成果物の流れ ビルド済みコンテナイメージ Concourse、Harbor、OpenShift

Argo CDが扱う中心はGitにあるデプロイ設定です。OpenShift上のワークロードが、設定に書かれたイメージをHarborから取得します。

4つの役割

Concourseはパイプラインを実行する

Concourseは、JobとResourceを組み合わせて処理を自動化するパイプライン基盤です。CIで利用する場合は、次のような処理を担当します。

ソースコード取得
↓
テスト
↓
ビルド
↓
コンテナイメージ作成
↓
Harborへpush

例えばGitへのpushをきっかけにテストを実行し、成功した場合だけコンテナイメージを作成できます。その後、デプロイ設定用のGitリポジトリにあるイメージ参照も更新できます。

Concourse自体はCI専用ではなく、外部状態をResourceとして扱う汎用的なパイプライン基盤です。OpenShiftへ直接デプロイする構成も作れます。この記事ではCIとCDの責務を分けるため、Concourseはビルドとデプロイ設定の更新までを担当するものとします。

Harborはビルド済み成果物を保管する

Harborは、コンテナイメージなどのOCI Artifactを保存・管理するレジストリです。Docker HubやAmazon ECRと同じ領域を担当します。

例えばConcourseが次のイメージを作成したとします。

harbor.example.com/team/my-app:git-a1b2c3d

ConcourseはイメージをHarborへpushします。OpenShiftでPodを起動するときは、ノード上のコンテナランタイムがHarborから対象イメージをpullします。

Harborは単なるファイル置き場ではありません。プロジェクト単位のアクセス制御、脆弱性スキャン、タグの不変化、署名など、組織で成果物を管理するための機能も持ちます。

Argo CDはGitの状態をクラスタへ同期する

Argo CDはKubernetes向けのGitOps CDツールです。Gitに保存したKubernetesマニフェスト、Kustomize、Helmなどの定義から目標状態を取得し、クラスタ上の実状態と比較します。

例えばGitに次のDeploymentがあるとします。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  template:
    spec:
      containers:
        - name: my-app
          image: harbor.example.com/team/my-app:git-a1b2c3d

Git上のイメージ参照が変わると、Argo CDは目標状態と実状態の差分を検知します。自動同期を有効にしていれば変更をOpenShiftへ反映し、無効なら利用者による同期操作を待ちます。

Argo CDがアプリケーションをビルドしたり、Harborからイメージを取得してOpenShiftへ転送したりするわけではありません。役割は、Gitに書かれた「あるべき状態」とOpenShift上のリソースを一致させることです。

OpenShiftはアプリケーションを実行する

OpenShiftはRed Hatが提供するKubernetesプラットフォームです。Kubernetesを基盤に、認証・権限管理、Webコンソール、ルーティング、監視、Operatorなど、企業利用を支える機能を提供します。

今回の構成では、Argo CDからDeploymentなどの設定が反映され、OpenShift上でPodが起動します。Podの起動に必要なイメージは、設定された参照先に従ってHarborからpullされます。

OpenShiftには統合イメージレジストリもあるため、Harborは必須ではありません。組織共通の外部レジストリとしてHarborを採用している場合に、OpenShiftからHarborを利用する関係になります。

実際のCI/CDの流れ

アプリケーション用Gitとデプロイ設定用Gitを分ける構成では、次のように進みます。2つのGitは論理的な役割であり、必ず別リポジトリにする必要はありません。

  1. 開発者がアプリケーション用Gitへコードをpushする
  2. Concourseが新しいコミットを検知する
  3. Concourseがテストとビルドを実行する
  4. Concourseがコンテナイメージを作成する
  5. Concourseが一意なビルドタグを付けてHarborへpushする
  6. リリース用タグを運用する場合は、承認したArtifactへバージョンタグを追加する
  7. Concourseまたは別の更新処理が、デプロイ設定用Gitのイメージ参照を更新する
  8. Argo CDがGitの変更とOpenShift上の状態との差分を検知する
  9. Argo CDがDeploymentなどをOpenShiftへ同期する
  10. OpenShiftがHarborから指定されたイメージをpullする
  11. 新しいPodが起動し、readiness probeに成功するとトラフィックを受ける

この構成では、ConcourseがOpenShiftのAPIへ直接アクセスする必要はありません。CIはGitへ変更を残し、CDはその変更をArgo CDが反映します。誰が何を変更したかをGitの履歴とレビューで追いやすくなることが、GitOps構成の利点です。

リリース時のタグ付けはどこで行うのか

リリースという単位がある運用では、Harbor上のArtifactへリリース用タグを付ける工程も整理しておくと分かりやすくなります。

ここでは、ビルドを識別するタグと、リリースを表すタグを分けます。

タグの種類 目的
ビルドタグ git-a1b2c3d どのソースコードから作ったかを追跡する
リリースタグ v1.2.3 利用者や運用者がリリース単位を識別する
環境名タグ stagingproduction 現在の昇格先を示す別名として使う

例えば、Concourseはビルド時にgit-a1b2c3dを付けてHarborへpushします。テスト、脆弱性スキャン、承認を通過した後、同じdigestのArtifactへv1.2.3を追加します。

my-app
└── sha256:0123...
    ├── git-a1b2c3d
    └── v1.2.3

Harborでは、同じArtifactへ複数のタグを追加できます。タグを追加してもArtifactのdigestは変わらず、同じビルド成果物をリリースへ昇格できます。リリースのたびにイメージを再ビルドしないため、テストした内容と本番で動かす内容がずれるリスクを減らせます。

タグ付けはHarborの画面でもできますが、通常はConcourseのリリースJobなどから自動化した方が履歴と権限を管理しやすくなります。処理の流れは次のようになります。

ただし、リリース用タグは必須ではありません。ビルドタグをそのままリリース識別子として使う場合や、デプロイ設定をdigestで固定する場合は、OpenShiftへデプロイするためだけにv1.2.3を作る必要はありません。リリース用タグは、人がリリースを識別しやすくすることや、承認済みArtifactを示すことに価値があります。

リリースタグは上書きできないようにする

v1.2.3のようなリリースタグを後から別のArtifactへ付け替えると、同じマニフェストから異なるイメージが起動し得ます。監査やロールバックの基準として使えなくなるため、HarborのTag Immutability Ruleでリリースタグを上書き・削除できないようにします。

一方、stagingproductionのような環境名タグは、昇格に合わせて参照先を変える運用があります。この種の可変タグだけをDeploymentへ書くと、Gitの文字列が変わらずArgo CDが変更を検知できません。環境名タグは補助的な別名として扱い、デプロイ設定では一意なバージョンタグまたはdigestを使う方が追跡しやすくなります。

人が読みやすい一意なリリースタグを使う場合は、次のように指定します。

image: harbor.example.com/team/my-app:v1.2.3

実体を厳密に固定する場合は、digestを指定します。

image: harbor.example.com/team/my-app@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef

Harborでリリースタグを追加しただけでは、Argo CDのデプロイは始まりません。最後にデプロイ設定用Gitのイメージ参照を更新し、その変更をArgo CDに同期させる必要があります。

イメージをHarborへpushしただけではデプロイされない

この構成で特に間違えやすい点です。新しいイメージをHarborへpushしても、Argo CDが監視するGitの内容に差分がなければ、通常は新しいデプロイは始まりません。

例えばDeploymentが常に次を参照しているとします。

image: harbor.example.com/team/my-app:latest

同じlatestタグへ別イメージをpushしても、Git上の文字列は変わりません。Argo CDから見ると目標状態に変更がなく、既存Podも自動では作り直されません。さらに、イメージのpull条件やノードのキャッシュによっては、再起動しても期待するイメージを使わない可能性があります。

変更を追跡しやすくするには、コミットSHAなどから一意なタグを作り、デプロイ設定のイメージ参照を毎回更新します。

image: harbor.example.com/team/my-app:git-a1b2c3d

再現性をさらに高める場合は、タグではなくdigestでイメージを固定します。

image: harbor.example.com/team/my-app@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef

digestを使うと、タグの参照先が後から変更されても同じ内容のイメージを指定できます。どの方法を選んでも、ビルドした成果物とGit上のデプロイ設定を同じ識別子で追えることが重要です。

ConcourseとArgo CDの違い

ConcourseとArgo CDはどちらもCI/CD周辺に登場しますが、判断の基準が異なります。

観点 Concourse Argo CD
主な入力 ソースコード、外部Resource Git上のデプロイ設定
主な処理 テスト、ビルド、成果物の公開 目標状態と実状態の比較・同期
主な出力 コンテナイメージ、Gitコミット Kubernetes/OpenShiftリソース
クラスタへの権限 GitOps構成では不要 同期対象への権限が必要
失敗時に最初に見る場所 Job、Task、Resourceのログ ApplicationのSync・Health状態

Concourseから直接oc applyhelm upgradeを実行する構成も可能です。ただし、その場合はCIパイプラインがクラスタの認証情報を持ち、実際の状態変更まで担当します。

GitOps構成では、Concourseはデプロイ設定のGit更新まで、Argo CDはクラスタへの同期を担当します。この境界によって、ビルド失敗とデプロイ失敗を切り分けやすくなります。

HarborとOpenShiftを接続するときの注意点

Harborがprivate projectの場合、OpenShiftは認証なしではイメージをpullできません。対象NamespaceのServiceAccountへpull secretを関連付けるか、WorkloadのimagePullSecretsで指定します。

spec:
  template:
    spec:
      imagePullSecrets:
        - name: harbor-pull-secret
      containers:
        - name: my-app
          image: harbor.example.com/team/my-app:git-a1b2c3d

接続時には、少なくとも次を確認します。

  • OpenShiftからHarborのホスト名を名前解決できるか
  • OpenShiftのノードからHarborへ通信できるか
  • pull secretの接続先、ユーザー名、権限が正しいか
  • HarborのTLS証明書をOpenShift側が信頼できるか
  • 指定したrepository、tag、digestが実際に存在するか

Argo CDの同期が成功しても、イメージ取得まで成功したとは限りません。Deploymentの作成は成功しても、PodがImagePullBackOffになることがあります。同期結果とPodの起動結果は分けて確認します。

反映されないときの確認順序

問題が起きたら、ツール名から推測するのではなく、処理の境界を上流から確認します。

1. Concourseで成果物が作られたか

  • 手順: 対象ビルドのJobとTaskの結果、出力したタグまたはdigestを確認します。
  • 理由: テスト成功とイメージpush成功は別の処理だからです。
  • 確認: Harborに同じタグまたはdigestのArtifactが存在します。
  • 異常時: build処理、registry-image Resource、Harborへのpush権限を確認します。

2. デプロイ設定用Gitが更新されたか

  • 手順: 対象環境のマニフェスト、Helm values、Kustomize定義の差分を確認します。
  • 理由: Harborへのpushだけでは、Argo CDの目標状態は変わらないからです。
  • 確認: Gitに新しいイメージ参照のコミットがあり、対象branchへ反映されています。
  • 異常時: 更新Jobのログ、push権限、branch protection、Pull Requestの状態を確認します。

3. Argo CDが正しいGitを見ているか

  • 手順: Applicationのrepository URL、path、target revision、Sync状態を確認します。
  • 理由: 別branchや別環境のpathを監視していると、正しいコミットでも反映されないからです。
  • 確認: Argo CDが期待するrevisionを読み、Syncedになっています。
  • 異常時: refresh、差分、同期エラー、対象Namespaceへの権限を確認します。

4. OpenShiftがイメージを取得してPodを起動できたか

  • 手順: Deploymentのイメージ参照、Podの状態、Eventを確認します。
  • 理由: マニフェストの同期成功とコンテナ起動成功は別だからです。
  • 確認: 新しいReplicaSetのPodがRunningかつReadyになっています。
  • 異常時: ImagePullBackOffならpull secret、TLS証明書、ネットワーク、tagやdigestの存在を確認します。CrashLoopBackOffならアプリケーションのログと起動設定を確認します。

4製品は固定のセットではない

この4製品は一緒に使えますが、互いを必須とする固定セットではありません。

  • Concourseの代わりにGitHub Actions、GitLab CI/CD、Jenkinsなどを使えます。
  • Harborの代わりにOpenShiftの統合レジストリ、Amazon ECR、Google Artifact Registryなどを使えます。
  • Argo CDを使わず、Concourseから直接OpenShiftへデプロイする構成も作れます。
  • OpenShiftではなく、ほかのKubernetes環境をArgo CDの同期先にできます。

そのため、製品名を覚えるよりも「誰がビルドするか」「成果物をどこに置くか」「誰が目標状態を反映するか」「どこで実行するか」という責務で構成を読む方が応用できます。

まとめ

Concourse、Harbor、Argo CD、OpenShiftは、同じCI/CDの流れに登場しても担当する対象が異なります。

Concourse = 作る
Harbor    = 置く
Argo CD   = 反映する
OpenShift = 動かす

より正確には、Concourseが作ったイメージをHarborへpushし、OpenShiftがHarborからpullします。Argo CDは、その間でイメージを運ぶのではなく、Git上のデプロイ設定をOpenShiftへ同期します。

構成を読むときは、次の4つを順番に確認します。

  1. 誰がテストとビルドを実行するのか
  2. ビルド済み成果物をどこへ保存するのか
  3. 誰がデプロイ設定をクラスタへ反映するのか
  4. アプリケーションはどこで実行されるのか

この分け方ができると、反映されないときもConcourse、Git、Argo CD、OpenShift、Harborのどこで流れが止まったかを追いやすくなります。

参考資料

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?