安装版本:K3s (v1.21.7+k3s1)

参考站内 K3s 实践高可用架构图。

官方文档参考顺序(官方文档记录的顺序有点乱)

1
2
3
4
5
6
0. 查看对应版本: https://www.suse.com/suse-rancher/support-matrix/all-supported-versions/rancher-v2-6-3/
1. 基础架构: https://rancher.com/docs/rancher/v2.6/en/installation/resources/k8s-tutorials/infrastructure-tutorials/infra-for-ha-with-external-db/
2. 负载均衡: https://rancher.com/docs/rancher/v2.6/en/installation/resources/k8s-tutorials/infrastructure-tutorials/nginx/
3. 部署 K3s: https://rancher.com/docs/rancher/v2.6/en/installation/resources/k8s-tutorials/ha-with-external-db/
4. 安装 Helm 和 Rancher: https://rancher.com/docs/rancher/v2.6/en/installation/install-rancher-on-k8s/
5. 添加 TLS: https://rancher.com/docs/rancher/v2.6/en/installation/resources/tls-secrets/

关于 Datastore 的选择

K3s 的 server 节点既是 master 也是 node,所以官方案例中只要两个 server 节点就可以做到高可用,但前提是使用非 etcd 数据源作为 datastore。

K3s 既支持外部数据源,官方也内置了 etcd 和 SQLite3,此部分可参考 https://docs.rancher.cn/docs/k3s/installation/ha-embedded/_index/

如果使用官方内置 etcd,可将配置替换如下:

master1

1
2
3
4
# 1. 去掉 K3S_DATASTORE_ENDPOINT
# export K3S_DATASTORE_ENDPOINT="mysql://root:xxx/k3s"
# 2. 如果不加 K3S_CLUSTER_INIT,则使用的是 SQLite3
export K3S_CLUSTER_INIT=true

master2/3...

1
2
3
4
5
# 1. 去掉 K3S_DATASTORE_ENDPOINT
# export K3S_DATASTORE_ENDPOINT="mysql://root:xxx/k3s"
# 2. 对于其他 master 节点,需要加 K3S_URL (master1 的 ip/host) 和 K3S_TOKEN
export K3S_TOKEN=XXX
export K3S_URL="https://xxx:6443"

主 Server

