「Argo CD」で実装するKubernetesの「GitOps」――基本と原則、実践時の考慮ポイント:Cloud Nativeチートシート(7)
Kubernetesやクラウドネイティブをより便利に利用する技術やツールの概要、使い方を凝縮して紹介する連載。今回は、「Argo CD」によるクラウドネイティブなCD(継続的デリバリー)「GitOps」について解説します。
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ベースのCDツール「Argo CD」の6つの特徴
- コラム Argo CD 2.0の新機能
- Argo CDの仕組み
- Argo CDの利用環境(サンプル)の概要
- 事前準備
- サンプルアプリケーションの概要
- サンプルアプリケーションをArgo CDに登録する
- コラム Argo CDで利用されているデプロイツールのバージョン
- マニフェストファイルの修正
- アプリケーションの削除
- 他環境へのデプロイ
- Argo CDの設定
- Argo CD Notificationsを利用した通知設定
- CIパイプラインとの連携
- GitOpsの原則と利点
- GitOpsにおける5つのベストプラクティス
- コラム Argo CDにおけるsecretの管理
「GitOps」とは?
GitOpsは、2017年にWeaveworksが提唱した開発手法です。GitOpsを使うと、「Git」とKubernetesクラスタで実行されているものとの差分を検出できます。違いがある場合は、クラスタの状態を自動的に更新またはロールバックすることで常にGitとKubernetes環境を同期し続けることができます。
また、GitをCDのベースとすることで、Gitのマージ/プルリクエストといったなじみのある開発方法でKubernetesにデプロイできます。
GitOpsでは、デプロイをCDツール、ビルド部分をCIツールが担い、CIとCDの責務を分離します。
従来の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の仕組み
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の概要は下記の通りです。
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
「overlays/dev」ディレクトリにある「patch.yaml」では、Applicationカスタムリソースを使って環境に依存するデプロイ定義を設定します。本稿では、「replica」数を差分として定義しました。
apiVersion: apps/v1 kind: Deployment metadata: name: wordpress labels: app: wordpress spec: replicas: 1
overlays/devディレクトリの「kustomization.yaml」では、リソースとしてベースとなるマニフェスト、パッチとして適用するマニフェストを指定します。
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: dev resources: - ../../base # ベースとなるマニフェストを定義 - mysql-pass.yaml # dev環境用のSecretマニフェストを定義 patches: - patch.yaml # パッチとして適用するマニフェストを定義
「overlays/dev」ディレクトリの「mysql-pass.yaml」では、「MySQL」に接続するためのパスワードを「Secret」リソースとして記述しています。
なお本稿では、Secretリソースをそのままリポジトリに格納していますが、本番の運用では後述の通りセキュリティリスクがあるので、暗号化した上で格納してください。
apiVersion: v1 data: password: c2FtcGxl kind: Secret metadata: creationTimestamp: null name: mysql-pass namespace: dev
サンプルアプリケーションをArgo CDに登録する
このサンプルアプリケーションをArgo CDに登録していきましょう。Argo CDにアプリケーションを登録するには、次の2つのステップが必要です。
- リポジトリの登録(リポジトリへの認証が必要な場合)
- アプリケーションの登録(リポジトリとマニフェストの場所、同期設定など)
Argo CDにリポジトリを登録
今回はGitLabのプライベートリポジトリにマニフェストを格納しているので、Argo CDにリポジトリ情報を設定する必要があります。Argo CDはHTTPS(パスワード認証)、HTTPS(証明書認証)とSSH(鍵認証)の認証方式をサポートしています。
本稿では、利用が最も簡単なHTTPS(パスワード認証)を使用して設定します。よりセキュリティを強固にしたい場合は、HTTPS(証明書認証)やSSH(鍵認証)の利用をお勧めします。HTTPS(証明書認証)やSSH(鍵認証)を使用した設定を確認したい場合は、公式ドキュメントをご覧ください。
Argo CDでリポジトリを定義する方法として下記の3つの方法があります。
- Webブラウザによる定義
- CLIによる定義
- カスタムリソースを用いたマニフェストによる定義
本稿では、簡単に使えるWebブラウザによる定義と、1コマンドで定義できるCLIの2つの方法を紹介します。
・Webブラウザからリポジトリを設定する
ログイン画面でusernameとpasswordを入力後、トップ画面が表示された状態で、左側にあるメニューの設定アイコンをクリックします。クリックすると、「Settings」画面が表示されます。
「Repositories」をクリックすると、リポジトリ設定画面が表示されます。初期状態では、リポジトリが設定されていないので、「No repositories connected」と表示されます。
「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」と表示されます。
・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ブラウザによる定義
- CLIによる定義
- カスタムリソースを用いたマニフェストによる定義
本稿では、簡単に使えるWebブラウザによる定義と、複雑なデプロイの定義に便利なカスタムリソースを用いたマニフェストによる定義の2つの方法を紹介します。
・Webブラウザからアプリケーションを登録する
「CREATE APPLICATION」をクリックすると、登録画面が表示されます。
「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がサポートするツールに対する設定です。本稿では紹介しないので、必要な方は下記公式ドキュメントをご覧ください。
- Helm:https://argo-cd.readthedocs.io/en/stable/user-guide/helm/
- Kustomize:https://argo-cd.readthedocs.io/en/stable/user-guide/kustomize/
- Jsonnet:https://argo-cd.readthedocs.io/en/stable/user-guide/jsonnet/
- その他プラグイン:https://argo-cd.readthedocs.io/en/stable/user-guide/config-management-plugins/
なお、設定画面上は「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の初期画面が表示されました。
・マニフェストを使用してアプリケーションを登録する
リポジトリの認証設定同様、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に相当)
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」ボタンをクリックすると、同期するための設定画面が表示されます。
同期時にリソースを削除する場合は「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 CDのアプリケーションの同期が実行されると結果がメールで通知されます。最新の設定内容については、GitHub上の設定サンプルをご覧ください。
CIパイプラインとの連携
KubernetesにおけるCI/CDでは、CIでコンテナイメージをリポジトリに登録し、CDでマニフェストをKubernetesクラスタにデプロイします。
CIを実施した後で、変更したイメージをクラスタに反映するには、Kubernetesにデプロイするマニフェスト(本稿ではKustomizeのファイル)を変更し、指定したコンテナイメージのバージョンをCIで新たに作成したバージョンに変更してコミットします。これにより、変更したイメージでアプリケーションのデプロイが更新されます。
その他、CIパイプライン内でKubernetesのデプロイマニフェストを更新して、リポジトリのコンテナイメージ更新後、自動的にKubernetesのマニフェストに新たなコンテナバージョンを登録する方法や、上述のImage Updaterの機能を利用してイメージを自動更新する方法もあります。
ここからはCIパイプラインとの連携方法の選択肢とメリデメを簡単に説明します。手動で連携する方法と自動化して連携する方法があります。
手動による連携
デプロイマニフェストを手動で修正してGitリポジトリにプッシュすることでCDのトリガーを引きます。
- メリット
- デプロイのタイミングを自分でコントロールできる
- 依存関係のある複数のデプロイを同期できる
- デプロイマニフェストの修正内容を柔軟にできる
- 導入しやすい
- デメリット
- デプロイに必要な手間が増えるのでリリース頻度が落ち、リリースまでのリードタイムが長くなる可能性がある
- 手作業によるミスが混入しやすい
手動による連携は、下記のような利用シーンが想定されます。
- 慎重なリリースが必要なケース
- 複数のデプロイを同期させる必要があるケース
- 後方互換性が保たれない変更が必要なケース
自動による連携
自動でデプロイマニフェストを修正してGitリポジトリにプッシュすることでCDのトリガーを引きます。
- メリット
- アプリケーションの修正からデプロイまでが自動化されるので、リリース頻度が向上し、リリースまでのリードタイムが短縮できる
- 作業ミスが混入しにくい
- デメリット
- バージョニングやデプロイ戦略の設計が必要なので、手動と比べて導入ハードルが高い
- 複雑な変更のデプロイに対応しにくい
- デプロイに失敗した場合のロールバックの戦略の検討が必要
自動による連携方法は、下記のような利用シーンが想定されます。
- 機械的なリリースが可能なケース
- 一サービスのデプロイのみ単独で実行できるケース
- 後方互換性が保たれ、コンテナイメージタグのバージョンアップなどの単純な変更のみで対応できるケース
自動的に連携する方法としては、下記2つの方法が考えられます。
- CI内でデプロイマニフェストを修正
- 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.
関連記事
- いまさら聞けない「CI/CD」の意義――GitHubとGitHub ActionsでCI/CDを試してみよう
GMOペパボにおけるCI/CD活用事例を紹介する本連載。第1回は組織でCI/CDを導入する目的と意義を整理し、GitHub/GitHub Actionsを利用してCI/CDを実践する方法を紹介します。 - CI/CDは何がまずいのか、コード作成から本番デプロイまでの時間短縮に注力
オブザーバビリティツールを手掛けるhoneycomb.ioの共同創業者でCTOを務めるチャリティ・メージャーズ氏が、CI/CDの問題点を指摘した。CIにばかり注力せず、CDにも気を配るべきであり、特にコード作成から本番環境へのデプロイまでの「時間の短縮」にフォーカスすべきだという。 - CNCF、継続的デリバリー技術のお薦めは?――新興技術ガイド「CNCF Technology Radar」の第1弾を公開
Cloud Native Computing Foundation(CNCF)は、「CNCF End User Community」の意見に基づく新興技術ガイド「CNCF Technology Radar」の第1弾を公開した。