1
0

More than 3 years have passed since last update.

ArgoCDの構築をパイプライン化する(ArgoCDの管理もArgoCDを利用してGitopsする)

Posted at

はじめに

前回の記事 でGKEのデプロイパイプラインを構築した。
GKEは費用の関係で頻繁に消したり作ったりしたかったため上記のパイプラインで実現したが、GKEの構築が自動化されていてもGKEへのアプリのデプロイが自動化されていなければ意味がないのでそこも自動化したい。
今回はGKE構築後にJOBを1つ実行するだけで、CD環境構築も行いつつGKEへのアプリのデプロイを自動で行われるパイプラインを構築する。
GKEへのCD環境として、タイトルにある通りArgoCDを利用する。また、パイプラインの実行はGithub Actionsで行い、マニフェストYAMLの管理としてkutomizeを利用する。
それぞれの技術要素の解説はしないため、参考に示す記事や公式サイトを参照してください。

環境

パイプライン上で利用する環境についてはソースコード内に記述されているため、ローカルの操作に必要なもののみ記述

* macOS Catalina Version 10.15.4
* fish (利用シェル)
* Google Cloud SDK 272.0.0

前準備

GKEの管理者としてのサービスアカウントを作成

GKEへのArgoのインストールのために、クラスタの管理者権限を持ったサービスアカウントを作成する。
サービスアカウント名はcontainer-admin-service-accountとして作成する。

# GCPにプロジェクト名を取得して環境変数に設定
$ set GCP_PROJECT (gcloud info --format='value(config.project)')

# サービスアカウント名を環境変数に設定
$ set CONTAINER_ADMIN_SA container-admin

# プロジェクトと名前を引数にサービスアカウント を作成
$ gcloud iam service-accounts create $CONTAINER_ADMIN_SA --project=$GCP_PROJECT --display-name $CONTAINER_ADMIN_SA

# 作成したサービスアカウントのID情報を環境変数に設定
$ set CONTAINER_ADMIN_SA_EMAIL (gcloud iam service-accounts list --project=$GCP_PROJECT --filter="displayName:$CONTAINER_ADMIN_SA" --format='value(email)')

# クラスタ管理に関わるAPIを使用する権限を付与する
$ gcloud projects add-iam-policy-binding $GCP_PROJECT \
    --role roles/container.admin \
    --member serviceAccount:$CONTAINER_ADMIN_SA_EMAIL

# 結果確認
$ gcloud projects get-iam-policy $GCP_PROJECT \
      --flatten="bindings[].members" \
      --filter="bindings.members:serviceAccount:$CONTAINER_ADMIN_SA_EMAIL" \
      --format='table(bindings.members,bindings.role)'

# サービスアカウントのkeyファイル(json)の作成
$ set CONTAINER_ADMIN_SA_DEST ~/.gcp/container-admin.json
$ mkdir -p (dirname $CONTAINER_ADMIN_SA_DEST)
$ gcloud iam service-accounts keys create $CONTAINER_ADMIN_SA_DEST --iam-account $CONTAINER_ADMIN_SA_EMAIL

ArgoCD

ArgoCDインストールのためのパイプライン構築について記述していく。
ArgoCD自体の詳細は、ArgoCD公式ドキュメントArgo CDによってGKEでGitOpsをするの記事を参照してください。

また、この章で紹介するコードは以下のGitリポジトリ上で公開しています。
https://github.com/sabure500/argocd-install

Github ActionsでArgoCDのインストールを行う

まずは、GKEへのArgoCDのインストールに関するパイプラインを作成する。
本章では、初期設定でのArgoCDのインストールまでのワークフローを記述する。
後ほどArgoCDの管理もArgoCDで行うための記述を追加するためargocd-install.yaml(仮)としている。
まず全体を示し、その後各stepを解説する。

argocd-install.yaml(仮)
name: 'argocd-install'
on:
  push:
    branches:
      - master
  repository_dispatch:
    types: [argocd-install]

env:
  PROJECT_ID: ${{secrets.PROJECT_ID}}
  GKE_CLUSTER: my-gke-cluster
  GKE_ZONE: us-west1-a
