개요
이 글에서는 kubeadm으로 클러스터를 생성하고, 컨테이너 엔진/런타임은 docker/cri-dockerd를 사용할 것이다.
설치 환경은 아래와 같다.
- AWS EC2
- Ubuntu 20.04 LTS arm64
- RAM >= 2GiB , CPU >= 2 core
참고로 master(controlplane)까지만 세팅할 것이다.
master/worker 설정 및 패키지 설치
아래 과정은 master(controlplane), node 모두 설정해두어야 한다.
1. iptables가 bridge 된 트래픽을 보도록 설정
# br_netfilter 모듈 로드
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
# 커널 파라미터 수정
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
# sysctl 파라미터 적용
sysctl --system
Applying 문이 나오면 된다.
2. Container Runtime 설치
Pod에서 Container를 실행하기 위한 런타임을 설치한다. 이 글에서는 도커 엔진을 사용할 것이다.
💡 주의
쿠버네티스 1.24부터는 Docker Container Runtime이 쿠버네티스와 호환되지 않아 cri-dockerd 설치가 추가로 필요하다.
# HTTPS로 저장소를 사용하기 위한 패키지 설치
apt update
apt install ca-certificates curl gnupg lsb-release
# Docker GPG Key 추가
mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 레포지터리 설정
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 도커 엔진 설치
apt update
apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 도커 설치 확인
docker version
Client, Server 정보가 모두 나오면 된다. 이제 cri-dockerd를 설치한다. cri-dockerd는 Github에서 바이너리를 다운로드하여 설치할 것이다. 내 경우에는 cri-dockerd-0.2.5.arm64.tgz를 설치한다.
# 바이너리 다운로드 및 압축 해제
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.2.5/cri-dockerd-0.2.5.arm64.tgz
tar -xf cri-dockerd-0.2.5.arm64.tgz
cp cri-dockerd/cri-dockerd /usr/bin/
chmod +x /usr/bin/cri-dockerd
# systemctl 데몬 시작파일 구성
cat <<"EOF" > /usr/lib/systemd/system/cri-docker.service
[Unit]
Description=CRI Interface for Docker Application Container Engine
Documentation=https://docs.mirantis.com
After=network-online.target firewalld.service docker.service
Wants=network-online.target
Requires=cri-docker.socket
[Service]
Type=notify
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd://
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
# Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
# Both the old, and new location are accepted by systemd 229 and up, so using the old location
# to make them work for either version of systemd.
StartLimitBurst=3
# Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
# Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
# this option work for either version of systemd.
StartLimitInterval=60s
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Comment TasksMax if your systemd version does not support it.
# Only systemd 226 and above support this option.
TasksMax=infinity
Delegate=yes
KillMode=process
[Install]
WantedBy=multi-user.target
EOF
# socket 파일 구성
cat <<"EOF" > /usr/lib/systemd/system/cri-docker.socket
[Unit]
Description=CRI Docker Socket for the API
PartOf=cri-docker.service
[Socket]
ListenStream=%t/cri-dockerd.sock
SocketMode=0660
SocketUser=root
SocketGroup=docker
[Install]
WantedBy=sockets.target
EOF
# cri-docker 시작
systemctl daemon-reload
systemctl enable --now cri-docker
systemctl status cri-docker
3. kubeadm, kubelet, kubectl 설치
- kubeadm : 클러스터 부트스트랩
- kubelet : 클러스터에서 실행되는 Pod와 Container 시작과 같은 작업을 수행한다.
- kubectl : 클러스터와 통신하기 위한 CLI
# 쿠버네티스 레포지터리를 사용하기 위한 패키지 설치
apt install apt-transport-https ca-certificates curl
# 공개 사이닝 키설정
curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
# 쿠버네티스 레포지터리 추가
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
# 설치
apt update
apt install kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl
# 설치 확인
kubeadm version
kubelet --version
kubectl version
Cluster 생성
이 과정은 master(controlplane)에서만 진행한다.
1. controlplane 구성
Cluster를 생성할 때 --cri-socket 옵션을 사용하여 사용할 컨테이너 런타임을 지정해주어야 한다.
# controlplane 구성
kubeadm init --pod-network-cidr=192.168.0.0/16 \
--cri-socket unix:///var/run/cri-dockerd.sock
로그를 보면 kubeconfig, apiserver, etcd와 같은 static pod, node join을 위한 토큰, CoreDNS, kube-proxy 등이 설정된 것을 확인할 수 있다. mulit node로 구성하는 경우, 아래 사진에 표시한 join 명령어는 복사해서 다른 곳에 저장해두도록 한다. join 할 노드에서 해당 명령어를 실행하면 된다.
참고로 token은 기본적으로 24시간 동안 유효하다고 한다.
2. kubeconfig 설정
kubectl을 사용하기 위한 kubeconfig 파일은 ~/.kube/ 아래로 복사한다.
이 과정은 kubectl을 사용할 컴퓨터에서 진행하면 된다.
# kubectl을 편하게 사용하기 위한 config 복사
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
복사 후 get nodes를 확인하면 NotReady 상태인 control-plane 노드를 확인할 수 있다.
3. CNI 배포
Pod 네트워킹을 위한 CNI를 배포한다. CNI는 Calico, Weave Net, Flannel 등이 있는데 이 글에서는 Weave Net를 사용할 것이다.
Weave Net은 TCP 6783, UDP 6783/6784를 사용하므로 EC2에 적용된 SG 규칙이 이를 허용하고 있어야 한다.
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
네트워킹을 위한 sa, role, daemonset 등이 생성되는 것을 확인할 수 있다. 이제 get nodes를 다시 해보면 Ready 상태인 것을 확인할 수 있다.
kubectl get nodes
참고 문서
https://docs.docker.com/engine/install/ubuntu/
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/
https://www.weave.works/docs/net/latest/kubernetes/kube-addon/#-installation