Github Actions을 사용하여 멀티플랫폼이 지원되는 이미지 빌드 방법과 Docker Hub 혹은 ECR에 Push하는 방법. 그리고 제 3의 Git Repo 파일 내용 변경 방법을 정리해보았다.

- Contents -

Github Actions 워크플로 yaml 파일 작성

⏤ Actions를 통해서 Java Application 빌드시, 다음과 같은 로직이 필요했다.

  • Application을 Docker image로 build 후 ECR Private repository에 image push

  • 위 Repo와는 별개의 Kubernetes manifest 관련 Github repository 특정 파일 image tag 갱신

  • 결국 Manifest 파일 변경 발생 → ArgoCD에 감지되어 Kubernetes Cluster에 Sync 동작

위 내용대로 Actions를 구현하였고 그 내용을 다음과 같이 기록하였다.

**Spring boot application repository > **.github/workflows/action.yml

※ Github Actions에서 ECR에 접근할 수 있도록 OIDC 방식 사용.

name: saas-oil application deploy

on:
  push:
    branches: [ "develop" ]
  pull_request:
    branches: [ "develop" ]

permissions:
  id-token: write   # This is required for requesting the JWT

env:
  APP_NAME: saas-oil
  BRANCH_NAME: develop

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up JDK 11
        uses: actions/setup-java@v4
        with:
          java-version: '11'
          distribution: 'temurin'
          cache: maven

      - name: Build with Maven
        run: mvn -B package --file pom.xml

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{env.APP_NAME}}-application-jar
          path: target/*.jar

      - name: List files in the working directory - 1
        run: ls target/

  docker:
    needs: build
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: ${{env.APP_NAME}}-application-jar
          path: target/

      # OIDC 인증
      - name: configure aws credentials
        uses: aws-actions/configure-aws-credentials@v3
        with:
          role-to-assume: ${{secrets.AWS_OIDC_ROLE}}
          role-session-name: ecrRoleSession
          aws-region: ${{secrets.AWS_REGION}}

      # ECR 로그인
      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

      # Docker 이미지 빌드 & ECR에 푸시
      - name: Build Docker image And Push to AWS ECR
        run: |
          docker build . -t ${{ secrets.AWS_ECR_URL }}/${{ env.APP_NAME }}:${{ env.BRANCH_NAME }}-${{ github.sha }}
          docker push ${{ secrets.AWS_ECR_URL }}/${{ env.APP_NAME }}:${{ env.BRANCH_NAME }}-${{ github.sha }}

  update-deployment:
    needs: docker
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Kubernetes manifest repository
        uses: actions/checkout@v2
        with:
          repository: ${{ vars.SAAS_KUBE_REPOSITORY }}
          token: ${{ secrets.SAAS_GITHUB_TOKEN }}
          ref: ${{ env.BRANCH_NAME }}

      - name: Update k8s oil file
        run: |
          sed -i 's|${{ secrets.AWS_ECR_URL }}/.*|${{ secrets.AWS_ECR_URL }}/${{ env.APP_NAME }}:${{ env.BRANCH_NAME }}-${{ github.sha }}|' kube/${{env.BRANCH_NAME}}/${{env.APP_NAME}}.yaml
          git config user.name ${{ vars.SAAS_GITHUB_EMAIL }}
          git config user.email ${{ vars.SAAS_GITHUB_NAME }}
          git add kube/${{env.BRANCH_NAME}}/${{env.APP_NAME}}.yaml
          git commit -m "Update image tag to ${{ github.sha }}"
          git push

📌 image build와 동시에 push하는 방법은 다음과 같이 더 간단하게 할 수도 있다.

docker buildx build --platform=linux/and64, 11nux/arm64 -t YOUR_DOCKERHUB_ID/YOUR_TAG_NAME . --push

빌드 명령어 뒤에 --push 명령어를 붙여주면, 별도로 push 명령을 하지 않아도 빌드와 동시에 이미지를 푸시한다.

(참고로 위 명령어는 buildx를 사용해서 amd64, larm64 플랫폼에서 사용할 수 있는 형태의 이미지로 빌드한다는 내용. Buildx는 밑에서 한번 더 다룰 예정)

Docker Hub Private repo에 push 하는 방법

기존에는 Docker image를 ECR이 아닌 Docker Hub Private repo에 push 하는 방식. 이를 위한 actions 일부 내용 ⬇

  docker:
    needs: build
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Download artifact
        uses: actions/download-artifact@v2
        with:
          name: spring-application-jar
          path: build/libs

      - name: Build Docker image
        run: docker build . -t ${{ secrets.DOCKER_REPO }}:tag-${{ github.sha }}

      - name: Log in to DockerHub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Push Docker image to DockerHub
        run: docker push ${{ secrets.DOCKER_REPO }}:tag-${{ github.sha }}
  • DOCKER_USERNAME ⇒ 도커 이미지가 올라갈 레파지토리에 접근할 사용자 이름

  • DOCKER_PASSWORD ⇒ 사용자의 Access token (토근 발급 방법: Docker Hub 사이트 로그인 → My Account → Security → New Access Token 발급)

Mult Platform 이미지 - Buildx를 사용한 Docker image build & push

위에서는 docker image를 build하고 push하는 방법으로 아래와 같은 커맨드 라인으로 수행하고있다.

run: docker build . -t ${{ secrets.DOCKER_REPO }}:tag-${{ github.sha }} run: docker push ${{ secrets.DOCKER_REPO }}:tag-${{ github.sha }}

이 방법은 위에도 명시되어 있듯이 “runs-on: ubuntu-latest” 이 부분에 의해 기본적으로 amd64 아키텍처로 설정된 이미지로 빌드되는 방식이다.

즉, 이미지를 pull하게 되는 컴퓨터의 하드웨어가 x86-64이라는 전제가 깔려있는 내용이다.

그래서 이 image를 가지고 로컬테스트 해보겠다고 맥북에서 pull하여 사용하면 당연히 에러가 발생한다. (exec format error 라는 에러메세지를 볼 수 있다)

따라서, 만약 이미지를 내 Mac에서도 사용할 수 있도록 Multi Platform을 지원하기 위한 방법은 buildx를 사용하여 arm64 아키텍쳐도 지원하도록 하면된다.

  docker:
    needs: build
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: ${{env.APP_NAME}}-application-jar
          path: target/

      # OIDC 인증
      - name: configure aws credentials
        uses: aws-actions/configure-aws-credentials@v3
        with:
          role-to-assume: ${{secrets.AWS_OIDC_ROLE}}
          role-session-name: ecrRoleSession
          aws-region: ${{secrets.AWS_REGION}}

      # ECR 로그인
      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

      # Docker 이미지 빌드 & ECR에 푸시
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Build and push Docker image
        uses: docker/build-push-action@v3
        with:
          context: .
          file: ./Dockerfile
          push: true
          tags: ${{ secrets.AWS_ECR_URL }}/${{ env.APP_NAME }}:${{ env.BRANCH_NAME }}-${{ github.sha }}
          platforms: linux/amd64,linux/arm64 

참고 링크: https://docs.docker.com/build/ci/github-actions/multi-platform/ (Docker Hub 공식문서)