Github에 위치한 application 소스와 k8s manifests의 변경 사항이 발생될 때마다 자동으로 Github Action을 통해서 빌드/통합(CI, Continuous Integration)함ArgoCD를 통해 k8s 클러스터에 배포(CD, Continuous Deployment)하는 일종의 gitops 파이프라인을 만드는 실습 진행

front-app-repo: Frontend 소스가 위치한 레파지토리
k8s-manifest-repo: K8S 관련 메니페스트가 위치한 레파지토리
Application repository 생성

git remote 설정을 위해 amazon-eks-frontend 디렉토리의 git 초기화

git remote repo 설정

front-app-repo에 frontend 소스코드 push

github에서 아래와 같이 확인 가능

front app을 빌드하고, docker 이미지로 만든 다음 ECR에 push하는 과정은 github action을 통해 이루어짐
따라서 해당 과정에서 사용할 IAM User를 least privilege를 준수하여 생성해야 함
IAM user 생성

ECR policy 생성(ecr-policy.json)

ecr-policy.json 파일을 통해 IAM policy를 생성
erc-policy 사용함
ECR policy를 IAM user에 부여
aws iam attach-user-policy --user-name github-action --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/ecr-policy
github action에서 사용할 AWS credential, github token을 생성하고 설정해야 함
AWS Credential 생성
Access Key, Secret Key를 생성
github personal access token 생성

github secret 설정

github-action의 AccessKeyId와 SecretAccessKey의 값도 동일한 방식으로 Secret에 저장

