はじめてのArgoCD
ArgoCDことはじめとして、Getting Startedをやってみたレポートです。ArgoCDをインストールし、インストールしたクラスター内にアプリケーションを作成します。
環境
- macOS Catalina 10.15.7 (19H524)
前提条件
EKSクラスター作成
以下を使ってEKSクラスターを作成します。
コンテキストの作成を忘れずに。
% aws eks update-kubeconfig --name blue-with-module
ArgoCD インストール
% kubectl create namespace argocd namespace/argocd created % kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/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-redis 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-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-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-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-server created configmap/argocd-cm created configmap/argocd-gpg-keys-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 created service/argocd-server-metrics created deployment.apps/argocd-dex-server created deployment.apps/argocd-redis created deployment.apps/argocd-repo-server created deployment.apps/argocd-server created statefulset.apps/argocd-application-controller created
CRD2つなどいろいろなリソースが作成されていますね。
Argo CD CLI のダウンロード
HomeBrewでインストール出来るとのことでしたが、私の環境だとエラーになってしまいました。
% brew install argocd (略) curl: (22) The requested URL returned error: 404 Error: Failed to download resource "argocd" Download failed: https://ghcr.io/v2/homebrew/core/argocd-2.0.0.catalina.bottle.tar.gz
代わりにcurlで最新版 v2.0.1をダウンロードしました。
% VERSION=$(curl --silent "https://api.github.com/repos/argoproj/argo-cd/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/') % curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/download/$VERSION/argocd-darwin-amd64 % chmod +x /usr/local/bin/argocd % argocd version argocd: v2.0.1+33eaf11 BuildDate: 2021-04-15T22:34:01Z GitCommit: 33eaf11e3abd8c761c726e815cbb4b6af7dcb030 GitTreeState: clean GoVersion: go1.16 Compiler: gc Platform: darwin/amd64 FATA[0000] Argo CD server address unspecified
ArgoCD API Serverにアクセス
ServiceのタイプをLoadBalancerに変える方法でアクセス出来るようにしました。
% kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}' service/argocd-server patched
kubectl get svc argocd-server -n argocd
の出力結果のEXTERNAL-IP
列の値を控えます。
% kubectl get svc argocd-server -n argocd NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE argocd-server LoadBalancer 172.20.114.241 afdb98ff0cc604d89bf72be854acf1b0-758120766.ap-northeast-1.elb.amazonaws.com 80:30907/TCP,443:31857/TCP 6h12m
CLIでログイン
まずはパスワードの値を取得します。
% kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo vcITNaHpilGRbAFh
argocd login
の後に先程控えたargocd-server
のEXTERNAL-IP
の値を入れます。
% argocd login afdb98ff0cc604d89bf72be854acf1b0-758120766.ap-northeast-1.elb.amazonaws.com WARNING: server certificate had error: x509: certificate is valid for localhost, argocd-server, argocd-server.argocd, argocd-server.argocd.svc, argocd-server.argocd.svc.cluster.local, not afdb98ff0cc604d89bf72be854acf1b0-758120766.ap-northeast-1.elb.amazonaws.com. Proceed insecurely (y/n)? y Username: admin Password: vcITNaHpilGRbAFh 'admin:login' logged in successfully Context 'afdb98ff0cc604d89bf72be854acf1b0-758120766.ap-northeast-1.elb.amazonaws.com' updated
アプリケーション作成(CLI)
https://github.com/argoproj/argocd-example-apps.git こちらのサンプルアプリを使います。
% argocd app create guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default
Sync
Sync前なので、Sync StatusがOutOfSyncになっています。
% argocd app get guestbook Name: guestbook Project: default Server: https://kubernetes.default.svc Namespace: default URL: https://afdb98ff0cc604d89bf72be854acf1b0-758120766.ap-northeast-1.elb.amazonaws.com/applications/guestbook Repo: https://github.com/argoproj/argocd-example-apps.git Target: Path: guestbook SyncWindow: Sync Allowed Sync Policy: <none> Sync Status: OutOfSync from (53e28ff) Health Status: Missing GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE Service default guestbook-ui OutOfSync Missing apps Deployment default guestbook-ui OutOfSync Missing
Syncします。
% argocd app sync guestbook TIMESTAMP GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE 2021-04-19T19:23:05+09:00 Service default guestbook-ui OutOfSync Missing 2021-04-19T19:23:05+09:00 apps Deployment default guestbook-ui OutOfSync Missing 2021-04-19T19:23:05+09:00 Service default guestbook-ui Synced Healthy 2021-04-19T19:23:05+09:00 apps Deployment default guestbook-ui OutOfSync Missing deployment.apps/guestbook-ui created 2021-04-19T19:23:05+09:00 Service default guestbook-ui Synced Healthy service/guestbook-ui created 2021-04-19T19:23:05+09:00 apps Deployment default guestbook-ui Synced Progressing deployment.apps/guestbook-ui created Name: guestbook Project: default Server: https://kubernetes.default.svc Namespace: default URL: https://afdb98ff0cc604d89bf72be854acf1b0-758120766.ap-northeast-1.elb.amazonaws.com/applications/guestbook Repo: https://github.com/argoproj/argocd-example-apps.git Target: Path: guestbook SyncWindow: Sync Allowed Sync Policy: <none> Sync Status: Synced to (53e28ff) Health Status: Progressing Operation: Sync Sync Revision: 53e28ff20cc530b9ada2173fbbd64d48338583ba Phase: Succeeded Start: 2021-04-19 19:23:04 +0900 JST Finished: 2021-04-19 19:23:05 +0900 JST Duration: 1s Message: successfully synced (all tasks run) GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE Service default guestbook-ui Synced Healthy service/guestbook-ui created apps Deployment default guestbook-ui Synced Progressing deployment.apps/guestbook-ui created
ArgoCIのUIでも確認してみましょう。先程控えたargocd-server
のEXTERNAL-IP
にブラウザアクセスします。
ログイン画面にリダイレクトします。入力内容は先程CLIで入力したのと同じ、usernameはadmin、passwordはkubectl get secret
で取得したものです。
UIでも状況が確認できます。 guestbookのパネルをクリックすると詳細画面に遷移し、リソース構成を図で確認できます。
アプリ確認
せっかくなので、デプロイしたアプリにブラウザアクセスしてみたいと思います。デプロイされたサービスはClusterIPだったので、外部からアクセス出来るように変更を加えます。
% kubectl patch svc guestbook-ui -p '{"spec": {"type": "LoadBalancer"}}'
kubectl get svc guestbook-ui
の出力結果のargocd-server
のEXTERNAL-IP
に表示されるCLBのDNS値にブラウザアクセスします。
おまけ:差分検知検証1
この後再度argocd app sync guestbook
を実行すれば、上記のServiceのタイプがGitリポジトリに上がっているものと異なっているので、差分を検知して修正してくれるのかなと思ったのですが、差分検知されませんでした。
% argocd app sync guestbook TIMESTAMP GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE 2021-04-19T21:15:35+09:00 Service default guestbook-ui Synced Healthy 2021-04-19T21:15:35+09:00 apps Deployment default guestbook-ui Synced Healthy 2021-04-19T21:15:36+09:00 Service default guestbook-ui Synced Healthy service/guestbook-ui unchanged 2021-04-19T21:15:36+09:00 apps Deployment default guestbook-ui Synced Healthy deployment.apps/guestbook-ui unchanged Name: guestbook Project: default Server: https://kubernetes.default.svc Namespace: default URL: https://afdb98ff0cc604d89bf72be854acf1b0-758120766.ap-northeast-1.elb.amazonaws.com/applications/guestbook Repo: https://github.com/argoproj/argocd-example-apps.git Target: Path: guestbook SyncWindow: Sync Allowed Sync Policy: <none> Sync Status: Synced to (53e28ff) Health Status: Healthy Operation: Sync Sync Revision: 53e28ff20cc530b9ada2173fbbd64d48338583ba Phase: Succeeded Start: 2021-04-19 21:15:35 +0900 JST Finished: 2021-04-19 21:15:36 +0900 JST Duration: 1s Message: successfully synced (all tasks run) GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE Service default guestbook-ui Synced Healthy service/guestbook-ui unchanged apps Deployment default guestbook-ui Synced Healthy deployment.apps/guestbook-ui unchanged kazue.masaki@HL00367 terraform % k get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE guestbook-ui LoadBalancer 172.20.26.176 a8089e731853f41c4b735df54a41deb3-1678029976.ap-northeast-1.elb.amazonaws.com 80:31390/TCP 112m kubernetes ClusterIP 172.20.0.1 <none>
おまけ:差分検知検証2
先程はkubectl patch
コマンドで設定変更(ServiceタイプをLoadBalancerに変える)しました。
argocdサブコマンドにはkubectl patch
コマンドと同等のものがもあり、それで設定変更した場合なら差分検知してくれるのかなと思ってやってみました。
まずは一度ServiceタイプをClusterIPに戻します。
LoadBalancerに変えたときと同様patchコマンドを使ってみましたが、エラーになります。
% kubectl patch svc guestbook-ui -p '{"spec": {"type": "ClusterIP"}}' The Service "guestbook-ui" is invalid: spec.ports[0].nodePort: Forbidden: may not be used when `type` is 'ClusterIP'
対処方法がわからなかったので、kubectl edit
で対応しました。
spec: clusterIP: 172.20.26.176 externalTrafficPolicy: Cluster ports: - - nodePort: 31373 - port: 80 + - port: 80 protocol: TCP targetPort: 80 selector: app: guestbook-ui sessionAffinity: None - type: LoadBalancer + type: ClusterIP
その後、argocdのコマンドで再度LoadBalancerに戻します。
% argocd app patch-resource guestbook --kind Service --resource-name guestbook-ui --patch '{"spec": {"type": "LoadBalancer"}}'
再度syncを試してみましたが、差分検知されませんでした。すみません今の私にはこの差分を検知させる方法がわからなかったです。分かり次第追記しようと思います。ご存じの方教えて下さい??
% argocd app sync guestbook TIMESTAMP GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE 2021-04-19T22:20:10+09:00 Service default guestbook-ui Synced Healthy 2021-04-19T22:20:10+09:00 apps Deployment default guestbook-ui Synced Healthy 2021-04-19T22:20:11+09:00 Service default guestbook-ui Synced Healthy service/guestbook-ui unchanged 2021-04-19T22:20:11+09:00 apps Deployment default guestbook-ui Synced Healthy deployment.apps/guestbook-ui unchanged Name: guestbook Project: default Server: https://kubernetes.default.svc Namespace: default URL: https://afdb98ff0cc604d89bf72be854acf1b0-758120766.ap-northeast-1.elb.amazonaws.com/applications/guestbook Repo: https://github.com/argoproj/argocd-example-apps.git Target: Path: guestbook SyncWindow: Sync Allowed Sync Policy: <none> Sync Status: Synced to (53e28ff) Health Status: Healthy Operation: Sync Sync Revision: 53e28ff20cc530b9ada2173fbbd64d48338583ba Phase: Succeeded Start: 2021-04-19 22:20:10 +0900 JST Finished: 2021-04-19 22:20:11 +0900 JST Duration: 1s Message: successfully synced (all tasks run) GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE Service default guestbook-ui Synced Healthy service/guestbook-ui unchanged apps Deployment default guestbook-ui Synced Healthy deployment.apps/guestbook-ui unchanged
追記おまけ:差分検知検証3
デフォルトの設定だと、今回の様なクラスターの設定変更を自動で検知して修正することはできないようです。Self-Healingという機能を有効化する必要がありました。というかデフォルトだとGitリポジトリに差分が発生(新規コミットがプッシュされる)しても自動同期してくれるわけではありませんでした。
というわけで設定変更です。Self-Healingを有効化するself-heal
オプションを加えます。この機能を使うには自動同期を有効化する必要もあるので、そのオプション--sync-policy automated
も加えます。
% argocd app set guestbook --self-heal --sync-policy automated
さあこれで差分が検知されて自動修正されるぞ…としばらく待ってみたのですがなにも起きません。
追記おまけ:差分検知検証4
Gitリポジトリに上がっている、今回修正をしたサービスのマニフェストファイルは以下です。
apiVersion: v1 kind: Service metadata: name: guestbook-ui spec: ports: - port: 80 targetPort: 80 selector: app: guestbook-ui
タイプについての記述がありませんね。この場合デフォルトのタイプであるClusterIPが使われます。
明示的にタイプが定義されていないから、差分検知がされないのでは?と仮説を立てました。これを検証したいと思います。
"type": "ClusterIP"
と明記したマニフェストファイルをGitリポジトリにプッシュする必要があります。現在sourceとして使っているリポジトリはargoprojのものなのでプッシュできません。自分のアカウントにForkしたリポジトリにsourceを変更します。
% argocd app patch guestbook --patch '{"spec": { "source": { "repoURL": "https://github.com/kazuemasaki/argocd-example-apps.git" } }}' --type merge (長いので出力結果は省略 おそらく `argocd app get guestbook -o yaml`と同じ結果が表示されている)
そしてtypeを明記したマニフェストファイルをコミットしてプッシュします。
ports: - port: 80 targetPort: 80 + type: ClusterIP selector: app: guestbook-ui
しばらくするとSyncStatusがOutOfSyncになり、syncが開始されました!
なのですが、最終的にはSyncは失敗しました。。状況を確認します。下から2行目にご注目ください。
% argocd app get guestbook Name: guestbook Project: default Server: https://kubernetes.default.svc Namespace: default URL: https://aeb20e694f65c4159be30376f75e0047-1861540336.ap-northeast-1.elb.amazonaws.com/applications/guestbook Repo: https://github.com/kazuemasaki/argocd-example-apps.git Target: Path: guestbook SyncWindow: Sync Allowed Sync Policy: Automated Sync Status: OutOfSync from (783a4d4) Health Status: Healthy GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE Service default guestbook-ui OutOfSync Healthy Service "guestbook-ui" is invalid: spec.ports[0].nodePort: Forbidden: may not be used when `type` is 'ClusterIP' apps Deployment default guestbook-ui Synced Healthy deployment.apps/guestbook-ui unchanged
Service "guestbook-ui" is invalid: spec.ports[0].nodePort: Forbidden: may not be used when
type
is 'ClusterIP'
と出てますね。これは「おまけ:差分検知検証2」で kubectl patch
コマンドでタイプをClusterIPに戻そうとした際に出たのと同じエラーですね。この差分を自動で修正するのはArgoCDでもできないみたいです。残念。ということで最終的には差分の自動検知はできましたが、自動修正には失敗したという結果になりました。