参考官网链接: https://docs.rancher.cn/docs/k3s/upgrades/_index/

注:如果要对server/master节点升级,绝对不要在流量高峰场景下进行

如果不希望清理所有容器及网络组件,不要轻易使用k3s-killall.sh脚本

官方文档描述升级过程为高可用模式,但最好还是在流量低峰期进行升级

否则可能会导致部署单元多个pod都部署在同一节点, 然后进行了pod转移, 如下

k8s在1.22版本新增了安全sysctlc参数net.ipv4.ip_unprivileged_port_start, 且需要将内核版本升级至4.4以上: https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/#enabling-unsafe-sysctls

我的sysctl配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 将桥接的IPV4流量传递到iptables的链, Disable the swap...
cat > /etc/sysctl.d/k3s.conf << EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
# 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭
net.ipv4.tcp_tw_recycle = 0
# 关闭swap虚拟内存
vm.swappiness = 0
# 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
vm.overcommit_memory = 1
# 内存不足时,启动 OOM killer
vm.panic_on_oom = 0
# 运行非特权用户使用端口从0开始,k8s1.22以上版本支持此参数,且内核支持版本需要大于4.4
net.ipv4.ip_unprivileged_port_start=0
# 禁用ipv6
net.ipv6.conf.all.disable_ipv6=1
net.ipv6.conf.default.disable_ipv6=1
net.ipv6.conf.lo.disable_ipv6=1
EOF

linux内核升级, 参考站内: linux内核升级过程篇

k3s进行基础升级

Server节点

  • 修改/etc/profile
1
2
3
4
5
6
7
8
9
10
11
12
# k3s
export K3S_CLUSTER_INIT=true
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
# 修改版本号
#export INSTALL_K3S_VERSION=v1.21.7+k3s1
export INSTALL_K3S_VERSION=v1.24.3+k3s1
export INSTALL_K3S_EXEC="server \
# 此参数是在v1.24.1+k3s之后新增的, 参考issue: https://github.com/k3s-io/k3s/issues/5637
--egress-selector-mode=disabled \
--tls-san rancher.k3s.cn \
--kubelet-arg max-pods=300 \
--kube-apiserver-arg service-node-port-range=30000-40000"

Agent节点

  • 修改/etc/profile
1
2
3
4
5
6
7
8
#k3s
export K3S_TOKEN="K10ed88cf924226d11ff411a8d5797fcad4dce224a4888442bcac7aad85f24abbf6::server:95845805df4dfe5d6acaee084f650f5f"
export K3S_URL="https://rancher.k3s.cn:6443"
# 修改版本号
#export INSTALL_K3S_VERSION=v1.21.7+k3s1
export INSTALL_K3S_VERSION=v1.24.3+k3s1
export INSTALL_K3S_EXEC="agent \
--kubelet-arg max-pods=300"

k3s进行自动升级 - system-upgrade-controller

如果 K3s 集群由 Rancher 管理,切记不要安装system-upgrade-controller,而是使用 Rancher UI 来管理升级。

  • 如果 K3s 集群是导入到 Rancher 的,Rancher 将管理 system-upgrade-controller 部署和计划。不需要安装system-upgrade-controller
  • 如果 K3s 集群是由 Rancher 预配的,Rancher 将使用系统 Agent 来管理版本升级。不需要安装system-upgrade-controller
  • 如果 K3s 集群不是由 Rancher 管理的,可以使用system-upgrade-controller

参考:https://docs.rancher.cn/docs/k3s/upgrades/automated/_index

适用于自建 k3s 集群,使用 Rancher 的 system-upgrad-controller 来管理手动/自动升级。

总共需要完成两步配置:

  1. 安装 system-upgrade-controller,会在集群内创建名为 plans.upgrade.cattle.io 的 CRD
  2. 配置更新计划。这里可以使用自动发现 release 模式,保证实时更新到最新版本,同时也可以创建升级到指定版本的一次性更新计划。

安装 system-upgrade-controller

联网执行一句话:

1
kubectl apply -f https://github.com/rancher/system-upgrade-controller/releases/latest/download/system-upgrade-controller.yaml

