検索
連載

「Argo CD」で実装するKubernetesの「GitOps」――基本と原則、実践時の考慮ポイントCloud Nativeチートシート(7)

Kubernetesやクラウドネイティブをより便利に利用する技術やツールの概要、使い方を凝縮して紹介する連載。今回は、「Argo CD」によるクラウドネイティブなCD(継続的デリバリー)「GitOps」について解説します。

Share
Tweet
LINE
Hatena

 Kubernetesやクラウドネイティブをより便利に利用する技術やツールの概要、使い方を凝縮して紹介する本連載「Cloud Nativeチートシート」。前回、前々回とクラウドネイティブにおけるCI/CD(継続的インテグレーション/継続的デリバリー)について説明してきましたが、今回はCDにフォーカスします。

 クラウドネイティブにおけるCI/CDの概要については『「Kubernetes Native」なCI/CDとは何か――クラウドネイティブ時代に至る歴史、主要ツール、パイプラインとフローの在り方』、CIについては「GitLabによるCI実践入門――Kubernetesで利用するコンテナイメージをビルドする」をご覧ください。

 本稿では、上記のCI/CDの概要で説明したクラウドネイティブなCD「GitOps」の詳細、および「Argo CD」によるGitOpsの実装方法、GitOpsの原則、実践ポイントを説明します。

「GitOps」とは?

 GitOpsは、2017年にWeaveworksが提唱した開発手法です。GitOpsを使うと、「Git」とKubernetesクラスタで実行されているものとの差分を検出できます。違いがある場合は、クラスタの状態を自動的に更新またはロールバックすることで常にGitとKubernetes環境を同期し続けることができます。

 また、GitをCDのベースとすることで、Gitのマージ/プルリクエストといったなじみのある開発方法でKubernetesにデプロイできます。

 GitOpsでは、デプロイをCDツール、ビルド部分をCIツールが担い、CIとCDの責務を分離します。


GitOps

 従来のCDと比較したGitOpsの特徴については、本連載の前々回記事で説明しているので、興味がある方は参考にしてください。

GitOpsベースのCDツール「Argo CD」の6つの特徴

 Argo CDは「Kubernetes Native」なGitOpsベースのCDツールです。Kubernetesと組み合わせて便利に使えます。どう便利なのかを見ていきましょう。

1. Kubernetesに気軽にインストールして使える

 Argo CDは、Kubernetesに「Helm」やYAMLでデプロイして簡単に使い始めることができます。また、オープンソースソフトウェア(OSS)で提供されているので、ライセンスの購入などを気にする必要もありません。

2. Gitリポジトリをサポート

 KubernetesマニフェストをGitリポジトリで管理している方も多いと思いますが、Argo CDはGitリポジトリをサポートしています。「GitHub」「GitLab」、自分で立てたGitリポジトリサーバなどのGitリポジトリを利用できます。

3. WebのUIとコマンドライン(CLI)を提供

 WebのUIを備え、アプリケーションのデプロイを直感的に定義できます。また、GUI上でデプロイされたリソースの確認や、リポジトリの定義情報とKubernetesクラスタ上のリソースの差分も分かりやすく確認できます。また、コマンドラインのCLIも利用できます。

4. YAMLでデプロイを記述でき、Gitリポジトリで管理できる

 WebブラウザやコマンドラインのCLIは、使い始めたときは便利ですが、デプロイ情報を本格的に管理したい場合には向きません。「Kubernetes Native」なツールなだけあり、YAMLファイルでデプロイ情報を記述してGitリポジトリなどでデプロイ情報を管理できます。

5. KustomizeやHelmと連携可能

 「Kustomize」やHelmのようなマニフェスト管理ツールとの連携機能を標準で備えています。

6. 変更検出によるデプロイではなく差分検出によるデプロイ

 リポジトリへの変更をトリガーにデプロイをするだけではなく、リポジトリで定義されたYAMLファイルとKubernetesにデプロイされているリソースの差分を検出してデプロイできます。Kubernetesを運用していると、誰かが勝手にKubernetes上のリソースを変更してしまうことがありますが、そのような場合の環境修復にも役に立ちます。

コラム Argo CD 2.0の新機能

 なお、2021年4月7日にリリースされたArgo CD 2.0からは、下記の機能が追加され、個別にリリースされています。これらは、それぞれ追加でインストールする必要があります。

Argo CD Notifications

 これまで、デプロイ完了などのイベントを通知するためには、各サービスに通知ジョブを実装した上で「Resource Hooks」の仕組みを利用してJobを起動する必要がありました。2.0からは、「Notifications」機能で簡単に通知できるようになりました。電子メール、「Slack」、GitHubなどのサービスに対応している他、任意のWebhookに対して通知を送ることもできます。

Argo CD ApplicationSet

 Argo CDでは「Application」というカスタムリソースでデプロイ設定を定義し、「Deployment」や「Service」などのマニフェスト群をまとめて管理します。

 「ApplicationSet」はApplicationのテンプレートに対して複数のパラメーターを適用し、自動的にApplicationを生成する機能です。同じApplicationを複数のクラスタに展開したい場合や、大量のApplicationを管理する場合に便利です。

Argo CD Image Updater

 「Image Updater」はArgo CDで管理されているKubernetesのコンテナイメージレジストリを監視し、クラスタ上のワークロードのイメージを自動的に更新する機能です。コンテナリポジトリ内のコンテナイメージのバージョンをトラッキングし、対象の選別を自動化してデプロイできます。従来はコンテナイメージを変更した後にマニフェストの内容を更新する必要がありましたが、その作業を自動化します。

 Argo Projectの実験的プロジェクトargoproj-labsのプロジェクトの一つです。


 なおArgo CDは「Argo Project」のプロダクトの一つです。Argo Projectでは、Argo CDの他にワークフローエンジンの「Argo Workflows」やイベント駆動フレームワークの「Argo Events」なども提供しています。

Argo CDの仕組み


Argo CDの概要

 Applicationリソースは、デプロイの単位ごと(アプリケーションやサービスなどまとまったデプロイ対象ごと)に作成します。WebブラウザやCLIで作成できる他、YAMLファイルを定義して、クラスタに「kubectl apply」で適用することもできます。Applicationリソースの定義には、下記のようにデプロイ設定を記述します。

  • 対象のマニフェスト群が管理されているGitリポジトリの情報
  • デプロイ先のクラスタの情報
  • マニフェスト管理ツール(Kustomize、Helmなど)の情報
  • Gitリポジトリ上のマニフェストの差分を検出するときの挙動

 Applicationリソースに定義された情報を基に、Argo CDのコンポーネントの一つである「Application Controller」がデプロイを管理します。Application Controllerはその名の通り、Kubernetesのコントローラーとして実装されており、クラスタ上のデプロイされたリソースの状態とGitリポジトリ上のマニフェストの内容を監視します。Gitリポジトリ上のマニフェストが更新された場合や、クラスタ上のリソースが直接変更された場合などに差分を検出し、変更内容の同期(デプロイ)などをします。

 Argo CDにはApplicationリソースの他、複数のApplicationをグルーピングする「AppProject」というカスタムリソースも存在します。AppProjectは、Argo CDをマルチテナントで使用する際にテナントごとにApplicationを管理するケースなどで役に立ちます。

 本稿では詳しく紹介しないので、詳細は「Declarative Setup - Argo CD - Declarative GitOps CD for Kubernetes」をご覧ください。

Argo CDの利用環境(サンプル)の概要

 ここからは、Argo CD v2(執筆時点ではv2.0.4)によるCD実装を説明します。プライベートリポジトリのGitLabからデプロイマニフェストを取得し、Kubernetesクラスタにデプロイするサンプルを例に紹介します。

 本稿で利用するArgo CDの概要は下記の通りです。


