Help us understand the problem. What is going on with this article?

GKEでArgoCDを使ってGitOpsしてみた

概要

Argo CDハンズオン

事前準備

Argo CD CLIのインストール

Kubernetesクラスタの構築

$ 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にアクセス

Cut2019_0608_0957_10.jpg

ログイン画面が表示された。

ログイン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:adminPW:pod名でログインしてみる。

Cut2019_0608_1003_43.jpg

2つ目のpod名でログインできた。

ArgoCDでGitOpsハンズオン

GUIでポチポチしながらApplicationを作成

Cut2019_0608_1059_27.jpg
Cut2019_0608_1104_12.jpg

設定を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

Cut2019_0608_1104_12.jpg

Error from server (NotFound): namespaces "handson" not found

Cut2019_0608_1104_55.jpg

やっぱり、事前にNamespaceは作る必要が有る。

そして、エラーログを見るUIも含めて、欲しい情報が直観的に取得できて素晴らしい。

先週Fluxを使ったけど、GUIが無いのでリソースの作成に失敗した場合や、同期の追跡で一々コマンドを叩く必要があった。(Fluxを少し使っただけなので、よりよい見方が有るのかもしれないが。)
例えば、K8s初心者な人も使うことを想定するとArgo CDのこのUIは欲しいなと思った。

Namespaceの作成もGitで管理したいので、クラスタ管理者向けのリポジトリも運用を考えると作らないと。

長くなったけど、作成。

$ kubectl create namespace handson
namespace/handson created

設定次第なのかもしれないけど、
エラーでデプロイが失敗した場合は、待ってても再デプロイしてくれないみたい。10分ぐらい待った。
手動でSYNCをクリックしてみる。

Cut2019_0608_1122_49.jpg

同期された。めちゃくちゃ分かりやすい。K8s初学者にリソースがどういう関連なのかを理解する助けにもなりそう。

ポイントとしては、
deploymentやserviceでnamespaceを指定していなかったけど、ArgoCDのアプリケーション作成時に選んだnamespace配下にリソースが作られているところ。
namespaceを指定するとどうなるのか試してみる。

設定したnamespace外へのデプロイ

namespaceを作成

新規にnamespaceを用意。
さっきはkubectlで作ったけど、ymlで書いて、GitOpsしてみる。

https://github.com/ssbtn/ArgoCD-handson/commit/d5dbe3df29fb1f36d76fe9432b82fa9babf0cabc

deploymentを書く

新規に作成したnamespaceにデプロイするように記述してpush

https://github.com/ssbtn/ArgoCD-handson/commit/cc63bbe92a367df1cef0333c22d516d001845494

オブジェクトの確認

namespaceも作成できたし、Applicationで指定したnamespace外にもデプロイできた。

Cut2019_0608_1143_08.jpg

作成したオブジェクトの削除

Fluxを使った時に、リポジトリ上からmanifestを削除しただけだと、クラスタ上にオブジェクトが残ってしまった。ArgoCDでも同様の事象が発生するか確認する。
本来であれば、追跡してくれることを期待したい。

リポジトリ上から削除
https://github.com/ssbtn/ArgoCD-handson/commit/3c58a2eee7790d984d9494bfebb00657ca75b38d

GUIではdeploymentが削除されたため、同期できていないと警告。

Cut2019_0608_1155_22.jpg

ちゃんとクラスタ上には存在。

$ kubectl get deployment -n handson2
NAME    DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx   5         5         5            5           10m

GUI上から同期されていないdeploymentを削除できるので、やってみる

Cut2019_0608_1156_33.jpg

削除されて、警告も消えた。
この時点で、個人的にFluxよりも確実に使いやすい。

ロールバック

GUIでHISTORY AND ROLLBACKボタンが有るのでやってみる。
deploymentを削除する前の状態にロールバック。

Cut2019_0608_1200_31.jpg

Unable to rollback application: rollback cannot be initiated when auto-sync is enabled

自動同期が有効だとロールバックできないとエラー。

自動同期を無効化してロールバックした。
(無効化するスクショ取り忘れた。GUIで簡単に無効化できる。)

Cut2019_0608_1204_09.jpg

ロールバックしてくれた。
そして、deploymentに×がついているので、最新のmasterの状態と比較もしてくれている。

namespaceの削除からの復旧

無効化した、自動同期設定は有効化に戻した。

うっかりオペレーションミスでnamespaceを削除した場合を考えて、やってみる。

$ kubectl delete ns handson handson2
namespace "handson" deleted

GUI上からリソースが無くなった。
Cut2019_0608_1206_41.jpg

同期走ってGitの状態に戻された。良いですね。
Cut2019_0608_1208_52.jpg

所感

好みも有るけど、Fluxよりも使いやすく、運用向きだと感じた。

Fluxだと1つのプロセスで1つのGitリポジトリしか管理できないので、複数のリポジトリを管理するにはFluxを複数起動する必要が有る。
ArgoCDだとアプリケーション単位でリポジトリを選べるので1つのプロセスで複数リポジトリも対応できて、管理がしやすそう。

Namespaceとか誰でもガシガシ作られると問題(?)なので、Applicationは指定したNamespace以下の権限しか持てないような権限設定ができるかとかも今後調べたい。

後はHelm、Kustomizeでのデプロイ方法も試したいな。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away