💨

Argo CDのセットアップ方法を解説してみる

に公開

はじめに

Argo CDとは、Kubernetesのための継続的デリバリー(CD)ツールです。GitOpsの原則に従い、Gitリポジトリの状態をKubernetesクラスターに同期させることができます。これにより、アプリケーションのデプロイメントや管理が容易になります。

Kubernetes環境では広く利用されているArgo CDですが、Argo CD自体のセットアップ方法はいくつかの方法があります。ここでは、Argo CDの初期セットアップについて解説します。

Argo CDの初期セットアップ

Argo CDを利用可能にするには、以下の手順が必要になります。

  • Argo CD CRDのインストール
  • Argo CDリソースのインストール
  • Argo CDアプリケーションの定義、インストール

Argo CD インストール

https://argo-cd.readthedocs.io/en/stable/#getting-started

まず、Argo CDのドキュメントに記載されている通り、以下のコマンドを実行してクラスターにArgo CDをインストールします。

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

このコマンドは何をしているのでしょうか? 実際にこのファイルの中身を確認してみましょう。raw.githubのリンクをクリックすると、およそ25000行からなるマニフェストファイルが存在します。これを全て読むのは大変なので、要点をまとめます。

CRDのインストール

まず最初に存在するのがCustom Resource Definition (CRD)です。CRDはKubernetesのリソースを拡張するための仕組みで、Argo CDでは以下のCRDが定義されています。

  • applications.argoproj.io
  • applicationsets.argoproj.io
  • appprojects.argoproj.io

これらのCRDは、Argo CDのリソースを定義するためのものです。

applications.argoproj.io

これは、最も基本的なCRDで、Argo CDの中心的な機能を提供します。

主な機能:

  • Gitリポジトリからのアプリケーションのデプロイメント管理
  • アプリケーションの同期状態の追跡
  • ヘルスチェックの実行
  • リビジョン管理

applicationsets.argoproj.io

これは、複数のアプリケーションを一括で管理するためのCRDです。

主な機能:

  • テンプレートベースのアプリケーション生成
  • 複数のGitリポジトリやクラスターへの一括デプロイ
  • 条件に基づくアプリケーションの自動生成

appprojects.argoproj.io

これは、アプリケーションの論理的なグループ化とアクセス制御を提供するCRDです。

主な機能:

  • プロジェクトベースのアクセス制御
  • リソースの制限設定
  • ソースリポジトリの制限
  • デスティネーションクラスターの制限

これらのCRDはargoproj.ioというグループに属しており、呼び出す際はargoproj.io/v1alpha1というバージョンを指定します。

サービスアカウントの作成

Argo CDの各コンポーネントは、Kubernetesクラスター内で特定の権限を持って動作する必要があります。そのため、以下のようなサービスアカウントが作成されます。

  • argocd-application-controller: アプリケーションの管理と同期を担当
  • argocd-applicationset-controller: アプリケーションセットの管理を担当
  • argocd-dex-server: 認証サーバーとして動作
  • argocd-notifications-controller: 通知機能を担当
  • argocd-redis: キャッシュサーバーとして動作
  • argocd-repo-server: リポジトリ管理を担当
  • argocd-server: メインのWebサーバーとして動作

ロールと権限の設定

各サービスアカウントには、必要な最小限の権限が付与されます。具体的には以下のような権限が設定されます。

  • argocd-application-controllerには、アプリケーションの管理に必要な広範な権限('*')が付与
  • その他のコンポーネントには、それぞれの役割に応じた最小限の権限が設定
  • セキュリティの観点から、readOnlyRootFilesystem: trueallowPrivilegeEscalation: falseなどの厳格なセキュリティコンテキストが設定

コンポーネントのデプロイメント

