[쿠버네티스] Self-managed k8s CI/CD 환경 구축 후기 / SSAFY 자율 프로젝트
k8s 환경을 처음 접하고 공부하면서 구축했던 경험으로 작성했으며,
잘못된 정보를 포함하고 있을 수 있습니다.
피드백 감사히 수용하겠습니다.
쿠버네티스 클러스터 아키텍처
"2개의 EC2 인스턴스를 각각 마스터, 워커노드로 분산해서 사용"
"비교적 많은 리소스가 남는 마스터 노드에 데이터베이스를 도커로 배포"
"워커노드에는 Spring Cloud Gateway와 마이크로서비스들, 그리고 EFK 스택을 파드로 배포"
"마이크로서비스들과 게이트웨이는 파드의 개수를 항상 2개로 유지(replicas = 2)"
"비정상 종료 또는 변경 감지 시 쿠버네티스가 롤링업데이트를 수행하도록 설정"
*롤링 업데이트 : 파드 인스턴스를 점진적으로 새로운 것으로 업데이트하여 디플로이먼트 업데이트가 서비스 중단 없이 이루어질 수 있도록 해준다.
Jenkins Pipeline
"Github Push 이벤트를 감지해 젠킨스파일의 파이프라인을 수행"
"파이프라인은 크게 도커 빌드 및 도커허브 푸시, 쿠버네티스 배포 두 단계로 수행"
전체 아키텍처 구성
1. 안드로이드에서 도메인으로 요청이 들어오면
2. Nginx Proxy Manager로 리버스 프록시
3. MetalLB의 외부 IP를 통해 로드밸런싱이 발생하고, 쿠버네티스 Gateway 파드에 요청
4. Gateway는 요청 uri에 따라 그에 맞는 파드에 라우팅
5. AI 작업 요청은 Jupyter GPU 서버에서 3개의 Flask 서버를 분산시켜 수행
6. Alarm, User, Picture (마이크로서비스들)은 Fluentd를 통해 로그를 수집
7. Fluentd를 통해 수집한 로그들을 통합해 엘라스틱서치로 전송
8. 엘라스틱서치는 키바나에 전송해 취합한 로그들을 시각화
상세한 구축 과정(가이드)이 궁금하다면?
https://github.com/sungwookoo/k8s-CI-CD-guide
리뷰
2개의 EC2 인스턴스를 사용해야 하는 제한된 환경이여서, 마스터/워커 노드를 각각 1개 씩 구성하기로 결정했다.
그로 인해, 노드 간의 가용성을 고려하지 못한 부분이 아쉬웠다.
Jenkins Statefulset에 플러그인을 설치하는 과정이 매끄럽지 못했다. 이유는 정확히 파악하지 못했다.
계속되는 설치 실패에, 될 때 까지 계속 설치 시도를 하며 하나씩 차근차근 설치하며, 결국 해결했다.
Jenkinsfile을 통한 Pipeline을 구축하고, 이를 작동하게 하는데 까지 대부분의 시간을 소요했다.
상당히 가치있는 시간이였고, 모든 과정을 가이드라인 형식으로 Notion에 기록하는 중이다.
이러한 활동의 목표는 다음과 같다.
- 내가 다시 k8s 환경을 구축할 때 사용할 수 있는 가이드를 작성 하는 것
- k8s을 처음 접하는 사람도 가이드라인을 따라 구축할 수 있도록 하는 것
6주 간의 노력을 하나의 가이드로 작성하기에 시간이 오래걸리겠지만, 시간을 투자할 가치는 충분히 있다고 생각한다.
또한, 클라우드 환경이 아닌 환경에서 로드밸런서를 사용하기 위해 오픈소스인 MetalLB를 사용했다.
MetalLB를 적용하고, 할당 받은 External-IP로 리버스프록시해 접속 가능한 환경을 만드는데에도 많은 시간을 소요했다.
이번에 쿠버네티스를 처음 학습하며 프로젝트를 진행했다.
Docker, Jenkins, Jenkins Pipeline 등을 활용한 MSA 아키텍처 인프라를 구축해봤던 자신감에 쉽게 생각했었다.
하지만, 쿠버네티스의 벽은 생각보다 높았고 공부해야 할 내용이 훨씬 많았다.
가장 걱정된 것은, 학습에 소요되는 시간이 길어 팀원들의 개발 속도에 맞추지 못할 수 있다는 점이였다.
클러스터를 구축하고, Jenkins를 통해 쿠버네티스 CI/CD 환경을 구축하며 그 걱정은 더 커졌었다.
그래서, 잠을 대폭 줄이고 프로젝트에 모든 시간을 쏟아부어 우려하던 상황은 생기지 않아 다행이었다.