jobs:
  argo-install:
    runs-on: ubuntu-latest
    steps:
      - name: 'Checkout'
        uses: actions/checkout@v2

      - name: Setup Google Cloud
        uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
        with:
          version: '289.0.0'
          project_id: ${{secrets.PROJECT_ID}}
          service_account_email: ${{ secrets.SA_EMAIL }}
          service_account_key: ${{ secrets.SA_KEY }}

      - name: Setup GKE
        run: |-
          gcloud container clusters get-credentials "$GKE_CLUSTER" --zone "$GKE_ZONE"

      - name: Install ArgoCD Application
        run: |-
          kubectl create namespace argocd
          kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v1.5.2/manifests/install.yaml
          kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
          kubectl get deploy,pod,svc -n argocd

      - name: Download Argocd CLI
        run: |-
          curl -sSL -o ./argocd https://github.com/argoproj/argo-cd/releases/download/v1.5.2/argocd-linux-amd64
          chmod +x ./argocd

      - name: ArgoCD change password
        run: |-
          sleep 3m
          ARGOCD_SERVER=$(kubectl get service argocd-server -n argocd |awk 'NR==2' | awk '{print $4}')
          echo $ARGOCD_SERVER
          ARGOCD_TEMP_PASSWORD=$(kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2)
          ./argocd login --insecure --username admin --password $ARGOCD_TEMP_PASSWORD $ARGOCD_SERVER
          ./argocd account update-password --current-password $ARGOCD_TEMP_PASSWORD --new-password ${{secrets.ARGOCD_PASSWORD}}

また、このワークフローの実行のために、事前にGithubにSecretsとして設定が必要な値は以下の通り

  • PROJECT_ID : GCPのプロジェクト
  • SA_EMAIL : パイプライン実行で利用するServiceAccountのID
  • SA_KEY : 上記サービスアカウントのKey
  • ARGOCD_PASSWORD : ArgoCDの管理者ユーザーのパスワードに設定する値

GCPへのログインと対象のクラスタ選択に関する記述

GCP公式で提供しているActionを利用してGCPへのログインを行っている。
事前にenvにて使用するクラスタの名前やゾーンを設定しておきそれを利用している。
また、GithubのSecretsで先ほど作成したServiceAccountのIDとKEYを入力して利用している。
withで設定できる引数等の詳細な記述方法については、使用しているActionの公式リポジトリを参照する

env:
  PROJECT_ID: ${{secrets.PROJECT_ID}}
  GKE_CLUSTER: my-gke-cluster
  GKE_ZONE: us-west1-a
      - name: Setup Google Cloud
        uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
        with:
          version: '289.0.0'
          project_id: ${{secrets.PROJECT_ID}}
          service_account_email: ${{ secrets.SA_EMAIL }}
          service_account_key: ${{ secrets.SA_KEY }}

      - name: Setup GKE
        run: |-
          gcloud container clusters get-credentials "$GKE_CLUSTER" --zone "$GKE_ZONE"

GKEへのArgoCDのインストールに関する記述

基本的にArgoCD公式のGetting Startedを参考にしている。

      - name: Install ArgoCD Application
        run: |-
          kubectl create namespace argocd
          kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v1.5.2/manifests/install.yaml
          kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
          kubectl get deploy,pod,svc -n argocd

この記述で以下の手順を実現している

  1. argocdのNamespaceの作成
  2. argocdの公式マニフェストファイルをGKEにデプロイする
  3. argocdの公開用のIPを作成

ArgoCDの管理者パスワードの変更

ArgoCDインストール後の初期パスワードはPOD名になる。
この初期パスワードについても、地震が指定する値にパイプラインで変更する。
こちらも、基本的にArgoCD公式のGetting Started を参考にしている。

      - name: Download Argocd CLI
        run: |-
          curl -sSL -o ./argocd https://github.com/argoproj/argo-cd/releases/download/v1.5.2/argocd-linux-amd64
          chmod +x ./argocd

      - name: ArgoCD change password
        run: |-
          sleep 3m
          ARGOCD_SERVER=$(kubectl get service argocd-server -n argocd |awk 'NR==2' | awk '{print $4}')
          echo $ARGOCD_SERVER
          ARGOCD_TEMP_PASSWORD=$(kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2)
          ./argocd login --insecure --username admin --password $ARGOCD_TEMP_PASSWORD $ARGOCD_SERVER
          ./argocd account update-password --current-password $ARGOCD_TEMP_PASSWORD --new-password ${{secrets.ARGOCD_PASSWORD}}

上記の記述にて以下の手順を実現している

  1. ArgoCDにログインするために、ArgoCDのCLIを取得する
  2. PODが立ち上がり公開用のIPが作成されるまで待機※1
  3. 管理者ユーザーの初期パスワード(POD名)を取得
  4. 作成された公開用IPを利用してArgoCDへのログイン
  5. ArgoCDの管理者パスワードを変更する

