Skip to Content
Infra & DevOpsK8s 1.13.1 온프레미스 클러스터 구축 가이드
☁️ Infra & DevOps2018년 12월 17일

K8s 1.13.1 온프레미스 클러스터 구축 가이드

#kubernetes#docker#infra-devops#centos#flannel#cluster-setup

1. 온프레미스 K8s 구축의 한계점

빌데이터 및 AI 플랫폼을 온프레미스(CentOS) 환경에 구축할 당시, 컨테이너 오케스트레이션의 표준인 Kubernetes(K8s) 클러스터를 처음부터 직접 셋업해야 했습니다. 가장 빈번하게 마주치는 장애물은 크게 세 가지였습니다.

  1. Docker Engine과 Kubernetes 버전 간의 호환성: 무턱대고 최신 버전을 섞어 설치하면 Kubelet 서비스가 올라오지 않습니다.
  2. OS 호스트 설정 누락: Swap 메모리, 방화벽, SELinux 컨트롤에 실패하면 프리플라이트(Preflight) 단계에서 끝없이 실패합니다.
  3. CNI(Container Network Interface) 꼬임 문제: Master Node를 초기화할 때 통신망 대역(pod-network-cidr)을 잘못 잡으면 파드 간 통신이 전면 마비됩니다.

본 문서는 이러한 시행착오를 수없이 겪으며 정리한 K8s 1.13.1 버전에 최적화된 가장 안정적인 클러스터 스크래치 빌드 가이드입니다.


2. 컨테이너 런타임과 CNI의 핵심 개념 이해

클러스터 구축 전 반드시 이해해야 하는 핵심 컴포넌트들의 관계입니다.

  • 컨테이너 런타임 (Docker): K8s는 내부적으로 컨테이너 런타임(CRI)을 구동합니다. Docker 데몬이 컨테이너의 cgroup(리소스 격리)을 관리하는 방식과 Kubelet의 방식(systemd)을 일치시켜주는 것이 가장 중요합니다.
  • OS 리소스 제어 (Swap): K8s는 오케스트레이션 시 노드의 리소스를 100% 통제해야 합니다. OS의 Swap 메모리가 켜져 있으면 컨테이너의 메모리 제한(QoS)이 우회되어 OOM(Out of Memory) 상황 통제가 불가능해집니다.
  • 가상 네트워크 (CNI): Master Node(kubeadm init)가 올라간 직후 CoreDNS가 구동되기 위해서는 파드 간 물리적 노드를 뛰어넘는 가상 네트워크 브릿지가 필요한데, 이 가이드에서는 온프레미스에 적합한 Flannel 플러그인을 사용합니다.

3. Step-by-Step 구축 가이드

단계 1: 호스트 OS 사전 준비 (모든 노드 공통)

가장 먼저 컨테이너 런타임과 네트워크 제어를 위해 모든 마스터(Master)와 워커(Worker) 노드에서 아래 setup_k8s_prereq.sh 스크립트를 실행합니다.

bash
#!/bin/bash # 1. SELinux 비활성화 (보안 정책 충돌 방지) sudo setenforce 0 sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config # 2. Swap 메모리 영구 비활성화 (Kubelet 구동 필수 조건) sudo swapoff -a sudo sed -i '/swap/d' /etc/fstab # 3. 브릿지 네트워크 트래픽 통과 설정 (CNI 플러그인용) cat <<EOF > /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF sudo sysctl --system # 4. 방화벽(firewalld) 비활성화 (포트 충돌 방지) sudo systemctl disable firewalld sudo systemctl stop firewalld # 5. K8s YUM 리포지토리 등록 (구글 클라우드) cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg exclude=kube* EOF # 6. K8s 컴포넌트(1.13.1) 강제 설치 sudo yum install -y kubelet-1.13.1 kubeadm-1.13.1 kubectl-1.13.1 --disableexcludes=kubernetes # 7. Kubelet 서비스 활성화 (시작은 아직 안 함, 이후 kubeadm이 제어) sudo systemctl enable kubelet && systemctl start kubelet

단계 2: 안정적인 Docker 18.06 런타임 설치 (모든 노드 공통)

