フューチャー技術ブログ

Argo CDを体感してみる

はじめに

TIG岸下です。CNCF連載6日目になります。
業務では主にCIとしてJenkinsを利用しているのですが、前々から気になっていたArgo CDを本連載を機に体感してみたいと思います。

CI/CD is 何?

画像引用元: CD Foundation - CI/CD Patterns and Practices

皆さんは、コードの作成からデプロイまでの流れをどのように行っていますか?

エンジニアは効率化が大好きで、プロセスが常に最適化されるような試行錯誤を常日頃行っております。その結果、過去には手作業で行われていたテストやデプロイが自動化され、開発者はより創造的な作業に集中できるようになりました。また、画像のようなDevOpsの潮流もあり、Dev(開発)とOps(運用)を合体させて、ユーザーへクイックにソフトウェアをデリバリーすることが要求されるようになったことも背景にあります。

その変革の一環として注目されているのが、CI/CD(Continuous Integration / Continuous Delivery)です。CI/CDは、エラーの早期発見や迅速な新機能のリリースを可能にするだけでなく、開発者が直面するストレスを減らし、創造性を高めることを目指しています。

Continuous Integration(継続的インテグレーション)は、コードの変更を頻繁にメインラインにマージするプラクティスです。これにより、バグやコンフリクトを早期に検出し、修正を容易にします。一方、Continuous Deployment(継続的デプロイメント)は、ビルドとテストが成功したコードの変更を自動的に本番環境にデプロイします。これにより、新しい機能や修正を素早くユーザーに提供することが可能となります。

開発プロセスの自動化が求められるようになった背景には、複数の開発者が同時に取り組む大規模なプロジェクトが増え、バグやエラーを早期に発見して修正し、新機能を安全かつ迅速にリリースする必要性が高まったことがあります。

参考: Red Hat - CI/CDとは

Argoって?

このような状況を背景に、CI/CDを実現する様々なツールが登場しました。

弊ブログでも過去にCI/CDツールを取り上げておりますので、ぜひ参考にして下さい。

こうした中でクラウドネイティブなアプリケーションの開発・デプロイメントと、そのためのツールと環境の必要性として生まれたのがArgoになります。Argoは、最初からKubernetesを基盤として設計されています。KubernetesのAPIを直接使用し、Kubernetes上での実行を自然にサポートしています。

また、 「Get More Done with Kubernetes」 を掲げていることからも、Kubernetesという現代のクラウドネイティブ環境を最大限活用することを目指し、自動化・効率化を更に進化させる手段として開発されていることがわかります。

Argoの核となる機能

ArgoはArgo CDを含めて4つの主要な機能を提供しております。

Argo CD

GitOpsの理念を追求するためのCDツールです。GitリポジトリをSingle Source of Truthと位置づけ、デプロイメントの状態が常にGitの内容と同期していることを保証します。

Argo Workflows

Kubernetes上で一連のタスクを連携させ、複雑なワークフローを作成、実行、管理するためのツールです。例えば、機械学習のパイプラインやデータ処理のワークフローなどを効率的に構築できます。

Argo Events

イベント駆動型のワークフローを支えるツールです。具体的には、Webhookやメッセージキューなどの外部イベントに反応して、ワークフローやKubernetesリソースを自動的に起動します。

Argo Rollouts

より高度なデプロイメント戦略を実装するためのツールです。例えば、カナリアリリースやBlue/Green DeploymentなどのProgressive Delivery戦略を簡単に実行できます。

本記事ではArgo CDを触ってみようと思います。

Argo CDを触ってみる

Kubernetesクラスタの準備

minikubeやkind、もしくはGoogle CloudのGKEなどを利用してクラスタを構築します。

terminal
# kind
kind create cluster
# minikube
minikube start

Argo CDとArgo CD CLIのインストール

以下のコマンドでArgo CDとArgo CD CLIをインストールします。

terminal
# Argo CDをインストールする前に、Namespace:argocdを作る必要がある
kubectl create namespace argocd
# Argo CDのインストール
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Argo CD CLIのインストール
# MacOSの場合
brew install argoproj/tap/argocd
# Linuxの場合
curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64 && chmod +x /usr/local/bin/argocd
# Argo CD CLIインストール後の確認
argocd version
# 以下が表示されればOK
argocd: v2.7.5+a2430af
BuildDate: 2023-06-16T15:00:03Z
GitCommit: a2430af1c356b283e5e3fc5bde1f5e2b5199f258
GitTreeState: clean
GoVersion: go1.19.10
Compiler: gc
Platform: linux/amd64
...

