多机K3S集群搭建踩坑记

1. 背景

由于笔者需要部署一些计算服务并实现扩展灵活、可用性高,所以决定用K8S体系来代替原有的Docker部署。K8S对于个人来说维护成本太高了,所以笔者选用了更轻量的K3S。

本篇文章记录的是笔者搭建这个K3S集群的过程。

2. 离线安装K3S服务

K3S的快速入门指南给出了简洁的安装脚本:

1
2
3
curl -sfL https://get.k3s.io | sh -
# 国内加速脚本👇
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -

但由于国内愈加恶劣的网络环境,即使这个脚本成功安装了K3S服务,也无法成功启动:K3S所需的pause镜像无法从docker.io上拉取下来。所以笔者选择离线安装K3S。

参考文档:Air-Gap Install | K3s

2.1 下载所需文件

在K3S的Releases页可以下载到我们所需的文件:k3s和k3s-airgap-images-amd64.tar.gz。

image-20240607082747333

1
2
3
wget <k3s链接>
wget <k3s镜像链接>
chmod +x k3s

本来还需要下载k3s-install.sh,但由于笔者的安装环境可以顺畅从rancher.cn获取该文件,所以笔者没有下载。

2.2 K3S主节点安装服务

1
2
3
4
5
6
# 准备文件
sudo mkdir -p /var/lib/rancher/k3s/agent/images
sudo cp ./k3s-airgap-images-amd64.tar.gz /var/lib/rancher/k3s/agent/images
sudo cp ./k3s /usr/local/bin/
# 开始安装
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_SKIP_DOWNLOAD=true sh -

2.3 K3S从节点安装服务

流程和主节点相同,只是需要先从主节点上获取K3S TOKEN:

1
sudo cat /var/lib/rancher/k3s/server/token

然后在从节点安装是加入环境变量:

1
2
3
4
5
6
7
8
# 准备文件
sudo mkdir -p /var/lib/rancher/k3s/agent/images
sudo cp ./k3s-airgap-images-amd64.tar.gz /var/lib/rancher/k3s/agent/images
sudo cp ./k3s /usr/local/bin/
# 开始安装
export K3S_URL="https://<主节点IP>:6443"
export K3S_TOKEN="<上一步获取到的K3S TOKEN>"
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_SKIP_DOWNLOAD=true sh -

3. 配置K3S服务

image-20240607085753410

上图是笔者的网络环境,每个节点有两张网卡,通过网段为100.x.x.x的网卡互相联通。

在主节点和从节点安装完K3S服务后,笔者发现从节点无法成功启动K3S服务:

1
2
3
4
5
6
7
8
9
10
11
12
$ sudo journalctl -u k3s-agent.service
...
Starting k3s agent v1.29.5+k3s1 (4e53a323)
Adding server to load balancer k3s-agent-load-balancer: 100.x.x.x:6443
Running load balancer k3s-agent-load-balancer 127.0.0.1:6444 -> [100.x.x.x:6443] [default: 100.x.x.x:6443]
...
Getting list of apiserver endpoints from server
Updated load balancer k3s-agent-load-balancer default server address -> 192.x.x.x:6443
Adding server to load balancer k3s-agent-load-balancer: 192.x.x.x:6443
Removing server from load balancer k3s-agent-load-balancer: 100.x.x.x:6443
...
error="dial tcp 192.x.x.x:6443: connect: connection timed out"

原来,即使在从节点安装K3S时已经指定了K3S_URL为100.x.x.x,但K3S Agent在连接上主节点后依然选择连接192.x.x.x,但从节点实际上无法连接这个IP。为此,我们需要强制指定节点IP。

参考:server | K3sagent | K3s

3.1 修改K3S服务文件

在主节点上修改配置/etc/systemd/system/k3s.service:

1
2
3
...
ExecStart=/usr/local/bin/k3s \
server --node-ip "100.x.x.x" --node-external-ip "100.x.x.x" \

