Skip to content

Kubeadm

Kubeadm은 쿠버네티스 클러스터 생성을 위한 "빠른 경로"의 모범 사례로 kubeadm init 및 kubeadm join 을 제공하도록 만들어진 도구이다.

kubeadm은 실행 가능한 최소 클러스터를 시작하고 실행하는 데 필요한 작업을 수행한다. 설계 상, 시스템 프로비저닝이 아닌 부트스트랩(bootstrapping)만 다룬다. 마찬가지로, 쿠버네티스 대시보드, 모니터링 솔루션 및 클라우드별 애드온과 같은 다양한 있으면 좋은(nice-to-have) 애드온을 설치하는 것은 범위에 포함되지 않는다.

대신, 우리는 더 높은 수준의 맞춤형 도구가 kubeadm 위에 구축될 것으로 기대하며, 이상적으로는, 모든 배포의 기반으로 kubeadm을 사용하면 규격을 따르는 클러스터를 더 쉽게 생성할 수 있다.

kubeadm 설치하기

이 페이지에서는 kubeadm 툴박스 설치 방법을 보여준다. 이 설치 프로세스를 수행한 후 kubeadm으로 클러스터를 만드는 방법에 대한 자세한 내용은 #kubeadm으로 클러스터 생성하기 항목을 참고.

시작하기 전에

  • 호환되는 리눅스 호스트. 쿠버네티스 프로젝트는 데비안 및 레드햇 기반 리눅스 배포판과 패키지 매니저가 없는 배포판에 대한 일반적인 지침을 제공한다.
  • 머신당 2GB 이상의 RAM (이보다 적으면 앱을 위한 공간이 거의 남지 않는다).
  • 컨트롤 플레인 머신에는 2개 이상의 CPU.
  • 클러스터의 모든 머신 간 완전한 네트워크 연결 (공용 또는 사설 네트워크 무관).
  • 모든 노드에 대해 고유한 호스트네임, MAC 주소, 그리고 product_uuid. 자세한 내용은 #모든 노드에서 MAC 주소와 product_uuid가 고유한지 확인 항목을 참고.
  • 머신에 특정 포트들이 열려있어야 한다. 자세한 내용은 #필수 포트 확인 항목을 참고.

WARNING

kubeadm 설치는 동적 링킹을 사용하는 바이너리를 통해 수행되며 대상 시스템이 glibc를 제공한다고 가정한다. 이는 많은 리눅스 배포판(데비안, 우분투, 페도라, CentOS 등 포함)에서 합리적인 가정이지만 알파인 리눅스(Alpine Linux)와 같이 기본적으로 glibc를 포함하지 않는 커스텀 및 경량 배포판에서는 항상 그런 것은 아니다. 배포판이 glibc를 포함하거나 예상되는 심볼을 제공하는 호환성 레이어를 포함할 것으로 예상된다.

OS 버전 확인

kubeadm으로 생성된 쿠버네티스 클러스터는 커널 기능을 사용하는 소프트웨어에 의존한다. 이 소프트웨어에는 컨테이너 런타임, kubelet, 그리고 컨테이너 네트워크 인터페이스 플러그인이 포함되지만 이에 국한되지 않는다.

지원되지 않는 커널 버전으로 인한 예기치 않은 오류를 방지하기 위해, kubeadm은 SystemVerification 사전 검사를 실행한다. 이 검사는 커널 버전이 지원되지 않으면 실패한다.

kubeadm이 커널 버전을 지원하지 않더라도, 커널이 필요한 기능을 제공한다는 것을 알고 있다면 검사를 건너뛰도록 선택할 수 있다.

모든 노드에서 MAC 주소와 product_uuid가 고유한지 확인

  • ip link 또는 ifconfig -a 명령을 사용하여 네트워크 인터페이스의 MAC 주소를 확인할 수 있다
  • sudo cat /sys/class/dmi/id/product_uuid 명령을 사용하여 product_uuid를 확인할 수 있다