K8s 1.13.1과 완벽히 호환 검증된 버전을 설치합니다. 이 역시 모든 노드에서 실행합니다.

bash
#!/bin/bash # 1. 필수 유틸리티 및 리포지토리 추가 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 2. 특정 호환 버전(18.06) 지정 설치 sudo yum install docker-ce-18.06.1.ce-3.el7 docker-ce-cli-18.06.1.ce-3.el7 containerd.io -y # 3. Docker 데몬 설정 디렉토리 생성 sudo mkdir /etc/docker # 4. cgroup 드라이버 시스템 일치화 및 사내 로컬 레지스트리(Insecure) 등록 cat <<EOF > /etc/docker/daemon.json { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2", "storage-opts": [ "overlay2.override_kernel_check=true" ], "insecure-registries": ["192.168.1.189:5000"] } EOF # 5. Docker 서비스 데몬 재시작 및 자동 실행 sudo mkdir -p /etc/systemd/system/docker.service.d sudo systemctl daemon-reload sudo systemctl restart docker sudo systemctl enable docker

주의: "native.cgroupdriver=systemd" 설정이 누락되어 Docker가 cgroupfs를 바라보게 되면 OOM 발생 시 노드가 죽어버리는 클러스터 파멸을 겪을 수 있습니다.


단계 3: 마스터 노드(Control Plane) 초기화 및 Flannel 적용

모든 사전 준비가 끝났으므로 마스터(Master) 역할을 할 1대의 노드에서만 다음 작업들을 수행합니다.

1. Kubeadm 클러스터 초기화 향후 적용할 Flannel CNI 플러그인을 위해 반드시 --pod-network-cidr10.244.0.0/16 기본값으로 강제 지정합니다.

bash
# apiserver-advertise-address에는 마스터 노드 본인의 내부 IP를 적습니다. kubeadm init --apiserver-advertise-address=192.168.1.134 --pod-network-cidr=10.244.0.0/16

명령어가 끝나면 하단에 출력되는 kubeadm join 192.168.1.134:6443 --token ... 값을 반드시 메모장에 복사해 둡니다. 워커 노드를 연결할 때 필요합니다.

2. Kubectl CLI 관리자 권한 복사 마스터 노드 터미널에서 클러스터 상태를 조회하기 위한 자격증명 설정을 가져옵니다.

bash
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config

3. Flannel CNI 네트워크 플러그인 설치 노드 간 통신망을 개통시켜 줍니다.

bash
# Flannel 기본 매니페스트 배포 kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

폐쇄망의 경우 인터넷 망에서 도커 이미지를 Tar로 빼와 로컬 레지스트리에 푸시한 뒤, 매니페스트의 이미지 주소를 로컬 저장소로 고쳐서 띄우면 됩니다.

마지막으로 마스터 노드 터미널에서 kubectl get nodes -o wide를 입력했을 때 노드의 상태가 Ready로 변경되면 코어 구축이 완벽하게 완료된 것입니다!


4. 클러스터 구축 요약 및 팁

swapoff -a를 터미널 커맨드로만 치고 /etc/fstab 영구 설정을 주석 처리하지 않으면 서버가 재부팅될 때 Kubelet이 모조리 데드 상태에 빠지는 참사를 자주 겪습니다. fstab 확인은 필수입니다.

또한 kubeadm init을 돌리다 인증서나 프리플라이트 충돌이 생기면 부분 수정을 하려 들지 마시고, 쿨하게 kubeadm reset을 쳐서 초기화한 다음 /etc/kubernetes 폴더와 Docker 컨테이너들을 싹 비우고 처음부터 다시 돌리는 길이 수명 단축을 막는 가장 빠른 지름길이었습니다.

망 분리가 잘 된 온프레미스 망에서는 과도한 OS 방화벽(firewalld) 정책보다는 과감하게 방화벽 데몬을 내리고, K8s 내부의 Network Policy를 활용해 파드 단위의 L4 트래픽 통제 아키텍처를 설계하는 것이 훨씬 깔끔한 엔지니어링 접근 방식입니다.

Last updated on