ArgoCD自体の管理をArgoCDで行う

上記の章でパイプラインでArgoCDの構築ができるようになったが、このままだと構築後にArgoCDのプロジェクトやアプリケーションは手動で作成する必要がある。
設定は全てGitOpsで行いたいため、ArgoCDの初期設定に関してもパイプライで構築時に読み込む方法について記述していく。

ArgoCD独自設定のマニフェストファイルの作成

Argo構築時に作成したいArgoProjectやArgoApplicationの設定をyamlにして、パイプラインを実行するリポジトリと別リポジトリで管理する。
※このリポジトリに関しては、Credential情報がリポジトリの外に出せなかったため、privateにしている。
リピジトリの公開ができないため、ディレクトリ構成を以下に示す。

argocd-admin/
  ├ AppProject/
  │   ├ admin.yaml
  │   └ guestbook.yaml
  ├ AppApplication/
  │   ├ argocd-admin.yaml
  │   ├ guestbook.yaml
  │   └ kubernetes-admin.yaml
  ├ argocd-server.yaml
  └ kustomization.yaml

それぞれのyamlファイルの中身を解説していく

また、AppProjectとAppApplicationのyamlファイルについてはGUIから作成後に以下のコマンドで出力することもできる

  • argocd proj get $APP_PROJECT_NAEM -o yaml
  • argocd app get $APP_APPLICATION_NAEM -o yaml

AppProject/admin.yaml

KubernetesやArgoの管理用のリソースをまとめて管理するためのArgoプロジェクトに関する設定
詳細な書き方は、ArgoCD公式の宣言的なセットアップのページ に記載されているが、以下に簡単な解説を示す。

  • spec.sourceReposでこのプロジェクト内のArgoアプリケーションがアクセス可能なGitリポジトリを指定する
    • この【Personal access tokens】の部分がGitの外に出せずにベタ書きしている
    • ここの値は各リポジトリの内容に合わせて修正する
    • Perspnal Access Tokenの作り方についてはGithub公式のこのページを参照する
  • spec.destinationsでこのプロジェクト内のArgoアプリケーションで利用できるNameSpeceとクラスタを指定する
  • spec.clusterResourceWhitelistでこのプロジェクト内のArgoアプリケーションで管理できるNameSpaceやPV等のクラスタリソースを指定する
  • spec.roleでこのプロジェクト内のArgoアプリケーションに関して、個々に実行可能なAction(CRUD)を指定する
admin.yaml
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: admin
  namespace: argocd
spec:
  sourceRepos:
  - https://【Personal access tokens】@github.com/sabure500/argocd-admin.git
  - https://【Personal access tokens】@github.com/sabure500/kubernetes-admin.git
  destinations:
  - namespace: default
    server: https://kubernetes.default.svc
  - namespace: argocd
    server: https://kubernetes.default.svc
  - namespace: kube-system
    server: https://kubernetes.default.svc
  clusterResourceWhitelist:
  - group: ""
    kind: Namespace
  - group: ""
    kind: PersistentVolume
  - group: rbac.authorization.k8s.io
    kind: ClusterRole
  - group: rbac.authorization.k8s.io
    kind: ClusterRoleBinding
  - group: storage.k8s.io
    kind: StorageClass
  - group: apiextensions.k8s.io
    kind: CustomResourceDefinition
  roles:
  - name: argocd-admin
    policies:
    - p, proj:admin:argocd-admin, applications, *, admin/argocd-admin, allow
    - p, proj:admin:kubernetes-admin, applications, *, admin/kubernetes-admin, allow

AppApplication/argocd-admin.yaml

ArgoCD自身のリソースを管理するマニフェストが入ったリピジトリ(自分自身)の内容を同期するためのArgoアプリケーションに関する設定
詳細な書き方については、ArgoCD公式の宣言的なセットアップのページ に記載されているが、以下に簡単な解説を示す。

  • spec.projetでこのアプリケーションが所属するプロジェクトを指定する
  • spec.source.repoURL,spec.source.targetRevisionで読み込むリポジトリとブランチを指定する
  • spec.source.pathでリピジトリ内におけるkustomization.yamlがある場所を指定する
  • spec.syncPolicy.automatedによって指定リポジトリの状況を読み込んでGKEクラスタに反映し続けるAutoSyncの設定を有効にしている
argocd-admin.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: argocd-admin
  namespace: argocd