.github 폴더 생성cd ~/environment/amazon-eks-frontend
mkdir -p ./.github/workflows
build.yaml 생성cd ~/environment/amazon-eks-frontend/.github/workflows
cat > build.yaml <<EOF
name: Build Front
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout source code
uses: actions/checkout@v2
- name: Check Node v
run: node -v
- name: Build front
run: |
npm install
npm run build
- 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: $AWS_REGION
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Get image tag(verion)
id: image
run: |
VERSION=\$(echo \${{ github.sha }} | cut -c1-8)
echo VERSION=\$VERSION
echo "::set-output name=version::\$VERSION"
- name: Build, tag, and push image to Amazon ECR
id: image-info
env:
ECR_REGISTRY: \${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: demo-frontend
IMAGE_TAG: \${{ steps.image.outputs.version }}
run: |
echo "::set-output name=ecr_repository::\$ECR_REPOSITORY"
echo "::set-output name=image_tag::\$IMAGE_TAG"
docker build -t \$ECR_REGISTRY/\$ECR_REPOSITORY:\$IMAGE_TAG .
docker push \$ECR_REGISTRY/\$ECR_REPOSITORY:\$IMAGE_TAG
EOF
$IMAGE_TAG : docker image tag코드를 front-app-repo로 push하여 github action workflow를 동작시킴
build.yaml을 기반으로 github action이 동작함

github action workflow 정상 동작 확인 가능

build 완료

front app의 이미지가 사용하는 ECR 레파지토리인 demo-frontend에서 새로운 $IMAGE_TAG를 갖는 이미지가 push 되었는지 확인

kubernetes manifest들은 별도의 독립된 github repository를 갖게되고, Kustomize를 통해 manifest들을 구성
디렉토리 생성

디렉토리 구조
base : kubernetes manifest 원본이 위치한 디렉토리kustomize.yaml 파일에 담긴 사용자 지정 설정 내용에 따라 변경됨overlays : 사용자 입맛에 맞는 설정 값이 위치한 디렉토리
kustomize.yaml 생성
kustomize을 통해 관리/변경할 kubernetes manifest 대상을 정의하는 목적의 파일cd ~/environment/k8s-manifest-repo/base
cat <<EOF> kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- frontend-deployment.yaml
- frontend-service.yaml
EOF
fronted-deployment.yaml을 위한 설정 값 정의cd ~/environment/k8s-manifest-repo/overlays/dev
cat <<EOF> front-deployment-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-frontend
namespace: default
labels:
env: dev
spec:
selector:
matchLabels:
app: frontend-fargate
template:
metadata:
labels:
app: frontend-fargate
EOF
frontend-service.yaml을 위한 설정값을 정의cd ~/environment/k8s-manifest-repo/overlays/dev
cat <<EOF> front-service-patch.yaml
apiVersion: v1
kind: Service
metadata:
name: demo-frontend
annotations:
alb.ingress.kubernetes.io/healthcheck-path: "/"
labels:
env: dev
spec:
selector:
app: frontend-fargate
EOF
frontend app 빌드에 따라 만들어진 새로운 Image Tag를 사용하기 위한 kustomization.yaml 생성name에 지정된 image는 newName의 image와 newTag의 값으로 사용하겠다는 의미cd ~/environment/k8s-manifest-repo/overlays/dev
cat <<EOF> kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
images:
- name: ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/demo-frontend
newName: ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/demo-frontend
newTag: abcdefg
resources:
- ../../base
patchesStrategicMerge:
- front-deployment-patch.yaml
- front-service-patch.yaml
EOF
kubernetes manifest를 위한 repo 생성

이전에 생성한 kubernetes manifest들을 새로 생성한 repo에 push



push 완료

ArgoCd를 EKS cluster에 설치

원래는 public하게 노출되지 않지만 실습의 목적상 ELB를 통해 접속 가능하도록 함

3~4분 뒤에 ELB 주소를 얻을 수 있음

a555a1ab32e0441e4bf651637db890ad-826459236.ap-northeast-2.elb.amazonaws.com
$ARGOCD_SERVER를 브라우저에서 오픈
admin$ARGO_PWD
Configure ArgoCD

배포대상이 되는 애플리케이션에 대한 기본 정보 입력


설정이 정상적으로 되면, eksworkshop-cd-pipeline이 생성됨

github action build 스크립트에 kustomize를 이용하여 컨테이너 image tag 정보를 업데이트한 후 k8s-manifest-repo에 commit/push하는 단계를 추가해야 함cd ~/environment/amazon-eks-frontend/.github/workflows
cat <<EOF>> build.yaml
- name: Setup Kustomize
uses: imranismail/setup-kustomize@v1
- name: Checkout kustomize repository
uses: actions/checkout@v2
with:
repository: $GITHUB_USERNAME/k8s-manifest-repo
ref: main
token: \${{ secrets.ACTION_TOKEN }}
path: k8s-manifest-repo
- name: Update Kubernetes resources
run: |
echo \${{ steps.login-ecr.outputs.registry }}
echo \${{ steps.image-info.outputs.ecr_repository }}
echo \${{ steps.image-info.outputs.image_tag }}
cd k8s-manifest-repo/overlays/dev/
kustomize edit set image \${{ steps.login-ecr.outputs.registry}}/\${{ steps.image-info.outputs.ecr_repository }}=\${{ steps.login-ecr.outputs.registry}}/\${{ steps.image-info.outputs.ecr_repository }}:\${{ steps.image-info.outputs.image_tag }}
cat kustomization.yaml
- name: Commit files
run: |
cd k8s-manifest-repo
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 main
EOF
front-app-repo에 코드 commit/push

github action 확인

job 정상 수행

k8s-manifest-repo의 commit 상태 확인
front-end-ap의 gitHub Action workflow에 의한 commit이 확인됨
ArgoCD 화면에서 배포 상태 확인git repository가 변경되면 자동으로 sync 작업이 수행되도록 Auto-Sync 활성화

k8s-manifest-repo의 commit 내용이 ArgoCD에 의해 eks 클러스터에 반영됨



k8s-manifest-repo의 commit history를 통해 새로운 Image Tag가 정상 반영되었는지 확인
frontend-deployment가 사용하는 Image Tag 값과 같은지 확인
amazon-eks-frontend/src/로 이동하여 App.js 파일 수정
EKS DEMO Blog version 1로 변경
변경한 코드를 commit/push



소스를 commit/push하면 github action(build) > ArgoCD(deploy) 작업이 순서대로 동작함

Sync 작업이 모두 완료된 후 아래 명령을 통해 샘플 애플리케이션 주소를 얻을 수 있음
echo http://$(kubectl get ingress/backend-ingress -o jsonpath='{.status.loadBalancer.ingress[*].hostname}')
