☸️

ArgoCDで複数クラスターにデプロイできる環境をローカルに構築してみた

に公開

はじめに

こんにちは、ひよつくです。
みなさん、Kubernetes(K8s)は使っていますか?
私は毎日マニフェストやHelmチャートとにらめっこする日々を過ごしています

最近だと某質問箱サービス終了の話題でK8sが登場していましたね
K8sは使い方を間違えると大変ですが、正しく構築、運用すればとても便利で素晴らしいツールです~

というわけで本題に入りますが、今回はローカル環境でkindクラスターを使ってArgoCDで複数のクラスターにアプリデプロイしてみたいと思います

kindクラスター? ArgoCD?

まずは用語を軽く説明しましょう

kindクラスター

kindクラスターはDockerを使ってローカル環境にK8sクラスターを簡単に作れるツールです
元々はK8s自体を開発するためのツールだったみたいですが、ローカルでさくっとK8sクラスターが作れるのでいろんな検証に使えて便利なのでおすすめです

kindの公式ドキュメントはこちら

ArgoCD

ArgoCDはK8s上のCDに特化したOSSツールです
GitOpsに基づいてリポジトリを監視して自動でデプロイしてくれます

ArgoCDの公式ドキュメントはこちら

今回はこのkindというツールを活用して、ArgoCDを検証していきたいと思います

ローカルでkindクラスター構築

kindクラスター立ち上げ

まずはローカル環境を構築しましょう
今回はローカル上で2つのkindクラスターを作ります

1つ目のクラスターはappと名付けましょう

kind create cluster --name=app

2つ目のクラスターはdeployと名付けましょう

kind create cluster --name=deploy

ArgoCDデプロイ

そしたらdeployの方にArgoCDをデプロイしましょう
今回はhelmfileを使ってデプロイしたいと思います
公式ドキュメントを確認したい方はこちらをご参考ください👇️

公式ドキュメント

まずはhelmfile.yaml.gotmplファイルを作成しましょう

repositories:
  - name: argo
    url: https://argoproj.github.io/argo-helm
releases:
  - name: argocd
    namespace: argocd
    chart: argo/argo-cd
    version: 8.3.0
    values:
      - ./argocd-values.yaml

もしhelmfileをインストールしてなかったらhomebrewを使ってインストールしておきましょう

brew install helmfile

次は後ほど使うvaluesファイルを予め作成しておきましょう。中身は空でも大丈夫です

touch argocd-values.yaml

そしたら現在のcontextをdeployクラスターに設定して

kubectl config use-context kind-deploy

helmfileでデプロイしましょう!
(Helmのバージョンが3.8以上であることを確認しましょう)

helmfile apply

そしたらArgoCDがdeployクラスターにデプロイされたと思います!

ここでディレクトリを一回確認してみましょ

.
├── argocd-values.yaml
└── helmfile.yaml.gotmpl

2つのファイルが同じ階層にあって、ArgoCDがクラスター内にデプロイされてればOKです!

ArgoCDでデモアプリをデプロイ

ArgoCDの準備

ArgoCDがデプロイできたら、今後のアプリは全部ArgoCDにデプロイさせましょう!

でもその前にまずArgoCDの初期セットアップをしておきましょう

HomebrewでArgoCD CLIをインストールしましょう

brew install argocd

公式ドキュメントにも載ってる方法でadmin userの初期PWそ取得します

argocd admin initial-password -n argocd

出力されたPWは後ほど使うので控えておきましょう

ArgoCDにクラスターを認証させる

さて、ここからが本題です!

ArgoCDが複数のクラスターにアプリをデプロイするには、対象となるクラスターを認証させてあげる必要があります

公式ドキュメントによれば、認証にはK8sのサービスアカウントを使用してるようです

サービスアカウントはArgoCD CLIを使えば比較的簡単に設定出来ますが、今回はせっかくなのでhelmで明示的にクラスター設定をしてみましょう

まずはappクラスターに以下のマニフェストを作成してapplyしておきましょう

cat > argocd-sa.yaml - <<'EOF'
apiVersion: v1
kind: ServiceAccount
metadata:
  name: argocd-manager
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: argocd-manager-role-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: argocd-manager
  namespace: kube-system
EOF
kubectl apply -f argocd-sa.yaml --context kind-app

次は上記で作成したサービスアカウントのトークンを取得してー

SECRET=$(kubectl -n kube-system get sa argocd-manager -o jsonpath='{.secrets[0].name}' --context kind-app)
kubectl -n kube-system get secret "$SECRET" -o jsonpath='{.data.token}' --context kind-app| base64 -D; echo

出てきたトークンを控えておきましょう

すぐに使います

あとはこちらで作成しておいたargocd-values.yamlに以下の内容を追加して、前のステップで取得したトークンをbearerTokenに入れておきましょう