Argo CD利用環境の概要

 Kubernetesクラスタ上にArgo CDをインストールし、デプロイメントをApplicationリソースとして定義すると、Applicationリソースの定義を基に、リソースごとに定義されたアプリケーションがデプロイされます。

 本稿では、「kubectl port-forward」でポートフォワードした操作端末の「8080」ポートを利用してArgo CDに接続します。Argo CDへの接続には、Webブラウザ(GUI)やArgo CDのCLIを利用します。

 Serviceリソースのロードバランサーや「Ingress」が利用できる場合は、ポートフォワードを利用する代わりにArgo CDを外部公開しても構いません。その場合は、Argo CDのCLIやWebブラウザ(GUI)で指定するURL「https://localhost:8080」を適宜読み替えてください。

事前準備

 Argo CDでの実装の前に下記を準備してください。

対象 説明 動作確認で利用した環境
Kubernetesクラスタ 「Docker Desktop」「kind」「Minikube」などのローカル環境やクラウドのマネージドサービス環境におけるKubernetesクラスタ Minikube v1.20.0(Kubernetes 1.20.2)
Amazon Elastic Kubernetes Service(EKS) 1.20
Gitリポジトリ アプリケーションコードやデプロイマニフェストを管理するGitリポジトリ GitLab
コンテナレジストリ コンテナイメージを格納するレジストリ dockerhub

リポジトリのフォーク

 Argo CDを利用する次の準備として、本稿で利用したサンプルプロジェクト「https://gitlab.com/cloudnativetips/cd-sample」をフォークします。

 フォークの仕方については、GitLabにログインし、上記URLにアクセスして、「フォーク(Fork)」ボタンを押します。フォークの仕方については、前回記事で記載しているので、参考にしてください。

 ここでは、フォークしたリポジトリを、「https://gitlab.com/myusername/cd-sample」とします。適宜ご自身でフォークしたリポジトリ名に読み替えてください。

ツールのインストール

 作業するには、下記のツールをインストールします。

ツール 説明 動作確認で利用したバージョン(2021年7月時点)
kubectl Kubernetesクラスタに接続するためのツール v1.21.1
Helm Argo CDなどのパッケージをKubernetesにインストールするためのパッケージマネジャーツール v3.6.0
argocdコマンド Argo CDをCLIで操作するツール v2.0.4

・kubectl

 Kubernetesの各種操作には、kubectlを操作PCにインストールします。

 Windowsを使っている方は、「https://storage.googleapis.com/kubernetes-release/release/v1.21.0/bin/windows/amd64/kubectl.exe」からダウンロードします。その後、「kubectl.exe」を環境変数「PATH」に記載されたパスに配置してください。

 環境変数PATHの設定方法については@IT記事「Windows 10でPath環境変数を設定/編集する」などをご覧ください。

 Kubernetesクラスタにアクセスするために、「kubeconfig」を設定しておく必要があります。kubeconfigの設定の取得方法については、アクセスするクラスタの手順に従ってください。

 Windowsの場合は、「%USERPROFILE%\.kube\config」にkubeconfigの設定をコピーします(「%USERPROFILE%」はログインしているユーザーのホームフォルダ、例えば「C:\Users\MyUserName」など)。LinuxやmacOSの場合は、「~/.kube/config」にコピーします。

・Helm

 パッケージマネジャーツールとして、Helmを操作PCにインストールします。

 「Releases · helm/helm · GitHub」からダウンロードします。例えば、操作端末がWindowsの場合は、「https://get.helm.sh/helm-v3.6.0-windows-amd64.zip」をダウンロードし、zipファイルを展開します。その後、展開したディレクトリにある「helm.exe」を環境変数PATHに記載されたパスに配置してください。

・argocdコマンド

 Argo CDをCLIから操作するために、argocdコマンドを操作PCにインストールします。

 「Releases · argoproj/argo-cd · GitHub」からダウンロードします。例えば、操作端末がWindowsの場合は、「argocd-windows-amd64.exe」をダウンロードし、ダウンロードしたバイナリを「argocd.exe」にリネームした上で、環境変数PATHに記載されたパスに配置してください。

Argo CDのインストール

 Argo CDのインストールには、Argo CDプロジェクトで提供されているマニフェストを直接デプロイする方法と、Helmチャートを用いる方法の2つがあります。マニフェストを利用する方法は、常に最新版のArgo CDをインストールするので、本稿では、読者が利用するバージョンと本稿で利用したバージョンを合わせるためにHelmを利用する方法を紹介します。

 Argo CDのマニフェストをデプロイする方法に興味がある方は、Argo CDの公式ドキュメントをご覧ください。

# Argo CDのリポジトリを追加
$ helm repo add argo https://argoproj.github.io/argo-helm
"argo" has been added to your repositories
 
# Argo CD(CHART VERSION: 3.6.11、APP VERSION: 2.0.4)をインストール
$ helm install argo-cd --namespace argocd --create-namespace argo/argo-cd --version 3.6.11
NAME: argo-cd
LAST DEPLOYED: Sun Jul  4 21:15:42 2021
NAMESPACE: argocd
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
 
.. 以降省略 ...
 
# インストールされたArgo CDのバージョンを確認
$ helm list -n argocd
NAME   	NAMESPACE	REVISION	UPDATED                             	STATUS  	CHART         	APP VERSION
argo-cd	argocd   	1       	2021-07-04 21:15:42.506517 +0900 JST	deployed	argo-cd-3.6.11	2.0.4
# Argo CDの起動を確認
$ kubectl get pods -n argocd
NAME                                                     READY   STATUS    RESTARTS   AGE
argo-cd-argocd-application-controller-5b96497cc6-5lftp   1/1     Running   0          2m19s
argo-cd-argocd-dex-server-69b5c69c9-2nn2z                1/1     Running   0          2m19s
argo-cd-argocd-redis-5f4b885579-gmc9b                    1/1     Running   0          2m19s
argo-cd-argocd-repo-server-56456f8bcd-pmt8w              1/1     Running   0          2m19s
argo-cd-argocd-server-698bbfbd6b-w4f7x                   1/1     Running   0          2m19s

Argo CDにアクセスするためのプロキシ作成

 インストールした直後のArgo CDには、「Load Balancer」やIngressのようなKubernetesクラスタ外からアクセスする手段が提供されていません。上述したように、ここでは、ポートフォワードを利用して、Argo CDにアクセスします。環境によっては、IngressやServiceのロードバランサーを利用して簡単に外部からアクセスできるようにしても構いません。その場合は、適宜、アクセスURLの「https://localhost:8080」を読み替えてください。

 Argo CDにポートフォワードしてアクセスするためにポートフォワード用のターミナルを起動し、操作PCで下記のコマンドを実行します。

$ kubectl port-forward service/argo-cd-argocd-server -n argocd 8080:443
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

 もし、エラーメッセージが表示された場合は、操作PCで8080ポートを利用した他のプロセスがないかどうかを確認してください。

 このターミナルはポートフォワード用なので、Argo CDアクセス時はターミナルを閉じたり、コマンドを停止したりしないでください。

Argo CDのログインと初期パスワードリセット

 Argo CDにアクセスできるようになったら、インストール時に設定された初期パスワードをリセットします。

 先ほどkubectl port-forwardコマンドを実行したターミナルとは別ターミナルで下記のコマンドを実行し、Argo CDにアクセスするための初期パスワードを取得します。

$ kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo
ZGPHIhNPnXWfoaWd  # 本稿における初期パスワード

 続いて、下記のコマンドを実行してCLIからArgo CDにログインします。アクセス先には、port-forwardで設定したポートを利用します。「Username」は「admin」です。

$ argocd login localhost:8080
WARNING: server certificate had error: x509: certificate signed by unknown authority. Proceed insecurely (y/n)? y
Username: admin
Password: // 上記で取得したパスワードを入力
'admin:login' logged in successfully
Context 'localhost:8080' updated

 ログインが成功したら、下記のコマンドでArgo CDの初期パスワードをリセットしましょう。

$ argocd account update-password
*** Enter current password:  // 上記で取得したパスワードを入力
*** Enter new password:  // 新しいパスワード
*** Confirm new password:  // 新しいパスワード
Password updated
Context 'localhost:8080' updated

 これで、Argo CDにアクセスする初期パスワードのリセットが完了しました。

Argo CDへのアクセス

 Argo CDにアクセスしてみましょう(上記でkubectlを使ってポートフォワードしている状態を前提としています)。ブラウザで「http://localhost:8080」にアクセスします。


ログイン画面

 「username」には「admin」を、「password」には先ほどリセットしたパスワードを入力し「SIGN IN」をクリックしましょう。下記の画面が表示されたらログイン成功です。


ログイン成功画面

サンプルアプリケーションの概要

 今回のサンプルアプリケーションはKubernetesの「Example」として用意されている「wordpress」を使用します。サンプルアプリケーションで使用するコンテナイメージ、マニフェストは下記の通りです。

イメージ名 タグ名 マニフェストファイルのURL
mysql 5.6 https://gitlab.com/cloudnativetips/cd-sample/-/blob/main/wordpress/base/mysql.yaml
wordpress 4.8-apache https://gitlab.com/cloudnativetips/cd-sample/-/blob/main/wordpress/base/wordpress.yaml

 今回のサンプルでは、複数環境(「prod」環境、「staging」環境、「dev」環境)へのデプロイを想定しています。複数環境を利用する場合、環境共通の設定と環境個別のカスタマイズ設定を分けて管理するKustomizeを利用すると便利です。本サンプルでも、Kustomizeを利用しました。Kustomizeについては、本連載の過去記事をご覧ください。

├── base
│   ├── kustomization.yaml          # 使用するリソースを定義したマニフェスト
│   ├── mysql.yaml                  # wordpressのDB(MySQL)を定義したマニフェスト
│   ├── wordpress.yaml              # wordpressのアプリケーションを定義したマニフェスト
└── overlays
    ├── dev
    │   ├── kustomization.yaml      # 適用するパッチを定義したマニフェスト
    │   ├── patch.yaml              # パッチを定義したマニフェスト(replicasを差分として定義)
    │   └── mysql-pass.yaml         # MySQL接続用パスワードが記載されたマニフェスト
    ├── prod
    │   ├── kustomization.yaml
    │   ├── patch.yaml
    │   └── mysql-pass.yaml
    └── staging
        ├── kustomization.yaml
        ├── patch.yaml
        └── mysql-pass.yaml

 「base」ディレクトリの「kustomization.yaml」では、環境に依存しない基本的なデプロイ定義を設定しています。

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - mysql.yaml       # ベースとなるマニフェストを定義
  - wordpress.yaml
kustomization.yaml

 「overlays/dev」ディレクトリにある「patch.yaml」では、Applicationカスタムリソースを使って環境に依存するデプロイ定義を設定します。本稿では、「replica」数を差分として定義しました。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  replicas: 1
patch.yaml

 overlays/devディレクトリの「kustomization.yaml」では、リソースとしてベースとなるマニフェスト、パッチとして適用するマニフェストを指定します。

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: dev
resources:
  - ../../base              # ベースとなるマニフェストを定義
  - mysql-pass.yaml         # dev環境用のSecretマニフェストを定義
patches:
  - patch.yaml              # パッチとして適用するマニフェストを定義
kustomization.yaml

 「overlays/dev」ディレクトリの「mysql-pass.yaml」では、「MySQL」に接続するためのパスワードを「Secret」リソースとして記述しています。

 なお本稿では、Secretリソースをそのままリポジトリに格納していますが、本番の運用では後述の通りセキュリティリスクがあるので、暗号化した上で格納してください。

apiVersion: v1
data:
  password: c2FtcGxl
kind: Secret
metadata:
  creationTimestamp: null
  name: mysql-pass
  namespace: dev
mysql-pass.yaml

サンプルアプリケーションをArgo CDに登録する

 このサンプルアプリケーションをArgo CDに登録していきましょう。Argo CDにアプリケーションを登録するには、次の2つのステップが必要です。

  1. リポジトリの登録(リポジトリへの認証が必要な場合)
  2. アプリケーションの登録(リポジトリとマニフェストの場所、同期設定など)


Argo CDにリポジトリを登録

 今回はGitLabのプライベートリポジトリにマニフェストを格納しているので、Argo CDにリポジトリ情報を設定する必要があります。Argo CDはHTTPS(パスワード認証)、HTTPS(証明書認証)とSSH(鍵認証)の認証方式をサポートしています。

 本稿では、利用が最も簡単なHTTPS(パスワード認証)を使用して設定します。よりセキュリティを強固にしたい場合は、HTTPS(証明書認証)やSSH(鍵認証)の利用をお勧めします。HTTPS(証明書認証)やSSH(鍵認証)を使用した設定を確認したい場合は、公式ドキュメントをご覧ください。

 Argo CDでリポジトリを定義する方法として下記の3つの方法があります。

 本稿では、簡単に使えるWebブラウザによる定義と、1コマンドで定義できるCLIの2つの方法を紹介します。

・Webブラウザからリポジトリを設定する

 ログイン画面でusernameとpasswordを入力後、トップ画面が表示された状態で、左側にあるメニューの設定アイコンをクリックします。クリックすると、「Settings」画面が表示されます。


「Settings」画面

 「Repositories」をクリックすると、リポジトリ設定画面が表示されます。初期状態では、リポジトリが設定されていないので、「No repositories connected」と表示されます。


「Repositories」画面

 「CONNECT REPO USING HTTPS」をクリックすると、リポジトリの設定画面が表示されます。


リポジトリの設定画面

 下記の通り入力し、「CONNCECT」をクリックします。

項目 説明 本稿での設定値
Type リポジトリの種類。「git」か「helm」を選択できる git
Repository URL マニフェストファイルを格納したリポジトリのURL https://gitlab.com/myusername/cd-sample
Username リポジトリに接続するためのユーザー名 kuritayu
Password リポジトリに接続するためのパスワード ●●●●●●●●(パスワード文字列は非表示)
TLS client certificate TLSクライアント証明書 なし
TLS client certificate key 秘密鍵 なし
Skip server verification Gitリポジトリとの接続テストをスキップするかどうか チェックしない
Enable LFS support Git LFS(Large File Storage)」を有効にするかどうか チェックしない

 入力された情報で接続が成功すると、「CONNECTION STATUS」列に「Successful」と表示されます。


「CONNECTION STATUS」列に「Successful」と表示されると、成功

・CLIからリポジトリを設定する

 リポジトリを登録します。なお、パスワードは伏せています。

$ argocd repo add https://gitlab.com/myusername/cd-sample.git --username kuritayu --password ●●●●●●●●
Repository 'https://gitlab.com/myusername/cd-sample.git' added 

 リポジトリの一覧を表示します。

$ argocd repo list
TYPE  NAME  REPO                                          INSECURE  OCI    LFS    CREDS  STATUS      MESSAGE
git         https://gitlab.com/myusername/cd-sample.git   false     false  false  true   Successful

