🌊

GithubActions+ArgoCD+Helmでコンテナイメージのバージョンタグで管理していく方法

2022/08/30に公開

構成

  • Github
  • EKS
  • ECR
  • ArgoCD

概要

  • アプリケーションを管理しているリポジトリとKubernetesマニフェストファイル(helm chart)を管理しているリポジトリの2つがあるという場合に使える
    • ちなみに、このようにリポジトリを分断するのはアンチパターンではなく推奨であるということを何処かで読んだ気がした
    • 1リポジトリであればGithubActions同士を連携させるという必要はないし、アクセストークンも使わなくていいという利点はある
  • latestイメージで管理する場合、ロールバック機能を封印することになってしまうためKubernetesの良いポイントを活かせないので、可能ならバージョンタグで管理したいところ

流れ

  1. アプリケーション用リポジトリでGitタグを付けてPushすることで以下を実行
    • DokcerイメージBuild&Push
    • Kubernetesマニフェストファイル用リポジトリのイメージタグを更新するプルリクを自動的に出す
  2. Kubernetesマニフェストファイル用リポジトリでイメージタグ部分のみが更新される
  3. ArgoCDにて、Kubernetesマニフェストファイル用リポジトリの変更を検知し自動的に最新イメージを起動

前提

個人アクセストークンを取得する

手順

アプリケーション用リポジトリに設定

  • GithubActionsでCIを作る
name: Build and Push web for stg

on:
  push:
    tags:
      - v* # gitタグの頭にvがついていれば実行される

jobs:
  build-and-push: # ECRへのBuildとPush
    runs-on: ubuntu-latest
    timeout-minutes: 300

    env:
      ACCOUNT_ID: 11111111111 # AWSアカウントIDEA
      ENV: stg

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_STG_KEY }}
          aws-secret-access-key: ${{ secrets.AWS_STG_SECRET }}
          aws-region: ap-northeast-1

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1

      - name: Build, tag, and push image to Amazon ECR web
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: vamdemic-${{ env.ENV }}-web
        run: |
          IMAGE_TAG=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g") # Gitタグからイメージタグを生成
          docker build -f server/Dockerfile.web -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG ./server/
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG

  update-helm-app-tag: # Kubernetesマニフェストファイル管理リポジトリのGithubActionsを非同期で実行
    runs-on: ubuntu-latest
    timeout-minutes: 300
    needs: build-and-push # build&pushが完了していることを条件に起動

    steps:
      - name: Checkout Helm Repository
        uses: actions/checkout@v2

      - name: Set Env
        run: |
          echo "GITHUB_REF=${{ github.ref_name }}" >> $GITHUB_ENV

      - name: Repository Dispatch
        uses: peter-evans/repository-dispatch@v1
        with:
          token: ${{ secrets.REPO_ACCESS_TOKEN }} # 個人アクセストークン
          repository: vamdemic-system/vamdemic-infra
          event-type: update-yml
          client-payload: '{"ref": "${{ env.GITHUB_REF }}"}'

kubernetesマニフェストファイルリポジトリ

変更をかけたいポイント

app:
  image: 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/vamdemic-stg-web
  tag: "v1.5" # ←ここ
name: Update Yml

on:
  repository_dispatch:
    types:
      - update-yml

jobs:
  update-yml:
    runs-on: ubuntu-latest

    env:
      ENV: stg

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Set Env
        run: |
          echo GITHUB_REF"=${{ github.event.client_payload.ref }}" >> $GITHUB_ENV # 実行元のGithubActionsから引き渡された値群(イメージタグを含む)を取得

      - name: Update app yaml
        uses: mikefarah/yq@master
        with:
          cmd: IMAGE_TAG='${{ env.GITHUB_REF }}' yq eval '.app.tag = env(IMAGE_TAG)' -i kubernetes/vamdemic-chart/stg_values.yaml # yqでイメージタグ部分を置換する

      - name: commit & push # 変更のcommitとPush
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # このSecretは自身のリポジトリに対しての操作であれば登録不要
        run: |
          BRANCH_NAME="master"
          git config user.name update-yml
          git config user.email update-yml@vamdemic.co.jp
          git checkout "$BRANCH_NAME"
          git add -A
          git commit -m "update image tag ${{ env.GITHUB_REF }}"
          git push origin "$BRANCH_NAME"

ArgoCD

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: vamdemic
  namespace: argocd
spec:
  project: vamdemic
  source:
    repoURL: git@github.com:vampire-yuta/vamdemic-Infra
    targetRevision: master
    path: kubernetes/vamdemic-chart
    helm:
      valueFiles:
        - values.yaml
  syncPolicy:
    automated:
      prune: true
    syncOptions:
      - CreateNamespace=true
  destination:
    server: https://kubernetes.default.svc
    namespace: vamdemic

実行

アプリケーション側のアップデートが終わったらタグを付けてPushすればOK

git tag -a v1.1 -m "v1.1"
git push origin v1.1

注意点

  • このサンプルは1環境のみでしか動かないです

参考

https://qiita.com/aidadada/items/6dd8efab57fb4c923adf

Discussion