spec:
  destination:
    namespace: argocd
    server: https://kubernetes.default.svc
  project: admin
  source:
    path: .
    repoURL: https://【Personal access tokens】@github.com/sabure500/argocd-admin.git
    targetRevision: master
  syncPolicy:
    automated: {}

AppApplication/kubernetes-admin.yaml

クラスタリソースのマニフェスト管理は別リポジトリにて行うこととし、その内容を同期するためのArgoアプリケーションに関する記述

kubernetes-admin.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: kubernetes-admin
  namespace: argocd
spec:
  destination:
    namespace: argocd
    server: https://kubernetes.default.svc
  project: admin
  source:
    path: .
    repoURL: https://【Personal access tokens】@github.com/sabure500/kubernetes-admin.git
    targetRevision: master
  syncPolicy:
    automated: {}
  • 別リポジトリである、kubernetes-admin.gitでは以下のような構成でNamespaceを作成するためのマニフェストが入っている(今回はサンプルアプリ用のNamespaceを作成している)
kubernetes-admin/
  ├ Namespace/
  │   └ guestbook.yaml
  └ kustomization.yaml
guestbook.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: guestbook
  labels:
    name: guestbook
kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
 - Namespace/guestbook.yaml

ArgoProject/guestbook.yaml

構築後に自動でアプリケーションがデプロイされていることを確かめるために、サンプルアプリ用のArgoプロジェクトを作成する

AppProject/guestbook.yaml
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: guestbook
  namespace: argocd
spec:
  sourceRepos:
  - https://github.com/sabure500/argocd-example-apps.git
  destinations:
  - namespace: guestbook
    server: https://kubernetes.default.svc
  roles:
  - name: guestbook
    policies:
    - p, proj:guestbook:guestbook, applications, *, guestbook/guestbook, allow

ArgoApplication/guestbook.yaml

サンプルアプリ用にArgoアプリケーションも作成する

  • spec.sourceReposにてArgoCDのサンプルアプリ用リポジトリを直接参照する
  • spec.destinations.namespaceにてこのプロジェクトが操作するNamespaceをguestbookに設定する
  • spec.source.pathにて対象リポジトリ内のkustomization.yamlがあるフォルダを指定する
AppApplication/guestbook.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: guestbook
  namespace: argocd
spec:
  destination:
    namespace: guestbook
    server: https://kubernetes.default.svc
  project: guestbook
  source:
    path: ./kustomize-guestbook
    repoURL: https://github.com/sabure500/argocd-example-apps.git
    targetRevision: master

公開用IPを作りたい場合

アプリデプロイ時に公開用IPも作成したい場合は、サンプルリポジトリをForkしてServiceの内容を以下の様に更新する(プロジェクトとアプリケーションの対象のリポジトリもFork先に変更する)
この記事の例でもFoekした自身のリポジトリを見ている

guestbook-ui-svc.yaml
apiVersion: v1  
kind: Service   
metadata:   
  name: guestbook-ui    
spec:   
  ports:    
  - port: 80    
    targetPort: 80  
  selector: 
    app: guestbook-ui
  type: LoadBalancer

kustomization.yaml $ argocd-server.yaml

ここまでで作成したリソースをまとめて管理するための設定を記述する

  • basesにてArgoCDインストール用のマニフェストファイルを指定する
  • resourcesにて上記で作成した自身独自のリソースを指定する
  • baseから取得したリソースの中で、argocd-serviceのみパブリックIPの追加といった設定変更を行いたいため、patchesStrategicMergeにて指定する
kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

bases:
 - github.com/argoproj/argo-cd//manifests/cluster-install?ref=v1.5.2

resources:
 - AppProject/admin.yaml
 - AppProject/guestbook.yaml
 - Application/argocd-admin.yaml
 - Application/kubernetes-admin.yaml
 - Application/filebeat.yaml
 - Application/guestbook.yaml

patchesStrategicMerge:
 - argocd-server.yaml
argocd-server.yaml
apiVersion: v1
kind: Service
metadata:
  name: argocd-server
spec:
  type: LoadBalancer

argocd-adminリポジトリの内容を読み込んでArgoCDを構築するパイプラインの作成

独自設定を読み込んでArgoCDのインストールを行うワークフローを記述する。

こちらもまず全体を示し、その後(仮)からの変更点を解説する。

argocd-install.yaml
name: 'argocd-install'
on:
  push:
    branches:
      - master
  repository_dispatch:
    types: [argocd-install]