Argo CDにアプリケーションを登録

 Argo CDにアプリケーションを登録します。本稿ではKustomizeで管理された複数環境のうち、dev環境を登録しますが、staging環境やprod環境についても同じ手順で登録が可能です。

 Argo CDでアプリケーションを登録する方法として下記の3つの方法があります。

 本稿では、簡単に使えるWebブラウザによる定義と、複雑なデプロイの定義に便利なカスタムリソースを用いたマニフェストによる定義の2つの方法を紹介します。

・Webブラウザからアプリケーションを登録する

 「CREATE APPLICATION」をクリックすると、登録画面が表示されます。


Argo CDアプリケーション登録画面

 「GENERALセクション」では下記項目を設定します。

項目 説明 本稿での設定値
Application Name アプリケーション名を指定する wordpress-dev
Project 「プロジェクト」名を選択する* default
SYNC POLICY リポジトリとの同期ポリシーを手動「Manual」にするか、自動「Automatic」にするかを選択する Automatic
*プロジェクトはアプリケーションを論理的にグルーピングする機能。デプロイするアプリケーションやデプロイ先(Kubernetesクラスタやネームスペースなど)を制限する機能を持つ。詳しくは公式ドキュメントを参照

 SYNC POLICYがAutomaticの場合は下記項目を追加で設定できます。

項目 説明 本稿での設定値
PRUNE RESOURCES チェックすると、Gitリポジトリで定義されていないリソースを削除する。例えば、Serviceリソースが起動している状態でリポジトリのServiceリソースを削除した場合に、本オプションが有効になっている場合は削除される。有効になっていない場合は、同期ステータスが「OutOfSync」となるが、リソース自体は削除されない チェックする
SELF HEAL デフォルトでは、クラスタ内でリソースに対する変更を適用し、Gitリポジトリの状態と乖離(かいり)しても、自動で同期されず、同期ステータスがOutOfSyncとなる。本設定をチェックすると、クラスタ内でリソース変更が検出された場合に、リポジトリに格納されたマニフェストの状態に強制的に戻す チェックする

 「SYNC OPTIONS」として下記項目を設定できます。

項目 説明 本稿での設定値
SKIP SCHEMA VALIDATION リポジトリと同期する際、「--validate=false」オプションを付与してマニフェストを検証しない チェックしない
AUTO-CREATE NAMESPACE チェックすると、デプロイ先のネームスペースが存在しない場合にArgo CDがネームスペースを自動で作成する チェックする
PRUNE LAST チェックすると、リソースの削除は他の同期が全て完了し、ステータスが「Healthy」状態になった後にリソースを削除する。例えば、Pod数の変更とServiceリソースの削除が同時の場合、本オプションが有効になっていると、Pod数の変更が完了してからServiceリソースが削除される。有効になっていない場合は、Pod数の変更とServiceリソースの削除が同時に行われる チェックしない
APPLY OUT OF SYNC POLICY 同期ポリシーが自動の場合、Argo CDは差分の有無にかかわらず、全てのリソースにマニフェストを適用する。チェックすると、同期されていないリソースのみマニフェストを適用するので、同期時間が速くなる チェックしない
REPLACE チェックすると、リポジトリと同期する際のコマンドが「kubectl replace」となる。チェックしないと、「kubectl apply」となる。同期対象リソースが大量に存在して同期に時間がかかる場合は本オプションが有用 チェックしない
PRUNE PROPAGATION POLICY リソースを削除するポリシーとして「foreground」(削除対象リソースについて、子リソースを削除してから親リソースを削除)、「background」(削除対象リソースについて、親リソースを削除してからバックグラウンドで子リソースを削除)、「orphan」(削除対象リソースについて、親リソースを削除し子リソースは削除しない)を選択できる foreground

 次に、ソースリポジトリを設定します。


ソースリポジトリの設定画面

 「SOURCE」セクションでは、リポジトリがGitの場合、下記項目を設定します。

項目 説明 本稿での設定値
Repository URL リポジトリ名を指定する https://gitlab.com/myusername/cd-sample.git
Revision 同期するリビジョンを指定する。ブランチ(例:main)、タグ(例:v1.2.0)、ハッシュ(例:0a1b2c3)、シンボリック参照(例:HEAD)が許可されている。Kustomizeなどの環境差分を管理するツールを使用せず、ブランチやタグで環境を管理する場合に設定するとよい。本稿ではKustomizeを使って環境差分を管理するので、mainブランチを設定する main
Path 同期対象のマニフェストが格納されているパスを指定する。リポジトリルートからの相対パスを設定する必要がある。本稿ではKustomizeを使用してdev環境のアプリケーションを登録するので、dev環境のkustomization.yamlがあるディレクトリを指定する wordpress/overlays/dev

 本稿ではGitリポジトリのURLを設定しますが、リポジトリがHelmの場合は下記項目を設定します。

項目 説明
Repository URL リポジトリ名を指定する
Chart デプロイツールにHelmを利用する場合、チャート名およびバージョンを指定する

 次に同期先を設定します。


同期先の設定画面

 「DESTINATION」セクションでは下記項目を設定します。

項目 説明 本稿での設定値
Cluster URL/Cluster Name クラスタURLもしくはクラスタ名を指定する。デフォルトではArgo CDをデプロイしたクラスタと同一のクラスタが指定できる。別のクラスタにデプロイする場合は、後述の通り、事前にクラスタを登録しておく必要がある。本稿ではArgo CDと同一クラスタにデプロイする https://kubernetes.default.svc
Namespace デプロイ対象アプリケーションのネームスペースを指定する dev

 最後に、Argo CDがサポートするツールに対する設定です。本稿では紹介しないので、必要な方は下記公式ドキュメントをご覧ください。

 なお、設定画面上は「Ksonnet」の設定はできますが、既にサポートされていないので、利用しないことをお勧めします。

 ここまでの設定を終え、「CREATE」ボタンをクリックすると、アプリケーションを登録できます。登録したアプリケーションをクリックすると、各リソースの状態が表示されます。


各リソースの状態

 アプリケーション(WordPress)にアクセスしてみます。本稿では、port-forwardを利用してアクセスします。ポートフォワード用のターミナルを起動し、操作PCで下記コマンドを実行します。

$ kubectl port-forward service/wordpress -n dev 30000:80
Forwarding from 127.0.0.1:30000 -> 80
Forwarding from [::1]:30000 -> 80

 エラーメッセージが表示された場合は、操作PCで「30000」ポートを利用した他のプロセスがないかどうかを確認してください。このターミナルはポートフォワード用のターミナルなので、WordPressにアクセスする間はターミナルを閉じたりコマンドを停止したりしないでください。

 ブラウザで「http://localhost:30000」にアクセスすると、WordPressの初期画面が表示されました。


WordPressの初期画面

・マニフェストを使用してアプリケーションを登録する

 リポジトリの認証設定同様、WebブラウザやCLIによる設定では、設定内容をGitに残せないので、管理面で難があります。Argo CDでは、アプリケーションの登録についても、カスタムリソースを使用したマニフェストが作成できるので紹介します。

 マニフェスト名は「applicaton_dev.yaml」とし、Webブラウザにおける設定項目と対比する形で記載します。

apiVersion: argoproj.io/v1alpha1
kind: Application                                               # アプリケーション名(WebブラウザのApplication Nameに相当)
metadata:
  name: wordpress-dev
  namespace: argocd
