什么是K3S

K3s 是轻量级的 Kubernetes。K3s 易于安装,仅需要 Kubernetes 内存的一半,所有组件都在一个小于 100 MB 的二进制文件中。K3s 是一个完全兼容的 Kubernetes 发行版,具有以下增强功能:

  • 打包为单个二进制文件。
  • 使用基于 sqlite3 作为默认存储机制的轻量级存储后端。同时支持使用 etcd3、MySQL 和 Postgres。
  • 封装在简单的启动程序中,可以处理很多复杂的 TLS 和选项。
  • 默认情况下是安全的,对轻量级环境有合理的默认值。
  • 所有 Kubernetes control plane 组件的操作都封装在单个二进制文件和进程中。因此,K3s 支持自动化和管理复杂的集群操作(例如证书分发等)。
  • 最大程度减轻了外部依赖性,K3s 仅需要现代内核和 cgroup 挂载。K3s 打包了所需的依赖,包括:
    • containerd
    • Flannel (CNI)
    • CoreDNS
    • Traefik (Ingress)
    • Klipper-lb (Service LB)
    • 嵌入式网络策略控制器
    • 嵌入式 local-path-provisioner
    • 主机实用程序(iptables、socat 等)
      k3s

节点准备

按照官方实践指南,主机配置使用2core CPU、2GiB Mem、40GiB Disk,并搭配Openruler22.03LTS。基本规划如下:

角色 主机名 IP地址 域名
Master1 k3master1 192.168.10.231 k3master1.contoso.com
Master2 k3master2 192.168.10.232 k3master2.contoso.com
Master3 k3master3 192.168.10.233 k3master3.contoso.com
Node1 k3node1 192.168.10.234 k3node1.contoso.com
Haproxy+KeepLived k3lb1 192.168.10.235 k3lb1.contoso.com
Haproxy+KeepLived k3lb2 192.168.10.236 k3lb2.contoso.com
External DataBase k3master1 192.168.10.231 k3master1.contoso.com
DNS Server k3master1 192.168.10.231 k3master1.contoso.com
Public IP 192.168.10.230

主机准备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# DNS Server 上创建对应主机解析

# 防火墙配置
firewall-cmd --set-default-zone=trusted
# pods
firewall-cmd --permanent --zone=trusted --add-source=10.42.0.0/16
# services
firewall-cmd --permanent --zone=trusted --add-source=10.43.0.0/16
# http,https,mysql,kube-apiserver
firewall-cmd --permanent --service={kube-apiserver,http,https,mysql}
firewall-cmd --reload

# 关闭selinux
sed -i 's/enforceing/disabled' /etc/selinux/config

# 关闭SWAP
swapoff -a ; sed -i '/swap/d' /etc/fstab

# 修改内核加载模块
cat > /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF

cat >> /etc/sysctl.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF

# 卸载Podman
dnf remove -y podman*
dnf install -y yum-utils device-mapper-persistent-data lvm2
dnf install -y ipvsadm bridge-utils jq
dnf install -y bash-completion mariadb

容器安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 添加软件源信息
dnf config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo

# 更新并安装Docker-CE
dnf makecache
dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 安装并锁定版本
dnf install -y python3-dnf-plugin-versionlock
dnf versionlock add docker-ce

# 配置加速源
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"group": "docker",
"registry-mirrors": ["https://37y8py0j.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF

# 重新加载并配置开机启动
systemctl daemon-reload
systemctl enable --now docker

# 拉取测试镜像
docker pull traefik/whoami
docker run -itd --rm -p 80:80 traefik/whoami:latest
curl localhost

# 加载github的Hosts地址
#sh -c 'sed -i "/# GitHub520 Host Start/Q" /etc/hosts && curl https://raw.hellogithub.com/hosts >> /etc/hosts'

# 重启
sync
ldconfig
reboot

数据库准备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 安装MariaDB
dnf install -y mariadb mariadb-server mariadb-server
# 指定客户端和服务端使用utf8来访问mariadb
cat > /etc/my.cnf.d/charset.cnf <<EOF
[mysqld]
character-set-server = utf8mb4

[client]
default-character-set = utf8mb4
EOF

# 拉起服务
systemctl enable --now mariadb.service
systemctl status --no-pager mariadb.service

# 创建kubernetes数据库,用户名为k3s,密码为kubernetes
mysql -uroot -hlocalhost<< EOF
CREATE USER 'k3s' IDENTIFIED BY 'kubernetes';
CREATE DATABASE kubernetes CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci';
GRANT ALL PRIVILEGES ON kubernetes.* TO 'k3s'@'%';
FLUSH PRIVILEGES;
exit
EOF

# 访问测试
mysql -uk3s -pkubernetes -hlocalhost <<EOF
show databases;
exit
EOF

# 远程访问测试
mysql -uk3s -pkubernetes -hmysql.contoso.com <<EOF
show databases;
exit
EOF

群集部署

配置主机信任

1
2
3
4
5
[root@k3master1 ~]# ssh-keygen -t rsa -b 2048 -C "sujx@live.cn"
[root@k3master1 ~]# ssh-copy-id root@k3master1.contoso.com
[root@k3master1 ~]# ssh-copy-id root@k3master2.contoso.com
[root@k3master1 ~]# ssh-copy-id root@k3master3.contoso.com
[root@k3master1 ~]# ssh-copy-id root@k3node1.contoso.com

部署负载均衡器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 软件安装
dnf makecache
dnf update -y
dnf install -y haproxy keeplived

# 开放端口
firewall-cmd --permanent --add-service=kube-apiserver
firewall-cmd --reload

# 配置haproxy
cat > /etc/haproxy/conf.d/k3s.cfg <<EOF
[root@k3lb1 keepalived]# cat > /etc/haproxy/conf.d/k3s.cfg << EOF
frontend k3s-frontend
bind *:6443
mode tcp
option tcplog
default_backend k3s-backend

backend k3s-backend
mode tcp
option tcp-check
balance roundrobin
default-server inter 10s downinter 5s
server server-1 192.168.10.231:6443 check
server server-2 192.168.10.232:6443 check
server server-3 192.168.10.233:6443 check
EOF

配置Keeplived

在k3lb1(MASTER)上配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
cat > /etc/keepalived/keepalived.conf <<EOF
global_defs {
router_id LVS_DEVEL
}

vrrp_script check_haproxy {
script "/usr/bin/systemctl is-active haproxy"
interval 2
weight 2
}

vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1234
}
virtual_ipaddress {
192.168.10.230/24 dev eth0 label eth0:1
}
track_script {
check_haproxy
}
}
EOF
在k3lb2(BACKUP)上配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
cat > /etc/keepalived/keepalived.conf <<EOF
global_defs {
router_id LVS_DEVEL
}

