# K8S从1.15.x(1.16.x)升级到 1.16.x
参考文档: kubernetes 文档 kubeadm upgrade (opens new window)
【漏洞详情】
2019年10月17日,Kubernetes发布漏洞公告 [ANNOUNCE] CVE-2019-11253: denial of service vulnerability from malicious YAML or JSON payloads (opens new window)。具备一定权限的攻击者通过发送恶意的 YAML 或 JSON 格式的攻击包可导致 kube-apiserver CPU 或内存资源耗尽,无法正常提供服务,1.14.0 之前的版本由于默认RBAC策略允许匿名用户提交请求,所以之前的版本均在影响范围。
【风险等级】
高风险
【影响版本】
- Kubernetes v1.0.0-1.12.x
- Kubernetes v1.13.0-1.13.11(v1.13.12版本已修复)
- Kubernetes v1.14.0-1.14.7(v1.14.8版本已修复)
- Kubernetes v1.15.0-1.15.4(v1.15.5版本已修复)
- Kubernetes v1.16.0-1.16.1(v1.16.2版本已修复)
【安全版本】
- Kubernetes v1.13.12
- Kubernetes v1.14.8
- Kubernetes v1.15.5
- Kubernetes v1.16.2
【修复建议】
请升级到对应的【安全版本】。本文提供了如何升级到 1.16.2 的方法。另可参考 K8S从1.15.x升级到 1.15.5
本文描述了如何从 kubernetes v1.15.x(或1.16.x)升级到 Kubernetes v1.16.y,前提是,您的 Kubernetes 集群是使用 kubeadm 安装的。
升级的高阶过程如下所示:
- 升级主 master 节点
- 升级从 master 节点
- 升级 worker 节点
# 预备工作
- 请确保您的 Kubernetes 集群是通过 kubeadm 安装的,且版本号不低于 1.15.0
- swap 已禁用(如果您参考 www.kuboard.cn 上的文档安装,swap已禁用)
- 集群使用静态Pod(apiserver、etcd)或者使用外部 etcd(如果您参考 www.kuboard.cn 上的文档安装,则您的集群符合此条件)
- 确保您备份了重要的信息,例如应用程序的数据库,部署配置信息等。
kubeadm upgrade
在升级过程中并不涉及到部署在 Kubernetes 上应用程序,而是只升级 Kubernetes 的内部组件,尽管如此,备份始终是推荐的
TIP
- 升级后,所有的容器都会重启,因为升级改变了容器定义的 hash 值
- 只能从一个小版本升级到下一个小版本,或者在小版本内部升级补丁版本,不能跳过小版本升级。例如,您可以从 1.15.0 升级到 1.15.4,也可以从 1.15.0 升级到 1.16.1,但是您不能从 1.14.9 升级到 1.16.0
# 确定当前版本
在 CentOS 上执行:
yum list --showduplicates kubeadm --disableexcludes=kubernetes
# 在列表中找到最新的 1.16 版本号
# 该版本号格式为 1.16.x-0,其中 x 是最新的补丁
2
3
# 升级 master 节点
# 升级第一个 master 节点
假设所有命令都以 root 身份执行
在第一个 master 节点上执行如下命令,升级 kubeadm
# 将 1.16.x-0 中的 x 替换为最新的补丁版本 yum install -y kubeadm-1.16.x-0 --disableexcludes=kubernetes
1
2执行命令
kubeadm version
,以验证升级结果替换 1.16.x 中的 x
本文中,所有碰到 1.16.x 的地方,都要将其中的 x 替换为您前面查询到的最新补丁号
在第一个 master 节点上执行命令
kubeadm upgrade plan
,输出结果如下所示:[upgrade/config] Making sure the configuration is correct: [upgrade/config] Reading configuration from the cluster... [upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml' [preflight] Running pre-flight checks. [upgrade] Making sure the cluster is healthy: [upgrade] Fetching available versions to upgrade to [upgrade/versions] Cluster version: v1.15.4 [upgrade/versions] kubeadm version: v1.16.0 W1002 21:49:38.572516 14315 version.go:101] could not fetch a Kubernetes version from the internet: unable to get URL "https://dl.k8s.io/release/stable.txt": Get https://dl.k8s.io/release/stable.txt: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) W1002 21:49:38.572555 14315 version.go:102] falling back to the local client version: v1.16.0 [upgrade/versions] Latest stable version: v1.16.0 W1002 21:49:48.655494 14315 version.go:101] could not fetch a Kubernetes version from the internet: unable to get URL "https://dl.k8s.io/release/stable-1.15.txt": Get https://dl.k8s.io/release/stable-1.15.txt: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) W1002 21:49:48.655532 14315 version.go:102] falling back to the local client version: v1.16.0 [upgrade/versions] Latest version in the v1.15 series: v1.16.0 Components that must be upgraded manually after you have upgraded the control plane with 'kubeadm upgrade apply': COMPONENT CURRENT AVAILABLE Kubelet 1 x v1.15.3 v1.16.0 3 x v1.15.4 v1.16.0 Upgrade to the latest version in the v1.15 series: COMPONENT CURRENT AVAILABLE API Server v1.15.4 v1.16.0 Controller Manager v1.15.4 v1.16.0 Scheduler v1.15.4 v1.16.0 Kube Proxy v1.15.4 v1.16.0 CoreDNS 1.3.1 1.6.2 Etcd 3.3.10 3.3.15-0 You can now apply the upgrade by executing the following command: kubeadm upgrade apply v1.16.0 _____________________________________________________________________
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
35TIP
- 请忽略错误
could not fetch a Kubernetes version from the internet: unable to get URL "https://dl.k8s.io/release/stable.txt"
,在不能获得最新 kubernetes 版本列表的情况下,将使用 kubeadm 的版本作为升级的目标版本(在前面的步骤中,已经从 yum 仓库找到了最新 kubeadm 的版本)
- 请忽略错误
执行如下命令以升级:
# 替换 x 为最新补丁的版本号 kubeadm upgrade apply v1.16.x
1
2TIP
kubeadm upgrade
同时会自动更新节点上的证书。如果不想更新证书,请使用参数--certificate-renewal=false
输出信息如下所示:
[upgrade/config] Making sure the configuration is correct: [upgrade/config] Reading configuration from the cluster... [upgrade/config] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml' [preflight] Running pre-flight checks. [upgrade] Making sure the cluster is healthy: [upgrade/version] You have chosen to change the cluster version to "v1.16.0" [upgrade/versions] Cluster version: v1.15.4 [upgrade/versions] kubeadm version: v1.16.0 [upgrade/confirm] Are you sure you want to proceed with the upgrade? [y/N]: y [upgrade/prepull] Will prepull images for components [kube-apiserver kube-controller-manager kube-scheduler etcd] ...省略部分内容以节省篇幅... [bootstrap-token] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token [bootstrap-token] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster [addons] Applied essential addon: CoreDNS [addons] Applied essential addon: kube-proxy [upgrade/successful] SUCCESS! Your cluster was upgraded to "v1.16.0". Enjoy! [upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 升级其他 master 节点
在其他 master 节点上执行命令
kubeadm upgrade node
1TIP
- 不需要执行
kubeadm upgrade plan
- 第一个 master 节点上执行的是
kubeadm upgrade apply v1.16.x
,此时执行的是kubeadm upgrade node
- 不需要执行
# 升级 kubelet 和 kubectl
在所有的 master 节点上执行如下命令以升级 kubelet 和 kubectl
# 替换 x 为最新补丁的版本号 yum install -y kubelet-1.16.x-0 kubectl-1.16.x-0 --disableexcludes=kubernetes
1
2执行如下命令,以重启 kubelet
systemctl daemon-reload systemctl restart kubelet
1
2
# 升级 worker 节点
建议逐个升级 worker 节点,或者同一时间点只升级少量的 worker 节点,以避免集群出现资源紧缺的状况。
# 升级 kubeadm
- 在所有的 worker 节点上执行如下命令,升级 kubeadm
# 将 1.16.x-0 中的 x 替换为最新的补丁版本 yum install -y kubeadm-1.16.x-0 --disableexcludes=kubernetes
1
2
# 排空(drain)节点
执行以下命令,将节点标记为
不可调度的
并驱逐节点上所有的 Pod,# 在可以执行 kubectl 命令的位置执行(通常是第一个 master节点) # $NODE 代表一个变量,实际执行时,请用您的节点名替换 kubectl drain $NODE --ignore-daemonsets
1
2
3输出结果如下所示:
node/ip-172-31-85-18 cordoned WARNING: ignoring DaemonSet-managed Pods: kube-system/kube-proxy-dj7d7, kube-system/weave-net-z65qx node/ip-172-31-85-18 drained
1
2
3
# 升级 kubelet 的配置
- 执行命令
kubeadm upgrade node
1
# 升级 kubelet 和 kubectl
在所有的 worker 节点执行命令
# 替换 x 为最新补丁的版本号 yum install -y kubelet-1.16.x-0 kubectl-1.16.x-0 --disableexcludes=kubernetes
1
2执行如下命令,以重启 kubelet
systemctl daemon-reload systemctl restart kubelet
1
2
# 恢复(uncordon)节点
执行如下命令,使节点重新接受调度并投入使用:
kubectl uncordon $NODE
1
# 检查集群的状态
在所有节点的 kubelet 本升级以后,执行如下命令以验证所有节点都可用:
kubectl get nodes -o wide
STATUS
字段应该为 Ready
,版本号也应该显示目标版本号。
# 从错误状态中恢复
如果 kubeadm upgrade
执行过程中出现错误且未曾回滚,例如执行过程中意外关机,您可以再次执行 kubeadm upgrade
。该命令是 幂等 的,并将最终保证您能够达到最终期望的升级结果。
从失败状态中恢复时,请执行 kubeadm upgrade --force
命令,注意要使用集群的当前版本号。
# 工作过程
在第一个 master 节点上,kubeadm upgrade apply
执行了如下操作:
- 检查集群是否处于可升级的状态:
- API Server 可以调用
- 所有的节点处于
Ready
装填 - master 节点处于
healthy
状态
- 检验是否可以从当前版本升级到目标版本
- 确保 master 节点所需要的镜像可以被抓取到节点上
- 升级 master 节点的组件,(如果碰到问题,则回滚)
- 应用新的
kube-dns
和kube-proxy
的 manifests 文件,并确保需要的 RBAC 规则被创建 - 如果证书在 180 天内将要过期,则为 API Server 创建新的证书文件,并备份旧的文件
在其他 master 节点上,kubeadm upgrade node
执行了如下操作:
- 从集群中抓取 kubeadm 的配置信息
ClusterConfiguration
- 备份 kube-apiserver 的证书
- 升级 master 节点上静态组件的 manifest 信息
- 升级 master 节点上 kubelet 的配置信息
在所有的 worker 节点上,kubeadm upgrade node
执行了如下操作:
- 从集群中抓取 kubeadm 的配置信息
ClusterConfiguration
- 升级 worker 节点上 kubelet 的配置信息