ArgoCDで複数クラスターにデプロイできる環境をローカルに構築してみた
はじめに
こんにちは、ひよつくです。
みなさん、Kubernetes(K8s)は使っていますか?
私は毎日マニフェストやHelmチャートとにらめっこする日々を過ごしています
最近だと某質問箱サービス終了の話題でK8sが登場していましたね
K8sは使い方を間違えると大変ですが、正しく構築、運用すればとても便利で素晴らしいツールです~
というわけで本題に入りますが、今回はローカル環境でkindクラスターを使ってArgoCDで複数のクラスターにアプリデプロイしてみたいと思います
kindクラスター? ArgoCD?
まずは用語を軽く説明しましょう
kindクラスター
kindクラスターはDockerを使ってローカル環境にK8sクラスターを簡単に作れるツールです
元々はK8s自体を開発するためのツールだったみたいですが、ローカルでさくっとK8sクラスターが作れるのでいろんな検証に使えて便利なのでおすすめです
ArgoCD
ArgoCDはK8s上のCDに特化したOSSツールです
GitOpsに基づいてリポジトリを監視して自動でデプロイしてくれます
今回はこの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 にアクセス
ログイン画面では以前控えておいた初期PWを使ってログインしましょう
IDはadmin
です
ログインできたら左側のセクションからSettings
を選択し、Clusters
を確認しましょう
この画像のようになっていれば成功です!
デモアプリのデプロイ
さて、複数のクラスターを認証させたのであとはクラスターを指定してアプリをデプロイするだけですね!
今回は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.name
にargocd-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
してあげれば、以下のような画面になります!
destination
がそれぞれ違うことがわかると思います!
ここでSync
してあげると、実際にそれぞれのクラスター内でデプロイが走ります〜
Sync
が完了したらこうなります!
確認してみよう
🤔「本当にArgoCDが別のクラスターにちゃんとデプロイしてるのか...?」
気になってきたので確認してみましょう!
確認大事
まずはapp
クラスターにcontextを変えましょう
kubectl config use-context kind-app
そしたらdefault
namespaceにちゃんと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 にアクセスしてみると...
ちゃんと動いてました!
これでArgoCDで複数のクラスターにアプリをデプロイできることがわかりましたね!
まとめ
今回はArgoCDから複数のクラスターにアプリをデプロイするローカル環境を構築してみました
これでみなさんのローカルK8sライフがさらに捗るんじゃないでしょうか
重要なポイントをまとめると
- ArgoCDは複数のクラスターを跨いでデプロイできる
- kindクラスターのDockerコンテナIPをエンドポイントに使う
- ArgoCDの認証はサービスアカウントとトークンで行う
みたいな感じでしょうか!
ArgoCDはGithub上のプライベートリポジトリも監視できるので、自作アプリやHelmチャートもどんどんローカルにデプロイしましょう笑
今回使った技術スタックもまとめておきます
- Kubernetes (kind)
- kubectl
- Docker
- ArgoCD
最後に余談ですが今年はなんとK8sの10周年です!
一緒にK8sを盛り上げて行きましょう〜
ではでは
Discussion