🌊
GithubActions+ArgoCD+Helmでコンテナイメージのバージョンタグで管理していく方法
構成
- Github
- EKS
- ECR
- ArgoCD
概要
- アプリケーションを管理しているリポジトリとKubernetesマニフェストファイル(helm chart)を管理しているリポジトリの2つがあるという場合に使える
- ちなみに、このようにリポジトリを分断するのはアンチパターンではなく推奨であるということを何処かで読んだ気がした
- 1リポジトリであればGithubActions同士を連携させるという必要はないし、アクセストークンも使わなくていいという利点はある
- latestイメージで管理する場合、ロールバック機能を封印することになってしまうためKubernetesの良いポイントを活かせないので、可能ならバージョンタグで管理したいところ
流れ
- アプリケーション用リポジトリでGitタグを付けてPushすることで以下を実行
- DokcerイメージBuild&Push
- Kubernetesマニフェストファイル用リポジトリのイメージタグを更新するプルリクを自動的に出す
- Kubernetesマニフェストファイル用リポジトリでイメージタグ部分のみが更新される
- ArgoCDにて、Kubernetesマニフェストファイル用リポジトリの変更を検知し自動的に最新イメージを起動
前提
個人アクセストークンを取得する
- Github - Settings - DeveloperSettings - Personal Access Tokensから取得
- 必要な権限はrepo系の権限があればよい
- 個人アクセストークンだとリポジトリごとに権限を割り振ることができないため権限が強すぎる
- そのため、このあたりの記事を参考にレポジトリを絞れるとなお良い
- https://dev.classmethod.jp/articles/getting-an-access-token-with-only-the-necessary-permissions-on-github-appsgithub-actions/
手順
アプリケーション用リポジトリに設定
- 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環境のみでしか動かないです
参考
Discussion