编辑 /etc/profile,在最末尾添加数据库连接(自行替换数据库连接参数,参考:https://rancher.com/docs/k3s/latest/en/installation/install-options/)

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
39
40
41
42
43
44
# 外部 MySQL 源
export K3S_DATASTORE_ENDPOINT="mysql://root:root@tcp(192.168.56.103:3306)/k3s_xiaowu"
# 外部 etcd 源
# export K3S_DATASTORE_ENDPOINT="https://10.0.0.60:2379,https://10.0.0.61:2379,https://10.0.0.62:2379"
# export K3S_DATASTORE_CAFILE='/etc/etcd/etcd-ca.crt'
# export K3S_DATASTORE_CERTFILE='/etc/etcd/server.crt'
# export K3S_DATASTORE_KEYFILE='/etc/etcd/server.key'

# KUBECONFIG: 解决 k3s 执行 helm 命令报错
# Error: Kubernetes cluster unreachable: Get "http://localhost:8080/version?timeout=32s": dial tcp [::1]:8080: connect: connection refused
# helm v3 版本不再需要 Tiller,而是直接访问 ApiServer 来与 k8s 交互,通过环境变量 KUBECONFIG 来读取存有 ApiServer 的地址与 token 的配置文件地址,默认地址为 ~/.kube/config
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
export INSTALL_K3S_VERSION=v1.21.7+k3s1

# 自定义安装执行项
# 如果将 K3s 服务器置于外部负载均衡器之后,应该在服务器上使用 --tls-san 标志将负载均衡器的主机名和/或 IP 地址添加到证书中
# 否则集群证书不认 rancher.k3s.cn 或者对应的 IP,可能会出现如下错误:Unable to connect to the server: x509: certificate is valid for xxx, xxx, xxx, xxx, 127.0.0.1, not rancher.k3s.cn
# 注:如果不使用 IPVS 模式部署(默认 iptables),将带有 kube-proxy-arg 的几行去掉
# max-pods: 默认单 node 110 个 pod
# --kube-apiserver-arg service-node-port-range: 端口范围
# --kube-proxy-arg --ipvs-scheduler=rr: 设置 IPVS 的负载均衡算法,默认是 rr
# --kube-proxy-arg --ipvs-min-sync-period=5s: 刷新 IPVS 规则的最小时间间隔
# --kube-proxy-arg --ipvs-sync-period=30s: 刷新 IPVS 规则的最大时间间隔
# --egress-selector-mode=disabled: 该 exec 参数可以参见 https://github.com/k3s-io/k3s/issues/5897
# --kube-apiserver-arg service-node-port-range: node port 范围,默认 30000-32767

# 启动 kubelet 的时候,可以配置这些参数控制镜像清理的策略:
# image-gc-high-threshold:磁盘使用率的上限,当达到这一使用率的时候会触发镜像清理。默认值为 90%
# image-gc-low-threshold:磁盘使用率的下限,每次清理直到使用率低于这个值或者没有可以清理的镜像了才会停止。默认值为 80%
# minimum-image-ttl-duration:镜像至少这么久没有被使用才会被清理,可以使用 h(小时)、m(分钟)、s(秒)和 ms(毫秒)时间单位进行配置,默认是 2m(两分钟)
# 默认情况下,当镜像占满所在盘 90% 容量的时候,kubelet 就会进行清理,一直到镜像占用率低于 80% 为止

export INSTALL_K3S_EXEC="server \
--tls-san rancher.k3s.cn \
--kube-proxy-arg proxy-mode=ipvs \
--kube-proxy-arg ipvs-scheduler=lc \
--kube-proxy-arg ipvs-min-sync-period=5s \
--kube-proxy-arg ipvs-sync-period=30s \
--kube-proxy-arg masquerade-all=true \
--kube-proxy-arg metrics-bind-address=0.0.0.0 \
--kubelet-arg max-pods=110 \
--kubelet-arg=image-gc-high-threshold=90 \
--kubelet-arg=image-gc-low-threshold=80 \
--kube-apiserver-arg service-node-port-range=30000-40000"

执行:

1
2
3
4
5
source /etc/profile
# 记录下两个国内源
# https://rancher-mirror.rancher.cn/k3s/k3s-install.sh
# https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh
curl -sfL https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -

配置镜像加速(小记:第一个 >> 是追加,> 是覆盖):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cat > /etc/rancher/k3s/registries.yaml <<EOF
mirrors:
"x.x.x.x:5000":
endpoint:
- "http://x.x.x.x:5000"
"docker.io":
endpoint:
# 如果是腾讯云主机,推荐使用:https://mirror.ccs.tencentyun.com
- "https://0vlzmqf0.mirror.aliyuncs.com"
configs:
"x.x.x.x:5000":
auth:
username: x
password: x
EOF

重启服务:

1
2
3
systemctl restart k3s
# 或者
systemctl restart k3s-agent

查看主 server 节点 token,需要留给之后的副 server 节点和 agent 节点使用:

1
cat /var/lib/rancher/k3s/server/node-token

副 Server

编辑 /etc/profile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
export K3S_TOKEN="添加上面 server 节点的 node-token"
# 外部 MySQL 源
export K3S_DATASTORE_ENDPOINT="mysql://root:root@tcp(192.168.56.103:3306)/k3s_xiaowu"
# 外部 etcd 源
# export K3S_DATASTORE_ENDPOINT="https://10.0.0.60:2379,https://10.0.0.61:2379,https://10.0.0.62:2379"
# export K3S_DATASTORE_CAFILE='/etc/etcd/etcd-ca.crt'
# export K3S_DATASTORE_CERTFILE='/etc/etcd/server.crt'
# export K3S_DATASTORE_KEYFILE='/etc/etcd/server.key'
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
export INSTALL_K3S_VERSION=v1.21.7+k3s1

# 自定义安装执行项(同主 server)
export INSTALL_K3S_EXEC="server \
--tls-san rancher.k3s.cn \
--kube-proxy-arg proxy-mode=ipvs \
--kube-proxy-arg ipvs-scheduler=rr \
--kube-proxy-arg ipvs-min-sync-period=5s \
--kube-proxy-arg ipvs-sync-period=30s \
--kube-proxy-arg masquerade-all=true \
--kube-proxy-arg metrics-bind-address=0.0.0.0 \
--kubelet-arg max-pods=110 \
--kube-apiserver-arg service-node-port-range=30000-40000"

执行:

1
2
source /etc/profile
curl -sfL https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -

配置镜像加速(同主 server

Agent 执行(之后再加 agent 节点也像这样执行)

编辑 /etc/profile

1
2
3
4
5
6
7
8
9
10
11
12
13
export K3S_TOKEN="添加上面 server 节点的 node-token"
# server 节点的地址,端口默认为 6443
# 必须使用 HTTPS 协议,且内网 IP,这里填 nginx_lb 的 IP:Only https:// URLs are supported for K3S_URL ip address
# 一定要保证证书内 trust IPs 内包含 master 节点参数 tls-san 对应的 lb-ip
export K3S_URL="主节点 URL:6443 或者配置的 loadbalance 地址(对应着 tls-san)"
export INSTALL_K3S_VERSION=v1.21.7+k3s1

# 自定义安装执行项,如果配置了 K3S_URL,默认是 agent exec 执行命令,否则是 server
export INSTALL_K3S_EXEC="agent \
--kube-proxy-arg proxy-mode=ipvs \
--kube-proxy-arg masquerade-all=true \
--kube-proxy-arg metrics-bind-address=0.0.0.0 \
--kubelet-arg max-pods=110"

执行:

1
2
source /etc/profile
curl -sfL https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -

创建配置目录并配置镜像加速:

1
2
mkdir -p /etc/rancher/k3s
touch /etc/rancher/k3s/registries.yaml

配置镜像加速(同主 server

检查

为 agent 节点添加标签(加上 worker ROLES),默认标签展示 none:

1
kubectl label node k3s-agent1 node-role.kubernetes.io/worker=worker

在任一 server 节点执行:

1
2
kubectl get nodes
kubectl get pods --all-namespaces

负载均衡 kubectl(此示例是结合 Nginx 配置负载 kubectl)

安装 Nginx 并配置 stream

1
2
3
4
5
6
7
8
9
10
11
12
13
# 这里配置的是 server 节点的 6443 端口
stream {
upstream k3s {
least_conn;
server 10.0.2.17:6443 max_fails=3 fail_timeout=5s;
server 10.0.2.16:6443 max_fails=3 fail_timeout=5s;
server 10.0.2.15:6443 max_fails=3 fail_timeout=5s;
}
server {
listen 6443;
proxy_pass k3s;
}
}

配置 kubectl

  1. /etc/rancher/k3s/k3s.yaml 文件放置在位于集群外部的计算机上,路径为 ~/.kube/config,然后将该 server 字段的值替换为 K3s 服务器的 IP 或名称(此示例填写的 <nginx 服务器所属 IP>:6443
  2. 安装 kubectl,参考站内 kubectl 的安装
  3. 编辑 ~/.kube/config
1
2
3
4
5
6
7
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: [CERTIFICATE-DATA]
server: rancher.k3s.cn:6443 # Edit this line,修改成负载均衡器的主机名和/或 IP 地址
name: default
...

进入 Helm 的安装篇

进入 kubectl 的安装篇