리눅스 20.04 이상 기준에서 kubeadm
을 설치하는 방법입니다.
2대의 노트북을 활용하여 마스터 노드
와 워커 노드
를 구성하였습니다.
인프라 구성입니다.
최소 요구사항
# 패키지를 최신 버전으로 갱신하고 리부팅한다.
$ sudo apt update && sudo apt -y full-upgrade
[ -f /var/run/reboot-required ] && sudo reboot -f
$ sudo apt -y install curl apt-transport-https net-tools
$ curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg|sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes.gpg
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
# 레포 버전 갱신
sudo apt update
# 필요한 리스트 설치
sudo apt -y install vim git curl wget kubeadm=1.27.6-00 kubelet=1.27.6-00 kubectl=1.27.3-00 --allow-downgrades
sudo apt-get update
# 버전 고정 (각각의 버전이 달라지면 안된다.)
sudo apt-mark hold kubelet kubeadm kubectl
버전을 고정하는 이유 :
kubeadm은 kubelet 또는 kubectl 을 설치하거나 관리하지 않으므로, kubeadm이 설치하려는 쿠버네티스 컨트롤 플레인의 버전과 일치하는지 확인해야 한다. 그렇지 않으면, 예상치 못한 버그 동작으로 이어질 수 있는 버전 차이(skew)가 발생할 위험이 있다. 그러나, kubelet과 컨트롤 플레인 사이에 하나의 마이너 버전 차이가 지원되지만, kubelet 버전은 API 서버 버전 보다 높을 수 없다. 예를 들어, 1.7.0 버전의 kubelet은 1.8.0 API 서버와 완전히 호환되어야 하지만, 그 반대의 경우는 아니다.
$ kubectl version --client && kubeadm version
...
Client Version: version.Info{Major:"1", Minor:"27", GitVersion:"v1.27.3"
...
kubeadm version: &version.Info{Major:"1", Minor:"27", GitVersion:"v1.27.6"
...
# 부팅 시에 overlay와 br_netfilter라는 두 가지 모듈을 로드하도록 설정합니다.
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
# overlay 커널 모듈을 즉시 로드합니다. 컨테이너 오버레이 파일 시스템에 사용됩니다.
sudo modprobe overlay
# br_netfilter 커널 모듈을 즉시 로드합니다. Linux 브리지 네트워크와 관련된 네트워크 필터링에 사용됩니다.
sudo modprobe br_netfilter
# 여기서는 몇 가지 중요한 파라미터를 설정합니다. 예를 들어, net.bridge.bridge-nf-call-iptables는 iptables가 브리지 트래픽을 처리할 수 있도록 하는 설정입니다.
# sysctl params required by setup, params persist across reboots
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
# 설정했던 값을 적용합니다.
sudo sysctl --system
정상적으로 설정되었는 지 확인
$ lsmod | grep br_netfilter
# Module Size Used by
br_netfilter 28672 0
$ lsmod | grep overlay
# Module Size Used by
overlay 151552 54
# 다음의 세가지가 모두 1 로 되어 있는 지 확인
## net.bridge.bridge-nf-call-iptables
## net.bridge.bridge-nf-call-ip6tables
## net.ipv4.ip_forward
$ sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
쿠버네티스는 3가지의 도커 컨테이너 인터페이스(CRI)를 지원한다.
이 중 원하는 컨테이너 런타임을 설치하면 되는데 나는 Containerd
을 설치했다. Docker 는 기본적으로 deprecated
판정을 받았기 때문이다. (그래도 내부적으로 docker 가 Containerd
를 사용하고 있어 Docker
로 가도 된다고 한다.)
$ sudo apt-get update
$ sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
$ 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
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
$ sudo usermod -aG docker $USER
$ sudo reboot
$ docker ps
$ sudo mkdir /etc/docker
# 이미 존재한다고 뜸. 계속 진행
$ cat <<EOF | sudo tee /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
$ sudo systemctl enable docker
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
쿠버네티스를 사용 시 원래는 swap 을 off 해주어야 하나 베타버전(1.28v)으로 swap on 이 가능하도록 할 수 있다고 한다.
관련 정보 : https://kubernetes.io/blog/2023/08/24/swap-linux-beta/
# Configure persistent loading of modules
> sudo tee /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF
# Load at runtime
sudo modprobe overlay
sudo modprobe br_netfilter
# Ensure sysctl params are set
> sudo tee /etc/sysctl.d/kubernetes.conf<<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
# Reload configs
sudo sysctl --system
# Install required packages
sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates
# Add Docker repo
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/docker-archive-keyring.gpg
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# Install containerd
sudo apt update
sudo apt install -y containerd.io
# Configure containerd and start service
sudo mkdir -p /etc/containerd
sudo containerd config default|sudo tee /etc/containerd/config.toml
# /etc/containerd/config.toml에서 disabled_plugins 라인을 비활성화하여 CRI 인터페이스를 활성화합니다.
$ sudo vim /etc/containerd/config.toml
# /etc/containerd/config.toml
...
disabled_plugins = ["cri"]
=>
# disabled_plugins = ["cri"]
...
# systemd를 cgroup driver로 사용하기
> vim /etc/containerd/config.toml
SystemdCgroup = true
===
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
...
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
sudo systemctl restart containerd
sudo systemctl enable containerd
systemctl status containerd
$ lsmod | grep br_netfilter
br_netfilter 22256 0
bridge 151336 2 br_netfilter,ebtable_broute
$ sudo systemctl enable kubelet
# CRI 를 Containerd 로 설치했을 경우
$ sudo kubeadm config images pull --cri-socket unix:///run/containerd/containerd.sock
# CRI 를 Docker 로 설치했을 경우
$ sudo kubeadm config images pull --cri-socket unix:///run/cri-dockerd.sock
kubeadm config 파일 작성
아래에서 criSocket
부분은 자신의 CRI
에 맞게 변경해준다.
CRI Path to Unix domain socket Docker unix:///run/cri-dockerd.sock containerd unix:///run/containerd/containerd.sock
아래는 containerd
기준 kubeadm init Config이다.
$ cd /tmp
$ cat > kub-config.yaml <<EOF
---
apiVersion: "kubeadm.k8s.io/v1beta3"
kind: InitConfiguration
nodeRegistration:
criSocket: "unix:///var/run/containerd/containerd.sock"
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
failSwapOn: false
featureGates:
NodeSwap: true
memorySwap:
swapBehavior: LimitedSwap
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
networking:
podSubnet: "172.24.0.0/24" # --pod-network-cidr
EOF
위의 config 설명
- swap on 으로 둔다. * 원래는 kubernetes 에서 swap off 밖에 지원하지 않았으나 1.28 버전에서는 베타버전으로 지원한다. (관련 문서)
- cri 은 containerd 을 사용한다.
- podSubnet 을 "172.24.0.0/24" 로 두겠다.
Master Cluster
생성
직전에 만들었던 kub-config.yaml
를 사용해 Master Cluster
를 생성한다.
출력 결과는 따로 저장해놓자.
🔹Worker Node 설치
에서 활용한다. (토큰 정보를 가져옴)
$ sudo kubeadm init --config kub-config.yaml
출력 결과:
[init] Using Kubernetes version: v1.28.2
[preflight] Running pre-flight checks
[WARNING Swap]: swap is enabled; production deployments should disable swap unless testing the NodeSwap feature gate of the kubelet
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection
[preflight] You can also perform this action in beforehand using 'kubeadm config images pull
...
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.0.213:6443 --token o6wpkd.nmdk6z******* \
--discovery-token-ca-cert-hash sha256:**********
mkdir -p $HOME/.kube
sudo cp -f /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Calico
Calico는 컨테이너 오케스트레이션 시스템인 Kubernetes와 같은 컨테이너 오케스트레이션 플랫폼에서 네트워크 정책 및 네트워킹 솔루션을 제공하는 오픈 소스 프로젝트입니다. Calico는 컨테이너화된 애플리케이션의 네트워크 요구 사항을 관리하고, 가상 머신 (VM) 및 물리적 서버와 통합하여 대규모 컨테이너 인프라스트럭처에서 확장 가능하고 안전한 네트워킹을 제공합니다
최신 버전 정보 링크 : releases page
$ curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/tigera-operator.yaml
$ curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/custom-resources.yaml
> kubectl create -f tigera-operator.yaml
===
namespace/tigera-operator created
...
clusterrole.rbac.authorization.k8s.io/tigera-operator created
clusterrolebinding.rbac.authorization.k8s.io/tigera-operator created
deployment.apps/tigera-operator created
custom-resources.yaml
의 CIDR 을 수정한다.> sed -ie 's/192.168.0.0/172.24.0.0/g' custom-resources.yaml
custom-resources.yaml
을 통해 custom-resource 를 설치한다.$ kubectl create -f custom-resources.yaml
installation.operator.tigera.io/default created
apiserver.operator.tigera.io/default created
$ kubectl get pods --all-namespaces -w
...
calico-apiserver calico-apiserver-68fdcdb86-2x424 1/1 Running 0 20s
calico-system csi-node-driver-g4bzl 2/2 Running 0 97s
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
# STATUS 가 READY 로 되어야 한다.
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
com Ready control-plane 21m v1.28.2
worker node 가 될 컴퓨터에서 진행합니다.
Master Node 설치
에서 진행했던 🔸STEP 1 ~ 4
까지 진행한다.
Master Node 설치
에서 진행했던 🔸STEP 5
의 5. Master Cluster 생성
에서 얻은 결과물을 참고하여 설치한다.
# 워커 노드가 될 컴퓨터에서 실행합니다.
$ kubeadm join 192.168.0.213:6443 --token o6wpkd.nmdk6z******* \
--discovery-token-ca-cert-hash sha256:**********
만약 Master Cluster 생성 시 얻었던 토큰을 잃어버렸다면 다시 마스터 노드에서 다음과 같이 토큰을 얻는다.
# 마스터 노드에서 커맨드 입력 => 조인할 수 있는 토큰을 다시 얻음 kubeadm token create --print-join-command
Master Node 에 다음의 명령어를 작성합니다.
$ kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
com Ready control-plane 10h v1.28.2 192.168.0.213 <none> Ubuntu 20.04.6 LTS 5.15.0-79-generic containerd://1.6.21
sub Ready <none> 109m v1.28.2 192.168.0.182 <none> Ubuntu 22.04.3 LTS 6.2.0-32-generic containerd://1.6.22
sub
라는 NAME 의 worker node
가 설치된 것을 확인할 수 있습니다.
워커노드와 마스터노드 전부 진행합니다.
sudo kubeadm reset
sudo apt-get -y purge kubeadm kubectl kubelet kubernetes-cni kube*
sudo apt-get -y autoremove
sudo rm -rf ~/.kube
sudo rm /etc/cni/net.d
# clean up iptables rules or IPVS tables.
sudo apt install ipvsadm
sudo ipvsadm --clear
kubectl에 다중 config 를 설정하는 방법
config
로 끝나는 config 파일을 모두 읽는 방법cat >> ~/.bashrc <<EOF
export KUBECONFIG=$(find ~/.kube -type f -name '*config' | tr '\n' ':')
EOF
Pakage 버전 확인하는 방법
# apt list -a {패키지}
apt list -a kubeadm