spec:
  destination:
    name: ""                                                    # Kubernetesクラスタ名(WebブラウザのCluster Nameに相当)
    namespace: dev                                              # ターゲットとなるネームスペース(WebブラウザのNamespaceに相当)
    server: https://kubernetes.default.svc                      # KubernetesクラスタURL(WebブラウザのCluster Nameに相当)
  project: default                                              # プロジェクト名(WebブラウザのProjectに相当)
  source:
    path: wordpress/overlays/dev                                # リポジトリ内のパス(WebブラウザのPathに相当)
    repoURL: https://gitlab.com/myusername/cd-sample.git        # リポジトリURL(WebブラウザのRepository URLに相当)
    targetRevision: HEAD                                        # 追跡対象のブランチ、タグ、コミット、Helm Chartのバージョン(WebブラウザのRevisionに相当)
  syncPolicy:                                                   # 同期ポリシー(WebブラウザのSYNC POLICYに相当)
    automated:                                                  # 自動同期(手動同期なら本項目は不要)
      prune: true                                               # 同期オプション(WebブラウザのPRUNE RESOURCESに相当)
      selfHeal: true                                            # 同期オプション(WebブラウザのSELF HEALに相当)
    syncOptions:
      - Validate=true                                           # 同期オプション(WebブラウザのSKIP SCHEMA VALIDATIONに相当)
      - CreateNamespace=true                                    # 同期オプション(WebブラウザのAUTO-CREATE NAMESPACEに相当)
      - PruneLast=false                                         # 同期オプション(WebブラウザのPRUNE LASTに相当)
      - Replace=false                                           # 同期オプション(WebブラウザのREPLACEに相当)
      - ApplyOutOfSyncOnly=false                                # 同期オプション(WebブラウザのAPPLY OUT OF SYNC POLICYに相当)
      - PrunePropagationPlocy=foreground                        # 同期オプション(WebブラウザのPRUNE PROPAGATION POLICYに相当)
applicaton_dev.yaml

 Webブラウザでは、SYNC POLICYについてAutomatic(自動)かManual(手動)の2パラメーターが設定可能でした。マニフェストでは、「automated:」の有無で自動か手動かを設定します。

 すなわち、自動同期を設定する場合は、下記のようになります。

  syncPolicy:
    automated:       # 本項目の有無で自動かどうかが決まる
      prune: true
      selfHeal: true
    syncOptions:
      - Validate=true
      - CreateNamespace=true
      - PruneLast=false
      - Replace=false
      - ApplyOutOfSyncOnly=false
      - PrunePropagationPlocy=foreground

 手動同期を設定する場合は、下記のようになります。

  syncPolicy:        # automatedがないので、手動同期
    syncOptions:
      - Validate=true
      - CreateNamespace=true
      - PruneLast=false
      - Replace=false
      - ApplyOutOfSyncOnly=false
      - PrunePropagationPlocy=foreground

 このマニフェストを「kubectl apply」コマンドで実行すると、アプリケーションを登録できます。

# prod環境用にマニフェストをビルドし、argocdネームスペースに適用することで、アプリケーションを登録できる
$ kubectl apply -f application_dev.yaml
application.argoproj.io/wordpress created
# 登録されたアプリケーションを表示
$ argocd app list
NAME       CLUSTER                         NAMESPACE  PROJECT  STATUS  HEALTH   SYNCPOLICY  CONDITIONS  REPO            PATH                     TARGET
wordpress  https://kubernetes.default.svc  dev        default  Synced  Healthy  Auto        <none>      repository URL  wordpress/overlays/dev   HEAD

コラム Argo CDで利用されているデプロイツールのバージョン

 Argo CDには、KustomizeやHelmといったデプロイツールが組み込まれているので、基本的に追加でインストールする必要はありません。

 ただし、デプロイツールのバージョンによっては機能の差があり、ローカルで動作したアプリケーションのデプロイに失敗する場合があります。使える機能があったり、Argo CDで利用されたりしているデプロイツールのバージョンは下記の手順で確認できます。

 まず、Argo CDのリポジトリサーバのPod(デプロイツールを用いてKubernetesのマニフェストを生成する)を確認します。

$ kubectl get pods -nargocd
NAME                                                     READY   STATUS    RESTARTS   AGE
argo-cd-argocd-application-controller-5f87847c89-9sbw2   1/1     Running   0          4h5m    
argo-cd-argocd-dex-server-5fdbf588f9-fnnw8               1/1     Running   0          4h5m
argo-cd-argocd-redis-6bfd9c4d46-zm62f                    1/1     Running   0          4h5m
argo-cd-argocd-repo-server-5d6fd7b89f-llcjg              1/1     Running   0          4h5m
argo-cd-argocd-server-55cf77b69-6gwkr                    1/1     Running   0          4h5m

 リポジトリサーバの名前(ここでは3行目の「argo-cd-argocd-repo-server-5d6fd7b89f-llcjg」)が分かったら、「exec」コマンドでデプロイツールのバージョンを確認します。下記はKustomizeの例です。

$ kubectl exec argo-cd-argocd-repo-server-5d6fd7b89f-llcjg -n argocd -- kustomize version$
{Version:kustomize/v3.9.4 GitCommit:e41d94ddef8cca7af2709c4104b41c4d43cd236c BuildDate:2021-02-09T19:22:10Z GoOs:linux GoArch:amd64}

 以上から、今回利用したArgo CDでは、Kustomizeの3.9.4が利用されていることが分かりました。

 利用するデプロイツールは、バージョンをカスタマイズすることもできます。興味がある方は、Argo CDの公式ドキュメントをご覧ください。


マニフェストファイルの修正

 アプリケーションが登録できたところで、マニフェストファイルを変更してみましょう。マニフェストファイル(overlays/dev/patch.yaml)を修正し、wordpressのレプリカPod数を増やしてみます。

 8行目の「replicas: 1」を「replicas: 3」に修正してください。

# アプリケーションのマニフェストを修正
$ vi overlays/dev/patch.yaml
 
# 修正した結果を表示
$ git diff
diff --git a/wordpress/overlays/dev/patch.yaml b/wordpress/overlays/dev/patch.yaml
index 761408c..e35b7bc 100644
--- a/wordpress/overlays/dev/patch.yaml
+++ b/wordpress/overlays/dev/patch.yaml
@@ -5,4 +5,4 @@ metadata:
   labels:
     app: wordpress
 spec:
-  replicas: 1
+  replicas: 3
 
# 修正したマニフェストをコミットおよびリモートリポジトリにプッシュ
$ git add .
$ git commit -m "change replicas"
$ git push

 しばらく待つと、Argo CDがリポジトリと同期し、wordpressのPod数が3になりました。本稿では自動同期を有効にした設定を紹介しましたが、手動同期設定の場合は画面上部の「SYNC」ボタンをクリックすることで同期できます。


マニフェストの修正

 通常3分間隔で、Gitリポジトリを監視して変更を検知しています。この設定は、後で説明する設定ファイルで変更できます。また、GitリポジトリからWebhookを受け取って、コミット時に自動同期される設定もできます。

アプリケーションの削除

 アプリケーションの削除はWebブラウザからできます。また、Applicationリソースのマニフェストを「kubectl delete」コマンドで、下記のように削除できます。

$ kubectl delete -f application_dev.yaml

 また、argocdコマンドを利用して、削除することもできます。

# 削除対象のApplicationを確認
$ argocd app list
NAME       CLUSTER                         NAMESPACE  PROJECT  STATUS  HEALTH   SYNCPOLICY  CONDITIONS  REPO            PATH                     TARGET
wordpress  https://kubernetes.default.svc  dev        default  Synced  Healthy  Auto        <none>      repository URL  wordpress/overlays/dev   HEAD
# wordpressアプリケーションを削除
$ argocd app delete wordpress

