https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
Installing kubeadm
This page shows how to install the kubeadm toolbox. For information on how to create a cluster with kubeadm once you have performed this installation process, see the Creating a cluster with kubeadm page. This installation guide is for Kubernetes v1.31. If
kubernetes.io
Kubernetes 환경을 구축해보려 합니다. kind나 minikube와 같이 간편하게 kubernetes 클러스터를 구축하기 위한 도구들이 존재하지만, 제로부터 시작하는 과정이기 때문에 kubernetes에서 권장하는 방법인 kubeadm을 사용하여 설치하고자 합니다.
MAC 주소 및 product_uuid 고유성 확인
# 네트워크 인터페이스의 MAC 주소확인
ip link
# product_uuid 확인
sudo cat sudo cat /sys/class/dmi/id/product_uuid
구축하려는 각각의 환경에서 위 명령어를 통해 고유한 MAC주소와 product_uuid 값을 갖고 있는 지 비교해봅니다. 이는 구축된 클러스터 환경에서 각 노드의 고유 식별자로써 활용됩니다. 사실 이게 겹칠 일이 많지는 않겠지만 그래도 한번 확인해봅니다.
Enable IPv4 packet forwarding
$ sysctl net.ipv4.ip_forward
이 값이 1이어야 IP포워딩이 가능한 상태입니다. 하지만 현재 시스템은 IP포워딩 값이 0이므로 비활성화 상태입니다. IP포워딩이 꺼져있으면 수신된 패킷이 자신의 것이 아니면 Drop됩니다. 이에 따라 컨테이너 간 통신이 불가능하게 됩니다.
$ sysctl net.bridge.bridge-nf-call-iptables
브리지된 네트워크 트래픽이 iptables 규칙을 따르도록 설정되어 있는지 확인하는 명령
$ lsmod | grep br_netfilter
lsmod 명령은 리눅스 커널에 있는 모듈들의 정보를 보여주는 명령입니다. br_netfilter 모듈은 l네트워크 브릿지와 관련된 네트워크 패킷 필터링을 수행합니다. 네트워크 연결을 관리하고 iptables에서 사용되는 필터링 규칙을 적용합니다.
이에 따라 다음과 같은 명령을 차례대로 수행합니다.
# 1. br_netfilter 모듈 로드
sudo modprobe br_netfilter
# 2. 부팅 시 자동 로드되도록 설정
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
# 3. 네트워크 설정 적용
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
# 4. 설정 즉시 적용
sudo sysctl --system
# 5. 확인
sysctl net.ipv4.ip_forward
sysctl net.bridge.bridge-nf-call-iptables
lsmod | grep br_netfilter
컨테이너 런타임 설치
예전에는 컨테이너 런타임에 docker를 썼는데 kubernetes v1.24 부터 도커 지원을 중단해서 요즘은 containerD를 사용합니다. containerD는 Docker에서 개발하여 CNCF재단에 기증한 오픈소스입니다. docker OCI 표준 스펙에 맞춰 구현한 것이며 사실상 표준 컨테이너 런타임이라고 합니다. 이렇게 설치된 컨테이너 런타임은 kubernetes에서 Pod를 실행하기 위해 사용됩니다.
다음 명령을 통해 containerd를 설치해줍니다.
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
# Install containerd
sudo apt-get install containerd.io
cgroup 드라이버 설정
containerd의 cgroup 드라이버는 cgroupfs입니다. 그리고, 우리가 설치한 우분투의 init 시스템은 systemd입니다. 무슨 말인지 모르겠습니다. 따라서 이 부분에 대해 차근차근 알아보겠습니다.
우리는 Kubelet이 Kubernetes 환경에서 각 노드에서 Pod 및 컨테이너 리소스에 대한 관리를 하는 오브젝트라는 것을 알고 있습니다. 그럼 kubelet은 실제 어떻게 컨테이너의 리소스를 관리할까요?
리눅스 환경에서 Control Groups(cgroup)은 프로세스 그룹 간에 시스템 리소스를 격리하고, 프로세스에 할당된 CPU, 메모리, 디스크, 네트워크 같은 리소스 사용량을 제한하거나 관리하기 위한 기능입니다. kubelet과 컨테이너 런타임은 이 cgroup과 상호작용하면서 각 컨테이너의 리소스를 관리하고, 노드에서 실행되는 컨테이너들이 CPU, 메모리, I/O 등의 리소스를 적절히 분배받을 수 있도록 보장합니다. 그리고, kubelet과 컨테이너 런타임 모두 cgroup과 상호작용하기 위해 cgroup 드라이버를 사용해야 합니다.
여기서 주의해야 할 사항이 있습니다. kubelet과 컨테이너 런타임은 동일한 드라이버를 사용해야 한다는 점입니다. 사용가능한 cgroup 드라이버는 두 가지(cgroupfs, systemd)가 있는데 이 둘의 차이는 다른 포스팅에서 다뤄보도록 하겠습니다.
PID가 1인 프로세스는 init 프로세스에 해당합니다. 우리가 설치한 우분투의 init프로세스는 systemd를 사용한다는 것을 알 수 있습니다.
그리고, containerd는 기본적으로 cgroup 드라이버로 cgroupfs를 사용합니다. 여기서 문제가 발생합니다. systemd를 init 시스템으로 사용하고 cgroupfs 드라이버를 사용하면, 그 시스템은 두 개의 다른 cgroup 관리자를 갖게 됩니다. 두 개의 cgroup 관리자는 시스템 상 사용 가능한 자원과 사용 중인 자원들에 대하여 두 가지 관점을 가져 혼동을 초래하게 됩니다. 따라서 컨테이너 런타임의 cgroup 드라이버 또한 systemd로 설정해주어야 합니다. 공식문서를 따라서 containerd 설정파일을 수정해줍니다.
# 기본설정 파일 작성
containerd config default | sudo tee /etc/containerd/config.toml
# 수정
sudo vi /etc/containerd/config.toml
# 서비스 재시작
sudo systemctl restart containerd
# 서비스 상태 확인
sudo systemctl status containerd
Kubeadm, Kubelet, Kubectl 설치
- kubeadm: 클러스터를 부트스트랩하는 명령
- kubelet: 클러스터의 모든 머신에서 실행되는 파드와 컨테이너 시작과 같은 작업 수행
- kubectl: 클러스터와 통신하기 위한 커맨드 라인 유틸리티
쿠버네티스 환경에서 각 컴포넌트의 버전 호환성은 중요한 문제입니다. kubeadm은 kubelet, kubectl 을 설치하지 않습니다. 따라서 kubeadm이 설치하려는 쿠버네티스 컨트롤 플레인의 버전과 일치하는지 확인해야 합니다. kubelet과 컨트롤 플레인 사이에 하나의 마이너 버전 차이가 지원되지만, kubelet 버전은 API 서버 버전 보다 높을 수 없습니다. 예를 들어, 1.7.0 버전의 kubelet은 1.8.0 API 서버와 완전히 호환되어야 하지만, 그 반대의 경우는 아닙니다.
아래 명령들을 통해 kubelet kubeadm kubectl을 설치해줍니다.
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
sudo systemctl enable --now kubelet
이제 kubenetes 클러스터를 설정하기 위한 기본 준비 작업을 마쳤습니다.
Creating a cluster with kubeadm
이제 본격적으로 kubeadm을 통해 쿠버네티스를 구축해보겠습니다. kubeadm을 통해 적합성 테스트를 통과하는 클러스터를 빠르게 구축할 수 있습니다.
1. Control-plane node 초기화
컨트롤플레인은 클러스터의 핵심 구성 요소인 API Server(kubectl 통해 상호작용), etcd(클러스터 상태 저장)등의 서비스가 실행되는 서버입니다. 클러스터에서 없어서는 안 될 역할이며, 클러스터의 상태를 관리하고 API요청을 처리합니다. 만약 컨트롤플레인에 대한 고가용성(HA)을 고려하고 있다면 --control-plane-endpoint를 사용하여 모든 Control-Plane 노드에 대한 공통 엔드포인트를 설정해주어야 합니다. 만약 단일 Control-Plane 클러스터로 설정했다면 고가용성(HA) 클러스터로 업그레이드하는 것은 불가능합니다. 저는 고가용성 클러스터를 구축할 만큼의 리소스가 없고, 공부용이니 따로 지정하지 않겠습니다.
kubeadm은 호스트의 기본 게이트웨이와 연결된 네트워크 인터페이스에서 사용가능한 IP를 찾으려고 시도합니다. 리눅스 환경에서 해당 IP가 무엇인지 확인하려면 다음 명령을 통해 확인할 수 있습니다.
default via 로 시작하는 IP가 기본 게이트웨이 IP입니다.
이제 해당 정보를 갖고 아래 명령어를 통해 마스터 노드를 초기화하겠습니다.
sudo kubeadm init --pod-network-cidr=10.10.0.0/16 --apiserver-advertise-address=192.168.0.5
--pod-network-cidr=10.10.0.0/16
Pod 네트워크의 IP 범위를 지정하는 옵션입니다. Pod들은 10.10.0.0 ~ 10.10.255.255 사이의 IP 주소를 할당받을 수 있습니다. 일방적으로 Pod 네트워크는 CNI에 의해 관리됩니다. 따라서 Flannel, Clico와 같은 네트워크 플러그인을 설정할 때 해당 값이 필요합니다. 실제로 다른 값을 주어도 괜찮지만 서브넷마스크는 16이 적당하다고 합니다.
--apiserver-advertise-address=192.168.0.5
해당 옵션은 API 서버가 클러스터 내에서 노출되는 주소를 지정할 때 사용됩니다. 설정하지 않으면 기본 네트워크 인터페이스가 사용됩니다.
해당 명령을 수행하면 초기화가 완료되면 kubernetes 클러스터를 사용하기 위해 필요한 필요한 명령어들을 일반 사용자로 실행하기 위한 설정이 필요합니다.
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
그리고 마지막 줄에 워커 노드에서 클러스터에 추가하기 위해 발급된 join 명령과 토큰을 저장합니다.
# 예시
kubeadm join 192.168.0.5:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
2. Worker node Join
이제 위에서 발급된 join명령을 worker 노드에서 실행해야 합니다. 이에 따라 위에서 마스터 노드에 작업한 내용을 init을 제외하고 똑같이 작업해준 뒤에 join 명령을 수행합니다.
join한 후에는 마스터 노드에서 worker01 노드가 클러스터에 추가되었음을 확인할 수 있습니다. 그런데 상태가 모두 NotReady입니다. 또한 같은 명령을 worker01노드에서 수행하면 에러로그가 우후죽순 생깁니다. 왜 그럴까요?
이는 CNI가 설정되어 있지 않기 때문에 kubernetes 클러스터가 네트워크를 통해 노드들 간에 통신을 할 수 없기 때문입니다. 이에 따라 클러스터 단의 네트워크 설정을 위해 CNI 플러그인을 사용해야 합니다.
3. Installing a Pod network add-on
Kubernetes에서 Pod 간의 통신을 가능하게 하려면 반드시 CNI 기반의 Pod 네트워크 애드온을 설치해야 합니다. CNI는 Kubernetes가 Pod 간의 통신을 위해 사용하는 네트워크 플러그인입니다. 만약 해당 과정이 없다면, CoreDNS(Kubernetes의 DNS 서비스)가 시작되지 않으며, Kubernetes 클러스터의 여러 기능이 제대로 작동하지 않습니다.
CNI에는 여러 종류가 있지만, 저는 Calico라는 오픈소스를 사용하여 CNI를 구성하겠습니다. 이에 대해서는 아래 포스팅에서 다루겠습니다.
-> < 작성 중 공개 예정 >
https://docs.tigera.io/calico/latest/getting-started/kubernetes/quickstart
Quickstart for Calico on Kubernetes | Calico Documentation
Install Calico on a single-host Kubernetes cluster for testing or development in under 15 minutes.
docs.tigera.io
Calico 패키지 설치
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.29.1/manifests/tigera-operator.yaml
Calico 설치 및 구성
이제 설치해주어야 하는데 공식문서를 보면 manifest를 생성하기 전에 체크해주어야 할 게 있습니다. 우리가 위에서 Master 노드를 초기화할 때 설정해주었던 Pod Network Ip 옵션이 기억나시나요? 우리가 설정해주었던 pod network CIDR에 맞게 manifest파일을 수정해주어야 한다고 합니다. 그렇지 않으면 Pod network와 호스트 네트워크가 겹쳐서 네트워크 중복이 일어날 수 있습니다.
먼저 manifest파일을 다운받습니다.
wget https://raw.githubusercontent.com/projectcalico/calico/v3.29.1/manifests/custom-resources.yaml
그리고 아래 CIDR를 정해주었던 값으로 수정해줍니다.
수정이 끝나면 클러스터에 적용합니다.
kubectl create -f custom-resources.yaml
다시 확인해보면 Ready상태가 된 것을 확인할 수 있습니다.
4. 로컬 환경에 작업환경 구축
작업환경을 로컬에 구축하고자 합니다. (로컬에서 kubectl과 같은 명령을 하겠다는 뜻) 이에 따라 미니PC의 kubeconfig 를 로컬 환경에 옮겨주는 것으로 로컬에서 해당 클러스터를 관리할 수 있습니다!
레퍼런스
https://jsyeo.tistory.com/entry/kubeadm-%EC%9D%B4%EC%9A%A9%ED
%95%B4-K8s-cluster-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0#3.%20cgroup%20driver%20%EC%84%A4%EC%A0%95-1
'HomeLab' 카테고리의 다른 글
[HomeLab] - 워커노드 추가 (1) | 2024.12.16 |
---|---|
[HomeLab] - 클러스터 관리환경 세팅 (0) | 2024.12.10 |
[HomeLab] - VM 생성 (1) | 2024.11.16 |
[HomeLab] - 라우터 추가 (0) | 2024.11.12 |
[HomeLab] - Proxmox 설정 (1) | 2024.11.06 |