GKEでArgoを使ったカナリアリリースを実現する(セットアップ編)


概要

KubernetesでGitOpsを実現するツールであるArgo CDとKubernetesでblue/grennデプロイやカナリアリリースを実現するためのデプロイメントコントローラーであるArgo Rolloutsを使用して、カナリアリリースを実現する方法を2回に渡ってご紹介します。
今回はセットアップ編となります。

Arog CDのオフィシャルサイト
https://argoproj.github.io/argo-cd/

構成図

構成要素

  • GKE
  • GCR ※今回は登場なし
  • Cloud Build ※今回は登場なし
  • Cloud Load balancer(ingress)
  • GitHub
  • argo cd
  • argo rollouts

前提条件

  • Googleアカウントがあること
  • GitHubアカウントがあること
  • デプロイしたいアプリケーションがあること
    • 今回は例としてオフィシャルサイトが用意しているguestbookのアプリケーションをForkし、仮想アプリケーションとして使用
    • 上記リポジトリをForkし、手元にCloneしてある状態であること

環境

  • macOS Majave
  • kubectl Client v1.15.1
  • kubectl Server v1.12.8-gke.10
  • Google Cloud SDK 259.0.0(gcloudはこれに含まれる)

構築の流れ

セットアップ編の大まかな流れがこちらです。

  1. 各種クライアントツールをインストール
  2. GKEクラスターのセットアッップ
  3. Argo CDのインストール
  4. Argo CDのセットアップ
  5. Argo Rolloutsのインストール
  6. Argo Rolloutsのセットアップ

手順

1. 各種クライアントツールをインストール

ここではセットアップに必要な各種クライアントツールをインストールしていきます。

$ brew tap argoproj/tap
$ brew install argoproj/tap/argocd

2. GKEクラスターのセットアップ

ここでは、GKEクラスターをセットアップしていきます。

# プロジェクトの設定
$ gcloud auth login
$ GCP_PRJ=<your GCP project ID>
$ gcloud config set project $GCP_PRJ

# GKEクラスターの作成
$ GKE_CLUSTER_NAME=<your GKE Cluseter Name>
$ gcloud container clusters create $GKE_CLUSTER_NAME
$ gcloud container clusters get-credentials $GKE_CLUSTER_NAME
$ gcloud container clusters list

# デフォルトで用意されているcluster-adminというClousterroleとuserをバインディング
# cluster-adminは、cluster内の全てのリソースに対し、どんなアクションでも可能な権限
$ APPNAME=<your name> # 任意。今回はアプリケーション名にした。
$ USER_NAME=<your GCP account> # GCPのアカウントに使用しているメールアドレス。
$ kubectl create clusterrolebinding ${APPNAME}-cluster-admin-binding --clusterrole=cluster-admin --user=$USER_NAME
$ kubectl get clusterrolebinding | grep ${APPNAME}

3. Argo CDのインストール

ここではArgo CDをインストールしていきます。
GKE内にArgo用のServiceやpodを起動させます。


# Namaspace作成
$ kubectl create ns argocd
$ kubectl get ns

# Argo CDインストール
$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
$ kubectl get service -n argocd
$ kubectl get pods -n argocd

# PublicAccessを実現するためにLoadbalancerの作成
$ 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.47.255.158   34.85.104.22   80:32676/TCP,443:31540/TCP   17m

#上記のEXTERNAL-IPをセットしておきます。
$ ARGOCD_SERVER=<EXTERNAL-IP> 

上記のEXTERNAL-IPで表示されたIPアドレスにブラウザからアクセスします。

次にArgoのログインパスワードを取得します。デフォルトはargocd-serverのpod名となっています。

# パスワード取得コマンド
$ kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2

パスワードが取得できたら Username: admin と上記で取得したパスワードでログインが可能となります。
次にargocdコマンドでもArgoにログインしておきます。

# パスワードは、上述の通り
$ argocd login $ARGOCD_SERVER 

なお、Argoのデフォルトパスワードを変更したい場合はこちらのコマンドで可能です。

$ argocd account update-password

4. Argo CDのセットアップ

デプロイ対象のGitHub repositoryを追加していきます。


$ REPO_URL=<your repository URL> # 今回は例としてForkしたExampleリポジトリのURL([email protected]:<your account name>/examples.git)を設定
$ SSH_KEY_PATH=<your ssh key path>
$ argocd repo add $REPO_URL --ssh-private-key-path $SSH_KEY_PATH

GUIでもリポジトリが追加されていることが確認できます。

続いて管理するkubernetesのclusterの追加します。


$ K8S_CLUSTER_NAME=`kubectl config get-contexts | grep "*" | awk '{print $3}'`
$ argocd cluster add $K8S_CLUSTER_NAME

GUIでもClusterが追加されていることが確認できます。

続いて、Argo上にアプリケーションを作成します。


$ ARGO_SYNC_PATH=guestbook/ # manifestファイルがあるディレクトリを指定します。
$ DEST_SERVER=`argocd cluster list | grep $K8S_CLUSTER_NAME | awk '{print $1}'`

# argo上にアプリケーションを作成。以下、補足説明
#  --repo:同期するGitHubリポジトリ
#  --path:同期するmanifestファイルがあるディレクトリ
#  --dest-server:ArgoのURL
#  --dest-namespace:Argo上Namespace 
#  --revision:同期するブランチ
#  --sync-policy automated:自動同期を有効
#  --auto-prune:同期時にリソースの削除を有効

$ argocd app create $APPNAME \
  --repo $REPO_URL \
  --path $ARGO_SYNC_PATH \
  --dest-server $DEST_SERVER \
  --dest-namespace default \
  --revision master \
  --sync-policy automated \
  --auto-prune

ArgoのGUIでもアプリケーションがデプロイされたことが確認できます。

これでGKE上にアプリケーションがデプロイされましたが、現状だとPublicに公開していない状態なので仮でingressを作ります。
以下のmanifestファイルをguestbook/ディレクトリ以下に作成し、masterブランチでコミットしてPushします。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: app-ingress
spec:
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: frontend
          servicePort: 80

しばらくするとArgoがGitHubと現構成との差分を検知し、同期することでingressが作成されます。
GitOpsですね。
以下のコマンドでingressに付与されたPublicIPAddressが確認できるのでそちらにアクセスします。

$ kubectl get ingress
NAME          HOSTS   ADDRESS         PORTS   AGE
app-ingress   *       35.190.119.89   80      14m

guestbookが確認できました。

5. Argo Rolloutsのインストール

つづいて、Argo Rolloutsのインストールします。
Argo CDだけでもデプロイは可能ですが、blue/greenデプロイやカナリアリリースをやろうと思った時に必要となります。


$ kubectl create ns argo-rollouts
$ kubectl get ns
$ kubectl apply -n argo-rollouts -f https://raw.githubusercontent.com/argoproj/argo-rollouts/stable/manifests/install.yaml
$ kubectl get service -n argo-rollouts
$ kubectl get pods -n argo-rollouts

以上でセットアップ完了となります。
次回、実際にカナリアリリースを実現する方法を書きたいと思います。


2019/08/29 続編書きました
GKEでArgoを使ったカナリアリリースを実現する(完結編)

参考文献

この記事は以下の情報を参考にして執筆しました。
EKSでArgo CDのチュートリアルを試してみた
GKEでArgoCDを使ってGitOpsしてみた
Argo CDによってGKEでGitOpsをする
デフォルトで用意されているClusterRole