他環境へのデプロイ

 ここまで、dev環境へのデプロイを例として解説してきました。ここからは、他の環境にデプロイする方法を解説します。ここでは、prod環境(商用環境)に変更する例で紹介します。

共通して行うべきこと

 他環境へのデプロイ方法は幾つかありますが、まずは、デプロイ方法によらない共通の設定について説明します。

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: wordpress-prod
  namespace: argocd
spec:
  destination:
    name: ""
    namespace: prod   # 環境によってデプロイ先のネームスペースを変える場合は変更する
    server: https://kubernetes.default.svc
  project: default
  source:
    path: wordpress/overlays/prod
    repoURL: https://gitlab.com/myusername/cd-sample.git
    targetRevision: main
  syncPolicy:
#    automated:
#    prune: true
#    selfHeal: true
  syncOptions:
    - validate=true
    - CreateNamespace=true
    - PruneLast=false
    - Replace=false
    - ApplyOutOfSyncOnly=false
    - PrunePropagationPlocy=foreground

・デプロイ先のネームスペースにprodを指定(上記コードの9行目)

 デプロイ先(destination)のネームスペースを変更します。商用環境へのデプロイとして他クラスタを利用する場合は、ネームスペースを変更する必要はありませんが、同じネームスペースだと紛らわしいのでここでは変更するものとします。

・Kustomizeのソースパスをdevの代わりにprodを指定(上記コードの13行目)

 source/pathをprodのマニフェストが格納されたパスに変更します。

・マニフェストリポジトリとの自動同期の設定を無効にする(上記コードの17〜19行目)

 ここでは、prod環境(商用環境)へのデプロイを想定し、自動同期を無効化して十分に変更を確認した後に手動でデプロイするものとします。

デプロイ先の指定

 次に、デプロイ先の指定方法ごとにやり方を説明します。

・同じクラスタでネームスペースを変更する場合

 上記で紹介したdestinationのnamespaceを変更したApplicationリソースを作成すればOKです。

・クラスタを変更する場合

 デプロイするクラスタを変更する場合は、次の2つの方法があります。

 1. 最初にインストールしたArgo CDで別のクラスタにデプロイする

 上記destinationで、下記のようにクラスタ名もしくはクラスタのAPIのURLを記述してください。両方指定するとアプリケーション登録時にエラーとなるので、どちらかを指定してください。

  destination:
    name: ""                                                                                      # Kubernetesクラスタ名
    server: 'https://A3CCDC26E1169F8D514ECA4BA3BCF013.gr7.ap-northeast-1.eks.amazonaws.com'       # KubernetesクラスタURL

 次に、デプロイするクラスタの情報を登録します。Webブラウザからは登録できないので、CLIで登録してください。認証情報を開発環境のクラスタに登録する必要があり、セキュリティに気を付ける必要があります。

# kubectlを使用してクラスタ情報を取得
$ kubectl config get-contexts
CURRENT   NAME                                           CLUSTER                               AUTHINFO                                       NAMESPACE
          cli-user@ekshandson.ap-northeast-1.eksctl.io   ekshandson.ap-northeast-1.eksctl.io   cli-user@ekshandson.ap-northeast-1.eksctl.io
*         minikube
# argo cdにクラスタ情報を登録する。登録するには、コンテキスト情報をコマンドライン引数に渡す
$ argocd cluster add cli-user@ekshandson.ap-northeast-1.eksctl.io
INFO[0001] ServiceAccount "argocd-manager" already exists in namespace "kube-system"
INFO[0001] ClusterRole "argocd-manager-role" updated
INFO[0001] ClusterRoleBinding "argocd-manager-role-binding" updated
Cluster 'https://A3CCDC26E1169F8D514ECA4BA3BCF013.gr7.ap-northeast-1.eks.amazonaws.com' added
# クラスタの登録状況を確認
$ argocd cluster list
SERVER                                                                         NAME                                          VERSION  STATUS      MESSAGE
https://A3CCDC26E1169F8D514ECA4BA3BCF013.gr7.ap-northeast-1.eks.amazonaws.com  cli-user@ekshandson.ap-northeast-1.eksctl.io           Unknown     Cluster has no application and not being monitored.
https://kubernetes.default.svc                                                 in-cluster                                    1.20     Successful

 最後にApplicationリソースのマニフェストを適用します。

$ kubectl apply -f application_prod.yaml
application.argoproj.io/wordpress-prod created
$ argocd app list
NAME            CLUSTER                                                                        NAMESPACE  PROJECT  STATUS  HEALTH    SYNCPOLICY  CONDITIONS  REPO                                         PATH                     TARGET
wordpress-dev   https://kubernetes.default.svc                                                 dev        default  Synced  Healthy   Auto-Prune  <none>      https://gitlab.com/myusername/cd-sample.git  wordpress/overlays/dev   HEAD
wordpress-prod  https://A3CCDC26E1169F8D514ECA4BA3BCF013.gr7.ap-northeast-1.eks.amazonaws.com  prod       default  Synced  Healthy   <none>      <none>      https://gitlab.com/myusername/cd-sample.git  wordpress/overlays/prod  HEAD

 2. クラスタごとにArgo CDをインストールする

 prod用のクラスタにArgo CDをインストールし、dev環境と同様にApplicationリソースを定義します。Argo CDのクラスタへの認証情報の登録する必要がなく、開発環境と商用環境の独立性を保つことができ、セキュアな運用が可能です。

 また、開発環境と商用環境間の通信が許されていないような厳しい環境でもこの方法を利用できます。

手動同期の方法

 Webブラウザから行う場合は、Application画面で「SYNC」ボタンをクリックすると、同期するための設定画面が表示されます。


Application画面で「SYNC」ボタンをクリック

 同期時にリソースを削除する場合は「PRUNE」にチェックし、削除しない場合はチェックを外してください。

 その他のオプションはkubectl applyコマンドのオプションと同様なので、説明は割愛します。また、「SYNC OPTIONS」「PRUNE PROPAGATION POLICY」についても、アプリケーション登録時と同内容なので、説明を割愛します。


手動同期のための設定画面

 「SYNCHRONIZE」ボタンをクリックすると同期が開始されます。

 CLIの場合は、下記コマンドで同期されます。

$ argocd app sync wordpress-prod
TIMESTAMP                  GROUP        KIND              NAMESPACE                  NAME    STATUS    HEALTH        HOOK  MESSAGE
2021-07-05T00:39:21+09:00            Service                   prod             wordpress  OutOfSync  Missing
2021-07-05T00:39:21+09:00            Service                   prod       wordpress-mysql  OutOfSync  Missing
.. 以降省略 ...

Argo CDの設定

 Argo CDでは、「Config」ファイルでいろいろと設定できます。Argo CDの設定は、Argo CDがデプロイされたネームスペース(本稿ではargocd)にある「argocd-cm ConfigMap」リソースを変更することで行います。

 例えば、Argo CDのGitリポジトリとの自動同期の設定は、デフォルトでは3分(180秒)となっていますが、同期間隔を変更したい場合は、下記のパラメーターを変更します。

   timeout.reconciliation: 180s

 設定の変更は、下記コマンドです。

$ kubectl edit cm/argocd-cm -nargocd

 大きく変更したり、ConfigMapをGitリポジトリで管理したりしたい場合は、一度、YAMLファイルとして出力し、エディタで編集してからkubectl applyコマンドで変更を反映するとよいでしょう。

