什么是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

主机准备

# 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

容器安装

# 添加软件源信息
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

数据库准备

# 安装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

群集部署

配置主机信任

[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

部署负载均衡器

# 软件安装
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)上配置
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)上配置
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 节点上分别执行:

systemctl enable --now haproxy keepalived
systemctl status haproxy keepalived

验证 VIP 是否已绑定:

ip addr show eth0

部署server

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

# 安装命令
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 上检查集群状态:

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

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

部署worker

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

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

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

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),检查集群是否仍可正常操作:

    kubectl get nodes

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

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

  1. 创建一个测试应用

    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 集群部署完成。