최근 프로젝트를 진행하면서 쿠버네티스 환경에 배포할 일이 생겼다. 그래서 이번 김에 프로젝트 릴리즈와 도커 이미지 빌드 및 푸시까지 자동화 하는 CI/CD 파이프라인을 구축하려고 한다.
원래는 jenkins를 사용하려고 했는데 서버 만들기도 귀찮고 복잡한 작업이 많아서 git hub actions를 사용해보기로 했다. git hub actions는 jenkins에 비해 서버가 따로 필요 없이 클라우드 위에서 동작하고 레포지토리가 public이면 무료다! 그리고 yaml 파일을 통해 쉽게 환경을 만들 수 있다는 장점이 있다.
프로젝트 폴더에 .github 디렉토리를 만들고 workflows 디렉토리를 생성해준다. 그 안에 릴리즈를 담당하는 yaml 파일과 docker 작업을 위한 yaml 파일을 작성해주었다.
먼저 docker 작업을 위한 yaml 파일이다.
name: "[Push] Build dev"
on:
push:
branches:
- main
paths-ignore:
- '.github/**'
- 'src/VERSION'
workflow_dispatch:
jobs:
versioning:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.versioning.outputs.VERSION }}
steps:
- uses: actions/checkout@v2
- name: get current date
run: |
sudo ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
echo "TIME=$(date +'%Y%m%d.%H%M%S')" >> $GITHUB_ENV
- name: set version with current date
id: versioning
run: |
echo "VERSION=$(cat src/VERSION | cut -c 2-).${{ env.TIME }}" >> $GITHUB_OUTPUT
echo "::set-output name=VERSION::$(cat src/VERSION | cut -c 2-).${{ env.TIME }}"
docker:
if: github.repository_owner == 'kiku99'
needs: versioning
runs-on: ubuntu-latest
env:
VERSION: ${{ needs.versioning.outputs.version }}
steps:
- uses: actions/checkout@v2
- name: get service name
run: |
echo "SERVICE=$(echo ${{ github.repository }} | cut -d '/' -f2)" >> $GITHUB_ENV
- name: Upload docker
uses: docker/build-push-action@v1
with:
path: .
repository: kiku99/${{ env.SERVICE }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
tags: ${{ env.VERSION }}
yaml 파일을 보면 main branch에 변경이 일어날 때 아래 정의한 job 들이 실행되는 구조를 알 수 있다. job은 2가지로 나뉘는데 버전 작업을 담당하는 versioning과 도커 작업을 담당하는 docker로 나누었다.
versiong 과정에서는 프로젝트의 버전과 현재 날짜와 시간을 조합하여 최종 버전을 만들고 github 환경변수에 저장한다.
docker 과정에서는 현재 프로젝트로 도커 이미지를 만들고 버전과 함께 도커 허브에 푸시한다. 여기서 username과 password는 git hub 레포지토리의 설정에서 도커 허브의 계정 정보를 넣어주면 된다.
다음은 릴리즈 작업을 위한 yaml 파일이다.
name: "[Dispatch] Release"
on:
push:
branches:
- main
jobs:
setup-build-deploy:
name: Setup, Build, and Deploy
runs-on: ubuntu-latest
permissions:
packages: write
contents: write
id-token: write
steps:
- name: Bump version and push tag
id: tag_version
uses: mathieudutour/github-tag-action@v6.1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- name: Create a GitHub release
uses: ncipollo/release-action@v1
with:
tag: ${{ steps.tag_version.outputs.new_tag }}
name: Release ${{ steps.tag_version.outputs.new_tag }}
body: ${{ steps.tag_version.outputs.changelog }}
마찬가지로 main branch에서 변경이 일어날 때 job이 실행되도록 설정해주었다. 작업은 태그를 만드는 작업과 릴리즈를 담당한 작업으로 나누었는데, 두 작업 모두 maketplace에 있는 자동화 tool을 사용했다. 그리고 아직 태그와 릴리즈에 대해 익숙하지 않아서 더 세부적인 설정은 하지 않았다.
참고로 github_token은 자동으로 생성되는 토큰이었다. 여기서 좀 헤맴...
이렇게 yaml 파일을 잘 작성해주면 actions 탭에 이렇게 워크플로우가 생성되어있는 모습을 볼 수 있다.
요런식으로 각 워크플로우마다 해당 작업들의 그래프와 실행 여부를 볼 수 있다. docker 작업이 꽤 걸리는걸 볼 수있는데 실제로 이미지 빌드하는데 시간이 걸리긴 한다.
또 작업을 누르면 이런식으로 작업 내용과 로그를 볼 수 있다. 여러 모로 편리한 기능.
이렇게 pipleline을 구축함으로써 다른 브랜치에서 작업을 하다가 릴리즈를 하기 위해 main 브랜치에 병합을 하면, 자동으로 릴리즈와 도커 이미지를 빌드하고 푸시를 하게 된다. 이제부턴 개발에만 집중하면 될 거 같다.
'개발 > devOps' 카테고리의 다른 글
[Kubernetes] Loki stack을 활용한 로그 시스템 구축기 (0) | 2024.06.26 |
---|---|
[docker] 쉽고 빠른 서비스를 향해 (3) (0) | 2023.12.09 |
[docker] 쉽고 빠른 서비스를 향해 (2) (2) | 2023.11.21 |
[docker] 쉽고 빠른 서비스를 향해 (1) (1) | 2023.11.20 |