更新配置存储在 configmap,默认配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: v1
data:
SYSTEM_UPGRADE_CONTROLLER_DEBUG: "false"
SYSTEM_UPGRADE_CONTROLLER_THREADS: "2"
SYSTEM_UPGRADE_JOB_ACTIVE_DEADLINE_SECONDS: "900"
SYSTEM_UPGRADE_JOB_BACKOFF_LIMIT: "99"
SYSTEM_UPGRADE_JOB_IMAGE_PULL_POLICY: Always
SYSTEM_UPGRADE_JOB_KUBECTL_IMAGE: rancher/kubectl:v1.25.4
SYSTEM_UPGRADE_JOB_PRIVILEGED: "true"
SYSTEM_UPGRADE_JOB_TTL_SECONDS_AFTER_FINISH: "900"
SYSTEM_UPGRADE_PLAN_POLLING_INTERVAL: 15m
kind: ConfigMap
metadata:
name: default-controller-env
namespace: system-upgrade

创建更新计划

按照官方文档说法,推荐使用两份计划,分别对应 server(master) 和 agent(worker) 节点的升级。

按照版本升级配置示例:

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
45
# Server plan
apiVersion: upgrade.cattle.io/v1
kind: Plan
metadata:
name: server-plan
namespace: system-upgrade
spec:
concurrency: 1 # 指定同时升级的节点个数
cordon: true # 升级禁止调度
nodeSelector:
matchExpressions:
- key: node-role.kubernetes.io/master # 指定 master 节点
operator: In
values:
- "true"
serviceAccountName: system-upgrade
upgrade:
image: rancher/k3s-upgrade
version: v1.25.16+k3s4 # 指定版本,也可替换为下面地址,自动升级到最新的 stable 版本
# channel: https://update.k3s.io/v1-release/channels/stable
# https://update.k3s.io/v1-release/channels:该地址可查看所有可更新的版本
---
# Agent plan
# 同名字段意义同上
apiVersion: upgrade.cattle.io/v1
kind: Plan
metadata:
name: agent-plan
namespace: system-upgrade
spec:
concurrency: 1
cordon: true
nodeSelector:
matchExpressions:
- key: node-role.kubernetes.io/master
operator: DoesNotExist
prepare:
args:
- prepare
- server-plan # 这里配置意思是等待 server-plan 计划结束后再执行升级
image: rancher/k3s-upgrade
serviceAccountName: system-upgrade
upgrade:
image: rancher/k3s-upgrade
version: v1.25.16+k3s4

查看升级进度:

1
2
kubectl -n system-upgrade get plans -o yaml
kubectl -n system-upgrade get jobs -o yaml

使用Rancher管理k3s版本

  • 进入Rancher首页
  • 点击Manage
  • 选择对应集群,并点击Edit Config,随后会跳至此页面
  • 该计划会先更新master,再更新node
  • 修改完配置后点击Save,然后集群会默认安装system-upgrade-controller,每更新一个节点时会将其置为Cordoned状态【并打上污点node.kubernetes.io/unschedulable=:NoSchedulenode.kubernetes.io/unreachable=:NoSchedulenode.kubernetes.io/unreachable=:NoExecute】,同时集群节点的更新状态会以如下方式展示
  • 更新过程中不会影响正在运行的服务,但保险起见,尽量选择一个非流量高峰期
  • 不需要关心节点在更新前是否配置了污点
  • 更新过程中会在每个节点部署以apply-k3s-worker-plan-on-开头的pod,此类pod会保持一段时间的Ready状态,不需要过多关心
  • 完成更新的节点会被打上以 plan.upgrade.cattle.io/k3s-{master/worker}-plan=开头的Label

问题

参考:https://github.com/k3s-io/k3s/issues/6869

helm-install-traefik-h5gjd with errors in log

1
Error: UPGRADE FAILED: rendered manifests contain a resource that already exists. Unable to continue with update: IngressRoute "traefik-dashboard" in namespace "kube-system" exists and cannot be imported into the current release: invalid ownership metadata; annotation validation error: missing key "meta.helm.sh/release-name": must be set to "traefik"; annotation validation error: missing key "meta.helm.sh/release-namespace": must be set to "kube-system"

解决办法:annotations补充缺失的missing key

1
2
3
4
5
6
7
8
9
# kubectl edit ingressroutes.traefik.containo.us -n kube-system traefik-dashboard

metadata:
annotations:
......
meta.helm.sh/release-name: traefik
meta.helm.sh/release-namespace: kube-system

# ingressroute.traefik.containo.us/traefik-dashboard edited