하드웨어 장치는 고유한 주소를 가질 가능성이 매우 높지만, 일부 가상 머신은 동일한 값을 가질 수 있다. 쿠버네티스는 이러한 값을 사용하여 클러스터의 노드를 고유하게 식별한다. 이러한 값이 각 노드에서 고유하지 않으면 설치 과정이 실패할 수 있다.

네트워크 어댑터 확인

네트워크 어댑터가 두 개 이상이고, 쿠버네티스 컴포넌트가 디폴트 라우트(default route)에서 도달할 수 없는 경우, 쿠버네티스 클러스터 주소가 적절한 어댑터를 통해 이동하도록 IP 경로를 추가하는 것이 좋다.

필수 포트 확인

쿠버네티스 컴포넌트가 서로 통신하려면 이러한 필수 포트가 열려 있어야 한다. netcat과 같은 도구를 사용하여 포트가 열려 있는지 확인할 수 있다.

예를 들어:

nc 127.0.0.1 6443 -zv -w 2

사용하는 파드 네트워크 플러그인도 특정 포트가 열려 있어야 할 수 있다. 각 파드 네트워크 플러그인마다 다르므로, 해당 플러그인이 필요로 하는 포트에 대해서는 플러그인 문서를 참고한다.

하단의 #iptables 규칙 항목 참조.

스왑 구성

노드에서 스왑 메모리가 감지되면 kubelet의 기본 동작은 시작에 실패하는 것이다. 이는 스왑이 비활성화되거나 kubelet에 의해 용인되어야 함을 의미한다.

  • 스왑을 용인하려면, kubelet 구성에 failSwapOn: false를 추가하거나 커맨드라인 인수로 설정한다. 참고: failSwapOn: false가 제공되더라도 워크로드는 기본적으로 스왑에 접근할 수 없다. 이는 kubelet 구성 파일에서 다시 swapBehavior를 설정하여 변경할 수 있다. 스왑을 사용하려면, 기본 NoSwap 설정이 아닌 다른 swapBehavior를 설정한다. 자세한 내용은 스왑 메모리 관리를 참고한다.
  • 스왑을 비활성화하려면, sudo swapoff -a를 사용하여 일시적으로 스와핑을 비활성화할 수 있다. 재부팅 후에도 이 변경사항을 유지하려면, 시스템 구성 방법에 따라 /etc/fstab, systemd.swap과 같은 구성 파일에서 스왑이 비활성화되어 있는지 확인한다.

컨테이너 런타임 설치

파드에서 컨테이너를 실행하기 위해, 쿠버네티스는 컨테이너 런타임을 사용한다.

기본적으로, 쿠버네티스는 컨테이너 런타임 인터페이스(CRI)를 사용하여 사용자가 선택한 컨테이너 런타임과 인터페이스한다.

런타임을 지정하지 않으면, kubeadm은 잘 알려진 엔드포인트를 스캐닝하여 설치된 컨테이너 런타임을 자동으로 감지하려고 한다.

컨테이너 런타임이 여러 개 감지되거나 하나도 감지되지 않은 경우, kubeadm은 에러를 반환하고 사용자가 어떤 것을 사용할지를 명시하도록 요청할 것이다.

자세한 정보는 컨테이너 런타임 을 참고한다.

아래 표는 지원 운영 체제에 대한 알려진 엔드포인트를 담고 있다.

Linux:

런타임

유닉스 도메인 소켓 경로

containerd

unix:///var/run/containerd/containerd.sock

CRI-O

unix:///var/run/crio/crio.sock

도커 엔진 (cri-dockerd 사용)

unix:///var/run/cri-dockerd.sock

Windows:

런타임

윈도우 네임드 파이프(named pipe) 경로

containerd

npipe:////./pipe/containerd-containerd

도커 엔진 (cri-dockerd 사용)

npipe:////./pipe/cri-dockerd

kubeadm, kubelet 및 kubectl 설치

모든 머신에 다음 패키지들을 설치한다.

  • kubeadm - 클러스터를 부트스트랩하는 명령이다.
  • kubelet - 클러스터의 모든 머신에서 실행되는 파드와 컨테이너 시작과 같은 작업을 수행하는 컴포넌트이다.
  • kubectl - 클러스터와 통신하기 위한 커맨드 라인 유틸리티이다.

