📢 참고했던 사이트 CI/CD for EKS cluster with Github Action
Github Action은 github에서 공식적으로 제공하는 CI/CD 툴, 다시 말해 개발의 work flow를 자동화할 수 있게 도와주는 툴이다.
Workflow
자동화된 전체 프로세스. 하나 이상의 Job으로 구성되고, Event에 의해 예약되거나 트리거될 수 있는 자동화된 절차를 말한다.
Workflow 파일은 YAML으로 작성되고, Github Repository의 .github/workflows 폴더 아래에 저장된다. Github에게 YAML 파일로 정의한 자동화 동작을 전달하면, Github Actions는 해당 파일을 기반으로 그대로 실행시킨다.
Event
Workflow를 트리거(실행)하는 특정 활동이나 규칙. 예를 들어, 누군가가 커밋을 리포지토리에 푸시하거나 풀 요청이 생성 될 때 GitHub에서 활동이 시작될 수 있다.
Job
Job은 여러 Step으로 구성되고, 단일 가상 환경에서 실행된다. 다른 Job에 의존 관계를 가질 수도 있고, 독립적으로 병렬로 실행될 수도 있다.
Step
Job 안에서 순차적으로 실행되는 프로세스 단위. step에서 명령을 내리거나, action을 실행할 수 있다.
Action
job을 구성하기 위한 step들의 조합으로 구성된 독립적인 명령. workflow의 가장 작은 빌드 단위이다. workflow에서 action을 사용하기 위해서는 action이 step을 포함해야 한다. action을 구성하기 위해서 레포지토리와 상호작용하는 커스텀 코드를 만들 수도 있다. 사용자가 직접 커스터마이징하거나, 마켓플레이스에 있는 action을 가져다 사용할 수도 있다. (더 자세한 설명은 아래에!)
Runner
Gitbub Action Runner 어플리케이션이 설치된 머신으로, Workflow가 실행될 인스턴스
프론트엔드 레포지토리 2개와 백엔드 레포지토리 3개에 모두 github action을 적용시켜야 하나 여기서는 예시로 exqress-admin-service 레포지토리에 적용시킨 것을 보여주겠다. 나머지 레포지토리에는 저장소 이름만 수정하여 똑같이 설정해주면 된다. 개발용 코드가 들어있는 저장소와 이전에 k8s manifest 파일들이 저장되어 있는 저장소 2개를 준비해둔다.
app을 빌드 하고, docker 이미지로 만든 다음 이를 ECR에 push 하는 과정은 gitHub Action을 통해 이루어진다. eks cluster를 생성했을때 사용한 IAM User와는 별도로 github-action만을 위한 최소 권한를 가진 User를 새로 생성해준다.
aws iam create-user --user-name github-action
vi ecr-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPush",
"Effect": "Allow",
"Action": [
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload"
],
"Resource": "arn:aws:ecr:ap-northeast-2:<계정 ID>:repository/*"
},
{
"Sid": "GetAuthorizationToken",
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken"
],
"Resource": "*"
}
]
}
aws iam create-policy --policy-name ecr-policy --policy-document file://ecr-policy.json
iam에 정책 부여할 때 resource 부분에서 repository/* 로 수정하였는데 이유는 하나의 ecr에만 접근하는 권한이 아닌 생성한 모든 ecr 레포에 대한 접근 권한이 필요하기 때문이다. 하지만 특정 리포지토리로 범위를 지정하지 않고 이미지를 푸시하는 데 필요한 권한을 부여하는 방법도 있기에 밑 참조 사이트에 들어가서 확인해보면 될 것이다.
📢 이미지 푸시에 필요한 IAM 권한
생성한 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 iam create-access-key --user-name github-action
{
"AccessKey": {
"UserName": "github-action",
"Status": "Active",
"CreateDate": "2021-07-29T08:41:04Z",
"SecretAccessKey": "***",
"AccessKeyId": "***"
}
}
github.com 로그인 후 User profile > Settings > Developer settings > Personal access tokens 으로 이동한다. 그리고 우측 상단에 위치한 Generate new token을 선택한다.
Note에 access token for github action라 입력 하고 Select scopes 에서 repo 를 선택한다. 그리고 화면 아래에서 Generate token 을 클릭한다.
화면에 출력되는 token 값을 복사한다. 한번 끄면 다시 확인이 불가능하기 때문에 저장해두는 것이 좋다.
우리는 모든 레포지터리에 github action를 설정할 것임으로 각 레포지토리에 secret를 설정하는 것이 아닌 Organization account에 secret를 설정하여 모든 레포지토리에서 사용 가능하도록 할 것이다. 따라서 Organization account에서 Settings > Secrets and variables > Actions 를 선택한다. 그리고 이어 화면 우측 상단의 New Organization secret 을 클릭한다.
gitub project 레포지토리의 Actions 탭에 들어가면 새로운 workflow를 만들 수 있다. yml 파일로 만들어지며, 생성된 파일은 default로 .github/workflows/{name}.yml 위치하게 된다.
아니면 직접 git 저장소를 클론해온 위치에 폴더와 파일을 만든 후 push를 진행해도 무관하다.
다른 블로그에서는 & 문자를 탈출시키기 위해서 /를 붙이는 경우도 봤지만 내 경우에는 안붙여도 잘 돌아갔다.
하지만 밑에 "" 안에 들어있는 &에서는 /로 문자를 탈출시켜줘야 제대로 작동하였음으로 참고하는 것이 좋다.
vi .github/workflows/build.yml
on:
push:
branches: [main]
pull_request:
branches: [main]
name: AWS ECR push & deploy k8s
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
environment: production
steps:
# Github에 저장된 코드를 CI 서버로 내려받아 뒷 step에서 사용할 수 있도록 하는 과정
- name: Checkout
uses: actions/checkout@v2
# Github Secret과 local env 에 저장된 값 불러오기
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} # secret에 저장되어 있는 값 불러오기
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-2
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push the image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: back-admin
IMAGE_TAG: ${{ github.run_number }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
echo "Pushing image to ECR..."
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
# kustomize 명령을 가져온다.
- name: Setup Kustomize
uses: imranismail/setup-kustomize@v1
- name: Checkout kustomize repository
uses: actions/checkout@v2
with:
# kubernetes 설정정보 저장소
repository: DGU2023xcapstone-parcel/exqress-kubernetes # k8s yaml 파일이 있는 repo
ref: main # branch 이름
# 다른 저장소에 push 하려면 Personal Access Token이 필요.
token: ${{ secrets.ACTION_TOKEN }}
path: exqress-kubernetes # 최상위 경로로 repository와 동일하게 설정
# 새 이미지 버전으로 파일 수정
- name: Update Kubernetes resources
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: back-admin
IMAGE_TAG: ${{ github.run_number }}
run: |
cd exqress-kubernetes
sed -i "s|image:.*|image: $ECR_REGISTRY\/$ECR_REPOSITORY:$IMAGE_TAG|g" back-admin-deploy.yaml # 새로 생성된 이미지로 교체하는 명령
# 수정된 파일 commit & push
- name: Commit files
env:
ECR_REPOSITORY: back-admin
IMAGE_TAG: ${{ github.run_number }}
run: |
cd exqress-kubernetes
git config --global user.email "<github 계정>@github.com"
git config --global user.name "<github 계정>"
git commit -am "Update image $ECR_REPOSITORY tag $IMAGE_TAG"
git push -u origin main
💡 에러발생, 퍼블릭 ecr 주소사용 불가능
steps.login-ecr.outputs.registry
이유를 찾아보니 내가 현재 만들었던 ecr 저장소는 퍼블릭 저장소로 만들었는데 위와 같은 형식의 github action을 사용하여 ecr 저장소에 이미지를 저장하는 방식은 프라이빗 방식에서만 가능하였다. 그래서 프라이빗 ecr 저장소를 만들어서 실행했더니 제대로 수행되었다.
-> 퍼블릭 저장소에 넣는 방법도 나중에 찾아볼 예정이다.
도커 캐시 삭제 -> build가 오류남
docker system prune --volumes