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 공식문서)