이번 실습에서는 2개의 Worker node를 bootstrap 하는 과정입니다. runc, container networking plugin, containerd, kubelet, kube-proxy 컴포넌트들을 설치합니다.
각 worker 서버에 Kubernetes 바이너리 및 system unit 파일들을 옮기기 전에 일부 파일들을 jumpbox
에서 생성합니다.
cat <<EOF > /k8s-hardway/configs/10-bridge.conf
{
"cniVersion": "1.0.0",
"name": "bridge",
"type": "bridge",
"bridge": "cni0",
"isGateway": true,
"ipMasq": true,
"ipam": {
"type": "host-local",
"ranges": [
[{"subnet": "SUBNET"}]
],
"routes": [{"dst": "0.0.0.0/0"}]
}
}
EOF
cat <<EOF > /k8s-hardway/configs/99-loopback.conf
{
"cniVersion": "1.1.0",
"name": "lo",
"type": "loopback"
}
EOF
cat <<EOF > /k8s-hardway/configs/containerd-config.toml
version = 2
[plugins."io.containerd.grpc.v1.cri"]
[plugins."io.containerd.grpc.v1.cri".containerd]
snapshotter = "overlayfs"
default_runtime_name = "runc"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
[plugins."io.containerd.grpc.v1.cri".cni]
bin_dir = "/opt/cni/bin"
conf_dir = "/etc/cni/net.d"
EOF
cat <<EOF > /k8s-hardway/configs/kube-proxy-config.yaml
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
clientConnection:
kubeconfig: "/var/lib/kube-proxy/kubeconfig"
mode: "iptables"
clusterCIDR: "192.168.0.0/16"
EOF
clusterCIDR
값은 POD 아이피 대역으로 설정해줍니다. kube-controller-manager.service
파일의 cluster-cidr
값과 동일합니다.
cat <<EOF > /k8s-hardway/configs/kubelet-config.yaml
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: false
webhook:
enabled: true
x509:
clientCAFile: "/var/lib/kubelet/ca.crt"
authorization:
mode: Webhook
clusterDomain: "cluster.local"
clusterDNS:
- "172.16.0.10"
cgroupDriver: systemd
containerRuntimeEndpoint: "unix:///var/run/containerd/containerd.sock"
podCIDR: "SUBNET"
resolvConf: "/etc/resolv.conf"
runtimeRequestTimeout: "15m"
tlsCertFile: "/var/lib/kubelet/kubelet.crt"
tlsPrivateKeyFile: "/var/lib/kubelet/kubelet.key"
EOF
clusterDNS
값은 kube-apiserver.service
파일의 service-cluster-ip-range
아이피 대역에서 끝자리를 10으로 설정해줍니다.
cat <<EOF > /k8s-hardway/units/containerd.service
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target
[Service]
ExecStartPre=/sbin/modprobe overlay
ExecStart=/bin/containerd
Restart=always
RestartSec=5
Delegate=yes
KillMode=process
OOMScoreAdjust=-999
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF > /k8s-hardway/units/kube-proxy.service
Unit]
Description=Kubernetes Kube Proxy
Documentation=https://github.com/kubernetes/kubernetes
[Service]
ExecStart=/usr/local/bin/kube-proxy \
--config=/var/lib/kube-proxy/kube-proxy-config.yaml
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
cat <<EOF > /k8s-hardway/units/kubelet.service
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/kubernetes/kubernetes
After=containerd.service
Requires=containerd.service
[Service]
ExecStart=/usr/local/bin/kubelet \
--config=/var/lib/kubelet/kubelet-config.yaml \
--kubeconfig=/var/lib/kubelet/kubeconfig \
--register-node=true \
--v=2
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
위 파일들을 다 생성했으면, 각 서버로 복사합니다.
for host in node-1 node-2; do
SUBNET=$(grep $host /k8s-hardway/machines.txt | cut -d " " -f 4)
sed "s|SUBNET|$SUBNET|g" \
/k8s-hardway/configs/10-bridge.conf > 10-bridge.conf
sed "s|SUBNET|$SUBNET|g" \
/k8s-hardway/configs/kubelet-config.yaml > kubelet-config.yaml
scp 10-bridge.conf kubelet-config.yaml \
root@$host:~/
done
for host in node-1 node-2; do
scp \
/k8s-hardway/downloads/runc.amd64 \
/k8s-hardway/downloads/crictl-v1.30.0-linux-amd64.tar.gz \
/k8s-hardway/downloads/cni-plugins-linux-amd64-v1.5.0.tgz \
/k8s-hardway/downloads/containerd-1.7.14-linux-amd64.tar.gz \
/k8s-hardway/downloads/kubectl \
/k8s-hardway/downloads/kubelet \
/k8s-hardway/downloads/kube-proxy \
/k8s-hardway/configs/99-loopback.conf \
/k8s-hardway/configs/containerd-config.toml \
/k8s-hardway/configs/kubelet-config.yaml \
/k8s-hardway/configs/kube-proxy-config.yaml \
/k8s-hardway/units/containerd.service \
/k8s-hardway/units/kubelet.service \
/k8s-hardway/units/kube-proxy.service \
root@$host:~/
done
이 실습은 각 worker node(node-1, node-2)에서 작업해야 합니다. ssh 명령어를 사용해 worker node로 접근합니다.
ssh root@node-1
OS 의존성 패키지들을 설치합니다.
{
apt-get update
apt-get -y install socat conntrack ipset
}
socat 바이너리는 kubectl port-forward
명령어를 지원합니다.
Disable Swap
기본적으로 kubelet 실행 시 swap이 활성화 되어있다면, 동작하지 않습니다. Kubernetes가 적절한 리소스 할당과 서비스 품질을 제공할 수 있도록 swap을 비활성화 하는게 좋습니다.
failSwapOn
, swapBehavior
설정을 하셔야합니다.swapon 명령어로 확인이 가능하며, 결과가 아무것도 없다면, swap은 현재 비활성화 상태입니다.
swapon --show
swap이 활성화 되어 있다면 다음과 같이 진행하여 비활성화를 진행합니다.
swapoff -a
하지만, 해당 명령어는 임시 조치이며, 완전히 비활성화 하려면 swap 관련 설정 파일(/etc/fstab, systemd.swap)을 통해 비활성화를 진행해야 합니다. 해당 설정은 시스템마다 다르기에 본 글에서는 다루지 않겠습니다.
디렉터리을 생성합니다.
mkdir -p \
/etc/cni/net.d \
/opt/cni/bin \
/var/lib/kubelet \
/var/lib/kube-proxy \
/var/lib/kubernetes \
/var/run/kubernetes
관련 바이너리들을 설치합니다.
{
mkdir -p containerd
tar -xvf crictl-v1.30.0-linux-amd64.tar.gz
tar -xvf containerd-1.7.14-linux-amd64.tar.gz -C containerd
tar -xvf cni-plugins-linux-amd64-v1.5.0.tgz -C /opt/cni/bin/
mv runc.amd64 runc
chmod +x crictl kubectl kube-proxy kubelet runc
mv crictl kubectl kube-proxy kubelet runc /usr/local/bin/
mv containerd/bin/* /bin/
}
Configure CNI Networking
bridge
network 설정 파일을 옮깁니다.
mv 10-bridge.conf 99-loopback.conf /etc/cni/net.d/
Configure containerd
containerd
설정 파일을 옮깁니다.
{
mkdir -p /etc/containerd/
mv containerd-config.toml /etc/containerd/config.toml
mv containerd.service /etc/systemd/system/
}
Configure the Kubelet
kubelet
설정 파일 및 system unit 파일을 옮깁니다.
{
mv kubelet-config.yaml /var/lib/kubelet/
mv kubelet.service /etc/systemd/system/
}
Configure the Kubernetes Proxy
kube-proxy
설정 파일 및 system unit 파일을 옮깁니다.
{
mv kube-proxy-config.yaml /var/lib/kube-proxy/
mv kube-proxy.service /etc/systemd/system/
}
Start the Worker Services
kubelet
, kube-proxy
서비스를 실행합니다.
{
systemctl daemon-reload
systemctl enable containerd kubelet kube-proxy
systemctl start containerd kubelet kube-proxy
}
여기까지의 과정을 node-2 서버에서도 진행합니다.
이번 섹션에서 작업한 worker 노드는 kubectl을 통해 확인할 수 없습니다. 다시 jumpbox
서버에서 아래 명령어를 실행해 확인합니다.
등록된 Kubernetes 노드를 확인합니다.
ssh root@controlplane-1 \
"kubectl get nodes \
--kubeconfig admin.kubeconfig"
NAME STATUS ROLES AGE VERSION
node-1 Ready <none> 3m31s v1.30.1
node-2 Ready <none> 100s v1.30.1