Skip to content
← 작업으로
Cloud Native · Automation

k8s-cluster-bootstrap

  • Provisioning
  • Bare-metal
  • Automation

Summary

온프레미스 Kubernetes 설치에서 반복하던 노드 설정과 구성요소 설치, 클러스터 연결을 자동화한 오픈소스 도구입니다. 공통 설치 절차와 환경별 옵션을 분리해, 각 노드에서 명령 한 번으로 마스터 초기화 또는 워커 조인까지 수행하도록 만들었습니다.

Role
Developer, Maintainer (설치 자동화 설계와 개발, 호환성 개선)
Stack
Bash, Kubernetes, kubeadm, containerd, Docker, Calico
Outcome
노드별 설치 자동화, 마스터와 워커 구성 통합, 오픈소스 공개
노드마다 부트스트랩 명령을 실행합니다. 사전 설정, 런타임과 Kubernetes 구성요소 설치 및 패키지 버전 고정은 공통입니다. Master는 kubeadm init과 선택적 Calico 배포를 수행하고, Worker는 SSH와 rsync로 Master의 join token을 가져와 kubeadm join으로 연결합니다. 역할 옵션을 지정하지 않으면 공통 구성요소만 설치합니다.
k8s-cluster-bootstrap 파이프라인

문제

노드가 늘어날수록 반복되던 설치와 설정

온프레미스 Kubernetes 클러스터를 구성할 때는 각 노드의 스왑과 커널, 네트워크를 설정한 뒤 컨테이너 런타임과 Kubernetes 구성요소를 설치해야 했습니다. 마스터를 초기화하고 CNI를 배포한 뒤에도 워커마다 조인 명령을 전달하는 일이 남았습니다.

노드가 늘어나면 같은 절차를 다시 수행해야 했고, 수작업으로 반복하는 동안 설정을 빠뜨리거나 노드마다 다르게 적용하는 문제가 생겼습니다. 설치할 때마다 순서와 조건을 사람이 기억하는 방식에서 벗어나, 같은 절차를 반복해서 실행할 수 있어야 했습니다.

설계 방향

설치 절차는 공통으로, 환경 차이는 옵션으로

모든 노드에 필요한 운영체제 설정과 런타임 설치를 Bash 스크립트의 공통 절차로 묶었습니다. Kubernetes 버전과 런타임, 마스터 주소, Pod 네트워크 대역처럼 환경에 따라 달라지는 값은 실행 옵션으로 분리했습니다. 환경이 바뀔 때마다 설치 명령을 직접 수정하지 않고, 필요한 값만 지정해 같은 흐름을 사용할 수 있도록 했습니다.

공통 설정 이후에는 노드 역할에 따라 경로를 나눴습니다. 마스터는 클러스터 초기화와 네트워크 구성까지, 워커는 기존 클러스터에 참여하는 단계까지 이어집니다. 각 노드에서 역할과 옵션을 지정해 명령 한 번을 실행하는 방식으로 구성했습니다.

자동화 구현

운영체제 설정부터 클러스터 연결까지 한 흐름으로

패키지 설치와 노드 연결을 따로 수행하지 않도록 사전 설정부터 마지막 구성 단계까지 연결했습니다. 아래는 Ubuntu 22.04에서 containerd와 Kubernetes 1.31.0을 선택해, 마스터 초기화와 Calico 배포까지 완료한 실제 실행 영상입니다.

k8s-cluster-bootstrap 실행 예시

먼저 스왑과 UFW를 비활성화하고, 컨테이너 실행과 네트워크 통신에 필요한 커널 모듈과 sysctl 설정을 적용했습니다. 재부팅 후에도 유지되도록 설정 파일에 저장하고, 선택한 런타임과 Kubernetes 구성요소를 설치하는 단계로 이어지게 했습니다.

마스터에서는 kubeadm으로 클러스터를 초기화하고 kubeconfig와 조인 명령을 생성했습니다. Calico는 클라우드와 온프레미스에서 사용할 수 있는 VXLAN을 기본으로 두고, 네트워크 환경에 따라 IPIP를 선택할 수 있게 했습니다. 워커에서는 SSH로 마스터의 조인 명령을 받아 실행하도록 해, 노드를 추가할 때마다 명령을 복사해 전달하던 과정도 자동화했습니다.

호환성 개선

지원 환경을 넓히며 드러난 버전과 의존성의 차이

설치 절차를 묶은 뒤에도 환경이 달라지면 같은 명령이 실패할 수 있었습니다. Kubernetes 버전만 보고 deb 패키지의 리비전을 정하던 방식이 그 예입니다. 저장소에 등록된 실제 버전이 예상과 달라 설치에 실패하는 경우가 있어, apt-cache madison으로 패키지 버전을 조회하고 kubelet과 kubeadm, kubectl을 같은 버전으로 설치하도록 바꿨습니다. 설치 후에는 패키지 업데이트로 Kubernetes 버전이 의도치 않게 바뀌지 않도록 고정했습니다.

Docker를 선택하면 Kubernetes와 연결할 cri-dockerd를 소스에서 빌드해야 했습니다. 필요한 Go 버전을 코드에 고정하면 외부 프로젝트가 바뀔 때마다 스크립트도 수정해야 했기 때문에, 해당 프로젝트의 go.mod에서 요구 버전을 읽어 툴체인을 준비하도록 했습니다. 설치에 필요한 값을 실제 패키지와 프로젝트 정보에서 가져오도록 보완한 부분입니다.

입력 조건도 먼저 확인하도록 했습니다. 노드 역할에 필요한 옵션과 주소, 런타임, 지원 버전을 검사하고, 지원 목록은 스크립트 옆의 VERSIONLIST를 우선 사용하되 없으면 GitHub에서 가져옵니다. 목록을 확인할 수 없으면 설치를 시작하지 않고, 패키지 조회 단계에서 요청한 버전을 찾지 못하면 오류 내용을 알리고 중단하도록 했습니다.

결과

반복 설치 자동화에서 계속 사용할 수 있는 도구로

노드 설정과 런타임 설치, 마스터 초기화 및 워커 조인을 하나의 도구로 묶어 Apache-2.0으로 공개했습니다. Ubuntu 18.04부터 26.04까지를 지원 대상으로 두고, Kubernetes 1.24.15부터 1.36.4까지 169개 버전을 지원 목록으로 관리합니다. 설치 과정의 문제와 환경별 차이를 보완하며 28차례 공개 릴리스를 이어왔습니다.

처음에는 반복되는 설치 절차를 줄이는 데서 출발했지만, 지원 환경이 늘어날수록 패키지 저장소와 빌드 도구의 변화도 함께 다뤄야 했습니다. 공통 절차와 환경별 값을 나누고, 외부 의존성에서 필요한 정보를 직접 조회하며, 진행할 수 없는 조건에서는 멈추도록 보완했습니다. 명령을 한 번 실행하는 편의에서, 환경이 달라져도 같은 설치 흐름을 다시 사용할 수 있는 방향으로 발전시킨 프로젝트입니다.