Argo CDは以下の主要なコンポーネントで構成されています。それぞれの役割を確認しましょう。

  1. argocd-server

    • メインのWebサーバーとして動作
    • ユーザーインターフェースとAPIを提供
    • 認証と認可を管理
  2. argocd-repo-server

    • Gitリポジトリの管理を実行
    • マニフェストの生成と検証を実行
    • リポジトリの同期状態を管理
  3. argocd-application-controller

    • アプリケーションの状態を管理
    • クラスターとの同期を実行
    • ヘルスチェックを実行
  4. argocd-applicationset-controller

    • アプリケーションセットを管理
    • テンプレートベースのアプリケーションを生成
    • 一括デプロイを管理
  5. argocd-dex-server

    • 認証サーバーとして動作
    • SSOを提供
    • ユーザーを管理
  6. argocd-notifications-controller

    • 通知機能を管理
    • イベント通知を送信
    • 通知ルールを管理
  7. argocd-redis

    • キャッシュサーバーとして動作
    • セッションを管理
    • データを一時保存

ネットワークとセキュリティ

Argo CDは以下のようなセキュリティ対策が実装されています。

  • コンポーネント間の通信は必要なポートのみを開放
  • 厳格なネットワークポリシーによる通信制御を実施
  • 各コンポーネントの分離と保護を実施
  • セキュリティコンテキストを設定

高可用性とスケーラビリティ

Argo CDは本番環境での使用を考慮して設計されており、以下の機能を提供します。

  • podAntiAffinityによる分散配置を実施
  • 冗長性を確保
  • フェイルオーバー対策を実施
  • スケーリング機能を提供

モニタリングとログ

各コンポーネントには以下のようなモニタリング機能が実装されています。

  • メトリクスエンドポイントを提供
  • ヘルスチェックを実装
  • ログ収集の設定を実施
  • 監視機能を統合

インストールマニフェストのポイント

  1. セキュリティ重視

    • 最小権限の原則に従う
    • 厳格なセキュリティコンテキストを設定
    • ネットワークポリシーによる保護を実施
  2. 高可用性

    • 冗長性を確保
    • フェイルオーバー対策を実施
    • 分散配置を実施
  3. 拡張性

    • プラグインに対応
    • カスタマイズ可能な設定を提供
    • スケーラビリティを考慮
  4. 運用性

    • モニタリング機能を提供
    • ログ収集を実施
    • 通知機能を提供

これらの機能により、Argo CDは本番環境での使用に耐えうる、堅牢なGitOpsツールとして機能します。適切に設定を行い、定期的に動作確認とセキュリティ監査を実施することで、安全なアプリケーション運用が可能になります。

アプリケーションのセットアップ

先ほど述べた通り、インストールスクリプトを実行するとArgo CDのコンポーネントがデプロイされます。
しかし肝心のアプリケーションのセットアップは行われていません。

この時点でArgo CDは起動しているため、GUIからリポジトリに接続することも可能です。

今回は宣言的にアプリケーションをセットアップする方法を解説します。

https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/

これは非常に簡単で、先程のインストールしたCRDにあったApplicationというリソースを使用します。

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/argoproj/argocd-example-apps.git
    targetRevision: HEAD
    path: guestbook
  destination:
    server: https://kubernetes.default.svc
    namespace: guestbook

これは、guestbookというアプリケーションを作成するためのマニフェストです。

これを適用すると、Argo CDのGUIからguestbookというアプリケーションを作成することができます。

Argo CD Autopilot

これまで説明してきたArgo CDのセットアップ方法は、基本的なインストールと設定に焦点を当てたものでした。

しかし最近になってArgo CD Autopilotというツールが登場しました。

これは、Argo CDのインストールと管理をGitOpsの原則に従って自動化するものです。

Autopilotは、Argo CD自体のインストールと管理をGitOpsの原則に従って自動化します。具体的には、bootstrapコマンドを使用してArgo CDのマニフェストをターゲットクラスターにデプロイし、同時にGitOpsリポジトリにApplicationマニフェストをコミットします。これにより、Argo CDのインストール自体がGitOpsで管理されるようになります。

