Ritolabo
  1. Home
  2. Kubernetes
  3. ArgoCD
  4. Argo CD の自動同期: automated・selfHeal・prune

Argo CD の自動同期: automated・selfHeal・prune

  • 公開日
  • カテゴリ:ArgoCD
  • タグ:Kubernetes,ArgoCD,学習メモ
Argo CD の自動同期: automated・selfHeal・prune

Argo CD の Application は、そのままでは Git とクラスタの違いを表示するだけで、人が Argo CD の画面(ブラウザで開く管理画面)のボタンを押すまでクラスタを変えない。

この記事では、Application の YAML に設定を 3 つ追加して、Git に push するだけでクラスタの中身が Git の内容に合う状態にする。

contents

  1. 前提
  2. 自動同期を決める 3 つの設定
  3. automated: push すると Pod が増える
    1. Git を変えて push する
  4. selfHeal: kubectl scale で変えた Pod の数が Git の数に戻る
    1. selfHeal がないときの動き
    2. selfHeal を追加する
  5. prune: Git から消した Deployment がクラスタからも消える
    1. prune がないときの動き
    2. prune を追加する
  6. Git で前のコミットに戻す
  7. 自動同期の全体像
  8. 用語メモ
  9. 参考 URL

前提

GitHub の private リポジトリ argocd-study に web/deployment.yaml(nginx の Deployment web。replicas: 1)があり、Argo CD の Application web がそれを default namespace に入れている状態から始める。Argo CD は v3.5.5。

$ kubectl get applications -n argocd
NAME   SYNC STATUS   HEALTH STATUS
web    Synced        Healthy

$ kubectl get deployment,pods -n default
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/web   1/1     1            1           23h

NAME                       READY   STATUS    RESTARTS   AGE
pod/web-557577df75-5m5lr   1/1     Running   1          23h

この記事で使う Argo CD の用語。

言葉意味
SyncGit の YAML をクラスタに apply すること。自分で kubectl apply を実行する代わりに、Argo CD が実行する
Synced / OutOfSyncGit の YAML とクラスタの中身を比べた結果。同じなら Synced、違えば OutOfSync
Argo CD の画面の SYNC ボタン / REFRESH ボタンArgo CD の画面は、kubectl port-forward svc/argocd-server -n argocd 8080:443 を実行して https://localhost:8080 をブラウザで開く。SYNC を押すと、Argo CD が Git の YAML を取得してクラスタに apply する。REFRESH を押すと、Git の YAML を取得してクラスタと比べ直すだけで、apply はしない

自動同期を決める 3 つの設定

追加する設定は 3 つで、いずれも Application の YAML の spec.syncPolicy に書く。

設定何をするか書かないとき
automatedGit の内容が変わって OutOfSync になったら、人が画面の SYNC ボタンを押さなくても Sync する人が画面の SYNC ボタンを押すまで Sync しない
selfHeal: trueクラスタの中身が変わって OutOfSync になったときも、Git の内容に合わせて戻すOutOfSync と表示するだけで、戻さない
prune: trueGit から消えたものを、クラスタからも消すクラスタに残したままにする

この 3 つを 1 つずつ追加して、追加する前と後で動きがどう変わるかを確認する。

automated: push すると Pod が増える

Application web の YAML に spec.syncPolicy.automated を追加して、apply し直す。automated: {} の {} は、automated の中に設定を何も書かないという意味。

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: web
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/example-user/argocd-study.git
    targetRevision: HEAD
    path: web
  destination:
    server: https://kubernetes.default.svc
    namespace: default
  syncPolicy:
    automated: {}
$ kubectl apply -f application.yaml
# => application.argoproj.io/web configured

apply しても、この時点では何も起きない。Git の内容とクラスタの中身が一致している(Synced)ので、Sync する対象がない。

Git を変えて push する

GitHub のリポジトリの web/deployment.yaml の replicas: 1 を replicas: 2 に変えて push する。

-  replicas: 1
+  replicas: 2

Argo CD は GitHub からファイルを定期的に取得する。既定では 2〜3 分に 1 回で、設定で変えられる。(すぐに反映したいときは、Argo CD の画面の REFRESH ボタンを押す)

別のターミナルで default namespace の Pod を -w 付きで表示しておくと、新しい Pod が作られるのが見える。

$ kubectl get pods -n default -w
NAME                   READY   STATUS    RESTARTS   AGE
web-557577df75-5m5lr   1/1     Running   1          25h
web-557577df75-lcjzc   0/1     Pending   0          0s
web-557577df75-lcjzc   0/1     ContainerCreating   0   0s
web-557577df75-lcjzc   1/1     Running             0   0s
$ kubectl get deployment web -n default
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web    2/2     2            2           25h

$ kubectl get applications -n argocd
NAME   SYNC STATUS   HEALTH STATUS
web    Synced        Healthy

ここで起きたことを順に書くと、次のようになる。

  1. Argo CD が GitHub からファイルを取得し、Git の replicas: 2 とクラスタの replicas: 1 が違うので OutOfSync になった
  2. automated が書いてあるので、人が画面の SYNC ボタンを押さなくても Argo CD が Sync(apply)した
  3. apply された replicas: 2 に合わせて、Kubernetes が Pod を 1 つ作った

selfHeal: kubectl scale で変えた Pod の数が Git の数に戻る

selfHeal がないときの動き

kubectl scale は、クラスタにある Deployment の replicas を直接書き換えるコマンド。Git の内容は変えずに、クラスタの中身だけを変える。

$ kubectl scale deployment web -n default --replicas=3
# => deployment.apps/web scaled

$ kubectl get applications -n argocd
NAME   SYNC STATUS   HEALTH STATUS
web    OutOfSync     Healthy

