GitOps というアプリデプロイ戦略が Cloud Native な CD *1 で普及し始めています。
ソースコードのリポジトリとは別にアプリの設定用リポジトリを用意し、リポジトリの状態とデプロイの状態を一致させるようにツールを利用して管理します。これにより設定の変更を GitHub(GitLab) flow に載せることができ、オペミスやスクリプトのバグによる事故を防ぐことが可能になるとのことです。
GitOps の CD ツールの一つである Argo CD を GKE で使ってみました。
GKE のクラスタを作って credentials を設定し kubectl で操作できるようにします。
$ gcloud container clusters get-credentials xxx-cluster --zone asia-northeast-a --project xxxxx
接続を確認。ノード2つのクラスタを作りました。
$ kubectl get node NAME STATUS ROLES AGE VERSION gke-standard-cluster-1-default-pool-xxxxxxxxxxxxxxx Ready <none> 11m v1.13.11-gke.14 gke-standard-cluster-1-default-pool-xxxxxxxxxxxxxxx Ready <none> 11m v1.13.11-gke.14
Argo CD が動作するための namespace argocd
を作ります。
$ kubectl create namespace argocd namespace/argocd created
Argo CD の現時点の最新リリース 1.3.6 のマニフェストを使ってインストールします*2。
Release v1.3.6 · argoproj/argo-cd · GitHub
$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v1.3.6/manifests/install.yaml customresourcedefinition.apiextensions.k8s.io/applications.argoproj.io created customresourcedefinition.apiextensions.k8s.io/appprojects.argoproj.io created serviceaccount/argocd-application-controller created serviceaccount/argocd-dex-server created serviceaccount/argocd-server created role.rbac.authorization.k8s.io/argocd-application-controller created role.rbac.authorization.k8s.io/argocd-dex-server created role.rbac.authorization.k8s.io/argocd-server created clusterrole.rbac.authorization.k8s.io/argocd-application-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-dex-server created rolebinding.rbac.authorization.k8s.io/argocd-server created clusterrolebinding.rbac.authorization.k8s.io/argocd-application-controller created clusterrolebinding.rbac.authorization.k8s.io/argocd-server created configmap/argocd-cm created configmap/argocd-rbac-cm created configmap/argocd-ssh-known-hosts-cm created configmap/argocd-tls-certs-cm created secret/argocd-secret created service/argocd-dex-server created service/argocd-metrics created service/argocd-redis created service/argocd-repo-server created service/argocd-server-metrics created service/argocd-server created deployment.apps/argocd-application-controller created deployment.apps/argocd-dex-server created deployment.apps/argocd-redis created deployment.apps/argocd-repo-server created deployment.apps/argocd-server created
デプロイが完了したので、argocd の namespace を覗いてみます。
$ kubectl get deploy,pod,svc -n argocd NAME READY UP-TO-DATE AVAILABLE AGE deployment.extensions/argocd-application-controller 1/1 1 1 3m29s deployment.extensions/argocd-dex-server 1/1 1 1 3m29s deployment.extensions/argocd-redis 1/1 1 1 3m29s deployment.extensions/argocd-repo-server 1/1 1 1 3m29s deployment.extensions/argocd-server 1/1 1 1 3m28s NAME READY STATUS RESTARTS AGE pod/argocd-application-controller-59b7c6958d-676kv 1/1 Running 0 3m29s pod/argocd-dex-server-658745cd65-kks5t 1/1 Running 0 3m29s pod/argocd-redis-fc585c648-nr7z2 1/1 Running 0 3m29s pod/argocd-repo-server-6746fdc4dd-64c2x 1/1 Running 0 3m29s pod/argocd-server-85b5959ffb-st7xt 1/1 Running 0 3m28s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/argocd-dex-server ClusterIP 10.4.1.108 <none> 5556/TCP,5557/TCP 3m30s service/argocd-metrics ClusterIP 10.4.5.166 <none> 8082/TCP 3m30s service/argocd-redis ClusterIP 10.4.3.179 <none> 6379/TCP 3m30s service/argocd-repo-server ClusterIP 10.4.8.63 <none> 8081/TCP,8084/TCP 3m30s service/argocd-server ClusterIP 10.4.7.233 <none> 80/TCP,443/TCP 3m29s service/argocd-server-metrics ClusterIP 10.4.15.178 <none> 8083/TCP 3m30s
外部から Argo CD に接続できるよう、LoadBalancer を設定します。
$ kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
しばらく待つと GCP のネットワークサービスに検知されてロードバランサーが作成され、argocd-server に EXTERNAL-IP が割り当てられます。
$ kubectl get svc argocd-server -n argocd NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE argocd-server LoadBalancer 10.4.7.233 xx.xx.xx.xx 80:30669/TCP,443:31636/TCP 16m
割り当てられた IP にブラウザでアクセスすると、Argo CD のログイン画面がでます*3。
admin のパスワードは argocd-server の pod 名になっていますので、kubectl で取得してログインします。
今回はアプリを作る手間を省くため Argo CD の example リポジトリをフォークして GitOps の設定をします。
Argo CD の Setting -> Repositories を開きます。
public なリポジトリとしてフォークしたので認証情報なしで CONNECT REPO USING HTTPS
に URL を設定するだけです。
接続に成功しました。
デプロイするアプリ用の namespace を作っておきます。
$ kubectl create ns prod namespace/prod created
CREATE NEW APP
を クリックして、デプロイ対象のアプリ情報を登録します。example の helm-guestbook をデプロイするので、先に登録したリポジトリを選択して Path で helm-guestbook を選択。
アプリの namespace は先ほど作成した prod を指定。
CREATE
をクリックすると GitHub との Sync が開始されデプロイが始まります。
kubectl で確認。すでに ロードバランサーも作られてアプリがデプロイされています。
$ kubectl get deployment,svc,pod -n prod NAME READY UP-TO-DATE AVAILABLE AGE deployment.extensions/guestbook-helm-guestbook 2/2 2 2 4m2s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/guestbook-helm-guestbook LoadBalancer 10.4.11.37 xx.xx.xx.xxx 80:32362/TCP 4m3s NAME READY STATUS RESTARTS AGE pod/guestbook-helm-guestbook-764f9f8885-bqzpz 1/1 Running 0 4m2s pod/guestbook-helm-guestbook-764f9f8885-hqvpd 1/1 Running 0 4m2s
アプリの IP にアクセスすると確かに起動しています。
Argo CD でアプリの詳細を見ると、kubectl で取得できる情報がグラフィカルに閲覧可能です。
グラフの各ノードをクリックすると、詳細情報が出て、状態、マニフェスト、イベント、ログなどを確認できます。
GitOps なので、設定のリポジトリを更新するとそれに応じてデプロイされたアプリの状態も変化します。
ということで、フォークしたリポジトリの設定ファイルで replicaCount を増やしてみます。
3分ほど待っていると、Pod が1個増えました。
kubectl でも確認できます。
$ kubectl get pod -n prod NAME READY STATUS RESTARTS AGE guestbook-helm-guestbook-764f9f8885-bqzpz 1/1 Running 0 29m guestbook-helm-guestbook-764f9f8885-hqvpd 1/1 Running 0 29m guestbook-helm-guestbook-764f9f8885-rfb6c 1/1 Running 0 4m25s
以上のように Argo CD は Git リポジトリとアプリのデプロイ状態を同期させることができます。
リアクティブな Web UI が使いやすいですが、もちろん argocd という CLI も提供されています。Helm chart 以外にも Kustomize / ksonnet などのパッケージにも対応しており、個別のツールをインストールしなくてもデプロイできます。
ビルド・テストやコンテナイメージの作成を CI で実施し GitOpt ツールを CD に適用すれば、開発からデプロイまでの自動化を実現できそうです。