また、Autopilotはアプリケーションの追加や更新、環境間でのプロモーションのための明確な構造を提供します。これにより、プロジェクトとアプリケーションの作成が自動化され、必要なマニフェストがリポジトリに自動的にコミットされます。このアプローチは、特にマルチクラスター環境での運用を容易にします。

災害復旧の観点からも、Autopilotは優れた機能を提供します。以前にインストールされたすべてのアプリケーションで新しいクラスターをブートストラップすることが可能で、システムの復旧を迅速に行うことができます。また、シークレットの管理も改善されており、平文でのGit保存のリスクを軽減します。

一方、これまでのセットアップ方法は、各コンポーネントを個別に設定し、手動で管理する必要があります。これは柔軟性はありますが、運用の手間がかかるというデメリットがあります。また、シークレットの管理や災害復旧の面でも、より慎重な対応が必要になります。

Autopilotは現在も開発中であり、一部の基本コマンドはまだ実装されていない点に注意が必要です。しかし、GitOpsの原則に従った一貫性のある管理や、より簡単なセットアップと運用、災害復旧の容易さ、マルチクラスター環境での柔軟な運用など、多くの利点を提供しています。


実際に使用してみます。まずは自分自身のリポジトリを作成します。そしてGitHubのトークンも生成しておきます。

自分は今回、argocd-autopilot-testというリポジトリを作成しました。

トークンを生成するときは、対象となるリポジトリに対して書き込み権限が必要です。

準備した情報をもとに、以下のコマンドを実行します

	GIT_TOKEN=$(GIT_TOKEN) GIT_REPO=$(GIT_REPO) argocd-autopilot repo bootstrap

そうすると、以下のようなログが出力されます。

INFO cloning repo: https://github.com/Mkamono/argocd-autopilot-test.git
Enumerating objects: 2, done.
Counting objects: 100% (2/2), done.
Total 2 (delta 0), reused 1 (delta 0), pack-reused 0 (from 0)
INFO using revision: "", installation path: ""
INFO using context: "minikube", namespace: "argocd"
INFO applying bootstrap manifests to cluster...
namespace/argocd created
customresourcedefinition.apiextensions.k8s.io/applications.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/applicationsets.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/appprojects.argoproj.io created
serviceaccount/argocd-application-controller created
serviceaccount/argocd-applicationset-controller created
serviceaccount/argocd-dex-server created
serviceaccount/argocd-notifications-controller created
serviceaccount/argocd-redis created
serviceaccount/argocd-repo-server created
serviceaccount/argocd-server created
role.rbac.authorization.k8s.io/argocd-application-controller created
role.rbac.authorization.k8s.io/argocd-applicationset-controller created
role.rbac.authorization.k8s.io/argocd-dex-server created
role.rbac.authorization.k8s.io/argocd-notifications-controller created
role.rbac.authorization.k8s.io/argocd-redis created
role.rbac.authorization.k8s.io/argocd-server created
clusterrole.rbac.authorization.k8s.io/argocd-application-controller created
clusterrole.rbac.authorization.k8s.io/argocd-applicationset-controller created
clusterrole.rbac.authorization.k8s.io/argocd-server created
rolebinding.rbac.authorization.k8s.io/argocd-application-controller created
rolebinding.rbac.authorization.k8s.io/argocd-applicationset-controller created
rolebinding.rbac.authorization.k8s.io/argocd-dex-server created
rolebinding.rbac.authorization.k8s.io/argocd-notifications-controller created
rolebinding.rbac.authorization.k8s.io/argocd-redis created
rolebinding.rbac.authorization.k8s.io/argocd-server created
clusterrolebinding.rbac.authorization.k8s.io/argocd-application-controller created
clusterrolebinding.rbac.authorization.k8s.io/argocd-applicationset-controller created
clusterrolebinding.rbac.authorization.k8s.io/argocd-server created
configmap/argocd-cm created
configmap/argocd-cmd-params-cm created
configmap/argocd-gpg-keys-cm created
configmap/argocd-notifications-cm created
configmap/argocd-rbac-cm created
configmap/argocd-ssh-known-hosts-cm created
configmap/argocd-tls-certs-cm created
secret/argocd-notifications-secret created
secret/argocd-secret created
service/argocd-applicationset-controller created
service/argocd-dex-server created
service/argocd-metrics created
service/argocd-notifications-controller-metrics created
service/argocd-redis created
service/argocd-repo-server created
service/argocd-server created
service/argocd-server-metrics created
deployment.apps/argocd-applicationset-controller created
deployment.apps/argocd-dex-server created
deployment.apps/argocd-notifications-controller created
deployment.apps/argocd-redis created
deployment.apps/argocd-repo-server created
deployment.apps/argocd-server created
statefulset.apps/argocd-application-controller created
networkpolicy.networking.k8s.io/argocd-application-controller-network-policy created
networkpolicy.networking.k8s.io/argocd-applicationset-controller-network-policy created
networkpolicy.networking.k8s.io/argocd-dex-server-network-policy created
networkpolicy.networking.k8s.io/argocd-notifications-controller-network-policy created
networkpolicy.networking.k8s.io/argocd-redis-network-policy created
networkpolicy.networking.k8s.io/argocd-repo-server-network-policy created
networkpolicy.networking.k8s.io/argocd-server-network-policy created
secret/autopilot-secret created

