💭

【Github actions/GitOps】Dockerイメージタグ更新Pull Requestの作成

5 min read

はじめに

この記事では、Kubernates(k8s)上のアプリケーションに対するデプロイを目的とした、Dockerイメージタグ更新更新Pull Requestの作成について説明します。作成ではGithub actionsをCIとして利用します

やりたいこと

今回自分が作成したデプロイフローの全体図は以下の通りです。

以上全体フローの中で、CIで行いたいことは具体的には以下のフローとなります。

  1. アプリケーションコードを管理するリポジトリで変更が行われたらCIが起動する
  2. 最新のアプリケーションコードをでDockerイメージをビルド、タグ更新、ECR(AWSのContainerRegistory)へPush
  3. k8sマニフェストリポジトリで、使用するDockerイメージのタグを更新するPull Requestの作成

作成されたPull Requestをマージすると、GitOpsツールが変更を検知し、k8sリソース変更することで、デプロイを実現します。

リポジトリ間のCI連携

今回2つのリポジトリに跨ってCIフローが行われますが、リポジトリ間のCI連携のために repository_dispatch と呼ばれるGithub actionsの機能を利用します。repository_dispatchはGithub APIを経由で通知をトリガーにワークフローを実行できる仕組みになります。

CIの設定

アプリケーションRepository側のCI

アプリケーションRepository側のCIの設定はファイルは以下の通りです。

実際に行っていることは、以下の2つです。

  1. build-and-push
    • Dockerイメージをビルド、タグ更新、ECR(AWSのContainerRegistory)へPush
  2. update-manifests
    • repository-dispatchを使って、マニフェストリポジトリに対して通知
ame: main branch workflows

on:
  push:
    branches:
      - main

jobs:
  build-and-push:
    runs-on: ubuntu-18.04
    timeout-minutes: 300

    steps:
    - uses: actions/checkout@v1
    
    # AWSの認証情報設定
    - name: Configure AWS Credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ap-northeast-1

    # ECRへログイン
    - name: Login to Amazon ECR
      id: login-ecr
      uses: aws-actions/amazon-ecr-login@v1

    # Dockerビルド、最新のコミットハッシュでタグづけ、RCRへプッシュ
    - name: Build, tag, and push image to Amazon ECR
      env:
        ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        ECR_REPOSITORY: ${{ secrets.AWS_ECR_REPO_NAME }}
      run: |
        docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$GITHUB_SHA .
        docker push $ECR_REGISTRY/$ECR_REPOSITORY:$GITHUB_SHA

  update-manifests:
    runs-on: ubuntu-18.04
    needs: build-and-push
    timeout-minutes: 300
    env:
      MANIFEST_REPOSITORY: Ushinji/fastapi_sample_manifest

    steps:
    # repository-dispatchを使って、マニフェストリポジトリに対して通知
    # その際に、Dockerイメージにタグつけしたコミットハッシュを合わせて送信
    - name: dispatch update-manifests
      uses: peter-evans/repository-dispatch@v1.1.3
      with:
        repository: ${{ env.MANIFEST_REPOSITORY }}
        token: ${{ secrets.REPO_ACCESS_TOKEN }}
        event-type: update-manifest
        client-payload: '{"sha": "${{ github.sha }}"}'

k8sマニフェストRepository側のCI

アプリケーションRepository側のCIの設定はファイルは以下の通りです。

実際に行っていることは、以下の通りです

  1. アプリケーションリポジトリのCIから送信されたrepository-dispatchの通知をトリガーにCIワークフローを開始
  2. kustomize edit set imageコマンドで、使用するイメージのタグを更新
  • その際に使用するタグは、repository-dispatch経由で受け取ったコミットハッシュを使用
  1. 使用するイメージのタグを更新のPull Requestを作成

今回はkustomizeを使ったk8sマニフェストファイルの管理を行なっています。そのため、kustomize edit set imageを使うことで、利用するDockerイメージを変更することができます。

name: update manifest

on:
  repository_dispatch:
    types: [update-manifest]

jobs:
  update-manifests:

    runs-on: ubuntu-18.04
    timeout-minutes: 300
    env:
      KUSTOMIZE_VERSION: 4.1.2

    steps:
    - name: Checkout manifest repository
      uses: actions/checkout@v2
    
    # kustomizeのインストール
    - name: Install kustomize
      run: |
        apt-get update && apt-get install -y curl
        curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash -s ${{ env.KUSTOMIZE_VERSION }}
        sudo mv ./kustomize /usr/local/bin/kustomize

    # `kustomize edit set image`コマンドで、使用するイメージのタグを更新
    # その際に使用するタグは、repository-dispatch経由で受け取ったコミットハッシュを使用
    - name: Update image tag
      run: |
        cd base
        /usr/local/bin/kustomize edit set image ${{ secrets.IMAGE_URL }}=${{ secrets.IMAGE_URL }}:${{ github.event.client_payload.sha }}
        cd -
	
    # 使用するイメージのタグを更新のPull Requestの作成
    - name: Create Pull Request
      uses: peter-evans/create-pull-request@v3.8.2
      with:
        token: ${{ secrets.REPO_ACCESS_TOKEN }}
        commit-message: 'Update manifest'
        title: Update manifest ${{ github.event.client_payload.sha }}
        body: ""
        labels: ""
        branch: update-manifest-${{ github.event.client_payload.sha }}
        base: main

以上のCIワークフローで作成されたPull Requestは以下の通りです。このPull Requestをマージすると、GitOpsツール経由でデプロイが開始されます。

以上です。

参考

Discussion

ログインするとコメントできます