
kubeadm
kubespray
💡CNI란?
- CNCF(Cloud Native Computing Foundation)의 프로젝트 중 하나인
CNI는 컨테이너 간의 네트워킹을 제어할 수 있는 플러그인을 만들기 위한 표준이다.- 다양한 형태의 컨테이너 런타임과 오케스트레이터 사이의 네트워크 계층을 구현하는 방식이 다양하게 분리되어 각자만의 방식으로 발전하게 되는 것을 방지하고 공통된 인터페이스를 제공하기 만들어졌다. 💡CNI vs Docker Network
- 표준화: CNI는 다양한 컨테이너 런타임 및 오케스트레이터 간의 표준 네트워킹 인터페이스를 제공하는 것을 목표로 하는 반면, Docker 네트워크는 주로 Docker 컨테이너 환경 내에서의 네트워킹을 관리하는 데 중점을 둠.
- 유연성 및 확장성: CNI는 플러그인 기반으로 다양한 네트워크 솔루션과의 통합이 용이하지만, Docker 네트워크는 Docker 환경 내에서 제공되는 네트워크 드라이버에 의존함.
- 사용 사례: CNI는 Kubernetes와 같은 복잡한 오케스트레이션 환경에서 주로 사용되며, Docker 네트워크는 독립적인 Docker 컨테이너 환경에서 주로 사용됨.
control plane(master node)
worker node

💡운영체제로는 Ubuntu 22.04를 사용했다. 각 노드에는 2 sockets, 4 cores(8 vCPU), 16GB RAM, 64GiB 디스크 용량을 할당했다.
MasterNode역할을 할 가상노드 1개와 WorkerNode역할을 할 가상노드 2개를 생성했다. 추후 확장가능성을 고려하여 초기화되어있는 Default노드도 하나 복제하였다. K8S & containerd 조합으로 클러스터를 구축할 것이기 때문에, 따로 Proxmox에서 제공하는 LXC는 사용하지 않을 것이다.
번외: 포트포워딩 및 ssh 구성
공유기 포트포워딩

~/.ssh/config 설정

