概要
- GitOpsを知らない人は、まずこちらを参照
- weaveworks GitOps - GitOpsを実現できる有名所なツールとして
Agro CD
、Flux
、Jenkins X
、の3種類が有る。今回はArgo CD
を使ってみる- Fluxは前回使ってみた
- Argo CDハンズオン自体はN番煎じですが、勉強も兼ねてやってみます
Argo CDハンズオン
事前準備
Argo CD CLIのインストール
- Windows版のバイナリがないので、WindowsからのCLIでの操作は対応してなさそう
- 今回はGUIだけで試してみる。。
Kubernetesクラスタの構築
- 以下の記事の通りに進めて、GKEクラスタを構築
$ gcloud container clusters create argocd-handson
$ gcloud container clusters list
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
argocd-handson asia-northeast1-a 1.12.8-gke.6 34.85.55.205 n1-standard-1 1.12.8-gke.6 3 RUNNING
ClusterRoleBindingを作る
※ここはGKE固有の準備部分
公式ドキュメントより
GKEでは、アカウントに新しいクラスタロールを作成する権限を付与する必要があります。
ArgoCDでリポジトリ毎にNamespaceの権限をよしなにやってくれるために必要で、GKEでは権限が制限されているのかと推測。
$ kubectl create clusterrolebinding YOURNAME-cluster-admin-binding --clusterrole=cluster-admin --user=YOUREMAIL@gmail.com
clusterrolebinding.rbac.authorization.k8s.io/YOURNAME-cluster-admin-binding created
YOURNAMEは何でも良さそうだったので、そのまま。
YOUREMAILにはGCPを登録したGmailアカウントを設定したけど、何でもよかったのかな?。
ClusterRoleBindingについてはこちらの記事が分かりやすかった。
Argo CDのインストール
Namespaceの作成
$ kubectl create namespace argocd
namespace/argocd created
Argocdのデプロイ
以下のコマンドでNon-HA構成でインストールできる。
$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
HA構成は以下でインストール。
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v1.0.1/manifests/ha/install.yaml
バグを踏むかもしれないけど、折角なのでHA構成でインストールしてみる。
$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v1.0.1/manifests/ha/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-ha 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-ha 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-ha 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-redis-ha-configmap created
configmap/argocd-redis-ha-probes created
secret/argocd-secret created
service/argocd-dex-server created
service/argocd-metrics created
service/argocd-redis-ha-announce-0 created
service/argocd-redis-ha-announce-1 created
service/argocd-redis-ha-announce-2 created
service/argocd-redis-ha 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-repo-server created
deployment.apps/argocd-server created
statefulset.apps/argocd-redis-ha-server created
インストールに問題無ければ、以下のようなserviceとdeploymentが見える。
HA構成にするためにメモリデータストアのredisを使っている様子。
$ kubectl get service -n argocd
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
argocd-dex-server ClusterIP 10.59.250.4 <none> 5556/TCP,5557/TCP 119s
argocd-metrics ClusterIP 10.59.245.87 <none> 8082/TCP 119s
argocd-redis-ha ClusterIP None <none> 6379/TCP,26379/TCP 119s
argocd-redis-ha-announce-0 ClusterIP 10.59.245.195 <none> 6379/TCP,26379/TCP 119s
argocd-redis-ha-announce-1 ClusterIP 10.59.255.114 <none> 6379/TCP,26379/TCP 119s
argocd-redis-ha-announce-2 ClusterIP 10.59.248.240 <none> 6379/TCP,26379/TCP 119s
argocd-repo-server ClusterIP 10.59.249.117 <none> 8081/TCP,8084/TCP 119s
argocd-server ClusterIP 10.59.245.104 <none> 80/TCP,443/TCP 119s
argocd-server-metrics ClusterIP 10.59.243.126 <none> 8083/TCP 119s
$ kubectl get deploy -n argocd
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
argocd-application-controller 1 1 1 1 4m28s
argocd-dex-server 1 1 1 1 4m28s
argocd-repo-server 2 2 2 2 4m28s
argocd-server 2 2 2 2 4m27s
Argo CDにアクセスできるようにする
公式ドキュメントでは、以下の方法かIngressを使うように言っている。
#ServiceのtypeをLoad Balancerにする方法
$ kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
#Port Forwardingする方法
$ kubectl port-forward svc/argocd-server -n argocd 8080:443
GKEなので、typeをLoadBalancerにするとGCPのネットワークロードバランサーが作成されるはず。
手軽にやるならPort Fowradingだと思うけど、ネットワークロードバランサーを使ってみる。
$ kubectl get service argocd-server -n argocd
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
argocd-server ClusterIP 10.59.245.104 <none> 80/TCP,443/TCP 9m43s
$ kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
$ kubectl get service argocd-server -n argocd
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
argocd-server LoadBalancer 10.59.245.104 34.85.52.106 80:31804/TCP,443:30731/TCP 16m
34.85.52.106
にアクセス
ログイン画面が表示された。
ログインIDとパスワードを取得
管理ユーザの初期パスワードはArgoCD APIサーバのpod名になっているので、取得する。
$ kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2
argocd-server-569c655c64-c7qzr
argocd-server-569c655c64-fld99
HA構成にしているためpodが2つでてきてしまった。
とりあえず、ID:admin
、PW:pod名
でログインしてみる。
2つ目のpod名でログインできた。
ArgoCDでGitOpsハンズオン
GUIでポチポチしながらApplicationを作成
設定をYAMLで表示・変更もできたので、今回設定した情報を記載
Namespaceにhandson
を指定したが、クラスタ上には存在しない。自動で作られるか挙動を確かめる。
apiVersion: argoproj.io/v1alpha1
metadata:
name: handson
spec:
destination:
namespace: handson
server: 'https://kubernetes.default.svc'
source:
path: /
repoURL: 'https://github.com/ssbtn/ArgoCD-handson.git'
targetRevision: master
directory:
recurse: true
project: default
syncPolicy:
automated:
prune: true
Create
してみたがエラー。
Failed sync attempt to c5aac260df1f66465a2ebc03042c9a049809de6b: one or more objects failed to apply
Error from server (NotFound): namespaces "handson" not found
やっぱり、事前にNamespaceは作る必要が有る。
そして、エラーログを見るUIも含めて、欲しい情報が直観的に取得できて素晴らしい。
先週Fluxを使ったけど、GUIが無いのでリソースの作成に失敗した場合や、同期の追跡で一々コマンドを叩く必要があった。(Fluxを少し使っただけなので、よりよい見方が有るのかもしれないが。)
例えば、K8s初心者な人も使うことを想定するとArgo CDのこのUIは欲しいなと思った。
Namespaceの作成もGitで管理したいので、クラスタ管理者向けのリポジトリも運用を考えると作らないと。
長くなったけど、作成。
$ kubectl create namespace handson
namespace/handson created
設定次第なのかもしれないけど、
エラーでデプロイが失敗した場合は、待ってても再デプロイしてくれないみたい。10分ぐらい待った。
手動でSYNC
をクリックしてみる。
同期された。めちゃくちゃ分かりやすい。K8s初学者にリソースがどういう関連なのかを理解する助けにもなりそう。
ポイントとしては、
deploymentやserviceでnamespaceを指定していなかったけど、ArgoCDのアプリケーション作成時に選んだnamespace配下にリソースが作られているところ。
namespaceを指定するとどうなるのか試してみる。
設定したnamespace外へのデプロイ
namespaceを作成
新規にnamespaceを用意。
さっきはkubectlで作ったけど、ymlで書いて、GitOpsしてみる。
deploymentを書く
新規に作成したnamespaceにデプロイするように記述してpush
オブジェクトの確認
namespaceも作成できたし、Applicationで指定したnamespace外にもデプロイできた。
作成したオブジェクトの削除
Fluxを使った時に、リポジトリ上からmanifestを削除しただけだと、クラスタ上にオブジェクトが残ってしまった。ArgoCDでも同様の事象が発生するか確認する。
本来であれば、追跡してくれることを期待したい。
リポジトリ上から削除
https://github.com/ssbtn/ArgoCD-handson/commit/3c58a2eee7790d984d9494bfebb00657ca75b38d
GUIではdeploymentが削除されたため、同期できていないと警告。
ちゃんとクラスタ上には存在。
$ kubectl get deployment -n handson2
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx 5 5 5 5 10m
GUI上から同期されていないdeploymentを削除できるので、やってみる
削除されて、警告も消えた。
この時点で、個人的にFluxよりも確実に使いやすい。
ロールバック
GUIでHISTORY AND ROLLBACK
ボタンが有るのでやってみる。
deploymentを削除する前の状態にロールバック。
Unable to rollback application: rollback cannot be initiated when auto-sync is enabled
自動同期が有効だとロールバックできないとエラー。
自動同期を無効化してロールバックした。
(無効化するスクショ取り忘れた。GUIで簡単に無効化できる。)
ロールバックしてくれた。
そして、deploymentに×
がついているので、最新のmasterの状態と比較もしてくれている。
namespaceの削除からの復旧
無効化した、自動同期設定は有効化に戻した。
うっかりオペレーションミスでnamespaceを削除した場合を考えて、やってみる。
$ kubectl delete ns handson handson2
namespace "handson" deleted
所感
好みも有るけど、Fluxよりも使いやすく、運用向きだと感じた。
Fluxだと1つのプロセスで1つのGitリポジトリしか管理できないので、複数のリポジトリを管理するにはFluxを複数起動する必要が有る。
ArgoCDだとアプリケーション単位でリポジトリを選べるので1つのプロセスで複数リポジトリも対応できて、管理がしやすそう。
Namespaceとか誰でもガシガシ作られると問題(?)なので、Applicationは指定したNamespace以下の権限しか持てないような権限設定ができるかとかも今後調べたい。
後はHelm、Kustomizeでのデプロイ方法も試したいな。