configs:
  clusterCredentials:
    deploycluster:
      server: https://kubernetes.default.svc
      config:
        tlsClientConfig:
          insecure: true
    appcluster:
      server: https://<DOCKER_CONTAINER_IP>:6443
      config:
        bearerToken: "<YOUR_TOKEN>"
        tlsClientConfig:
          insecure: true

さて、ローカル検証で重要なポイントはここです!

よーく見てみると configs.clusterCredentials.appcluster.server の値が足りないですね

ここに入れるIPは「appクラスターが動いてるDockerコンテナのIP」になります

理屈は簡単で、kindはdockerコンテナを1つのノードとしてクラスターを構築するので、コンテナのIP向けにK8sのAPIを送る必要があるためです

これがクラウドに載っているK8sだったらちゃんとしたエンドポイントがあるんですが、ローカルなのでコンテナIPを使っているというわけです

appクラスターのコンテナIPは以下のコマンドで取得しましょう

docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' app-control-plane

取得したIPをargocd-values.yamlに書き足したら、helmfileでArgoCDを更新しましょう!

helmfile sync

そしたらいよいよArgoCDのダッシュボードにアクセスしてみましょう!

まずはport-forwardしときましょ

kubectl -n argocd port-forward svc/argocd-server 8081:443

そして https://localhost:8081 にアクセス

ArgoCDログイン画面

ログイン画面では以前控えておいた初期PWを使ってログインしましょう

IDはadminです

ログインできたら左側のセクションからSettingsを選択し、Clustersを確認しましょう

この画像のようになっていれば成功です!

ArgoCDクラスター設定画面

デモアプリのデプロイ

さて、複数のクラスターを認証させたのであとはクラスターを指定してアプリをデプロイするだけですね!

今回はApplicationというyamlを利用してguestbookというアプリをデプロイします

デモアプリのソースはこちら

まずは普通にArgoCDがホストされているdeployクラスターにデプロイしてみましょう

以下のようなApplicationを作成してkubectl applyしてみましょう

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook-deploy
  namespace: argocd
  labels:
    name: guestbook
spec:
  project: default
  source:
    repoURL: https://github.com/argoproj/argocd-example-apps.git
    targetRevision: HEAD
    path: helm-guestbook
    helm:
      valueFiles:
      - values.yaml
  destination:
    name: deploycluster
    namespace: default

重要なポイントはspec.destination.nameargocd-values.yamlで決めたクラスター名を入れてあげることです!

これだけでdestination(目的地)を決めれるわけですね〜

この調子でappクラスターにも同じアプリをデプロイしてみましょう

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook-app
  namespace: argocd
  labels:
    name: guestbook
spec:
  project: default
  source:
    repoURL: https://github.com/argoproj/argocd-example-apps.git
    targetRevision: HEAD
    path: helm-guestbook
    helm:
      valueFiles:
      - values.yaml
  destination:
    name: appcluster
    namespace: default

こちらをkubectl applyしてあげれば、以下のような画面になります!

ArgoCDアプリデプロイ後

destinationがそれぞれ違うことがわかると思います!

ここでSyncしてあげると、実際にそれぞれのクラスター内でデプロイが走ります〜

Syncが完了したらこうなります!

ArgoCD_Sync完了

確認してみよう

🤔「本当にArgoCDが別のクラスターにちゃんとデプロイしてるのか...?」

気になってきたので確認してみましょう!

確認大事

まずはappクラスターにcontextを変えましょう

kubectl config use-context kind-app

そしたらdefaultnamespaceにちゃんとguestbookがデプロイされたか見てみましょう

kubectl -n default get pod
NAME                                           READY   STATUS    RESTARTS   AGE
guestbook-app-helm-guestbook-8b4447bd4-trtbp   1/1     Running   0          4m56s

おお〜ちゃんと入ってますね〜

せっかくなのでport-forwardで中も見てみましょう

kubectl port-forward svc/guestbook-app-helm-guestbook 8080:80

そのあと https://localhost:8080 にアクセスしてみると...

guestbook

ちゃんと動いてました!

これでArgoCDで複数のクラスターにアプリをデプロイできることがわかりましたね!

まとめ

今回はArgoCDから複数のクラスターにアプリをデプロイするローカル環境を構築してみました

これでみなさんのローカルK8sライフがさらに捗るんじゃないでしょうか

重要なポイントをまとめると

  • ArgoCDは複数のクラスターを跨いでデプロイできる
  • kindクラスターのDockerコンテナIPをエンドポイントに使う
  • ArgoCDの認証はサービスアカウントとトークンで行う

みたいな感じでしょうか!

ArgoCDはGithub上のプライベートリポジトリも監視できるので、自作アプリやHelmチャートもどんどんローカルにデプロイしましょう笑

今回使った技術スタックもまとめておきます

  • Kubernetes (kind)
  • kubectl
  • Docker
  • ArgoCD

最後に余談ですが今年はなんとK8sの10周年です!

一緒にK8sを盛り上げて行きましょう〜

ではでは

Discussion