DevOps
여기어때 EKS Update는?
Jensen여기어때
2022년 11월 9일
원문에서 보기 ↗안녕하세요. 여기어때 인프라개발팀에서 Kubernetes를 담당하고 있는 젠슨 입니다.
여기어때에서는 2022년 1월, 당시 최신인 1.20 버전의 EKS를 상용환경에 적용 하였습니다. 개발팀의 어플리케이션이 하나 둘 배포 되고 안정적인 운영이 이루어지던 어느 날 갑작스럽게 심판의 날이 찾아왔습니다.

EKS는 최신 버전을 생성할 경우 해당 버전을 약 1년 간 사용할 수 있으며 이후에는 반드시 업데이트를 해야 합니다.
위의 링크는 EKS의 릴리즈 일정이며 아래와 같이 1.20 버전의 EKS는 2022년 11월 1일에 지원 종료 됩니다.

또한 우리가 최신버전으로 올릴 수 있는 EKS는 1.23이며 2023년 10월에 지원 종료 된다는 것을 알 수 있습니다. 한 가지 아쉬운 점은 1.24 버전이 11월 중AWS에 릴리즈 되기 때문에 해당 버전을 사용할 수 없다는 점입니다.
이렇게 EKS 버전업을 해야 할 경우 제일 먼저 확인해 봐야 할 사항은 Kubernetes 공식 사이트에서 Migration Guide를 확인하는 것입니다.
https://kubernetes.io/docs/reference/using-api/deprecation-guide
해당 사이트에 들어가 보면 Kubernetes 버전 별로 변경되는 사항들이 나와 있습니다. 여러가지 변경 사항들 중 여기어때에서 적용할 내용은 hpa 와 cronjob 이였으며, 정식 release 되어서 beta를 제거해야 한다는 것을 알 수 있었습니다. manifest에 크게 변경된 내용이 없어서 다행이지만 사용하는 방식이 완전히 변경되는 경우도 있으니 해당 사이트를 꼭 확인하시는 것을 추천 드립니다.
여기어때의 EKS 배포 환경은 아래와 같습니다.
Gitlab, GitlabRunner, ECR, Argocd를 사용하고 있습니다.

이제 EKS를 업데이트하는 전략을 세워야 하는 과정인데 EKS를 업데이트 하는 방법은 크게 2가지로 고민할 수 있었습니다.
EKS 1.20 → 1.21 → 1.22 → 1.23 순서대로 Cluster와 WorkerNode를 순차적으로 업데이트 한다.
EKS 1.23 버전의 신규 Cluster 와 WorkerNode를 생성하여 도메인을 1.20의 Ingress에서 1.23으로 변경한다.
첫 번째 방법을 사용하면 기존 사이더카를 그대로 사용 가능하며 별도의 도메인 작업이 불필요하지만 버전업을 할 때마다 문제가 없는지 확인해야 하며 총 3번의 작업을 해야 합니다. 또한 결정적으로 업데이트 도중 문제가 발생하면 롤백이 불가능하며 그대로 장애로 이어진다는 위험 부담을 안고 가야 했습니다.
두 번째 방법을 사용하면 한 번의 작업만으로 최신 버전으로 갈 수 있으며 장애가 발생할 경우 바로 기존 버전으로 롤백이 가능합니다. 하지만 기존 사이더카 설정을 새로 해야 하며 별도의 도메인 작업이 필요 합니다.
위에서 비교한 내용을 보시면 아시겠지만 저희는 두 번째 방법을 선택 했습니다.
최신 버전의 EKS를 구축 후 사이더카를 설치 후에 설정 내용들을 복구하고 도메인을 변경했습니다. EKS 내부에 설치되어 있는 Argocd, Prometheus, Alertmanager 등의 configmap 내용들은 이미 Gitlab에 올려서 운영 중 이었기 때문에 큰 문제가 없을 것으로 판단 되었습니다. Gitlab은 별도 인스턴스로 설치된 서버였기 때문에 EKS Update에 영향을 받지는 않았습니다.
이제 EKS Update 작업을 할 때 고민이 되었던 부분을 공유할 때가 된 것 같습니다.
여기어때는 Dev, Qa, Stage, Prod 환경을 사용하고 있으며 모든 환경이 하나의 Gitlab 서버에서 같은 Repo를 바라보고 있는 구조로 되어 있습니다. 그렇기 때문에 개발자들이 배포한 Application 의 Manifest Repo에 변경사항이 발생하면 모든 환경에 적용 된다는 이슈가 있었습니다. 이러한 이슈가 발생하는 이유는 환경별로 EKS를 업데이트할 때 한번에 모든 환경을 업데이트 하는 것이 아니라 순차적으로 변경이 이루어 지기 때문입니다. 예를 들어, DEV 환경을 1.23으로 올려서 운영하고 이상이 없으면 Stage에 적용하는 식입니다.
위에서 보여드렸던 내용 중 1.20과 1.23의 manifest 에는 차이점이 있습니다. 그 것은 hpa와 cronjob에 beta가 제거된다는 사항입니다. 그렇기 때문에 Dev 환경의 manifest를 1.23에 맞추어서 배포하면 기존 1.20 환경에 문제가 발생합니다.