env:
  PROJECT_ID: ${{secrets.PROJECT_ID}}
  GKE_CLUSTER: my-gke-cluster
  GKE_ZONE: us-west1-a
jobs:
  argocd-install:
    runs-on: ubuntu-latest
    steps:
      - name: 'Checkout'
        uses: actions/checkout@v2

      - name: Setup Google Cloud
        uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
        with:
          version: '289.0.0'
          project_id: ${{secrets.PROJECT_ID}}
          service_account_email: ${{ secrets.SA_EMAIL }}
          service_account_key: ${{ secrets.SA_KEY }}

      - name: Setup GKE
        run: |-
          gcloud container clusters get-credentials "$GKE_CLUSTER" --zone "$GKE_ZONE"

      - name: Checkout argocd-admin repository
        uses: actions/checkout@v2
        with:
          repository: sabure500/argocd-admin
          ref: master
          token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}

      - name: Setup Kustomize
        run: |-
          curl -sfLo kustomize https://github.com/kubernetes-sigs/kustomize/releases/download/v3.1.0/kustomize_3.1.0_linux_amd64
          chmod u+x ./kustomize

      - name: Install ArgoCD Application
        run: |-
          kubectl create namespace argocd
          ./kustomize build . | kubectl apply -n argocd -f -
          kubectl get deploy,pod,svc -n argocd

      - name: Download ArgoCD CLI
        run: |-
          curl -sSL -o ./argocd https://github.com/argoproj/argo-cd/releases/download/v1.5.2/argocd-linux-amd64
          chmod +x ./argocd

      - name: ArgoCD change password
        run: |-
          sleep 3m
          ARGOCD_SERVER=$(kubectl get service argocd-server -n argocd |awk 'NR==2' | awk '{print $4}')
          echo $ARGOCD_SERVER
          ARGOCD_TEMP_PASSWORD=$(kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2)
          ./argocd login --insecure --username admin --password $ARGOCD_TEMP_PASSWORD $ARGOCD_SERVER
          ./argocd account update-password --current-password $ARGOCD_TEMP_PASSWORD --new-password ${{secrets.ARGOCD_PASSWORD}}

変更点1:jobを実行しているリポジトリとは別のリポジトリへのCheckout

以下のstepを追加することで,別リポジトリの内容をこのアクションで利用することができる。

actions/checkoutの詳細な使用方法は公式リポジトリ参照

また、この処理を実施するために事前に作成済みの、PERSONAL_ACCESS_TOKENをこのリピジトリのSecretに新しく登録する必要がある

      - name: Checkout argocd-admin repository
        uses: actions/checkout@v2
        with:
          repository: sabure500/argocd-admin
          ref: master
          token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}

変更点2:kustomizeコマンドの取得

今回は、別リポジトリから取得した内容をkustomizeによってbuildするため以下のstepを追加することでkustomizeを取得している
kustomizeインストールの詳細情報は公式リポジトリ参照

      - name: Setup Kustomize
        run: |-
          curl -sfLo kustomize https://github.com/kubernetes-sigs/kustomize/releases/download/v3.1.0/kustomize_3.1.0_linux_amd64
          chmod u+x ./kustomize

変更点3:自身で用意した独自設定を読み込んでArgoCDのインストールを行う

ここまでの処理で別リポジトリの内容の所得とkustomizeコマンドの準備ができているため、以下の様なstepを追加することで独自設定を読み込んだArgoCDのインストールを行うことができる

ArgoCDがKubernetesにインストールされていない状態で、apiVersion: argoproj.io/v1alpha1が使用できないため、事前に初期設定でインストール後に独自設定を反映する形にしている。

argocd-adminのkustomization.yamlにてbaseで元々のArgoCD公式のマニフェストを指定しているため、変更点の独自設定だけが更新される形になる

また、パブリックIPの付与をyamlファイルで定義する形に変更したため、CLIによって行っていた行は削除している

      - name: Install ArgoCD Application
        run: |-
          kubectl create namespace argocd
          kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v1.5.2/manifests/install.yaml
          ./kustomize build . | kubectl apply -n argocd -f -
          kubectl get deploy,pod,svc -n argocd

実行結果

作成したパイプラインを実行するだけで、以下の画像の様にすでにArgoCDの設定が反映され、Argoアプリケーションやプロジェクト、またサンプルアプリそのものがデプロイされた状態で構築される

argocd1.png
argocd2.png
argocd3.png

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0