搭建高可用K3S集群
k3s是经CNCF一致性认证的Kubernetes发行版,专为物联网及边缘计算设计。
1 k3s单机
# 定义安装参数
export INSTALL_K3S_VERSION=v1.18.9+k3s1
export INSTALL_K3S_EXEC="--docker --kube-apiserver-arg service-node-port-range=1-65000 --no-deploy traefik --write-kubeconfig ~/.kube/config --write-kubeconfig-mode 666"
# 安装
sudo curl -sfL http://rancher-mirror.cnrancher.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -
2 集群规划
- MySQL,LB,Rancher UI单独部署
- 3个master节点,实现最基本的
K3S-Server
冗余 - 2个worker节点,通过LB 接入master节点
数据库也可以做HA LB 只需要支持4层负载均衡,此处使用
nginx
服务器 | 用途 | 配置 | IP |
---|---|---|---|
k3s-lb | LB/Rancher UI/MySQL | 2C4G | 10.11.12.100 |
k3s-m1 | K3S-Server(master 节点) | 1C2G | 10.11.12.101 |
k3s-m2 | K3S-Server(master 节点) | 1C2G | 10.11.12.102 |
k3s-m3 | K3S-Server(master 节点) | 1C2G | 10.11.12.103 |
k3s-worker1 | K3S-Agent(worker 节点) | 2C2G | 10.11.12.104 |
k3s-worker2 | K3S-Agent(worker 节点) | 2C2G | 10.11.12.105 |
- 操作系统:
CentOS 7.6
,Alpine 3.12
也实验通过- Docker Version: 19.03.9
2.1 架构图
高可用架构图
对比一下单机版架构图
3 OS 准备
全新系统,主要是安装
docker
,并配置加速镜像,以及一些内核参数优化。
登录每一个服务器,修改对应的机器名
hostnamectl --static set-hostname k3s-lb && hostnamectl set-hostname k3s-lb
hostnamectl --static set-hostname k3s-m1 && hostnamectl set-hostname k3s-m1
hostnamectl --static set-hostname k3s-m2 && hostnamectl set-hostname k3s-m2
hostnamectl --static set-hostname k3s-m3 && hostnamectl set-hostname k3s-m3
hostnamectl --static set-hostname k3s-worker1 && hostnamectl set-hostname k3s-worker1
hostnamectl --static set-hostname k3s-worker2 && hostnamectl set-hostname k3s-worker2
4 节点安装配置
4.1 k3s-lb
安装MySQL(已有MySQL可忽略)
docker run -d \
--name k3s-mysql \
--restart=always \
-v /data/k3s-cluster/mysql/conf:/etc/mysql/conf.d \
-v /data/k3s-cluster/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-p 3306:3306 \
mysql:5.7.29 \
--default-time-zone=+8:00
安装 Rancher UI
docker run -d \
--restart=unless-stopped \
--name rancher-server \
-v /data/rancher/:/var/lib/rancher/ \
-p 8088:80 -p 8443:443 \
--privileged \
rancher/rancher:stable
与 2.4.x 或之前的版本相比,使用docker run
命令安装 Rancher 2.5.x 时,需要添加--privileged
标志变量,启用特权模式安装 Rancher。
你需要记下这个容器的运行参数,升级的时候还会用到(如果忘记,可以
docker inspect rancher-server
查看)。访问地址 https://10.11.12.100:8443
安装Nginx(略)
注意:编译时需要添加stream模块
配置 nginx ,添加stream配置
events {
# ....
}
http {
# ...
}
# 新加的部分
stream {
upstream k3s {
server 10.11.12.101:6443;
server 10.11.12.102:6443;
server 10.11.12.103:6443;
}
server {
listen 6443;
proxy_pass k3s;
}
}
4.2 master 节点
配置 host (/etc/hosts
)
echo "10.11.12.100 k3s-mysql-server" >> /etc/hosts
安装K3S-Server,使用开始创建的用户运行(不要使用root用户执行)
4.2.1 最简单的方式
curl -sfL http://rancher-mirror.cnrancher.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -s - server \
--datastore-endpoint="mysql://root:root@tcp(k3s-mysql-server:3306)/database-name"
4.2.2 高级玩法
INSTALL_K3S_VERSION=v1.19.9+k3s1
从 Github 下载 K3s 的版本。如果没有指定,将尝试从"stable"频道下载。INSTALL_K3S_EXEC='args'
为 k3s 提供其他参数。
# 定义安装参数
export INSTALL_K3S_VERSION=v1.19.9+k3s1
export INSTALL_K3S_EXEC="--datastore-endpoint mysql://root:root@tcp(k3s-mysql-server:3306)/k3s \
--docker \
--kube-apiserver-arg service-node-port-range=1-65000 \
--kube-proxy-arg proxy-mode=ipvs \
--no-deploy traefik \
--write-kubeconfig ~/.kube/config \
--write-kubeconfig-mode 644 \
--node-taint k3s-controlplane=true:NoExecute"
参数说明:
--datastore-endpoint value # 指定 etcd、Mysql、Postgres 或 Sqlite(默认)数据源名称
--docker # 用docker代替containerd
--kube-proxy-arg value # 自定义 kube-proxy 进程的参数
--kube-apiserver-arg value # 自定义kube-apiserver进程的参数
--no-deploy value # 不需要部署的组件 (有效选项: coredns, servicelb, traefik, local-storage, metrics-server)
--write-kubeconfig value # 将管理客户端的kubeconfig写入这个文件
--write-kubeconfig-mode # 用这种模式编写kubeconfig,例如:644
--node-taint value # 用一组污点注册kubelet
安装
curl -sfL http://rancher-mirror.cnrancher.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -
执行命令后,使用
kubectl get nodes
查看状态,如果成功能看到3个节点 如需重新安装可以卸载脚本/usr/local/bin/k3s-uninstall.sh
4.2.3 注意事项
默认情况下,k3s 启动 master 节点也同时具有 worker 角色,是可调度的,因此可以在它们上启动工作
4.2.3.1 解决方案
1、通过 --node-taint
curl -sfL http://rancher-mirror.cnrancher.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn INSTALL_K3S_EXEC="--node-taint k3s-controlplane=true:NoExecute" sh -
–node-taint key1=value1:NoExecute NoSchedule: 不调度 PreferNoSchedule: 尽量不调度 NoExecute: 不调度并且立即驱逐节点上现存pod
2、通过 --disable-agent
curl -sfL http://rancher-mirror.cnrancher.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn INSTALL_K3S_EXEC="--disable-agent" sh -
去除taint
kubectl describe node k3s-m1 | grep Taint
kubectl taint nodes k3s-m1 k3s-controlplane:NoExecute-
更多参数参考:K3s Server 配置参考的K3s Server CLI 帮助
4.3 worker 节点
先登录任意一个master节点,查看node-token
cat /var/lib/rancher/k3s/server/node-token
在worker节点上执行,使用开始创建的用户(不要使用root用户执行)
export K3S_TOKEN={node-token的内容}
# export K3S_TOKEN=K106f30302c8e0e3e07a4476d8add6712043c154b668e1f4f8c128c2687c5b994a6::server:5b5e57722986d80b8d2db3b75064709a
export INSTALL_K3S_VERSION=v1.19.9+k3s1
# LB的地址
export K3S_URL=https://10.11.12.100:6443
export INSTALL_K3S_EXEC="--docker \
--kube-proxy-arg proxy-mode=ipvs"
参数说明:
--docker # 用docker代替containerd
--kube-proxy-arg value # 自定义 kube-proxy 进程的参数
更多参数参考:K3s Agent配置参考的K3s Agent CLI 帮助
安装
curl -sfL http://rancher-mirror.cnrancher.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -
执行命令后,在master节点使用
kubectl get nodes
查看状态,如果成功能看到新的节点如需重新安装可以卸载脚本
/usr/local/bin/k3s-agent-uninstall.sh
K3s worker 节点的角色默认为none,添加标签
kubectl label node ${node} node-role.kubernetes.io/worker=worker
kubectl label node k3s-worker1 node-role.kubernetes.io/worker=worker
删除Label
kubectl describe node k3s-worker1 |grep Labels
kubectl label nodes k3s-worker1 k3s-worker1-
4.3.1 节点注册失败
为什么会出现passwd不一致呢?正常来说如果用k3s-agent-uninstall.sh
来清理安装过的 agent node,并不会删除password文件(/etc/rancher/node/password
),那么问题很可能是VM重建或者手动操作删除的这个文件。因为agent上删除了password,agent再次注册时会重新生成password,就导致了新的password和server上原先存储的不一致。
解决办法可以有三种:
- 手动在agent上创建password,内容和server中存储保持一致
- 修改了server中的原始内容,让password和agent上新生成的保持一致
- 可以试试agent注册时使用
--with-node-id
,这样server中认为这完全是新node,不会用原始信息比对
4.4 配置kubectl
k3s安装时已自动安装kubectl命令行工具
因为使用的是 k3s 集群需要指定kubeconfig
的位置或者将文件复制到~/.kube/config
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
4.5 Helm配置
Helm 是 kubernetes 非常好用的软件管理工具
本次安装 helm3
4.5.1 使用官方提供的脚本一键安装
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
4.5.2 手动下载安装
从官网下载最新版本的二进制安装包到本地(推荐用迅雷下载后上传服务器)
curl -O https://get.helm.sh/helm-v3.3.4-linux-amd64.tar.gz
tar -zxf helm-v3.3.4-linux-amd64.tar.gz
cd linux-amd64/
cp helm /usr/local/bin/
验证
helm version
测试一下,创建一个Chart
helm create hello-helm
tree hello-helm
为了测试方便,我们把 Service 的类型改成 NodePort。安装一下这个 Chart 。在 Helm 2 中,如果没有指定 release 的名称,则会自动随机生成一个名称。但是在 Helm 3 中,则必须主动指定名称,或者增加--generate-name
的参数。
helm install ./hello-helm --generate-name
等到 Pod 创建完成后,我们可以根据创建的 Service 的 NodePort 来访问该服务了,然后在浏览器中 打开 http://10.11.12.101:49641
4.6 集群导入
为了方便使用,可用rancher管理面板来简化集群管理工作
打开Rancher UI (https://10.11.12.100:8443
),选择导入集群,我们会得到导入K3S集群所需的命令,请保存好第三条命令以备后用。 为什么不是第二条?因为目前访问HTTPS API使用的是自签证书,直接用第二条会产生证书不信任的报错。复制生成的命令,在其中一台master 节点上执行即可。
4.7 证书过期问题
在证书有效期小于90天时,K3S会自动进行续期。
Certificates rotate automatically if they are <90 days from expiration when k3s is started. This has been the case since v0.10: #805
As long as you are patching and restarting your k3s infrastructure at least every couple months, you shouldn’t run into expired certificates.
4.8 升级
节点(K3S-Server
,K3S-Agent
)支持手动升级和自动升级,更换版本号,使用相同的参数再次执行安装脚本即可
Rancher UI升级(就是那个rancher/rancher
的容器),重新拉取新版本镜像版本即可,最好先备份
# 停止容器
docker stop rancher-server
# 备份数据
docker create --volumes-from rancher-server --name rancher-data rancher/rancher:stable
docker run --volumes-from rancher-data -v $PWD:/backup busybox tar zcvf /backup/rancher-data-backup-<RANCHER_VERSION>-<DATE>.tar.gz /var/lib/rancher
# 重新拉取镜像
docker pull rancher/rancher:stable
# 然后使用之前相同参数,重新 docker run
参考 https://rancher.com/docs/rancher/v2.x/en/upgrades/upgrades/single-node/