在从节点上修改配置/etc/systemd/system/k3s-agent.service:

1
2
ExecStart=/usr/local/bin/k3s \
agent --node-ip "100.x.x.x" --node-external-ip "100.x.x.x" \

然后各自重启服务:

1
2
3
sudo systemctl daemon-reload
sudo systemctl restart k3s # 主节点
sudo systemctl restart k3s-agent # 从节点

现在从节点正常加入集群了:

1
2
3
4
$ sudo kubectl get nodes
NAME STATUS ROLES AGE VERSION
xxxxxxx Ready <none> 10m v1.30.1+k3s1
xxxxx Ready control-plane,master 32m v1.30.1+k3s1

3.2 查看Node信息

此时如果我们查看节点信息(sudo kubectl describe node xxx),会发现注解flannel.alpha.coreos.com/public-ip依然是节点另一张网卡的IP。目前影响未知。

1
2
3
4
5
6
7
8
Annotations:        alpha.kubernetes.io/provided-node-ip: 100.x.x.x
flannel.alpha.coreos.com/backend-data: {"VNI":1,"VtepMAC":"xx"}
flannel.alpha.coreos.com/backend-type: vxlan
flannel.alpha.coreos.com/kube-subnet-manager: true
flannel.alpha.coreos.com/public-ip: 10.x.x.x
k3s.io/external-ip: 100.x.x.x
k3s.io/hostname: xx
k3s.io/internal-ip: 100.x.x.x

4. 设置静态CPU调度策略

Docker/K8S体系下,CPU默认是按时间片调度的。容器获取到CPU时间片后,可以在不同的CPU核心中切换。这在IO密集型场景中可以提升资源利用率。

但笔者的场景是计算密集型,切换CPU核心会导致性能下降,所以需要将容器和CPU进行绑定。

4.1 Docker实现

用docker命令运行容器时,可以用--cpuset-cpus等参数绑定CPU核心(Runtime options with Memory, CPUs, and GPUs | Docker Docs),或者用docker-compose配置实现类似效果(Services top-level elements | Docker Docs):

1
2
3
4
5
6
7
8
9
10
11
12
13
version: '2.4'

services:
xxx:
image: xxx

# 绑定cpu核心
cpuset: "0-3"
cpu_count: 4
# 预留内存
mem_limit: '4g'
memswap_limit: '4g'
mem_reservation: '2g'

4.2 K3S实现

kubelet也可以设置类似的调度策略:static 策略(控制节点上的 CPU 管理策略 | Kubernetes)。但由于K3S已经将kubelet集成到了二进制内容里,所以无法单独配置kubelet。编辑K3S的配置文件:

1
2
sudo mkdir -p /etc/rancher/k3s/
sudo vim /etc/rancher/k3s/config.yaml
1
2
3
kubelet-arg:
- "--cpu-manager-policy=static"
- "--system-reserved=cpu=1,memory=1Gi"

删除已有CPU调度策略并重启K3S服务:

1
2
3
sudo rm /var/lib/kubelet/cpu_manager_state
sudo systemctl restart k3s # 主节点
sudo systemctl restart k3s-agent # 从节点

此时可以看到配置生效:

1
2
3
4
5
6
7
8
9
10
11
12
$ sudo kubectl describe node xxx
...
Annotations: alpha.kubernetes.io/provided-node-ip: 100.x.x.x
k3s.io/node-args:
["agent","--kubelet-arg","--cpu-manager-policy=static","--kubelet-arg","--system-reserved=cpu=1,memory=1Gi","--node-ip","10
...
Capacity:
cpu: 16
...
Allocatable:
cpu: 15
...

大功告成,愉快享受K3S了~


多机K3S集群搭建踩坑记
https://www.yooo.ltd/2024/06/07/multi-node-k3s-cluster/
作者
OrangeWolf
发布于
2024年6月7日
许可协议