Argo CDのインストールができたらサーバーへアクセスしてみましょう。
以下のコマンド実行後、https://localhost:8080からダッシュボードへアクセスできます。

terminal
# Argo CDのServiceをポートフォワード
kubectl port-forward svc/argocd-server -n argocd 8080:443

Usernameはadmin、Passwordは以下のコマンドから取得できます。

terminal
# Secretからパスワードを取得
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

アプリケーションのデプロイ

今回はArgo CDが公開している下記のサンプルリポジトリをForkしてデプロイできるように設定していきます。

https://github.com/argoproj/argocd-example-apps

以下のコマンドでアプリケーションをArgo CDへ登録します。

terminal
argocd app create guestbook \
--repo https://github.com/<YOUR_GITHUB_ACCOUNT>/argocd-example-apps.git \
--path guestbook \
--dest-server https://kubernetes.default.svc \
--dest-namespace default \
--revision master \
--sync-policy automated
  • --repo: Argo CDに登録するリポジトリ。
  • --path: リポジトリ内に存在するアプリケーションのパス。
  • --dest-server: クラスタ内部のPodがKubernetes APIに接続するためのアドレス。
  • --dest-namespace: デプロイ先のNamespace。
  • --revision: Argo CDで監視するブランチ。今回の場合、masterブランチに変更があった場合、CDが走る。
  • --sync-policy: リポジトリとの同期オプション。automatedで自動で同期されるようになる。

上記コマンド実行後、以下のようにアプリケーションが登録されていればOKです。
アプリケーション内の「SYNC」→「SYNCHRONIZE」からアプリケーションをデプロイしてみましょう。

アプリケーションのデプロイ後、アプリケーションをクリックするとそれぞれのマニフェストの関係がグラフ化されます。マニフェストはそれぞれ独立して書くこと多く、マニフェスト同士の関係がうまく想像できなくなることがよくあるのですが、このように可視化されるとわかりやすいですね。

さらに、SYNCされた際の情報やヘルスチェック情報なども表示されています。

デプロイされたアプリケーションにもアクセスして動作確認をしてみます。

以下のコマンドを実行後、http://localhost:8081にアクセスするとアプリケーションを見ることができます。

terminal
# guestbookアプリケーションのServiceをポートフォワード
kubectl port-forward svc/guestbook-ui -n default 8081:80

CDを走らせてみる

監視先のリポジトリのマニフェストファイルを変更し、CDを走らせてみます。

今回は、guestbook/guestbook-ui-deployment.yamlのimage versionを変更します。適当なブランチを切り、プルリクエストを投げてApprove後、マージというような状態を想定してみましょう。(もちろん、masterブランチにそのままPushしてもCDは走ってくれます。)

Forkしたリポジトリ内でプルリクエストを出す際はマージ先にFork元を指定できてしまうため、
間違えてFork元にPRを作成しないように気を付けてください。

guestbook/guestbook-ui-deployment.yaml
...
spec:
containers:
- - image: gcr.io/heptio-images/ks-guestbook-demo:0.2
+ - image: gcr.io/heptio-images/ks-guestbook-demo:0.1

Argo CDでは--sync-policyautomatedにしている場合、デフォルトで180秒毎にSync先のリポジトリにポーリングしに行くので、少し待っていると「LAST SYNC」の箇所が最新化され、アプリも以下の様なversion 0.1のimageがデプロイされます。

環境差分を考慮する

実運用を考えるうえで、デプロイ先のdev/stg/prdといった環境の違いを考慮する必要があります。

例えば、devであればPod数1、stg/prdはPod数3にしたり、dev/stg/prd毎でサービス公開先のドメインを変更したりするなどアプリケーションのインフラとなる以上、1つのファイルで管理することはほぼ不可能です。デプロイの度に変数を変更するという運用で頑張ろうスタイルもありますが、人間はミスをする生き物である以上、その運用は確実に破綻します。

