3. Github Action 으로 image build 해 github image Registry 에 올리기

jjuyaa·2023년 1월 10일
1

GitOps

목록 보기
3/7

Application Repository 에 새로운 push 가 발생하면 작성한 Dockerfile 을 이용해 새로운 Image 를 build 하고 Github image Registry 에 생성한 image 를 올린다.

Container Registry(github image registry) 란

생성한 image 를 github organization 혹은 personal account 내에 저장시켜, repository 에서 image 에 접근할 수 있도록 한다.

  • Image 를 생성한 후 저장,공유하고 생성될 경우 접근할 수 있는 곳이 필요하다. local 에서 image 를 생성한 후 image registry 에 push 하고, 그것을 k8s 환경에서 registry 를 통해 받아올 수 있다. 따라서 image registry 는 CI/CD workflow 에서 중요한 역할을 한다.

  • repository 의 접근 허용 범위를 그대로 따르게 할수도 있고, 독립적으로 container registry 에 대한 접근을 설정할 수 있다.

  • Docker image 또는 OCI image 를 저장할 수 있고, 저장공간의 namespacehttps://ghcr.io 이다.

  • public image 에 대해서 무료이고, beta 기간동안 private image 또한 무료이다.

Authentication to the Container registry

workflow 에서 Container registry 에 접근해 image 를 build & push 하기 위해 GITHUB_TOKEN 을 사용한다.

  • GITHUB_TOKEN 은 packages 를 read/write 하는 권한을 가진다.
  • 새로운 Personal Access Token 을 생성해 image registry 에 인증하기 위해 사용한다면 read:packages , write packages, delete:pacakges 권한을 설정해 등록한다.

GITHUB_TOKEN

  • workflow 가 실행될 때 github 는 자동으로 workflow 내부에 unique 한 GITHUB_TOKEN 을 생성한다. 이 GITHUB_TOKEN 을 사용해 workflow 내부에서 인증 시 사용할 수 있다.
  • 해당 토큰의 접근 권한은 해당 workflow 가 존재하는 repository 에 한정된다. 토큰과 관련된 자세한 권한 정보는 다음을 참고한다.
  • workflow 에서 GITHUB_TOKEN 이 가진 권한 외에 다른 권한이 필요할 경우 자신의 Personal access Token 을 생성한 후 , 해당 workflow 가 존재하는 repository 에 Repository Secret 으로 등록해 ${{secrets.SECRET_NAME}} 으로 불러와 사용할 수 있다.

Docker 이미지 build 후 Github Packages(Registry) 로 Publish 하기

새로운 push 발생시 , image build 후 registry로 push 한다.


name: Create and publish a Docker image

on:
  push:
    branches: ['release'] # release branch 로 push 발생할 경우

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-push-image:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Log in to the Container registry
        uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

      - name: Build and push Docker image
        uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
  • Docker login-action , metadata-action 그리고 build-push-action 를 사용해서 Docker 이미지를 build 하고 build 성공 시 Github Packages 로 생성된 이미지를 push 한다.

  • checkout : CI 서버에서 branch 를 checkout 해 repository 의 code 를 받아오고 workflow 내의 동작을 시작할 수 있도록 한다.

  • login-action : Github Image registry 에 인증해 로그인한다.

    • registry : 반드시 ghcr.io
    • username : ${{ github.actor }} workflow 가 run 하도록 trigger 한 사용자의 username 을 자동으로 사용할 수 있다.
    • password : GITHUB_TOKEN 또는 알맞은 권한을 가진 personal access token 을 사용할 수 있다.
  • metadata-action : image 를 build 하기 위한 tag , label 의 정보를 추출한다.

    • images : build 한 Docker image 의 이름
  • build-push-action : 추출한 tag , label 을 달아 Dockerfile 를 사용해 image 를 build 하고 registry 로 push 한다.

    • context : 특정한 path 에 위치한 files 즉 build’s context
    • push : true 로 설정할 경우 image가 성공적으로 build 될 경우 registry로 push 된다.
    • tags , labels : metadata-action 의 결과물

unique 한 tag 달기

unique 한 tag 를 생성한 image 에 달아, 이미지 배포 후 오류가 발생했을시 , 기존에 잘 동작하는 image 를 tag 로 찾아 다시 되돌리는데 용이하다.

1. github context 의 unigue 한 값 사용하기

contexts information 에서 unique 한 값을 사용해서 tag 를 생성할 수 있다.

  1. github.run_number : 특정 workflow 실행 시 고유 숫자로 1부터 시작해 새 실행마다 1씩 증가한다. 워크플로우 run 한 결과를 다시 re-run 할 경우 숫자는 변경되지 않는다.

  2. github.run_id : 레포지토리 내에서 실행되는 각workflow의 고유한 숫자이다. 워크플로의 run 을 re-run 하는 경우 변경되지 않는다.

  3. github.run_attempt : 특정한 workflow가 run 한 횟수 1부터 시작한다.

=> github.run_attempt 로 고유한 값 생성 가능

앞선 예제와 같이 workflow 를 생성한다면, 해당 값을 metadata-action 의 tag type=raw 의 value 값으로 적어 사용할 수 있다.

2. commit hash 값 사용하기

이전의 commit 순서를 기억하는 Hash 값을 사용해, 온/오프라인 상태에 상관없이 바로 commit 할 수 있기 때문에 Git 은 commit id 로 hash 값을 사용한다.
commit id 를 추출해 tag 로 붙인다면, 어떤 commit 에서 생성되었던 이미지인지 추적하기도 용이하다.

  • metadata-actiontag option 사용 : type=sha 를 사용한다.

workflow trigger button

workflow test 를 편하게 하기 위해 새로운 push 가 발생하지 않더라도, workflow 를 실행시킬 수 있는 수동 버튼을 생성한다.

수동으로 workflow 를 trigger 하기 위해 workflow_dispatch event 를 사용한다.

on:
	workflow_dispatch:
  •  workflow_dispatch event 를 trigger 하기 위해서는 해당 workflow 가 default branch 에 존재해야한다.

결과 workflow

name: Create and publish a Docker image

on:
  push: # PUSH & PR merge 될 경우
    branches: ["main"] # juya branch 로 push 발생할 경우
  # workflow trigger button
  workflow_dispatch:

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-push-image:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Log in to the Container registry
        uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata (tags, labels) for Docker
        id: meta
        uses: docker/metadata-action@v4
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          # 가장 최신 image 에 latest tag 달기
#          flavor: |
#            latest=true
          # Git short commit, use git version tag
          tags: |
            type=sha
            
      - name: Build and push Docker image
        id: build
        uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
        with:
          context: .
          file: Dockerfile # repository 기준 도커파일 위치
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

workflow 과정 확인

  • repository -> actions -> workflow 명을 클릭해 새로운 workflow 실행을 확인할 수 있다.

결과 확인

  • 계정 -> packages 에서 새롭게 build & push 된 이미지를 확인하고 받아올 수 있다.

참고

0개의 댓글