Github을 사용해 코드 관리 및 저장을 한다면 github action을 이용해 코드를 업데이트 할때 마다 자동화된 workflow 를 사용할 수 있다. 레포지토리에 포함된 .github/workflows 디렉토리에 YAML 파일로 워크플로우를 정의한다. 워크플로우 파일은 이벤트가 발생할 때 실행되는 작업 단계를 정의하는 데 사용한다. 예를 들어 코드 push나 pull request 같은 이벤트 발생시 워크플로우에 정의해놓은 대로 특정 action(Build, Test, Deploy 등)이 실행된다.
workflow 설정 예시
yaml 파일 템플릿을 보면서 설명. aws 연결과 배포 과정이 포함되어 있음.
실행 조건, 환경 변수
on: 아래의 조건은 production 브랜치에 코드 수정이 일어났다면 실행된다는 실행 조건
env : github action 안에서 사용할 변수 설정, 하단 예시는 도커 이미지 빌드 후 AWS ECR에 푸시하기 위해 푸시할 ECR_REPOSITORY의 이름과 이미지 태그 생성을 어떻게 할지 정의한 것이다. 깃헙에 커밋을 할때 각 커밋이 어떤 커밋인지 구분짓기 위해 고유 식별자, 즉 커밋해시가 생성이 된다. github.sha 는 그 커밋해시 값으로 이미지 태그를 생성하겠다는 뜻이다. 그렇게 하면 워크플로우가 실행될때 마다 마지막 커밋해시 값으로 동적인 이미지 태그를 생성 할 수 있다.
name: Example
on:
push:
branches: [ production ]
env:
ECR_REPOSITORY: repository_name
IMAGE_TAG: ${{ github.sha }}
jobs 설정
이제 어떤 액션을 할지 jobs에 정의 해놓으면 해당 job을 순서대로 실행한다.
build
build라는 작업을 우분투 환경에서 실행 하라는 뜻.
jobs:
build:
name: BUILD
runs-on: ubuntu-latest
steps에 job의 하위 집합으로 step에서 정의한 작업을 순차적으로 진행한다.
Checkout을 통해 레퍼지토리에 있는 코드를 가져온다.
steps:
- run: echo ${{github.ref}}
- name: Checkout
uses: actions/checkout@v2
build의 step은
1. AWS 연결
2. AWS secret manager를 통해 환경 변수 가져오기
3. Docker build 후 이미지 ECR에 push
AWS 연결
AWS에 연결하기 위해 id와 시크릿 키가 필요하다. 노출되면 안되는 비밀 정보이므로 secrets을 이용해 보안관리 해야한다.
repository - settings - actions 에 가서 시크릿 환경변수들을 등록하고 아래와 같이 불러와서 사용하면 된다.
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ID }}
aws-secret-access-key: ${{ secrets.AWS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
AWS secret manager를 통해 환경 변수 가져오기
aws에 연결을 했다면 이제 시크릿 매니저에서 환경변수들을 가져와 .env 파일로 만들어 준다. 그러면 Dockerfile에서 .env 파일을 가져와서 활용 할 수 있게 된다.
아래는 env를 json 으로 가져와서 json을 조작할 수 있는 jq 명령어를 사용, key=value 형태의 .env 파일로 추출하는 코드
- name: Read secrets
uses: abhilash1in/aws-secrets-manager-action@v2.0.0
with:
secrets: |
시크릿 가져올곳
parse-json: True
- name: Create .env file
run: |
jq -r 'to_entries|map("\(.key)=\(.value|tostring)")|.[]' <<< "$SECRETS_CONTEXT" > .env
env:
SECRETS_CONTEXT: ${{ toJson(env) }}
Docker build 후 이미지 ECR에 push
ECR에 로그인하고 Docker buildx 라는 도커 빌드 도구를 세팅.
그 다음 docker/build-push-action@v2 액션을 사용하여 Docker 이미지를 빌드하고 태그를 지정한 후 Amazon ECR에 푸시
env : 로그인한 ECR 레지스트리 가져와서 ECR_REGISTRY 환경변수로 설정.
tags 에서 이전 단계와 맨 처음 지정했던 환경변수 활용해 태그를 생성한다.
- name: Login to ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Build, tag, and push image to ECR
uses: docker/build-push-action@v2
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
with:
context: .
push: true
tags: ${{env.ECR_REGISTRY}}/${{env.ECR_REPOSITORY }}:${{env.IMAGE_TAG }}
cache-to: type=gha,mode=max
Deploy
다음 job은 배포이다. build 작업 완료 후 진행된다. 동일하게 깃 레포에서 코드를 가져와야 한다.
deploy:
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout
uses: actions/checkout@v2
앞선 빌드 작업을 통해 수정된 코드가 새로운 이미지 태그로 생성되어 ECR에 올라간 상태이다. 이 새로운 이미지의 주소로 쿠버네티스 deployment를 수정해줘야 한다. 그 다음 kustomize를 통해 overlay를 적용 할 수 있다. (여기서는 argoCD를 사용해 자동으로 변경사항을 감지하고 deployment를 수정)
if 로 production 브랜치에 푸시됐을때 실행되도록 한 후 kustomization.yaml 에 새 이미지 태그로 업데이트 해준다.
- name: Setup Kustomize
uses: imranismail/setup-kustomize@v1
- name: Update Kubernetes resources - prod
if: github.ref == 'refs/heads/production'
id: ecr_build_push_prod
env:
ECR_REGISTRY: blahblah.amazonaws.com
run: |
cd ./k8s/overlays/prod/
echo $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
kustomize edit set image $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
cat kustomization.yaml
마지막으로 위의 kustomize 단계를 통해 수정된 파일을 현재 작업중인 브랜치에 commit, push 해서 최종적으로 새 이미지 태그가 반영될 수 있게 한다. 그럼 argoCD가 또 변경된 kustomization.yaml 을 인식해 kubectl apply를 적용, 새롭게 정의된 내용으로 Pod이 생성된다.
- name: Commit files
id: modified_yaml_commit
continue-on-error: true
run: |
cd ./k8s
git config --global user.email "github-actions@github.com"
git config --global user.name "github-actions"
git commit -am "Update image tag"
git push -u ${{ github.head_ref }}
이렇게 깃헙 액션을 통해 production 브랜치의 코드 변경이 일어났을때 이미지를 빌드, ECR에 push, 바뀐 이미지 태그로 yaml 파일 수정, pod 배포 까지 자동화 할 수 있다.(중간에 argoCD 역할도 있지만..)
'개발 환경 및 운영' 카테고리의 다른 글
환경변수 주입하는 두 가지 방법 (2) | 2024.12.08 |
---|---|
Amazon Aurora DB (0) | 2024.04.17 |
EC2 인스턴스 복제부터 로드밸런서 설정 및 Route53 DNS 설정까지 (0) | 2024.02.21 |