Argo CD Notificationsを利用した通知設定

 「コラム Argo CD 2.0の新機能」で紹介したNotificationsを利用すると、Argo CDでのデプロイ結果をSlackやメールで通知できます。ここからは、メールで通知する方法を簡単に紹介します。

 なお、ここではv1.1.0の利用方法を紹介します。Notificationsは現在活発に開発され、バージョンによって仕様が変わる可能性があるのでご注意ください。最新の情報については公式サイトをご覧ください。

Notificationsのインストール

 Notificationsとカタログをインストールします。

$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-notifications/v1.1.0/manifests/install.yaml
$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-notifications/v1.1.0/catalog/install.yaml

認証用secretの作成

 SMTPサーバ認証用のsecretを作成し、メール認証のユーザー名とパスワードを安全にアクセスできるようにします。下記の手順で作成します。

 環境変数にユーザー名とパスワードを設定します。ここでは、Gmailを利用した例を紹介します。

$ export EMAIL_USER=okamura  # SMTPサーバのユーザー名
$ export PASSWORD=mypassword   # SMTPのパスワード(Googleの場合はアプリパスワード)

 SMTPサーバのパスワードには、Gmailを利用する場合は、Googleアカウントのログインパスワードではなく、アプリパスワードを利用する必要があります。Googleアカウントのアプリパスワードを生成する方法については、アプリ パスワードでログインするをご覧ください。

 次に、SMTPサーバ認証用のsecretを上記の環境変数から作成します。

$ kubectl apply -n argocd -f - << EOF
apiVersion: v1
kind: Secret
metadata:
  name: argocd-notifications-secret
stringData:
  email-username: $EMAIL_USER
  email-password: $PASSWORD
type: Opaque
EOF
 
$ kubectl get secret/argocd-notifications-secret  -n argocd      # 作成したsecretの確認
NAME                          TYPE     DATA   AGE
argocd-notifications-secret   Opaque   2      10s

メール通知の設定

 メール通知の設定は、Notifications用のConfigMapで、下記の手順で行います。

 まず、Notificationsのデフォルトの設定(ConfigMap)を取得します。

$ kubectl get -oyaml cm/argocd-notifications-cm -nargocd > argo-notifications-cm.yaml

 argo-notifications-cm.yamlを編集し、dataフィールドに下記の3〜17行目(context〜on-sync-status-unknown)を追加します。

apiVersion: v1
data:
  context: |
    argocdUrl: https://my-argocd.example.com/       # Argo CDのURL。ロードバランサーやIngressで公開している場合は、公開URLを指定
  service.email: |
    host: smtp.gmail.com                            # SMTPサーバ
    port: 587                                       # SMTPサーバのポート
    from:xxxx@gmail.com                             # from
    username: $email-username
    password: $email-password
  subscriptions: |
    - recipients:
      - email:xxxx@gmail.com                        # usernameで指定したメール名
      triggers:                                     # メール送信するトリガを指定
      - on-sync-succeeded                           #   同期成功
      - on-sync-failed                              #   同期失敗
      - on-sync-status-unknown                      #   ステータス不明
 
  template.app-created: |
    email:
argo-notifications-cm.yaml

 上記の設定により、Argo CDのアプリケーションの同期が実行されると結果がメールで通知されます。最新の設定内容については、GitHub上の設定サンプルをご覧ください。

CIパイプラインとの連携

 KubernetesにおけるCI/CDでは、CIでコンテナイメージをリポジトリに登録し、CDでマニフェストをKubernetesクラスタにデプロイします。

 CIを実施した後で、変更したイメージをクラスタに反映するには、Kubernetesにデプロイするマニフェスト(本稿ではKustomizeのファイル)を変更し、指定したコンテナイメージのバージョンをCIで新たに作成したバージョンに変更してコミットします。これにより、変更したイメージでアプリケーションのデプロイが更新されます。

 その他、CIパイプライン内でKubernetesのデプロイマニフェストを更新して、リポジトリのコンテナイメージ更新後、自動的にKubernetesのマニフェストに新たなコンテナバージョンを登録する方法や、上述のImage Updaterの機能を利用してイメージを自動更新する方法もあります。

 ここからはCIパイプラインとの連携方法の選択肢とメリデメを簡単に説明します。手動で連携する方法と自動化して連携する方法があります。

手動による連携

 デプロイマニフェストを手動で修正してGitリポジトリにプッシュすることでCDのトリガーを引きます。

  • メリット
    1. デプロイのタイミングを自分でコントロールできる
    2. 依存関係のある複数のデプロイを同期できる
    3. デプロイマニフェストの修正内容を柔軟にできる
    4. 導入しやすい
  • デメリット
    1. デプロイに必要な手間が増えるのでリリース頻度が落ち、リリースまでのリードタイムが長くなる可能性がある
    2. 手作業によるミスが混入しやすい

 手動による連携は、下記のような利用シーンが想定されます。

  • 慎重なリリースが必要なケース
  • 複数のデプロイを同期させる必要があるケース
  • 後方互換性が保たれない変更が必要なケース

自動による連携

 自動でデプロイマニフェストを修正してGitリポジトリにプッシュすることでCDのトリガーを引きます。

  • メリット
    1. アプリケーションの修正からデプロイまでが自動化されるので、リリース頻度が向上し、リリースまでのリードタイムが短縮できる
    2. 作業ミスが混入しにくい
  • デメリット
    1. バージョニングやデプロイ戦略の設計が必要なので、手動と比べて導入ハードルが高い
    2. 複雑な変更のデプロイに対応しにくい
    3. デプロイに失敗した場合のロールバックの戦略の検討が必要

 自動による連携方法は、下記のような利用シーンが想定されます。

  • 機械的なリリースが可能なケース
  • 一サービスのデプロイのみ単独で実行できるケース
  • 後方互換性が保たれ、コンテナイメージタグのバージョンアップなどの単純な変更のみで対応できるケース

 自動的に連携する方法としては、下記2つの方法が考えられます。

  1. CI内でデプロイマニフェストを修正
  2. Argo CD Image Updaterを利用

 CI内でデプロイマニフェストを修正する方法は、処理スクリプトを実装したり、Gitリポジトリの権限管理が複雑化したりする必要があるので、Image Updaterを利用する方法に比べてパイプラインや実装が複雑化しやすくなります。

 一方で、Image Updaterを導入するとパイプラインや設定をシンプル化できますが、2021年7月時点でバージョンはv1.0になっていないので、動作が安定しない可能性、バージョンアップに伴い大きな変更を余儀なくされる可能性、十分な機能を要していない可能性を考慮して採用する必要があります。

 執筆時点においてv1.0までのロードマップが公開されています。このような情報を確認しながら導入を検討するといいでしょう。

手動と自動を組み合わせた連携

 上述した内容を鑑みると、手動と自動とそれぞれのCI連携方法を組み合わせるとGitOpsをベースとしたCDをより上手に活用できるでしょう。例示します。

  • コンテナイメージには例えばセマンティックバージョニングを活用し、
    • 後方互換性を保つことができるパッチバージョンアップでは自動デプロイを活用
    • 後方互換がないメジャーバージョンアップでは手動デプロイを活用し、自動デプロイのトラッキング対象のバージョンを手動で変更
  • devやprodといった各環境へのデプロイ戦略を設計
    • prod環境は必ず手動デプロイのみとする、パッチバージョンアップのみは自動にするなどの設計と上記手法を組み合わせる

 このように手動と自動との連携方法を組み合わせることで、システム開発における体制や方針に合った方法を検討できるので、検討の参考にしてもらえれば幸いです。

GitOpsの原則と利点

 GitOpsでは、Gitを「Single Source of Truth」(唯一の信頼できる情報源)とし、GitOpsの原則を適用することで多くのメリットを享受できます。そこでGitOpsの原則とGitOpsのメリットについて解説します。

 GitOpsの原則は、GitOpsを提唱したWeaveworksからGitOpsのコンセプトを導入するためのガイド「Guide To GitOps」として公開されています。