kubeadm은 kubelet 또는 kubectl 을 설치하거나 관리하지 않으므로, kubeadm이 설치하려는 쿠버네티스 컨트롤 플레인의 버전과 일치하는지 확인해야 한다. 그렇지 않으면, 예상치 못한 버그 동작으로 이어질 수 있는 버전 차이(skew)가 발생할 위험이 있다. 그러나, kubelet과 컨트롤 플레인 사이에 하나의 마이너 버전 차이가 지원되지만, kubelet 버전은 API 서버 버전 보다 높을 수 없다. 예를 들어, 1.7.0 버전의 kubelet은 1.8.0 API 서버와 완전히 호환되어야 하지만, 그 반대의 경우는 아니다.

kubectl 설치에 대한 정보는 kubectl 설치 및 설정을 참고한다.

cgroup 드라이버 구성

컨테이너 런타임과 kubelet은 "cgroup 드라이버"라는 속성을 갖고 있으며, cgroup 드라이버는 리눅스 머신의 cgroup 관리 측면에 있어서 중요하다.

컨테이너 런타임과 kubelet의 cgroup 드라이버를 일치시켜야 하며, 그렇지 않으면 kubelet 프로세스에 오류가 발생한다.

더 자세한 사항은 cgroup 드라이버 설정하기를 참고.

Commands

  • kubeadm init - 마스터 노드 초기화
  • kubeadm join - 워커 노드를 초기화하고 클러스터에 연결
  • kubeadm token - 토큰 확인

커널 모듈 로드

재부팅 후 로드되도록:

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

그리고 각각 로드한다:

sudo modprobe overlay
sudo modprobe br_netfilter

잘 로드되었는지 확인:

lsmod | grep overlay
lsmod | grep br_netfilter

각각에 대한 자세한 내용은 다음 내용 참조:

iptables 규칙

# Kubernetes Control plane
-A INPUT -p tcp --dport 6443      -j ACCEPT -m comment --comment "Kubernetes API server"
-A INPUT -p tcp --dport 2379:2380 -j ACCEPT -m comment --comment "etcd server client API"
-A INPUT -p tcp --dport 10250     -j ACCEPT -m comment --comment "Kubelet API"
-A INPUT -p tcp --dport 10259     -j ACCEPT -m comment --comment "kube-scheduler"
-A INPUT -p tcp --dport 10257     -j ACCEPT -m comment --comment "kube-controller-manager"

# Kubernetes Worker node(s)
-A INPUT -p tcp --dport 10250       -j ACCEPT -m comment --comment "Kubelet API"
-A INPUT -p tcp --dport 10256       -j ACCEPT -m comment --comment "kube-proxy"
-A INPUT -p tcp --dport 30000:32767 -j ACCEPT -m comment --comment "NodePort Services"
-A INPUT -p udp --dport 30000:32767 -j ACCEPT -m comment --comment "NodePort Services"

# FORWARD 체인 설정 (컨테이너 간 통신)
-A FORWARD -j ACCEPT

브리지 트래픽 허용 (Kubernetes 필수)

sysctl 설정을 추가하자.

대략 /etc/sysctl.d/80-kubernetes.conf 파일로 설정하면 될듯? 실제로는 디렉토리 들어가서 확인한 후 편집하라.

net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1

각 항목에 대하여 설명은 별도 페이지 참조:

파일 추가 후 sudo sysctl --system 명령으로 바로 적용하자.

kubeadm으로 클러스터 생성하기

WSL 에서 설치하기

각 단계별 설명은 생략한다. 주요 내용만 요약하여 아래에 정리함.

C:\Users\<사용자명>\.wslconfig 위치에 WSL 설정 추가:

[wsl2]
swap=0

wsl --shutdown 으로 재시작.

Troubleshooting

=== kubelet : Depends: kubernetes-cni (>= 1.2.0) but it is not installable ===

The following packages have unmet dependencies:
 kubelet : Depends: kubernetes-cni (>= 1.2.0) but it is not installable
E: Unable to correct problems, you have held broken packages.
root@ubuntu-jammy:/home/vagrant#

See also

Favorite site