Intro
오늘은 git action을 사용하여 전체 어플리케이션의 CI/CD자동화를 구축 해보도록 하겠습니다.
우선 CI/CD의 흐름도와 인프라/플랫폼/어플리케이션 구성을 살표 보겠습니다.
CI/CD 흐름도
아래 흐름도의 특징은 code repo와 k8s gitOps repo가 별도로 구성되어 있다는 점입니다. 또한 kustomize를 통해서 이미지 태그를 업데이트하며, ArgoCD를 통해 배포를 진행합니다.
인프라
- AWS EKS Cluster
- Code Repository : github
- Docker Registry : AWS ECR
플랫폼
CI/CD 파이프라인
- github action workflow
CD툴
- ArgoCD
- kustomize
어플리케이션
Frontend
- 사용언어 : node.js
- 빌드 : npm
Backend
- 사용언어 : Java spring boot (JDK 11)
- 빌드 : Maven
gitaction workflow
frontend-cicd.yaml
npm build는 소스코드안에 있는 dockerfile의 설정에 의해 진행됩니다.
name: frontend web - CI CD
on:
workflow_dispatch:
inputs:
logLevel:
description: 'Log level'
required: true
default: 'warning'
tags:
description: 'Test scenario tags'
env:
AWS_REGION: ap-northeast-2 # set this to your preferred AWS region, e.g. us-west-1
ECR_REPOSITORY: frontend-web # set this to your Amazon ECR repository name
jobs:
ecr-build-push-and-deploy:
name: ecr-build-push-and-deploy
runs-on: ubuntu-latest
environment: production
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Docker Build and ECR Push
id: docker_build
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
push: true
tags: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:${{ github.sha }}
- name: Get verion
id: image
run: |
VERSION=$(echo ${{ github.sha }} | cut -c1-8)
echo VERSION=$VERSION
echo "::set-output name=version::$VERSION"
# kustomize 명령을 가져온다.
- name: Setup Kustomize
uses: imranismail/setup-kustomize@v1
- name: Checkout kustomize repository
uses: actions/checkout@v2
with:
# kubernetes 설정정보 저장소
repository: kimdragon50/emp-gitops
ref: frontend-web
# 다른 저장소에 push 하려면 Personal Access Token이 필요.
token: ${{ secrets.ACTION_TOKEN }}
path: emp-gitops
# 새 이미지 버전으로 파일 수정
- name: Update Kubernetes resources
run: |
pwd
cd emp-gitops/overlays/prd/
echo \${{ steps.login-ecr.outputs.registry }}/\${{ env.ECR_REPOSITORY }}
echo \${{ steps.login-ecr.outputs.registry }}/\${{ env.ECR_REPOSITORY }}:\${{ github.sha }}
kustomize edit set image \${{ steps.login-ecr.outputs.registry }}/\${{ env.ECR_REPOSITORY }}=\${{ steps.login-ecr.outputs.registry }}/\${{ env.ECR_REPOSITORY }}:\${{ github.sha }}
cat kustomization.yaml
# 수정된 파일 commit & push
- name: Commit minifest files
run: |
cd emp-gitops
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 origin frontend-web
backend-cicd.yaml
name: backend emp - CI CD
on:
workflow_dispatch:
inputs:
logLevel:
description: 'Log level'
required: true
default: 'warning'
tags:
description: 'Test scenario tags'
env:
AWS_REGION: ap-northeast-2 # set this to your preferred AWS region, e.g. us-west-1
ECR_REPOSITORY: backend-emp # set this to your Amazon ECR repository name
KUBE_NAMESPACE: backend
jobs:
mvn-build:
name: mvn-build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'adopt'
cache: maven
- name: Build with Maven
run: mvn -B package --file pom.xml
ecr-build-push-and-deploy:
name: ecr-build-push-and-deploy
runs-on: ubuntu-latest
needs: mvn-build
environment: production
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Docker Build and ECR Push
id: docker_build
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
push: true
tags: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:${{ github.sha }}
- name: Get verion
id: image
run: |
VERSION=$(echo ${{ github.sha }} | cut -c1-8)
echo VERSION=$VERSION
echo "::set-output name=version::$VERSION"
# kustomize 명령을 가져온다.
- name: Setup Kustomize
uses: imranismail/setup-kustomize@v1
- name: Checkout kustomize repository
uses: actions/checkout@v2
with:
# kubernetes 설정정보 저장소
repository: kimdragon50/emp-gitops
ref: backend-emp
# 다른 저장소에 push 하려면 Personal Access Token이 필요.
token: ${{ secrets.ACTION_TOKEN }}
path: emp-gitops
# 새 이미지 버전으로 파일 수정
- name: Update Kubernetes resources
run: |
pwd
cd emp-gitops/overlays/prd/
echo \${{ steps.login-ecr.outputs.registry }}/\${{ env.ECR_REPOSITORY }}
echo \${{ steps.login-ecr.outputs.registry }}/\${{ env.ECR_REPOSITORY }}:\${{ github.sha }}
kustomize edit set image \${{ steps.login-ecr.outputs.registry }}/\${{ env.ECR_REPOSITORY }}=\${{ steps.login-ecr.outputs.registry }}/\${{ env.ECR_REPOSITORY }}:\${{ github.sha }}
cat kustomization.yaml
# 수정된 파일 commit & push
- name: Commit minifest files
run: |
cd emp-gitops
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 origin backend-emp
Source Code 주소
code repository
- frontend : https://github.com/kimdragon50/frontend.git
- backend : https://github.com/kimdragon50/backend.git
k8s gitops repository
kustomize
kustomize는 k8s deployment에 들어가는 image tag를 변경 해주는 툴입니다. 물론 deployemnt.yaml을 읽어와서 sed 와 같은 쉘 명령어로 텍스트를 변경해줄 수 있긴하지만 그렇게되면 변경에 대한 이력관리가 어렵습니다.
kustomize는 폴더규칙을 준수하고 간단히 yaml 설정을 한뒤 kustomize cli를 사용하여 tag변경을 할 수 있습니다. 이미지 태그에 대한 변경 이력관리가 되기때문에 k8s 리소스를 배포에 유용하게 사용되고 있습니다. 위에 backend-cicd.yaml에서 kustomize edit set image
부분이 kustomize를 통해서 이미지 태그 정보를 업데이트하는 부분 입니다.
kustomize 폴더 구조
.
├── overlays
│ └── prd
│ └── kustomization.yaml
└── resources
├── deployment.yaml
├── gateway.yaml
├── kustomization.yaml
├── namespace.sh
├── service.yaml
└── virtualservice.yaml
overlays/prd/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
images:
- name: /
newName: /
resources:
- ../../resources
resources/kustomization.yaml
resources:
- deployment.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
ArgoCD
ArgoCD설치를 한 뒤 Create App을 하여 아래와 같이 설정합니다.
github action을 통해서 CI/CD가 완료 되면 ArgoCD에서 sync를 맞춰주면 완성입니다.
참고로 Auto sync 설정을 통해 Sync가 맞지 않으면 자동으로 Sync해주는 설정도 할 수 있습니다만 휴먼에러가 발생할 수 있으므로 직접 확인하여 Sync 하는 것을 추천드립니다.
gitAction 사용후기
저는 과거에 MSA로 설계된 어플리케이션을 jenkins로 CI/CD를 구축 운영을 해본 경험이 있습니다. 경험을 바탕으로 gitAction 대비 jenkins의 단점은 jenkins 서버를 별도로 구성해야하며, jenkins와 Plugin설치가 꽤나 번거로웠습니다. 또한 ci/cd 에 필요한 여러가지 툴을 OS내부에 설치해야 했고 linux OS에서 사용자권한 관리까지 해야했습니다.
그런데 gitAction을 사용하면 이런 설정이 전혀 필요 없습니다. 이 모든게 갖추어져 있기 때문에 관리자는 yaml 설정만 잘 해주면 그만입니다. (정말 너~~어무 편한 것 같습니다.)
하지만 여전히 젠킨스의 장점은 있는 것 같습니다. MSA로 설계가되면 서비스모듈이 1,2개가 아닌 20-30개 이상으로 구성됩니다. 젠킨스는 빌드배포 Job에 대한 전체 대시보드를 제공해주기 때문에 한눈에 배포 진행 상태를 확인할 수 있습니다. 하지만 gitaction은 repository에 의존되기 때문에 배포할때 각각의 repository에 접근하여 배포를 해야하며 한 눈에 전체 배포에 대한 대시보드를 확인할 수가 없습니다.
또한, 젠킨스는 서버를 별도로 관리할 수 있기 때문에 빌드 배포시 발생하는 서버 성능을 스스로 컨트롤 할 수 있다는 장점이 있는 것 같습니다.
그럼에도 불구하고 저는 gitAction을 사용할 것 같습니다.
몇가지 단점에 비해 장점이 너무나 뚜렷하기 때문인데요, 가장 큰 장점은 간단함 때문입니다. gitaction을 사용하면 빠르고 쉽게 CI/CD를 구축할 수 있으며 관리 포인트가 단순해집니다. 간단하고 안정적으로 CI/CD를 구축하고 운영할 수 있다면 사용하지 않을 이유가 없어 보입니다.
'IT > DevOps' 카테고리의 다른 글
Atlantis 란? (Terraform Pull Request Automation) (0) | 2022.05.11 |
---|---|
[Git] 폴더 화살표 모양에 클릭 안되는 문제 해결 (0) | 2022.02.16 |
[CI/CD] Github Action과 친해지기 - Maven Build 하기 (0) | 2021.10.28 |
[CI/CD] Github Action과 친해지기 - AWS ECR push 하기 (2) | 2021.10.28 |
Calico 란? - EKS에서 Calico 사용하는 방법 (1) | 2021.10.20 |