Kubernetes + ArgoCD 기반으로 전환

조승빈·2025년 5월 8일

CI / CD

목록 보기
7/8

들어가며

이전에 구축한 CI/CD 환경은 Jenkins script하나에 의존한 단순한 구조였다. GitHub 저장소의 코드를 Jenkins가 직접 빌드하고, Docker 컨테이너를 생성하는 방식이었다. 개인 프로젝트를 배포하기에는 문제가 없었지만 항상 쿠버네티스를 도입해야겠다는 생각을 가지고 있었고 새로운 홈서버를 구축하면서 Docker Hub, Kubernetes(k3s), ArgoCD 기반의 파이프라인으로 전환하게 되었다.


기본 구조의 문제점

  • 불안정한 배포
    • 실행 중 서비스에 바로 덮어쓰면 장애 발생 가능
  • 버전 관리 부족
    • 어떤 코드가 배포됐는지 추적 어려움, 롤백 불가능
  • 확장성 한계

개선 방향

  • 애플리케이션을 이미지로 패키징

    • 실행환경을 포함하는 Docker Image로 애플리케이션을 배포
    • 버전별로 이미지 태깅 가능 -> 배포 이력 추적 가능
  • 코드가 아닌 이미지로 배포

    • 서버에서 직접 실행하는 대신, 이미지를 배포하도록 구성하여 배포 안정성 증가
  • 쿠버네티스를 이용한 안정적인 배포

    • k3sArgoCD를 이용한 안정적인 배포

간단한 개념정리

쿠버네티스

  • 컨테이너 오케스트레이션 툴이다.

  • docker와 같은 컨테이너들을 클러스터 환경에서 자동으로 배포, 스케일링, 모니터링을 해주는 시스템이다.

  • kubernetes는 다음과 같은 구조로 이루어져 있다.

클러스터
├── 마스터 노드 (제어 노드)
│   ├── API Server
│   ├── Scheduler
│   ├── Controller Manager
│   └── etcd (클러스터 상태 저장)
│
├── 워커 노드들
│   ├── Kubelet (각 노드에서 Pod 관리)
│   ├── Kube Proxy (네트워크 처리)
│   └── Pod (애플리케이션 컨테이너들)

클러스터 (Cluster)

Kubernetes 전체 시스템을 하나로 묶은 단위이다.

  • 여러 노드가 모여서 클러스터를 이룬다.
  • 마스터 노드가 모든 것을 통제하고, 워커 노드는 실제로 애플리케이션을 실행시킨다.

    쉽게 말해서, 클러스터 == 회사, 마스터 노드 == 관리자, 워커 노드 == 직원


노드 (Node)

  • 클러스터 내에 포함된 서버 한 대를 말한다.
  • 워커 노드에서 Pod가 실행된다.

노드 확인 명령어

kubectl get nodes

현재 클러스터에 연결된 노드 목록 및 상태 확인

kubectl describe node <노드이름>

네임스페이스 (Namespace)

  • Kubernetes 리소스를 논리적으로 구분하는 단위이다.

클러스터에 존재하는 모든 네임스페이스 목록

kubectl get namespaces

해당 네임스페이스의 모든 리소스(Pod, Service, Deployment 등) 확인

kubectl get all -n <네임스페이스>

파드 (Pod)

Kubernetes에서 가장 작은 배포 단위이다.

  • 하나의 이상의 컨테이너에 들어있다. (보통은 하나만 사용)
  • 같은 Pod에 있는 컨테이너는 같은 ip, 저장소를 공유한다.

해당 네임스페이스에 있는 파드 목록 확인

kubectl get pods -n <네임스페이스>

특정 파드의 상세 상태, 이벤트, 컨테이너 상태 확인

kubectl describe pod <파드이름> -n <네임스페이스>

서비스 (Service)

클러스터 내에서 네트워크 연결을 담당하는 객체

  • Pod들은 죽고 다시 생성되기 때문에 IP가 계속 변경되는데, Service는 고정된 엔드포인트를 제공한다.

서비스 목록 및 ClusterIP / NodePort 등 확인

kubectl get svc -n <네임스페이스>

서비스의 구체적인 설정과 연결된 엔드포인트 확인

kubectl describe svc <서비스이름> -n <네임스페이스>

ArgoCD

Deployment ( deploy )

  • pod를 선언적으로 관리하는 객체

Endpoints ( ep )

  • service와 실제 pod의 ip를 연결해주는 내부 객체

EndpointSlice ( endpointslice )

  • Endpoints의 확장 버전

ReplicaSet ( rs )

  • 특정 수의 동일한 pod를 유지시키는 역할
  • deployment가 내부적으로 rs를 생성하여 pod를 관리

최종 구조 (CI / CD Flow)

  1. GitHub 스프링부트 =Repo에 코드를 업데이트한다.
  2. WebHook Trigger를 통해 Jenkins CI Pipeline을 실행한다.
  3. GitHub의 파일을 이용해 빌드하고 Docker Hub에 이미지를 푸시한다.
  4. 태그를 Jenkins CD Pipeline으로 전달한다.
  5. GitOps Repokustomization.yaml을 업데이트한다.
  6. Argo CDGitOps Repo의 변경을 통해 쿠버네티스에 배포한다.

마치며

지금의 구조도 아쉬운 부분이 많고 갈길이 멀다.
CI 과정도 다양한 도구를 추가해야 하고 모니터링 도구도 추가해야 한다.

profile
평범

0개의 댓글