Helm 도입 이후 CI/CD 구조까지 정리한 방법
이전에 Kustomize에서 Helm으로 넘어간 이유랑, Helm chart 구조를 어떻게 잡았는지 정리했는데
막상 구조만 잡고 보니까 다음 고민이 바로 생겼다.
“그래서 이걸 어떻게 배포하지?”
처음에는 그냥 수동으로 배포했다. 이미지 빌드하고, 태그 붙이고, helm 명령어로 직접 올리는 방식이었다.
docker build -t example/api-server:1.0.0 .
docker push example/api-server:1.0.0
helm upgrade --install api ./helm/app -f values-api.yaml처음에는 이걸로 충분했다. 서비스도 많지 않았고, 배포도 자주 하는 편이 아니라서 크게 불편하다는 느낌은 없었다.
근데 조금만 지나니까 바로 불편해지기 시작했다. 이미지 태그 매번 수동으로 관리해야 하고 배포할 때마다 명령어 직접 쳐야 하고 서비스 늘어나니까 반복 작업이 계속 생겼다
특히 같은 작업을 계속 반복하는 게 제일 거슬렸다.
“이걸 왜 계속 수동으로 하고 있지?”
이 생각이 들면서 CI/CD를 붙이게 됐다.
구조는 최대한 단순하게 가져갔다.
흐름은 그냥 이거 하나였다.
코드 변경
Docker 이미지 빌드
이미지 push
Helm으로 배포
CI/CD에서는 이미지 태그를 자동으로 만들게 했다.
예를 들어 커밋 기준으로 태그를 찍는 방식이다. 이렇게 해두니까 태그 관리할 필요가 없어졌다.
IMAGE_TAG=${GITHUB_SHA}
docker build -t example/api-server:$IMAGE_TAG .
docker push example/api-server:$IMAGE_TAG그 다음은 Helm에서 이 태그를 쓰도록 맞춰줬다.
image:
repository: example/api-server
tag: "latest"이걸 CI/CD에서 override 해서 넘기는 방식으로 썼다.
helm upgrade --install api ./helm/app \
-f values-api.yaml \
--set image.tag=$IMAGE_TAG이렇게 바꾸고 나니까 배포 흐름이 완전히 정리됐다.
이전에는
이미지 만들고
태그 고민하고
명령어 치고
또 서비스별로 반복하고
이런 흐름이었다면 지금은
push 하면 자동 빌드
자동 배포
이걸로 끝났다.
근데 붙이면서 문제도 몇 개 있었다.
처음에는 환경변수가 제대로 안 먹는 경우가 있었다.
특히 프론트 쪽에서 NEXT_PUBLIC_API_URL 같은 값이 빌드 타임에 박히는 구조라 CI/CD에서 값을 제대로 안 넘기면 그대로 잘못된 값으로 배포됐다.
이건 결국 “런타임 환경변수냐, 빌드타임 환경변수냐” 이걸 제대로 구분해야 해결되는 문제였다.
그리고 이미지 태그 관련해서도 한 번 꼬였다.
latest만 계속 쓰다가 어떤 버전이 올라간 건지 헷갈리는 상황이 생겼다.
그래서 결국 "무조건 태그는 커밋 기준으로 분리/latest는 안 쓰는 방향"으로 정리했다.
배포 속도 문제도 있었다.
이미지 빌드가 생각보다 오래 걸렸는데, 이건 나중에 보니까 Docker 레이어 캐싱 문제였다. 이 부분은 Dockerfile 구조를 바꿔서 해결했다.
이렇게 하나씩 정리하고 나니까 전체 흐름이 깔끔해졌다.
지금 구조를 보면
Helm → 구조 관리
CI/CD → 배포 자동화
이렇게 역할이 나뉜다.
Helm은 “어떻게 배포할지”를 담당하고, CI/CD는 “언제, 어떻게 실행할지”를 담당하는 느낌이다.
댓글
댓글이 없습니다.