먼저, 패키지 목록을 업데이트하고 시스템을 최신 상태로 유지해야 한다.
sudo apt update
sudo apt upgrade -y
Docker를 설치하기 전에 몇 가지 필수 패키지를 설치해야 한다.
sudo apt install apt-transport-https ca-certificates curl software-properties-common -y
Docker 패키지를 검증할 수 있도록 공식 GPG 키를 추가한다.
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
Docker 패키지를 설치할 수 있도록 Docker APT 저장소를 추가한다.
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
패키지 목록을 다시 업데이트한 후, Docker를 설치한다.
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io -y
Docker가 올바르게 설치되었는지 확인하고, Docker 서비스를 시작한다. 재부팅 시, 자동으로 시작되도록 한다.
sudo systemctl status docker
sudo systemctl enable docker
sudo systemctl start docker
임시 컨테이너 hello-world를 통해 도커가 잘 작동하는지 확인한다.
docker --version
docker run hello-world
모든 가상 노드에 설치가 되어야 한다. 설치한 후 복제하는 것을 추천한다.
시스템 업데이트 및 의존성 설치
sudo apt update && sudo apt upgrade -y
sudo apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
containerd 설치
sudo apt install -y containerd
containerd 설정
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
kubeadm을 안정적으로 설치하기 위해선 2GB이상의 메모리, 2개 이상의 CPU, SWAP 메모리 비활성화가 필요하다.
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
minseoky@masternode:~$ systemctl list-unit-files --type swap
UNIT FILE STATE VENDOR PRESET
swap.img.swap generated -
1 unit files listed.
minseoky@masternode:~$ systemctl mask swap.img.swap
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/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.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt update
어차피 앞단에서 방화벽이 막아줄테니 내부 방화벽을 끈다는 얘기가 있는데, 내부에서 위협이 발생하면 어떡하나 싶어서 일단 제대로 방화벽 설정을 하도록 하겠다.
먼저 방화벽 설정을 편하게 하도록 ufw를 설치한다.
sudo apt install ufw -y
ssh 연결을 허용하고, 기본옵션으로 모든 인바운드 차단, 모든 아웃바운드 허용한다.
sudo ufw allow ssh
sudo ufw default deny incoming
sudo ufw default allow outgoing
쿠버네티스 운용에 필요한 노드들을 켜준다.
마스터 노드
sudo ufw allow 6443/tcp # Kubernetes API 서버
sudo ufw allow 2379:2380/tcp # etcd 서버 클라이언트 API
sudo ufw allow 10250/tcp # Kubelet API
sudo ufw allow 10251/tcp # kube-scheduler
sudo ufw allow 10252/tcp # kube-controller-manager
# Weave Net 포트
sudo ufw allow 6783/tcp
sudo ufw allow 6783/udp
sudo ufw allow 6784/udp
# (선택사항) Kubernetes 대시보드가 8001 포트를 사용하는 경우
sudo ufw allow 8001/tcp
워커 노드
sudo ufw allow 10250/tcp # Kubelet API
sudo ufw allow 30000:32767/tcp # NodePort 서비스 범위
# Weave Net 포트
sudo ufw allow 6783/tcp
sudo ufw allow 6783/udp
sudo ufw allow 6784/udp
그리고 방화벽 설정을 재부팅 시 유지하도록 한다.
sudo ufw enable
sudo ufw status
Kubeadm: 클러스터 초기 설정 및 구축을 위한 부트스트랩 도구Kubelet: 데몬으로, 각 노드에서 실행되는 Kubenetes 에이전트, Kubelet은 마스터 노드의 지시에 따라 컨테이너를 실행하고 관리한다.Kubectl: 클러스터 관리를 위한 명령줄 도구, 클러스터의 상태를 조회하고 리소스를 관리할 수 있다.sudo apt install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
마스터 노드
kubelet kubeadm kubectl을 설치한다.
sudo modprobe overlay
sudo modprobe br_netfilter
sudo tee /etc/modules-load.d/k8s.conf <<EOF
overlay
br_netfilter
EOF
sudo tee /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
워커 노드
워커 노드에는 kubectl을 설치하지 않아도 된다.
sudo apt install -y kubelet kubeadm
sudo apt-mark hold kubelet kubeadm
마스터노드 초기화
sudo kubeadm init --pod-network-cidr=10.32.0.0/12 --cri-socket=/run/containerd/containerd.sock
로컬 kubeconfig 설정
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubeadm init 명령어를 실행하면,
추후 조인을 위해 kubeadm init에서 나온 토큰 값 및 인증서 기억하기
kubeadm join {your_ip}:6443 --token uayyf9.eakzqdiskzg73zl7 \
--discovery-token-ca-cert-hash sha256:07dc89ef2b3e2b043a3c058b089aca497a8a8e1c980b1c81cfda973f2abb0d87 --cri-socket=unix:///run/containerd/containerd.sock
쿠버네티스 클러스터 접근을 위한 설정파일 생성
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
CNI 플러그인 설치(Weavenet)
kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s-1.11.yaml
CNI 플로그인 설치가 완료되면 위와 같이 STATUS가 Ready로 변한다.
kubelet 재실행
sudo systemctl restart kubelet
클러스터에 워커노드 조인
kubeadm join {your_ip}:6443 --token {your_token} \
--discovery-token-ca-cert-hash sha256:{your_cert} --cri-socket=/run/containerd/containerd.sock
조인에 성공하면 위같은 메세지가 나온다.
그 후 마스터 노드에서 노드를 확인해보면...

k8s버전 1.20부터 Dockershim 지원이 중단됨에 따라 k8s의 CRI에 도커를 연결하는 것이 불가능해졌다. k8s가 도커 지원을 중단(deprecated)하면서 좀 더 경량화된 containerd가 주류가 되었다.
본 포스트에서는 docker를 설치했으나, docker의 기본 컨테이너 런타임으로 containerd가 포함되어있기 때문에 따로 containerd를 설치할 필요는 없다. 원한다면 본 포스팅에서 도커 설치 대신 containerd만 설치해도 된다.