$ kubectl get deployment web -n default
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web    3/3     3            3           25h

Git の内容は replicas: 2、クラスタの Deployment は replicas: 3。違いがあるので、数秒で OutOfSync になる。ところが、そのまま待っても Pod は 3 つのまま変わらない。

automated は、Git の内容が変わったときに Sync する設定。クラスタの中身が変わったときは、OutOfSync と表示するだけで Sync しない。これが selfHeal を書かないときの動き。

selfHeal を追加する

automated の下に selfHeal: true を書いて、Application を apply し直す。

  syncPolicy:
    automated:
      selfHeal: true
$ kubectl apply -f application.yaml
# => application.argoproj.io/web configured

数秒後に Pod が 1 つ Terminating になり、Deployment の replicas は Git の内容と同じ 2 に戻る。

$ kubectl get applications -n argocd
NAME   SYNC STATUS   HEALTH STATUS
web    Synced        Healthy

$ kubectl get deployment web -n default
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web    2/2     2            2           25h

この状態でもう一度 kubectl scale deployment web -n default --replicas=3 を実行すると、新しい Pod は ContainerCreating から Terminating になり、Running になる前に消える。クラスタの Deployment を自分で変えても、Git に書いてある数に戻される。

prune: Git から消した Deployment がクラスタからも消える

prune がないときの動き

消す対象を先に用意する。GitHub の web/ ディレクトリに、Deployment hello の YAML(web と同じ nginx の Deployment で、名前だけ違う)を hello.yaml として追加して push する。Application の path: web が指しているのはディレクトリなので、同じディレクトリに追加したファイルは、Application を変えなくても一緒にクラスタに入る。

$ git add web/hello.yaml
$ git commit -m "Add hello"
$ git push

しばらく待つと、クラスタに Deployment hello が作られる。次に、hello.yaml を Git から削除して push する。

$ git rm web/hello.yaml
$ git commit -m "Remove hello"
$ git push
$ kubectl get applications -n argocd
NAME   SYNC STATUS   HEALTH STATUS
web    OutOfSync     Healthy

$ kubectl get deployment -n default
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
hello   1/1     1            1           53s
web     2/2     2            2           25h

Git に hello.yaml はもうないが、クラスタには Deployment hello がある。違いがあるので OutOfSync になる。ところが、Deployment hello は消えない。

自動同期がするのは「Git にあるものを apply する」ことだけで、「Git にないものを消す」ことはしない。これが prune を書かないときの動き。

prune を追加する

automated の下に prune: true を書いて、Application を apply し直す。

  syncPolicy:
    automated:
      selfHeal: true
      prune: true
$ kubectl apply -f application.yaml
# => application.argoproj.io/web configured

しばらく待つと、クラスタから Deployment hello が消える。

$ kubectl get applications -n argocd
NAME   SYNC STATUS   HEALTH STATUS
web    Synced        Healthy

$ kubectl get deployment -n default
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web    2/2     2            2           25h

prune が消すのは、Argo CD がクラスタに入れたもの(annotation argocd.argoproj.io/tracking-id が付いている)のうち、Git にないものだけ。同じ namespace にあっても、Argo CD が入れたものでなければ消さない。

Git で前のコミットに戻す

selfHeal: true があると、kubectl scale で戻しても Git の内容に戻される。画面の HISTORY AND ROLLBACK にある Rollback も、公式ドキュメントによると automated が有効な Application では使えない。変更を取り消すときも Git を使う。

git revert は、指定したコミットの逆の変更を新しいコミットとして作るコマンド。replicas を 2 にしたコミットを revert して push する。

$ git log --oneline
xxxxxxx Remove hello
xxxxxxx Add hello
xxxxxxx Scale web to 2
xxxxxxx Move deployment to web/
xxxxxxx Add web deployment

$ git revert --no-edit <Scale web to 2 のハッシュ>
# => [main xxxxxxx] Revert "Scale web to 2"

$ git push

しばらく待つと、Pod が 1 つ Terminating になり、Deployment の replicas は 1 に戻る。

$ kubectl get deployment,pods -n default
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/web   1/1     1            1           25h

NAME                       READY   STATUS    RESTARTS   AGE
pod/web-557577df75-5m5lr   1/1     Running   1          25h

$ kubectl get applications -n argocd
NAME   SYNC STATUS   HEALTH STATUS
web    Synced        Healthy

自動同期の全体像

Deployment と Pod を変えたのは、すべて argocd-application-controller。(図の角が二重の箱は動くプログラム、それ以外の箱は etcd に保存されたデータ)

図を描画しています…

用語メモ

用語読み方意味
SyncシンクGit の YAML をクラスタに apply すること。kubectl apply 相当
RefreshリフレッシュGit の YAML を取り直して、クラスタと比べ直すこと。apply はしない
automatedオートメイテッドOutOfSync になったら、人が画面の SYNC ボタンを押さなくても Sync する設定。自動同期
selfHealセルフヒールクラスタの中身が変わったときも、Git の内容に合わせて戻す設定
pruneプルーンGit から消えたものを、クラスタからも消す設定。もとは「剪定」の意味

まとめ

  • automated: Git の内容が変わって OutOfSync になったら、Argo CD が自動で Sync する
  • selfHeal: true: クラスタの中身を kubectl scale などで直接変えても、Git の内容に戻す
  • prune: true: Git から消えたものを、クラスタからも消す

参考 URL


[Prev] Argo CD のインストールから Git の YAML を反映するまで

Author

rito

rito

  • Backend Engineer
  • Tokyo, Japan
  • PHP 5 技術者認定上級試験 認定者
  • 統計検定 3 級