위와 같은 상황을 해결할 방법은 크게 두 가지가 있습니다.
별도의 1.23용 Repo를 생성하여 개발한 App에서 바라보는 Repo 정보를 변경한다.
별도의 1.23용 Repo를 생성하여 신규 Repo에 기존 Repo를 복제하는 파이프라인을 생성한다.
대부분 예상하셨겠지만 이번에도 두 번째 방법을 선택하였습니다. 첫 번째 방법의 경우 개발 소스를 변경해야 하는 번거로운 작업이 필요했기 때문입니다. 두 번째 방법을 선택하여 Argocd에서 바라보는 Repo만 변경하는 것이 가장 효율적이라고 생각 했습니다.

또한 다음과 같은 신규 pipeline을 생성 했습니다. manifest Repo에 변경된 이미지 태그가 들어오면 manifest-temp Repo로 해당 이미지 태그를 복사하는 것입니다. 물론 manifest Repo는 현재 1.20 버전 양식이고 manifest-temp Repo는 1.23 버전 양식으로 설정되어 있어야 합니다.

default:
tags:
- docker
copy_project:
stage: deploy
image:
name: alpine/git
entrypoint: [ "" ]
variables:
GIT_HOST: $GIT_HOST
SSH_PATH: /root/.ssh
MANIFEST_TEMP_DIR: manifest_temp
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: always
script:
- mkdir -p $SSH_PATH
- cat $MANIFEST_GIT_SSH_PRIVATE_KEY > $SSH_PATH/id_rsa
- ssh-keyscan -H $GIT_HOST > $SSH_PATH/known_hosts
- chmod 600 $SSH_PATH/id_rsa $SSH_PATH/known_hosts
- git config --global user.name $GITLAB_USER_NAME
- git config --global user.email $GITLAB_USER_EMAIL
- git clone --single-branch --branch master "git@$GIT_HOST:$MANIFEST_PROJECT_TEMP_PATH.git" $MANIFEST_TEMP_DIR
- find . ! \( -path ./$MANIFEST_TEMP_DIR -prune \) -name "values.*.yaml"
- find . ! \( -path ./$MANIFEST_TEMP_DIR -prune \) -name "values.*.yaml" | cpio -pudm $MANIFEST_TEMP_DIR
- cd $MANIFEST_TEMP_DIR
- git init
- git add .
- git commit -m "$CI_COMMIT_MESSAGE"
- git push origin master
manifest에는 기존에 없던 .gitlab-ci.yml 파일을 생성해 주어야 합니다.
include:
- project: 'gitlab/ci-template'
file: 'templates/copy-manifest.gitlab-ci.yml'
variables:
MANIFEST_PROJECT_TEMP_PATH: {{해당App 경로}}/manifest-temp
이제 1.23 버전의 Argocd 설정만 해주면 거의 모든 과정은 완료됩니다.
Argocd 에는 User, Repo, Project, App 등의 설정이 있습니다. 여기어때에서 User는 Gitlab에 설정해서 사용 중 이었고 App은 yaml 파일을 이용하여 일괄배포가 가능했기에 큰 문제가 되지는 않았습니다. 문제는 개발팀마다 다른 Repo와 Project 설정 등을 해 주어야 한다는 점이었습니다. 이를 위해 Argocd 공식 사이트를 통하여 일괄적으로 기존 설정을 복구할 수 있는 방법을 참고하였습니다.
Repo 설정
기존 1.20 의 Argocd Server에 Argocd Cli 명령어를 통하여 Repo list를 읽을 수 있습니다.
[ec2-user@dev-eks-mgmt:~] argocd repo list
TYPE NAME REPO INSECURE OCI LFS CREDS STATUS MESSAGE PROJECT
git https://${gitlab url}/${project path}/manifest-temp.git false false false true Successful
git https://${gitlab url}/${project path}/argocd-configmap.git false false false true Successful
git https://${gitlab url}/${project path}/manifest.git false false false true Successful
git https://${gitlab url}/${project path}/manifest.git false false false true Successful
git https://${gitlab url}/${project path}/manifest-temp.git false false false true Successful
또한 다음과 같은 명령어를 통하여 위에서 나온 Repo들을 일괄등록할 수 있습니다. 신규 1.23 의 Argocd Server에 Argocd Cli 명령어를 통하여 작업합니다.
[ec2-user@dev-eks-mgmt:~] argocd repo add https://${gitlab url}/${project path}/manifest.git --username ${id} --password ${password} --insecure-skip-server-verification
Repository 'https://{{gitlab url}}/${project path}/manifest.git' added
Project 설정
1.20 EKS Management 서버에서 다음 명령어를 통하여 Project yaml을 만듭니다.
[ec2-user@dev-eks-mgmt:~]# vi project-maker.sh
sed -i '/creationTimestamp:/d' argocd-project.yaml
sed -i '/generation:/d' argocd-project.yaml
sed -i '/managedFields/,+1d' argocd-project.yaml
sed -i '/fieldsType:/d' argocd-project.yaml
sed -i '/fieldsV1:/d' argocd-project.yaml
sed -i '/f:spec:/d' argocd-project.yaml
sed -i '/.: {}/d' argocd-project.yaml
sed -i '/f:description:/d' argocd-project.yaml
sed -i '/f:destinations:/d' argocd-project.yaml
sed -i '/f:sourceRepos:/d' argocd-project.yaml
sed -i '/f:status:/d' argocd-project.yaml
sed -i '/manager:/d' argocd-project.yaml
sed -i '/operation:/d' argocd-project.yaml
sed -i '/time:/d' argocd-project.yaml
sed -i '/resourceVersion:/d' argocd-project.yaml
sed -i '/uid:/d' argocd-project.yaml
# 스크립트 실행
[ec2-user@dev-eks-mgmt:~]# sh project-maker.sh
다시 정리된 project 생성용 yaml이 생성되고 해당 yaml을 신규 1.23 버전의 eks management 서버에서 배포하면 기존 환경과 동일한 project 가 생성 됩니다.
[ec2-user@dev-eks-mgmt:~]# kubectl apply -f argocd-project.yaml
appproject.argoproj.io/dev-infra configured
appproject.argoproj.io/dev-infra-service created
appproject.argoproj.io/dev-partnerbenefit created
appproject.argoproj.io/dev-payment created
appproject.argoproj.io/dev-userbenefit created
모든 설정이 완료 되었고 개발자들의 application을 배포하면 큰 문제 없이 어플리케이션이 동작하는 것을 확인 할 수 있을 것입니다. 다음으로 개발자들의 어플리케이션이 배포되고 ingress가 생성되면 기존 1.20에서 바라보던 도메인을 1.23의 ingress로 전환해 주면 됩니다.
이외에도 Update와 관련한 내용들이 많이 있지만 해당 블로그에서는 Update 당시 가장 이슈가 되고 고민되는 부분들을 위주로 설명 드렸습니다. EKS를 업데이트 하는 방법에는 여러가지가 있고 여기어때에서 수행한 방법보다 쉽고 간단한 방법이 분명히 존재 합니다. 해당 문서는 EKS Update를 처음으로 경험하게 되실 분들이나 심판의 날이 다가오시는 분들에게 조금이라도 도움이 되어 드리고 싶어서 작성하게 되었습니다.
이 블로그를 보시는 분들은 누구보다 효율적인 EKS 업데이트를 하시길 바라겠습니다.
감사합니다.