概述
软件版本:rke2 version v1.22.5+rke2r1
os:ubuntu18.04
RKE2是Rancher Kubernetes新的发行版,结合和k3s和RKE1的一些特性。与RKE1相比主要特性在于安全性,符合美国联邦政府部门的安全性和合规性,完整通过CIS安全基线标准,符合FIPS-140-2 标准和定期的镜像安全扫描。
比如结合k3s的一个单体二进制文件启动,底层runtime集成containerd。
与其他Kubernetes部署工具对比
|
组件集成度 |
安全性 |
组件容器化 |
部署简易性 |
kubeadm |
低,需要单独部署kubelet、runtime等组件,然后在通过static-pod启动其他组件。 |
中,默认安全配置 |
除kubelet外全部容器化 |
低,组件HA需要用户自己完成。 |
RKE-1 |
低,单独部署runtime然后在通过rke部署集群。 |
中,默认安全配置 |
全部容器化 |
高,一键部署,组件HA自动完成 |
RKE-2 |
高,单体二进制文件集成runtime和kubelet,一键启动。 |
高,专为安全而生,符合各项安全测试规范 |
除kubelet外全部容器化 |
中,每台节点需要单独操作安装,组件HA自动完成 |
RKE2部署
部署前提:
Linux部署前提条件:
- 关闭swap。
- 关闭NetworkManager(若有),或配置NetworkManager忽略 calico/flannel 相关网络接口。
- 关闭Selinux,或参考下述链接配置Selinux规则。
- 节点主机名采用标准FQDN格式。
若需要开启NetworkManager和Selinux,策略配置NetworkManager和Selinux策略链接:
https://rancher2.docs.rancher.cn/docs/rke2/known_issues/_index#networkmanager
通过完整兼容性测试的操作系统:
Ubuntu 18.04 (amd64)
Ubuntu 20.04 (amd64)
CentOS/RHEL 7.8 (amd64)
CentOS/RHEL 8.2 (amd64)
SLES 15 SP2 (amd64) (v1.18.16+rke2r1 和更新版本)
注:使用Cilium网络插件时,因为ebpf依赖内核技术,所以需要保证以下内核版本
1 、kernel版本 >= 4.9.17
通过RKE2单机方式快速部署Kubernetes
部署Server
下载rke2二进制可执行文件,和自动配置rke2-server
1
| curl -sfL http://rancher-mirror.rancher.cn/rke2/install.sh | INSTALL_RKE2_MIRROR=cn sh -
|
设置rke2-server开机自启
1
| systemctl enable rke2-server.service
|
启动rke2-server
1
| systemctl start rke2-server.service
|
此时,将会通过rke2自动拉起kubelet,然后以static-pod方式启动api-server、Controller-manager、etcd、scheduler
日志查看:
1
| journalctl -u rke2-server -f
|
默认情况下rke2将创建以下目录:
/var/lib/rancher/rke2/:存放额外部署的集群插件(core-dns、网络插件、Ingress-Controller)、etcd数据库存放路径、其他worker连接的token。
/etc/rancher/rke2/:连接集群的kubeconfig文件,以及集群组件参数配置信息。
将常用CLI配置软链接
1 2 3
| ln -s /var/lib/rancher/rke2/bin/kubectl /usr/bin/kubectl ln -s /var/lib/rancher/rke2/bin/ctr /usr/bin/ctr ln -s /var/lib/rancher/rke2/bin/crictl /usr/bin/crictl
|
配置kubeconfig
1 2
| mkdir -p ~/.kube/ cp /etc/rancher/rke2/rke2.yaml ~/.kube/config
|
验证查看:
1 2 3
| kubectl get node NAME STATUS ROLES AGE VERSION rke-node6 Ready control-plane,etcd,master 72m v1.22.5+rke2r1
|
获取worker注册到server的token文件
1
| cat /var/lib/rancher/rke2/server/token
|
部署worker
下载rke2二进制可执行文件,和自动配置rke2-server
1
| curl -sfL http://rancher-mirror.rancher.cn/rke2/install.sh | INSTALL_RKE2_MIRROR=cn INSTALL_RKE2_TYPE="agent" sh -
|
启动rke2-agent服务
1
| systemctl enable rke2-agent.service
|
配置rke2-agent服务
1 2
| mkdir -p /etc/rancher/rke2/ vim /etc/rancher/rke2/config.yaml
|
配置文件内容如下:
1 2
| server: https://<server>:9345 token: <token from server node>
|
注:
rke2 server 进程通过端口 9345 监听新节点的注册。Kubernetes API 仍然监听端口 6443。
启动服务,等待服务启动注册成功。
1
| systemctl start rke2-agent.service
|
日志查看
1
| journalctl -u rke2-agent -f
|
查看最终部署
1 2 3 4
| kubectl get node NAME STATUS ROLES AGE VERSION rke-node6 Ready control-plane,etcd,master 81m v1.22.5+rke2r1 rke-node7 Ready <none> 70m v1.22.5+rke2r1
|
测试验证
1
| kubectl create deployment test --image=busybox:1.28 --replicas=2 -- sleep 30000
|
通过RKE2高可用方式部署Kubernetes
前提条件:
部署顺序
- 启动第一个 server 节点
- 加入其他 server 节点
- 加入 agent 节点
部署负载均衡器(可选)
以nginx为例,配置转发到9345和后端6443端口
创建nginx.conf文件
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
| events { worker_connections 1024; ## Default: 1024 } stream { upstream kube-apiserver { server host1:6443 max_fails=3 fail_timeout=30s; server host2:6443 max_fails=3 fail_timeout=30s; server host3:6443 max_fails=3 fail_timeout=30s; } upstream rke2 { server host1:9345 max_fails=3 fail_timeout=30s; server host2:9345 max_fails=3 fail_timeout=30s; server host3:9345 max_fails=3 fail_timeout=30s; } server { listen 6443; proxy_connect_timeout 2s; proxy_timeout 900s; proxy_pass kube-apiserver; } server { listen 9345; proxy_connect_timeout 2s; proxy_timeout 900s; proxy_pass rke2; } }
|
将对应的3个ip地址修改为实际server节点ip地址
启动nginx
1
| docker run -itd -p 9345:9345 -p 6443:6443 -v ~/nginx.conf:/etc/nginx/nginx.conf nginx
|
实际生产环境部署建议部署两个nginx,中间通过keepalived维持vip实现统一入口。
部署第一个Server
下载rke2二进制可执行文件,和自动配置rke2-server
1
| curl -sfL http://rancher-mirror.rancher.cn/rke2/install.sh | INSTALL_RKE2_MIRROR=cn sh -
|
设置rke2-server开机自启
1
| systemctl enable rke2-server.service
|
配置config.yaml文件
1
| mkdir /etc/rancher/rke2/ -p
|
输入以内容
1 2 3
| tls-san: - xxx.xxx.xxx.xxx - www.xxx.com
|
此处填写LB的统一入口ip地址或域名,如果有多个换行分组方式隔开。
启动rke2-server
1
| systemctl start rke2-server.service
|
将常用CLI配置软链接
1 2 3
| ln -s /var/lib/rancher/rke2/bin/kubectl /usr/bin/kubectl ln -s /var/lib/rancher/rke2/bin/ctr /usr/bin/ctr ln -s /var/lib/rancher/rke2/bin/crictl /usr/bin/crictl
|
配置kubeconfig
1 2
| mkdir -p ~/.kube/ cp /etc/rancher/rke2/rke2.yaml ~/.kube/config
|
可以将kubeconfig文件中的中的ip地址由127.0.0.1替换为实际LB的IP地址。
获取注册到server的token文件
1
| cat /var/lib/rancher/rke2/server/token
|
配置其他Server
配置rke2-agent服务
1 2
| mkdir -p /etc/rancher/rke2/ vim /etc/rancher/rke2/config.yaml
|
配置文件内容如下:
1 2 3 4 5
| server: https://<server>:9345 token: <token from server node> tls-san: - xxx.xxx.xxx.xxx - www.xxx.com
|
注:
- server地址可以填写第一台Server的地址,也可以填写外部统一入口的地址,最佳实践是填写统一入口地址,这样当第一个Server出现问题后,agent还可以通过统一入口地址通过其他Server获取集群信息。
- token填写第一台server的token
- tls-san跟第一台server一样,一般填写统一入口的ip地址或域名,用于TLS证书注册。
下载rke2二进制可执行文件,和自动配置rke2-server
1
| curl -sfL http://rancher-mirror.rancher.cn/rke2/install.sh | INSTALL_RKE2_MIRROR=cn sh -
|
设置rke2-server开机自启
1
| systemctl enable rke2-server.service
|
启动rke2-server
1
| systemctl start rke2-server.service
|
等待注册和集群启动
验证:
1 2 3 4 5 6
| kubectl get node NAME STATUS ROLES AGE VERSION rke-node4 Ready control-plane,etcd,master 140m v1.22.5+rke2r1 rke-node5 Ready control-plane,etcd,master 138m v1.22.5+rke2r1 rke-node6 Ready control-plane,etcd,master 19h v1.22.5+rke2r1 rke-node7 Ready <none> 19h v1.22.5+rke2r1
|
进入etcd-pod,查看etcd集群状态。
1 2 3 4
| etcdctl --cert /var/lib/rancher/rke2/server/tls/etcd/server-client.crt --key /var/lib/rancher/rke2/server/tls/etcd/server-client.key --endpoints https://127.0.0.1:2379 --cacert /var/lib/rancher/rke2/server/tls/etcd/server-ca.crt member list e19d2834bb177be1, started, rke-node4-896165c9, https://192.168.0.25:2380, https://192.168.0.25:2379, false ec67af24a94fb07c, started, rke-node6-fed10843, https://192.168.0.32:2380, https://192.168.0.32:2379, false f7e9f28da0a6e5e6, started, rke-node5-4a4b6af5, https://192.168.0.29:2380, https://192.168.0.29:2379, false
|
按单机操作加入agent节点。
通过RKE2离线部署kubernetes集群
Tarball模式
RKE2的离线部署方式与k3s比较相似,都是提前将对应的离线介质下载放置到对应的目录,启动二进制进程执行。
在RKE2对应的Release页下载对应的离线安装介质
https://github.com/rancher/rke2/releases
主要为以下离线安装介质
- rke2-images.linux-amd64.tar
- rke2.linux-amd64.tar.gz
- sha256sum-amd64.txt
根据所需要的不同网络插件,下载对应的镜像包
- rke2-images-canal.linux-amd64.tar.gz
- 离线安装脚本
将这些下载后的安装介质放置在节点的一个统一目录如/root/images
下载离线安装脚本
1
| curl -sfL https://get.rke2.io --output install.sh
|
部署安装
1
| INSTALL_RKE2_ARTIFACT_PATH=/root/images sh install.sh
|
执行此脚本,将自动对离线介质进行解压到对应目录。
接下来就跟在线安装一样,启动RKE2的进程,进行部署server和agent
启动rke2
设置rke2-server开机自启
1
| systemctl enable rke2-server.service
|
启动rke2-server
1
| systemctl start rke2-server.service
|
等待注册和集群启动
Private Registry
将镜像上传到镜像仓库
可以使用rancher的rancher-load-images.sh脚本结合rke2-images-all.linux-amd64.txt文件进行镜像上传。
下载rke2可执行文件rke2.linux-amd64.tar.gz
解压,将systemctl文件和rke2可执行文件复制到对应目录
1
| cp lib/systemd/system/* /usr/local/lib/systemd/system/
|
1
| cp bin/* /usr/local/bin/
|
1
| cp share/* /usr/local/share/ -rf
|
配置config.yaml,指定默认拉取镜像
1
| system-default-registry: xxx.xxx.xxx.xxx
|
若私有镜像仓库为http或自签名https需要在/etc/rancher/rke2 /registries.yaml
进行配置
但这里我配置的insecure-registry没有生效,具体issue查看:https://github.com/rancher/rke2/issues/2317
通过RKE2部署Kubernetes高可用实现原理
RKE2部署的Kubernetes和其他Kubernetes的组件需要HA的方式是一致的.
Kubernetes 集群的高可用是针对:
- etcd
- controller-manager
- scheduler
- apiserver
etcd:通过本身的 Raft 算法 Leader 选主机制,组成ETCD集群,实现 etcd 高可用。
controller manager:leader election 选举竞争锁的机制来保证高可用。
scheduler:leader election 选举竞争锁的机制来保证高可用。
apiserver:无状态,通过前端负载均衡实现高可用。
另外一个在于在rke2集群中,containerd、kubelet组件集成到了rke2服务中,这点和k3s非常相式,同时在rke2服务中还集成了nginx服务,主要用于做为kubelet连接api-server的方向代理。
HA的主要区别在于API-server统一入口,因为RKE2会帮助其他组件自动做HA,

当有统一入口时,跟kubeadm和其他原生Kubernetes一样,所有请求都会通过统一负载均衡器连接到后端的rke2-server。

如果api-server没有统一入口,kubelet和rke2-agent去连接rke2-server时,会用一个server地址去注册即可,然后agent会获取 所有rke2 server 的地址,然后存储到 /var/lib/rancher/rke2/agent/etc/rke2-api-server-agent-load-balancer.json中,生成nginx反向代理配置
比如:
1 2 3 4 5 6 7 8
| cat rke2-agent-load-balancer.json { "ServerURL": "https://192.168.3.10:9345", "ServerAddresses": [ "192.168.3.11:9345", "192.168.3.12:9345" ], "Listener": null
|
当192.168.3.10 挂掉之后,会自动切换到另一个rke2 server 去连接。当192.168.3.10恢复后,回重新连接192.168.3.10。
另外在前面也提到,rke2里面也集成了containerd,那么问题来了,如果rke2-agent进程出现问题down了,是否会影响平台上业务正常运行呢?
答案是,不会影响业务正常运行,因为containerd创建容器是通过containerd-shim-runc-v2调用runc创建,当containerd出现问题时containerd-shim-runc-v2会被init进程托管,不会导致退出影响现有业务POD。但需要注意的是rke2-agent退出后kubelet也退出了,对应的业务状态探测就没有了,在默认超时5分钟后,Controller-manager会将业务pod重建。
其他使用技巧
使用RKE2部署Kubernetes使用其他网络插件
默认情况下rke2部署使用的是canal做为网络插件,还支持calico和cilium网络插件,若想使用其他网络插件只需要进行配置即可。
如cilium
cilium依赖内核bfp特性,在启用前需要先进行挂载。
检查是否有进行挂载
1
| mount | grep /sys/fs/bpf
|
进行挂载
1 2 3 4
| sudo mount bpffs -t bpf /sys/fs/bpf sudo bash -c 'cat <<EOF >> /etc/fstab none /sys/fs/bpf bpf rw,relatime 0 0 EOF'
|
在次检查
1 2 3
| mount | grep /sys/fs/bpf bpffs on /sys/fs/bpf type bpf (rw,relatime) bpffs on /sys/fs/bpf type bpf (rw,relatime)
|
在start rke2-server和agent服务前先配置config.yaml
1 2
| mkdir -p /etc/rancher/rke2/ vim /etc/rancher/rke2/config.yaml
|
添加以下参数
启动rke2-server
1
| systemctl start rke2-server.service
|
查看是否部署成功
1 2 3 4 5 6 7 8
| kubectl get pod -A NAMESPACE NAME READY STATUS RESTARTS AGE kube-system cilium-6rfzw 1/1 Running 0 52s kube-system cilium-node-init-998vd 1/1 Running 0 52s kube-system cilium-operator-85f67b5cb7-nw7n8 1/1 Running 0 52s kube-system cilium-operator-85f67b5cb7-qc2vh 0/1 Pending 0 52s kube-system cloud-controller-manager-rke-node4 1/1 Running 0 65s kube-system etcd-rke-node4 1/1 Running 0 73s
|
组件参数配置
在/etc/rancher/rke2/config.yaml 文件中,按照对应组件,添加对应的参数,如apiserver对应为kube-apiserver-arg,组件对应参数为etcd-arg。kube-controller-manager-arg、kube-scheduler-arg、kubelet-arg、kube-proxy-arg。
1 2 3 4 5 6 7
| etcd-arg: - "quota-backend-bytes=858993459" - "max-request-bytes=33554432" kube-apiserver-arg: - "watch-cache=true" kubelet-arg: - "system-reserved=cpu=1,memory=2048Mi"
|
配置完成后启动rke2-server。agent节点要同步时配置,否则kubelet和kube-proxy参数将不生效
检查参数是否生效
如:
1
| ps aux|grep system-reserved
|
集群备份和还原
rke2备份文件保存在每个拥有etcd角色的节点的/var/lib/rancher/rke2/server/db/snapshots目录内,拥有多副本保存。
默认每隔12小时备份一次,保留5份。
注:目前版本只能通过定时备份,没有立刻备份的选型。
将
指定备份文件恢复
关闭rke2-server进程
1
| systemctl stop rke2-server
|
指定文件恢复
1 2 3
| rke2 server \ --cluster-reset \ --cluster-reset-restore-path=<PATH-TO-SNAPSHOT>
|
若是HA集群,还原成功后在其他server节点将执行rm -rf /var/lib/rancher/rke2/server/db
然后重新启动server,加入集群。
rke2跟rke1一样也支持将备份文件在一个新集群进行还原。
常见操作
参考链接:
https://gist.github.com/superseb/3b78f47989e0dbc1295486c186e944bf
查看本机运行的容器
ctr命令
1
| /var/lib/rancher/rke2/bin/ctr --address /run/k3s/containerd/containerd.sock --namespace k8s.io container ls
|
crictl命令
1 2
| export CRI_CONFIG_FILE=/var/lib/rancher/rke2/agent/etc/crictl.yaml /var/lib/rancher/rke2/bin/crictl ps
|
1
| /var/lib/rancher/rke2/bin/crictl --config /var/lib/rancher/rke2/agent/etc/crictl.yaml ps
|
1
| /var/lib/rancher/rke2/bin/crictl --runtime-endpoint unix:///run/k3s/containerd/containerd.sock ps -a
|
最终都是连接到containerd的socket文件
查看日志
1 2 3
| journalctl -f -u rke2-server /var/lib/rancher/rke2/agent/containerd/containerd.log /var/lib/rancher/rke2/agent/logs/kubelet.log
|
etcd操作
etcdctl check perf
1
| for etcdpod in $(kubectl -n kube-system get pod -l component=etcd --no-headers -o custom-columns=NAME:.metadata.name); do kubectl -n kube-system exec $etcdpod -- sh -c "ETCDCTL_ENDPOINTS='https://127.0.0.1:2379' ETCDCTL_CACERT='/var/lib/rancher/rke2/server/tls/etcd/server-ca.crt' ETCDCTL_CERT='/var/lib/rancher/rke2/server/tls/etcd/server-client.crt' ETCDCTL_KEY='/var/lib/rancher/rke2/server/tls/etcd/server-client.key' ETCDCTL_API=3 etcdctl check perf"; done
|
etcdctl endpoint status
1
| for etcdpod in $(kubectl -n kube-system get pod -l component=etcd --no-headers -o custom-columns=NAME:.metadata.name); do kubectl -n kube-system exec $etcdpod -- sh -c "ETCDCTL_ENDPOINTS='https://127.0.0.1:2379' ETCDCTL_CACERT='/var/lib/rancher/rke2/server/tls/etcd/server-ca.crt' ETCDCTL_CERT='/var/lib/rancher/rke2/server/tls/etcd/server-client.crt' ETCDCTL_KEY='/var/lib/rancher/rke2/server/tls/etcd/server-client.key' ETCDCTL_API=3 etcdctl endpoint status"; done
|
etcdctl endpoint health
1
| for etcdpod in $(kubectl -n kube-system get pod -l component=etcd --no-headers -o custom-columns=NAME:.metadata.name); do kubectl -n kube-system exec $etcdpod -- sh -c "ETCDCTL_ENDPOINTS='https://127.0.0.1:2379' ETCDCTL_CACERT='/var/lib/rancher/rke2/server/tls/etcd/server-ca.crt' ETCDCTL_CERT='/var/lib/rancher/rke2/server/tls/etcd/server-client.crt' ETCDCTL_KEY='/var/lib/rancher/rke2/server/tls/etcd/server-client.key' ETCDCTL_API=3 etcdctl endpoint health"; done
|
etcdctl compact
1 2
| rev=$(kubectl -n kube-system exec $(kubectl -n kube-system get pod -l component=etcd --no-headers -o custom-columns=NAME:.metadata.name | head -1) -- sh -c "ETCDCTL_ENDPOINTS='https://127.0.0.1:2379' ETCDCTL_CACERT='/var/lib/rancher/rke2/server/tls/etcd/server-ca.crt' ETCDCTL_CERT='/var/lib/rancher/rke2/server/tls/etcd/server-client.crt' ETCDCTL_KEY='/var/lib/rancher/rke2/server/tls/etcd/server-client.key' ETCDCTL_API=3 etcdctl endpoint status --write-out fields | grep Revision | cut -d: -f2") kubectl -n kube-system exec $(kubectl -n kube-system get pod -l component=etcd --no-headers -o custom-columns=NAME:.metadata.name | head -1) -- sh -c "ETCDCTL_ENDPOINTS='https://127.0.0.1:2379' ETCDCTL_CACERT='/var/lib/rancher/rke2/server/tls/etcd/server-ca.crt' ETCDCTL_CERT='/var/lib/rancher/rke2/server/tls/etcd/server-client.crt' ETCDCTL_KEY='/var/lib/rancher/rke2/server/tls/etcd/server-client.key' ETCDCTL_API=3 etcdctl compact \"$(echo $rev)\""
|
etcdctl defrag
1
| kubectl -n kube-system exec $(kubectl -n kube-system get pod -l component=etcd --no-headers -o custom-columns=NAME:.metadata.name | head -1) -- sh -c "ETCDCTL_ENDPOINTS='https://127.0.0.1:2379' ETCDCTL_CACERT='/var/lib/rancher/rke2/server/tls/etcd/server-ca.crt' ETCDCTL_CERT='/var/lib/rancher/rke2/server/tls/etcd/server-client.crt' ETCDCTL_KEY='/var/lib/rancher/rke2/server/tls/etcd/server-client.key' ETCDCTL_API=3 etcdctl defrag --cluster"
|
对应的,直接操作etcdctl
参考:https://gist.github.com/superseb/3b78f47989e0dbc1295486c186e944bf