본문 바로가기

Memo

GKE 기반 쿠버네티스와 GitHub Actions으로 배포 자동화

언제 한번 프로젝트를 하게 된다면 쿠버네티스로 배포 한번 해야겠다고 생각하고 있었는데, 이번에 Meet-Up-Spot 개인프로젝트 하면서 경험 삼아해 봤다. 목표 자체가 쿠버네티스 개념적인 공부라기 보단 서비스 배포 자동화를 클라우드 환경을 사용해서 하는 것이었기 때문에 필요한 것들만 최소한으로 적용시켜 보았다.

아예 처음부터 CI/CD를 적용해 본 적이 없어서 배포도 좀 걸릴 거라 생각하긴 했는데, 생각보다 오래 걸렸다.

하면서 좀,  트러블 슈팅이라 할거 까진 없지만, 시간이 걸렸던 것들 위주로 정리해보려고 한다. 

 

계획했던 구조는 다음과 같다.  

최종 생각한 구조

사실 쿠버네티스 매니패스트 파일 작성하는 부분도 처음 하는 작업이여서 오래 걸리긴 했지만 워낙 찾아보면 자료들이 많아서 내가 계획했던 정도는 쉽게 작성한 거 같다.  밑에 블로그에서 도움을 많이 받았다. 구체적인 매니페스트 파일 작성에 대한 글은 아니지만.  쿠버네티스 기본 개념에 대한 부분을 보기 쉽게 정리해 주셔서 공부하기 편했다. 

도움받은 블로그: https://bcho.tistory.com/1256

 

쿠버네티스 #2 - 개념 이해 (1/2)

쿠버네티스 #2 개념 이해 (1/2) 조대협 (http://bcho.tistory.com) 쿠버네티스를 공부하면서 가장 헷갈리는 부분이 용어와 컨셉이다. 이 컨셉만 잘 이해하면 쿠버네티스를 쉽게 이해하고 사용할 수 있지

bcho.tistory.com

고민했던 부분 

대부분은 GKE 공식문서에서 친절하게 설명 되어 있어서 설정하기 편했던 거 같다.

DB를 Pod으로 띄울거냐, 다른 DBaaS를 쓸 거냐

참고한 문서 : https://cloud.google.com/sql/docs/postgres/connect-instance-kubernetes?hl=ko#python 

매니페스트 파일을 어느 정도 작성 후에 위와 같은 고민을 하게 되었다. 처음에는 DB 서버를 다른 Pod으로 띄워서 PVC를 설정해주려고 했는데 하기 전에  실제로 서비스들은 어떻게 하는지를 먼지 고민하게 되었다. 왜냐면 그냥 경험 삼아한다면 PVC 설정하고 동적으로 PV 프로비저닝 하면 되긴 했다. 그래서 조금 찾아보니까 DBaaS를  사용하는 경우들이 많이 있었다. 직관적으로 생각해도 이게 더 편할 거 같긴했다. 일단 관리 측면도 그렇고 제공해주는 서비스들이 더 편할거 같았다. 물론 Pod 띄워서 관리하는 것도 GKE를 통해서 관리하기 때문에 편하긴 하지만 사용자가 어느 정도 컨트롤이 필요했다. 그래서 찾아보니까 쿠버네티스로 운영하는 좋은 예시가 있었다. 아래 영상인데 데브시스터즈에서 어떻게 쿠버네티스로 인프라를 관리하는지에 대해 설명하는 영상이었다.

https://www.youtube.com/watch?v=8R4DDEqjc0I

짧게 요약하면 게임 인프라 말고 퍼블리싱에도 쿠버네티스를 사용하는데 여기서 서버 팜 하나가 서비스 가능한 게임 하나를 말한다. 그리고 이게 각 단계별 환경(QA, Develop, Production)마다 서버팜이 필요하니까 이렇게 여러 개를 찍어 낼 수 있게 관리한다고 한다. 이 서버팜에서 전부다 컨테이너화 되어서 DB도 개별로 운영된다. 아무튼 이런 환경에서는 저렇게 하는 게 훨씬 효율적일 거 같다. 결국은 규모의 문제가있는 거 같다.

결국에는 클라우드 환경에서 작업하니까 Cloud SQL 도 경험 삼아해 볼 겸 따로 운영하기로 했다. 그리고 설정은 굉장히 간단했는데, Cloud SQL 같은 경우 내 서비스 Pod에서 Kubernetes 사이드카 패턴으로 실행되는 Cloud SQL 프록시를 통해 Cloud SQL 인스터스에 연결되었다. 그래서 그냥 Web Pod 에 같이 컨테이너로 띄울 수 있게 매니페스트 파일에서 설정하면 됐다.

Dockerfile 빌드 이미지 올리는 과정 중 했던 고민

막상 배포를 하려고 하니까 지금 까지는 로컬에서 도커 파일을 빌드하고 사용해서 빌드한 이미지를 올려야 했다. 여기서 약간 시간 잡아먹은 부분이 있는데, 원래는 GCR에 이미지를 빌드하려고 했다. 근데 최근에 들어가서 사용하려고 하니까 이게 서비스 지원이 끝나서 2024년 5월 이후부터는 아예 사용 못하고 Artifact Registry로 전환된다고 한다. 그리고 어차피 공식 문서도 이 서비스로 설명을 하는데, 여기서 이미지를 빌드하고 push 하는데 권한이 자꾸 없다고 나왔다. 그전 단계에서 service account 만들고 권한 부여까지 다했는데도 안돼서.  일단은 GCR에 빌드 이미지를 올렸다. (이 부분은 나중에 다시 봐야 함)