vrrp_script check_haproxy {
script "/usr/bin/systemctl is-active haproxy"
interval 2
weight 2
}

vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1234
}
virtual_ipaddress {
192.168.10.230/24 dev eth0 label eth0:1
}
track_script {
check_haproxy
}
}
EOF

启动服务

在两台 LB 节点上分别执行:

1
2
systemctl enable --now haproxy keepalived
systemctl status haproxy keepalived

验证 VIP 是否已绑定:

1
ip addr show eth0

部署server

在三个 Master 节点(k3master1、k3master2、k3master3)上依次执行 K3s 安装命令。注意:第一个节点执行后即初始化集群,后续节点只需指向相同的数据库端点即可自动加入。

1
2
3
4
5
6
7
8
9
# 安装命令
curl -sfL https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh | \
INSTALL_K3S_MIRROR=cn \
INSTALL_K3S_SKIP_SELINUX_RPM=true \
INSTALL_K3S_EXEC="--docker --disable servicelb --disable traefik" \
sh -s - \
--system-default-registry registry.cn-hangzhou.aliyuncs.com \
--datastore-endpoint="mysql://k3s:kubernetes@tcp(mysql.contoso.com:3306)/kubernetes" \
--tls-san 192.168.10.230

参数说明:

  • --docker:使用 Docker 作为容器运行时(也可用默认的 containerd)。
  • --disable servicelb --disable traefik:禁用自带的负载均衡器和 Ingress,后续可自行部署 Metallb 或 Nginx Ingress。
  • --tls-san:在 TLS 证书中添加额外的主机名或 IP,此处添加 VIP 地址,防止证书校验失败。

所有三个 Master 节点上执行上述命令。安装完成后,可在任意 Master 上检查集群状态:

1
2
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
kubectl get nodes

应该看到三个 Master 节点均处于 Ready 状态,且角色均为 Control-Plane

部署worker

在 Worker 节点(k3node1)上执行加入命令。首先从任一 Master 获取 Node Token:

1
2
cat /var/lib/rancher/k3s/server/node-token
# 输出类似:K1071ec63f7b...::server:...

然后执行安装命令,将 K3S_URL 指向负载均衡器的 VIP 和端口,K3S_TOKEN 替换为实际 token:

1
2
3
4
5
6
curl -sfL https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh | \
INSTALL_K3S_MIRROR=cn \
INSTALL_K3S_SKIP_SELINUX_RPM=true \
K3S_URL=https://192.168.10.230:6443 \
K3S_TOKEN=K1071ec63f7b...::server: \
sh -s - --docker

等待片刻后,在 Master 上再次运行 kubectl get nodes,应能看到 Worker 节点状态为 Ready


验证高可用

  1. 关闭一个 Master 节点(如 k3master1),检查集群是否仍可正常操作:

    1
    kubectl get nodes

    应仍能返回节点列表,只是故障节点状态变为 NotReady

  2. 重启 k3lb1 上的 Keepalived 或 HAProxy,观察 VIP 是否平滑切换到 k3lb2。

  3. 创建一个测试应用

    1
    2
    3
    kubectl create deployment whoami --image=traefik/whoami
    kubectl expose deployment whoami --port=80 --type=NodePort
    kubectl get svc

    通过任意节点 IP + NodePort 访问服务,验证网络连通性。


附加说明

  • 若需使用域名访问 API Server,请在 DNS 中添加 api.contoso.com 指向 VIP 192.168.10.230,并在安装时增加 --tls-san api.contoso.com
  • 如需部署 Ingress Controller,可后续安装 Nginx Ingress 或 Traefik,但需先移除 --disable traefik 选项或自行覆盖。
  • 所有节点的防火墙规则已在主机准备阶段配置,若仍有通信问题,请检查 firewalld 是否放行了相关端口(如 6443、2379 等)。

至此,基于 OpenRuler 22.03 LTS 的 K3s HA 集群部署完成。