INFO pushing bootstrap manifests to repo
Resolving deltas: 100% (1/1), done.
INFO applying argo-cd bootstrap application
W0502 19:18:38.347011   62027 warnings.go:70] metadata.finalizers: "resources-finalizer.argocd.argoproj.io": prefer a dom
ain-qualified finalizer name including a path (/) to avoid accidental conflicts with other finalizer writers
application.argoproj.io/autopilot-bootstrap created
INFO running argocd login to initialize argocd config
E0502 19:18:38.415961   62027 portforward.go:385] "Unhandled Error" err="error copying from remote stream to local connec
tion: readfrom tcp4 127.0.0.1:56954->127.0.0.1:56956: write tcp4 127.0.0.1:56954->127.0.0.1:56956: write: broken pipe" logger="UnhandledError"                                                                                                    'admin:login' logged in successfully
Context 'autopilot' updated

INFO argocd initialized. password: Q3pvKsBQJaOVjANB
INFO run:

    kubectl port-forward -n argocd svc/argocd-server 8080:80

なにやら少しエラーが出ているようですが、一旦気にせず進めます。
ログを確認すると、先程でてきたインストールマニフェストの内容が作成されているようです。

Kubernetesクラスターを確認してみると、Argo CDのコンポーネントが作成されていることが確認できます。

❯ kubectl get -n argocd pod
NAME                                               READY   STATUS    RESTARTS   AGE
argocd-application-controller-0                    1/1     Running   0          1m
argocd-applicationset-controller-986b445f-mrzrt    1/1     Running   0          1m
argocd-dex-server-86d46dc659-glnbj                 1/1     Running   0          1m
argocd-notifications-controller-6b57cb9df8-x57dx   1/1     Running   0          1m
argocd-redis-7bb46fc4dd-dbsz9                      1/1     Running   0          1m
argocd-repo-server-55475d8c9f-xqb6b                1/1     Running   0          1m
argocd-server-68789d47c9-w2wzk                     1/1     Running   0          1m

そしてログの最後に出ていたコマンドと、初期パスワードを使ってArgo CDのGUIにアクセスしてみます。

kubectl port-forward -n argocd svc/argocd-server 8080:80

ユーザー名はadminで、パスワードは先程のログの最後に出ているQ3pvKsBQJaOVjANBを使ってログインします。

また、GitHubのリポジトリを確認してみましょう。
以下のようなディレクトリ構造が作成されているはずです。