이걸 하는 과정에서 몇몇 문제들이 생겼는데 크게 2가지다

exec format-error

이건 찾아보니까 몇몇 사람들도 이런 문제들을 해결한 케이스가 있었다. arm 기반 이미지를 amd 기반 머신에 올려서 생긴 문제다. GKE 클러스터를 만들 때 아무 생각 없이 기본 E2 시리즈로 만들었는데 이게 amd 기반이었다. 아무튼 그래서 도커 이미지 빌드 할 때 멀티 플랫폼 빌드를 실행하면 된다.  밑에 처럼 해주면 된다. 기본적으로 docker buildx ls를 실행해서 제공하는 플랫폼들 종류를 확인 가능하다.

$ docker buildx build --platform=linux/amd64,

더욱 자세한 건 이분 블로그에 있다 https://velog.io/@baeyuna97/exec-user-process-caused-exec-format-error-%EC%97%90%EB%9F%AC%ED%95%B4%EA%B2%B0  

 

exec user process caused “exec format error” 에러해결

docker image build시 이런에러가 날 떄가 있습니다.원인 : 운영체제 차이해결방법 : 빌드시 태그 추가

velog.io

워크로드 아이덴티티

참고한 문서: https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity?hl=ko

이 부분은 공식문서 제대로 안 읽어서 생긴 문제긴 하다. 기존에 문서를 찾아보면서 설정하면 몇 가지 필요한 역할들을 설정해 주고 진행하면 된다. 근데 워크로드 아이덴티티를 클러스터 수준에서 설정해야 하는 거 까지는 했는데,  그 뒤에 이미 만들어진 클러스터는 따로 설정해줘야 한다고 한다. 그리고 그 안의 이미 생성된 노드 풀 들고 따로 다시 설정을 해줘야 하는데 이걸 빼먹어서 권한 설정했어도 계속 Pod이 꺼졌던 거 같다. 

마이그레이션은 언제 할 건지

사실 이 부분은 고민만 하고 그냥 넘어간 부분이긴 한데, 추후에 수정해야 할 부분이어서 작성했다. 현재는 워낙 적용할 마이그레이션이 적어서 도커 빌드 하고 엔트리 포인트에서 바로 처리하는데, 나중에 Actions 파일 배포 하는 단계에서 마이그레이션 단계를 따로 추가해서 해줘야겠다. (Jobs 추가)

일단 현재 엔트리 포인트에서 하면 생기는 문제는 실패 처리, 모니터링등이 쿠버네티스의 다른 부분과 통합하기 어려운 부분이 있다. 그니까 디버깅도 어렵다.  실 서비스에서는 이렇게 하면 안 될 거 같다.

Actions 배포 Workflow 작성

배포 yaml 파일은 로컬에서 act라는 프로그램으로 테스트를 할 수 있었다. 근데 뒤에 kubectl 부분은 환경이 달라서 그런지 자꾸 인식을 못해서 이건 직접 배포해서 되는 걸 확인했다. 이게 환경 문제라고 생각한 건 로컬에서 차례로 명령어 실행하면 잘 됐던 부분이어서 그랬다.

근데 특이하게 로컬에서 빌드한 이미지 gcr에 배포할 때 권한 문제가 없었는데, act에서 테스트할 때는 계속 권한이 없다고 나왔다. gcloud auth configure-docker 실행하고 배포하는 부분이었다. 그래서 찾아보니 원래 사용하는 service accout 에 버킷 관련 권한이 있어야 된다고 해서 추가했다. 근데 여기서 시간 쓴 부분이 권한을 수정하고 테스트 할때 딜레이 시간을 좀 가졌어야 했다. 그렇지 않고 급하게 하니까 계속 권한 줬는데도 안된다고 나왔다. 의문인 건 왜 로컬에서는 같은 service account에 같은 권한이었는데 빌드 이미지가 올라갔는지 모르겠다. 

그리고 처음에 빌드를 다른 action으로 빼려고 했었는데 그 이유는 배포 자체 action이 너무 느려질 거 같아서 그랬다. 그래도 배포할 때 한 이유는 프로덕션 배포 이미지 버전을 구별하기 편해서 그랬다. 따로 해주면 좀 번거로운 과정을 거쳐야 하는데, 같이 해주게 되면 github.sha를 사용해서 프로덕션 이미지를 구분하기 쉬워서 이렇게 했다.

 

최소한의 설정으로 GKE와 Github Actions 를 사용해서 배포하려고 했기 때문에 아직 수정해야 할 부분들이 많이 있다. 추후에 좀 더 공부해서 수정해야겠다.

'Memo' 카테고리의 다른 글

웹은 고전적인 검은 백조였다.  (0) 2024.02.18
선착순 처리 기능 구현에 대한 고민  (0) 2023.11.23
외부 API 결과에 캐싱 도입  (0) 2023.10.14
서비스 계층과 도메인 서비스  (0) 2023.10.04
저장소 패턴  (0) 2023.09.29