在Openrule上部署K3S群集 | Word Count: 1.9k | Reading Time: 8mins | Post Views:
什么是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 等)
节点准备 按照官方实践指南,主机配置使用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 是否已绑定:
部署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。
验证高可用
关闭一个 Master 节点 (如 k3master1),检查集群是否仍可正常操作:
应仍能返回节点列表,只是故障节点状态变为 NotReady。
重启 k3lb1 上的 Keepalived 或 HAProxy ,观察 VIP 是否平滑切换到 k3lb2。
创建一个测试应用 :
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 集群部署完成。