Argo CDではkubectlだけでなく、下記のツールを利用することで環境差分を考慮したデプロイが可能となっております。

  • Kustomize
    • 「kustomization.yaml」または「kustomization.yml」というファイルがある場合。
  • Ksonnet
    • 「app.yaml」と「components/params.libsonnet」という2つのファイルがある場合。
  • Helm
    • 「Chat.yaml」というファイルがある場合。
  • kubectl
    • 上記以外の場合。

参考:Kubernetes CI/CDパイプラインの実装

今回はKustomizeを利用してみます。

Kustomize

Kustomizeの構文の基本は、変更元のマニフェストファイルに対して変更箇所だけを記載したマニフェストを足す形でデプロイ用のマニフェストファイルを作成します。

kubectl v1.14以降であれば、Kustomizeをサポートしているため特にインストールの必要はありません。

今回利用しているアプリケーションでもKustomizeのサンプルは付いているのですが、実運用をシミュレーションするうえで以下のようなフォルダ構成に変更します。

kustomize-guestbook
├── base
│ ├── guestbook-ui-deployment.yaml
│ ├── guestbook-ui-svc.yaml
│ └── kustomization.yaml
└── overlays
├── dev
│ └── kustomization.yaml
└── stg
└── kustomization.yaml

base配下には基本となるマニフェストファイルを配置し、overlays配下には環境識別子毎の差分を格納したkustomizeファイルを配置します。baseのkustomization.yamlファイルの中身は以下のようになります。

base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- guestbook-ui-deployment.yaml
- guestbook-ui-svc.yaml

また、overlays配下は以下のようになります。

overlays/dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namePrefix: dev-
commonLabels:
env: dev
namespace: dev
resources:
- ../../base

stg側のkustomization.yamlはdevの箇所がstgに変わるだけで、その他は違いがありません。
Gitリポジトリ内にdevstgのブランチを作成後、それぞれをArgo CDにデプロイします。
今回はどちらも同じクラスターにデプロイしていますが、実運用上だと環境ごとに異なるクラスターが用意されていることが想定されます。

terminal
for env in dev stg; do
argocd app create $env-guestbook \
--repo https://github.com/<YOUR_GITHUB_ACCOUNT>/argocd-example-apps.git \
--path kustomize-guestbook/overlays/$env \
--dest-server https://kubernetes.default.svc \
--dest-namespace $env \
--revision $env \
--sync-policy automated
done

デプロイ後、ダッシュボードからそれぞれを確認すると各マニフェストの名前に環境識別子のプレフィクスがついていることがわかります。(以下はSTG)

このように、環境を考慮したCDができるようになりました。

今回はArgo CDを体感するのみでしたが、imageのversionやハッシュを置き換えたり、別のdeployment.yamlを用意しておいてPatch機能を使ってマニフェストの中身を置き換えたりすることもできます。

また、運用に合わせてHelmやKsonnetの方が適用しやすいこともあるので、実情に合わせたデプロイツールの選択が大切になります。

まとめ

本記事ではArgo CDの特性と利便性について説明し、簡単なハンズオンをやってみました。UIが非常に見やすく、マニフェストの関係同士を可視化してくれるなど、Kubernetesを利用するにあたって非常に便利なツールだなと実感しました。

本連載ではCNCFが公認したクラウドネイティブなソフトウェアを取り扱ってきました。ただ、Kubernetesなんかは響きはカッコいいものの取り扱いが難しいと感じることもありますが、CNCF(Cloud Native Computing Foundation)では、それらを導入するハードルを下げる取り組みが多々行われています。

特に、ArgoのようなCNCFが公認したGraduatedと認定したツール群はKubernetesの難解さを緩和し、その真の力を引き出す一助となります。また、これらのツールはクラウドネイティブのエコシステム全体を理解することにも役立ちます。

またGraduatedなプロジェクトだけでなく、本連載でも取り上げたIncubating/Sandboxのような期待値の高いプロジェクトも多く存在します。この連載を通じて、クラウドネイティブに興味を持った方はぜひCNCFのプロジェクトを覗き、一緒にクラウドネイティブの未来を切り開いていきましょう。

アイキャッチ画像にはCNCF公式のArgoロゴを利用させていただいております。