原則(英語表記) 原則(意訳) 解説
The entire system described declaratively システム全体を宣言的に記述すること Kubernetesで構築するシステム全体をマニフェストファイルとして記述すること。kubernetesでは宣言的に記述されたマニフェストファイルから構築されるシステムは再現可能で、かつ記述された定義とシステムの状態が一致する。これにより、Gitとシステムとの状態が同期した状態を保てる
The canonical desired system state versioned in Git 正しく望ましいシステム状態をGit上でバージョン管理すること マニフェストファイルで望ましいシステム状態を記述し、Git上で適切にバージョン管理すること。GitではTagやリリースブランチ、コミットハッシュ値などを利用してバージョン管理を容易にできる。Gitで管理されているマニフェストファイルからいつでもシステムを再現可能なので、システムの状態をGit上のバージョンで適切に管理することで、特定のバージョンのシステム状態をいつでも再現可能にする。これにより、例えばシステムで問題が発生した際に以前の安定したバージョンにシステム状態を復元することで、稼働を安定化させたり、問題が発生したシステム状態を再現して解析したりするなどが容易になる
Approved changes that can be automatically applied to the system 承認された変更は自動的にシステムに適用できること マニフェストファイルはプル/マージリクエストにより適切にレビューしてマージし、常にシステムに適用可能な状態とすること。Gitを使った開発手法では、プル/マージリクエストにより適切な承認者のレビューを受けて承認され、マージすることで、マージされたファイルの品質を安定的に保てる。そのため、マニフェストファイルは常にシステムに適用され得る状態を保つように適切にマージして品質を確保する。この状態を保つことにより、Git上で必要な承認を受けた変更を、システムに安定して自動デプロイすることも可能になり、生産性の向上や運用の安定化にもつながる
Software agents to ensure correctness and alert on divergence 適正さを保証し、逸脱を警告するソフトウェアエージェントであること GitOpsのツールは、Gitとシステムの状態に対し逸脱があれば開発/運用者に適切に警告を通知させること。バグや障害対応により緊急で環境を直接操作してしまったり、新しくデプロイされたアプリケーションにバグが混入したりしていたために、システム上は一時的に前のバージョンにロールバックする対応をしている状態では、Gitとシステムの状態は同期が取れないので、有事の際に現在のシステムの状態を再現することが困難になる。そのため、開発/運用者はアプリケーションやマニフェストファイルを修正するか、Gitを操作するかし、適切にGitとシステムの状態を同一に保つように対応する必要がある。GitOpsのツールはGitとシステムの状態に対して逸脱があれば開発/運用者に適切に警告を通知することでGitとシステムの状態を同一に保つサポートができるようにしておくべきだ

 上記から、GitOpsはクラウドネイティブなアプローチ(コンテナ、イミュータブルインフラストラクチャ、宣言型APIなど)によるメリットをベースにGitの開発技法をOps(CD)に最適化した手法だと分かります。これらの原則を適用することで、下記のようなメリットを得ることができるでしょう。

  • 開発者体験や生産性の向上
  • 運用の改善や安定性の向上
  • セキュリティや監査の強化

GitOpsにおける5つのベストプラクティス

 Argo CDのAlex Collins氏がGitOpsを実装するベストプラクティスの記事「5 GitOps Best Practices」を発表しました。これらのプラクティスはいずれも重要なので、実例も交えて解説します。

Two Repos: One For App Source Code, Another For Manifests

 アプリケーションコード用のGitリポジトリと、デプロイマニフェストファイル用のGitリポジトリとをそれぞれ用意することです。

 同一のリポジトリで管理するとどうなるでしょうか? 例えば、アプリケーションコードをコミットするたびにデプロイされることになります。また、Gitのログにアプリの変更とデプロイマニフェストの変更が混ざってしまい、コミットログから状態を復元したい際に複雑になってしまいます。そのため、アプリケーションとデプロイマニフェストはそれぞれライフサイクルが異なるので分離すべきです。

Choose The Right Number Of Deployment Config Repos

 デプロイマニフェスト用のリポジトリの適数を検討して選択することです。

 唯一解はありませんが、管理体制に合わせてリポジトリの単位と数を検討するといいでしょう。例えば、チームごとに開発、運用してチームごとに管理している状況ならチームごとにリポジトリを用意し、規模が大きくなりサービスごとにリリース管理しているならサービス単位でリポジトリを管理するといった具合です。

Test Your Manifests Before You Commit

 デプロイマニフェストをコミットやプッシュする前にテストすることです。

 マニフェストの変更をコミット、プッシュすることでGitOpsツールにデプロイできるかどうかを検証させるケースがありますが、本番/ステージング環境に問題が入り込んでしまうことがあります。このような問題を極力避けるためには、kindやminikubeなどのローカル環境を使った事前検証が重要です。左記は一例ですが、ブランチ戦略やバージョン管理、(ローカル環境を含むさまざまな)環境面の戦略を併せて検討し、問題が本番やステージング環境に入り込まないようにする工夫を検討しておくとよいでしょう。

Git Manifests Should Not Change Due To External Changes

 外部変更により、Gitで管理しているデプロイマニフェストが影響を受けないようにすべきではないということです。

 例えば、Git上のmainブランチやコンテナレジストリのlatestタグを参照しているケースでは、ファイルを取得するタイミングによってはそのファイルの内容が異なる可能性があります。何も変更を加えていないつもりでもどこかのタイミングで新しい変更が取り込まれ、問題を引き起こす原因になってしまうことはしばしばあります。そのため、取得対象のバージョンを指定することで常に意図した固定のファイルを取得できるようにすべきです。

Plan How You'll Manage Secrets

 どのようにSecretリソースの管理をするかを計画すべきということです。

 GitOpsとは無関係に機密情報をSecretリソースとしてマニフェストファイルに記述してそのままGit上で管理すると、例えばデータベースに接続するためのクレデンシャル情報が思いも寄らない形で漏えいするリスクが発生し得ます。そのため、「機密情報をどのように扱うべきか」を検討する必要があります。システムのセキュリティ要件や開発/運用体制などにより適切な管理方法は異なるので、唯一解はありません。

 本稿では詳細は説明しませんが、幾つか候補となる機密情報を扱うツールを紹介します。

 これらのツールを利用すると、Secretリソースでは暗号化された機密情報や、機密情報へのリソースパスが管理されるようになるので、Git上で機密情報を扱う必要がなくなります。機密情報はKubernetesクラスタに適用されたタイミング、もしくはPodが起動したタイミングでマウントされるので、機密情報はKubernetesクラスタ内のみで扱うことができます。

コラム Argo CDにおけるsecretの管理

 Argo CDにおけるsecretの管理方法については、2019年4月から議論されていますが、下記2点から「secretの管理手法については明確な意見を述べない」というスタンスを取っており、公式ドキュメントにおいてもその旨を明記しています。

  • 管理方法は多数存在すること
  • 全てのユースケースを充足する万能なソリューションはないこと

まとめ

 今回は、GitOpsによるCDの実装方法についてArgo CDを中心に説明しました。GitOpsの原則やベストプラクティスをベースに、Argo CDの適用方法を検討するといいでしょう。

 今回で、3回にわたる「クラウドネイティブのCI/CDについて」はいったん終わりです。クラウドネイティブなCI/CDを構築する参考にしてもらえれば幸いです。

Copyright © ITmedia, Inc. All Rights Reserved.

[an error occurred while processing this directive]
ページトップに戻る