.
├── apps
│   └── README.md
├── bootstrap
│   ├── argo-cd
│   │   └── kustomization.yaml
│   ├── argo-cd.yaml
│   ├── cluster-resources
│   │   ├── in-cluster
│   │   │   ├── argocd-ns.yaml
│   │   │   └── README.md
│   │   └── in-cluster.json
│   ├── cluster-resources.yaml
│   └── root.yaml
└── projects
    └── README.md

それぞれのアプリケーションを確認してみます。まずは、argo-cdというアプリを確認してみます。

この中には、Argo CDのconfig map、secret、service、service account、CRD、deployment、statefulset、networkpolicy、clusterrole、clusterrolebinding、role、rolebindingが作成されています。

Argo CDに関してのリソースはすべてこの中で管理されていることがわかります。そしてこの内容はリポジトリのbootstrap/argo-cd.yamlファイルでGit管理されています。


次に、autopilot-bootstrapというアプリケーションを確認してみます。

このアプリケーションは、Argo CDの他のアプリケーションをapp of appsの構成で管理しているようです。アプリケーションセットとしてcluster-resourcesというものが作成されています。

autopilot-bootstrapはどうやらGit管理されておらず、変更することは想定していないような雰囲気があります。


次にcluster-resource-in-clusterというアプリケーションを確認してみます。

これは、cluster-resourcesというアプリケーションセットの中に作成されているアプリケーションです

管理されているのはArgo CDのnamespaceのみで、何を管理するアプリケーションなのか一目ではわかりませんね。

リポジトリのbootstrap/cluster-resources/in-clusterディレクトリで管理されており、READMEがあるので確認してみましょう。

Cluster Resources

This directory contains all cluster resources that should be applied to cluster: in-cluster. For example Namespace resources that are shared by multiple applications on the same namespace.

これは、特定の単一アプリケーションのためだけではなく、Kubernetesクラスター全体、あるいはクラスター内の複数のアプリケーションやコンポーネントによって共有されるようなKubernetesリソースを管理するためのもののようです。

例えばすでにあるようなnamespaceであったり、ResourceQuota、LimitRange、NetworkPolicy、CustomResourceDefinition (CRD)、ClusterRole、ClusterRoleBindingなど、クラスターレベルで定義されたり、特定のネームスペース全体に影響を与えたりする設定が含まれます。

ポイントとなるのは、複数のアプリケーションにとって共通の基盤や制約を提供する、ということです。


最後に、rootというアプリケーションを確認してみます。

現状はこのアプリケーションの中には何も登録されていないようです。

リポジトリのbootstrap/root.yamlファイルで管理されているのでそれを見ると、projectsというディレクトリを見ているので、そのREADMEを確認してみましょう。

これは、Argo CDのプロジェクトを管理するためのもののようです。Autopilotでは、簡単なコマンドを使用することによってプロジェクトを作成することができます。


ここまでで、Argo CDのコンポーネントが作成され、それぞれのアプリケーションが作成されました。では、自分のアプリケーションはどのように作成するのでしょうか?

それは、appsディレクトリのREADMEに記載があります。

試しに以下のコマンドを実行してみます。

argocd-autopilot project create testing
argocd-autopilot app create hello-world --app github.com/argoproj-labs/argocd-autopilot/examples/demo-app/ -p testing --wait-timeout 2m

このコマンドを実行すると、testingというプロジェクトが作成され、hello-worldというアプリケーションが作成されます。

argocd-autopilotコマンドはGit操作を伴うコマンドなので、リポジトリの方にもtestingプロジェクトと、appsディレクトリにhello-worldというアプリケーションが作成されます。

このように、Argo CD AutopilotではGit操作を伴うコマンドを実行することで、アプリケーションの作成やプロジェクトの作成を行うことができます。

まとめ

今回は、Argo CDのセットアップ方法を解説しました。

また、Argo CD Autopilotを使用することで、Git操作を伴うコマンドを実行することで、アプリケーションの作成やプロジェクトの作成を行うことができます。非常に便利で、セットアップが大幅に容易になるので積極的に活用していきたいと思います。

参考資料

Discussion