k3s集群部署

K3s 是 Rancher 实验室(现为 SUSE 的一部分)开发的一个轻量级的 Kubernetes 发行版,专为资源受限和边缘计算环境设计。它被打包成一个小于 100MB 的二进制文件,包含了运行一个完整 Kubernetes 集群所需的所有组件

环境准备:

机器IP节点系统
192.168.51.102k3s-master01ubuntu24.04
192.168.51.103k3s-master02ubuntu24.04
192.168.51.104k3s-master03ubuntu24.04
192.168.51.100k3s-node01ubuntu24.04
192.168.51.101k3s-node02ubuntu24.04

注:etcd 和 calico 都单独部署,不使用K3S内置的

1、关闭防火墙 或者 放开端口

ufw disable

2、禁用swap,Kubernetes(含K3S)和etcd均要求禁用Swap,否则会影响内存调度,导致集群或etcd异常

swapoff -a   #临时禁止
vim /etc/fstab #永久禁止

3、配置主机名和IP映射

vim /etc/hosts
192.168.51.100  k3s-node01
192.168.51.101  k3s-node02
192.168.51.102  k3s-master01
192.168.51.103  k3s-master02 
192.168.51.104  k3s-master03

4、配置内核参数

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

5、配置时间同步,etcd集群对节点时间同步要求极高,时间误差超过1s会导致集群分裂,所有节点(尤其是etcd节点)必须配置时间同步,K3S集群也配置下

可通过chronyd来实现内网时间同步,再次不详细说

6、安装依赖包,如下:

apt-get update && apt-get install -y libseccomp2 socat conntrack wget curl openssl

7、重启节点,部分配置(如内核参数、主机名)需重启节点才能完全生效,建议执行重启:

reboot

8、容器运行时,不用单独部署,k3s已经内置了containerd

9、etcd集群,单独部署,可参考etcd集群部署

10、部署第一个master节点,如下:

curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_TOKEN=97540231abcdef sh -s - server \
--server --disable-etcd  \
--datastore-endpoint=https://192.168.51.242:2379,https://192.168.51.250:2379,https://192.168.51.251:2379 \
--datastore-cafile=/etc/ssl/etcd/etcd-ca.pem \
--datastore-certfile=/etc/ssl/etcd/server.pem \
--datastore-keyfile=/etc/ssl/etcd/server-key.pem \
--flannel-backend=none
  • INSTALL_K3S_MIRROR=cn:启用国内镜像源,加速K3S组件及镜像拉取
  • K3S_TOKEN:集群密钥,用于其他节点加入集群,需妥善保管,拥有该token即拥有集群完全管理员权限
  • –disable-etcd:禁用K3S内置的嵌入式etcd,使用外部etcd集群
  • –datastore-endpoint:指定外部etcd集群地址,多个地址用逗号分隔
  • –datastore-cafile/ –datastore-certfile/  –datastore-keyfile:指定etcd集群的CA证书、服务端证书和密钥,确保K3S能正常访问外部etcd(这里需要先从etcd集群里把证书copy到三个master节点)
  • –flannel-backend=none:禁用K3S默认的Flannel网络插件,后续将部署Calico
  • –server: 加了 --disable-etcd 必须同时加 --server

查看k3s状态,如图:

获取集群token(备用,若忘记自定义token,可通过此命令获取)

#该token为安全格式,包含集群CA哈希和凭证,可用于验证加入集群的节点身份
cat /var/lib/rancher/k3s/server/node-token

11、部署其余两个master节点,如下:

curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_TOKEN=97540231abcdef sh -s - server \
--server --disable-etcd  \
--datastore-endpoint=https://192.168.51.242:2379,https://192.168.51.250:2379,https://192.168.51.251:2379 \
--datastore-cafile=/etc/ssl/etcd/etcd-ca.pem \
--datastore-certfile=/etc/ssl/etcd/server.pem \
--datastore-keyfile=/etc/ssl/etcd/server-key.pem \
--flannel-backend=none \
--server https://192.168.51.102:6443
  • 其他参数与初始化节点完全一致,确保token、外部etcd配置、网络禁用参数统一,避免集群异常
  • –server:指定初始化Master节点的API Server地址(格式:https://初始化节点IP:6443)

此时的kubectl get nodes 还是NotReady状态,因为网络插件还没安装

12、将k3s-node01和ks3-node02加入到集群中,执行如下命令:

curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh \
| INSTALL_K3S_MIRROR=cn \
K3S_URL=https://192.168.51.102:6443 \
K3S_TOKEN=K10e42162c98c2b8a7e69a6e2fc8ac26ef324c72a9e87612181c0a0e43ed2742367::server:97540231abcdef \
sh -

注:如果机器没有网络,那执行脚本肯定会失败,此时可以先配置下临时代理,安装后再将代理删除,如下

export http_proxy=http://192.168.51.248:3128
export https_proxy=http://192.168.51.248:3128

配置好代理后,再次执行上面的curl 命令安装k3s-agent,安装后,编辑环境变量删除代理,如下:

vim /etc/systemd/system/k3s-agent.service.env

13、安装calico(3.30.0版本),离线安装,在线会导致镜像拉取失败,如下:

先下载tigera-operator,首先执行如下命令:

wget https://raw.githubusercontent.com/projectcalico/calico/v3.30.0/manifests/tigera-operator.yaml

查看tigera-operator需要的镜像,将镜像下载回来,三个master都要有此镜像如下:

cat tigera-operator.yaml | grep image:

注:如果镜像下载回来后或者保存到私有仓库再拉取到master节点后,镜像名字跟tigera-operator.yaml中的名字会不一样,此时可通过如果下命令修改镜像名字,如下:

k3s ctr -n k8s.io images tag 旧镜像名 新镜像名    #没有docker,不能使用docker tag修改的
  • k3s中,管理容器的命令是crictl,crictl是容器运行时的接口封装,后面可以对接多个容器运行时,比如containerd、docker等

然后执行命令创建tigera-operator,如下:

kubectl create -f tigera-operator.yaml

第一次执行可能显示容器一直在创建,kubectl describe显示还需要拉取一个底层镜像,同样道理,拉回来修改名字如下:

docker.io/rancher/mirrored-pause:3.6  #本例子为3.6版本

最后查看容器已经运行起来,如图:

将custom-resources.yaml下载回来,修改cidr 地址,如图:

wget  https://raw.githubusercontent.com/projectcalico/calico/v3.30.0/manifests/custom-resources.yaml

执行如下命令创建calico,如下:

kubectl create -f custom-resources.yaml

同样需要把容器先拉取回来本地,再修改为实际的镜像名字,否则失败,需要拉取的镜像有:

  • docker.io/calico/pod2daemon-flexvol:v3.30.0
  • docker.io/calico/cni:v3.30.0
  • docker.io/calico/node:v3.30.0
  • docker.io/calico/node-driver-registrar:v3.30.0
  • docker.io/calico/typha:v3.30.0
  • docker.io/calico/goldmane:v3.30.0
  • docker.io/calico/whisker:v3.30.0
  • docker.io/rancher/mirrored-pause:3.6
  • docker.io/calico/whisker-backend:v3.30.0
  • docker.io/calico/kube-controllers:v3.30.0
  • docker.io/calico/csi:v3.30.0
  • docker.io/calico/apiserver:v3.30.0

13、再次验证集群节点,已经变为Ready状态,如图:

此时执行kubectl get po -A,还有部分容器没成功,还需要拉取镜像如下:

  • docker.io/rancher/mirrored-coredns-coredns:1.14.2
  • docker.io/rancher/klipper-helm:v0.9.14-build20260309
  • docker.io/rancher/local-path-provisioner:v0.0.35
  • docker.io/rancher/klipper-lb:v0.4.15
  • docker.io/rancher/mirrored-library-traefik:3.6.10
  • docker.io/rancher/mirrored-metrics-server:v0.8.1

如果要导出镜像再导入镜像,可执行如下命令:

k3s ctr images export nginx.tar   nginx:latest #导出
k3s ctr images import nginx.tar   #导入

重要!!!!

k3s集群默认安装完成后,有几个pod默认只有一个副本,这容易导致单点故障,需要手动扩容,如下:

1、CoreDNS(集群 DNS,最关键)

  • 命名空间kube-system
  • 默认副本1
  • 作用:所有 Pod 的域名解析
  • 风险:单点故障 → 集群内 DNS 完全失效
  • 生产建议replicas: 23(与控制平面节点数一致)
#扩容为3个
kubectl scale deploy coredns --replicas=3 -n kube-system

2、Traefik Ingress Controller(默认 Ingress)

  • 命名空间kube-system
  • 默认副本1
  • 作用:外部 HTTP/HTTPS 流量入口
  • 风险:单点故障 → 所有 Ingress 路由不可用
  • 生产建议replicas: 23,配合 podAntiAffinity 打散
kubectl scale deployment traefik --replicas=2 -n kube-system

3、local-path-provisioner(本地存储供给器)

  • 命名空间kube-system
  • 默认副本1
  • 作用:默认动态 PV 供给(local-path存储类)
  • 风险:单点故障 → 无法创建新 PVC
  • 生产建议replicas: 2,或改用外部分布式存储

注:使用外部存储,因此这里就不改了

4、metrics-server(监控指标采集)

  • 命名空间kube-system
  • 默认副本1
  • 作用:提供 kubectl top、HPA 指标
  • 风险:单点故障 → 监控与自动扩缩容失效
  • 生产建议replicas: 2
kubectl scale deploy metrics-server --replicas=2 -n kube-system

5、klipper-lb(ServiceLB 负载均衡),本项目没使用,已改为Metallb + traefik,因此这个不用

k3s配置本地docker仓库

1、在所有节点执行命令(master + worker),创建文件,如下:

mkdir -p /etc/rancher/k3s
vi /etc/rancher/k3s/registry.yaml

2、编辑registry.yaml,添加内容如下:

mirrors:
  registry.oa.com:
    endpoint:
      - "https://registry.oa.com"   #本地仓库地址

configs:
  registry.oa.com:
    auth:
      username: "username"
      password: "password"
    tls:
      insecure_skip_verify: true
  • 证书是正规公网证书(Let’s Encrypt、阿里云、腾讯云等)→ 不需要 insecure_skip_verify: true
  • 证书是自签名 / 内网自建 CA必须加 insecure_skip_verify: true

3、重启k3s即可,如下:

systemctl restart k3s         #master节点
systemctl restart k3s-agent   #worker节点

将节点从集群中彻底剔除

1、先把节点设为不可调度,在master节点执行,如下:

kubectl cordon k3s-node01

2、驱逐节点上的所有pod,在master节点执行,如下:

kubectl drain k3s-node01 --ignore-daemonsets --delete-emptydir-data --force

3、从集群删除节点,在maste节点执行,如下:

kubectl delete node k3s-node01

4、在worker节点执行卸载 k3s-agent,如下:

/usr/local/bin/k3s-agent-uninstall.sh

5、清理残留目录,如下:

rm -rf /etc/rancher/k3s
rm -rf /var/lib/kubelet
rm -rf /var/lib/rancher/k3s
rm -rf /var/lib/cni/*
rm -rf /etc/cni/net.d/*

6、重启服务器(可选但推荐,干净)

reboot

注:后续如果想重新加入,按照上面获取token,然后重新加入即可

traefik 重新部署

1、先删除冲突的ingress,如下:

# 查看是否存在
kubectl get ingressclass traefik

# 强制删除(关键一步)
kubectl delete ingressclass traefik

2、再彻底清理所有 Traefik 残留

# 删 HelmChart(阻止自动重建)
kubectl delete helmchart traefik traefik-crd -n kube-system

# 删 Pod/Job/Service/Deployment
kubectl delete all -n kube-system -l app.kubernetes.io/name=traefik

# 删所有 Traefik CRD
kubectl delete crd $(kubectl get crd | grep traefik | awk '{print $1}')

# 删 Secret/ConfigMap
kubectl delete secret,configmap -n kube-system -l app.kubernetes.io/name=traefik

# 删失败 Job
kubectl delete job -n kube-system -l app.kubernetes.io/name=traefik

3、用 K3s 标准方式恢复(推荐)

# 清空旧配置
rm -f /var/lib/rancher/k3s/server/manifests/traefik*.yaml

# 重启 K3s 自动用内置 Chart 重装
systemctl restart k3s

标签