Files
kuboard-press/install/upgrade-k8s/1.15.x-1.16.x.md
2020-12-24 13:57:19 +08:00

293 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
vssueId: 107
description: Kubernetes升级1.16.x。本文描述了如何从 kubernetes v1.15.x或1.16.x升级到 Kubernetes v1.16.y前提是您的 Kubernetes 集群是使用 kubeadm 安装的。
metaTitle: Kubernetes高危漏洞及解决办法CVE-2019-11253
meta:
- name: keywords
content: Kubernetes升级,K8S升级,升级Kuberentes1.16.x,Kubernetes升级到1.16
---
# K8S从1.15.x(1.16.x)升级到 1.16.x
<AdSenseTitle/>
参考文档: kubernetes 文档 [kubeadm upgrade](https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-upgrade/)
**【漏洞详情】**
2019年10月17日Kubernetes发布漏洞公告 [[ANNOUNCE] CVE-2019-11253: denial of service vulnerability from malicious YAML or JSON payloads](https://discuss.kubernetes.io/t/announce-cve-2019-11253-denial-of-service-vulnerability-from-malicious-yaml-or-json-payloads/8349)。具备一定权限的攻击者通过发送恶意的 YAML 或 JSON 格式的攻击包可导致 kube-apiserver CPU 或内存资源耗尽无法正常提供服务1.14.0 之前的版本由于默认RBAC策略允许匿名用户提交请求所以之前的版本均在影响范围。
【风险等级】
<font color="red" weight="500">高风险</font>
【影响版本】
* Kubernetes v1.0.0-1.12.x
* Kubernetes v1.13.0-1.13.11v1.13.12版本已修复)
* Kubernetes v1.14.0-1.14.7v1.14.8版本已修复)
* Kubernetes v1.15.0-1.15.4v1.15.5版本已修复)
* Kubernetes v1.16.0-1.16.1v1.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](./1.15.x-1.15.4.html)
本文描述了如何从 kubernetes v1.15.x或1.16.x升级到 Kubernetes v1.16.y前提是您的 Kubernetes 集群是使用 kubeadm 安装的。
升级的高阶过程如下所示:
1. 升级主 master 节点
2. 升级从 master 节点
3. 升级 worker 节点
## 预备工作
* 请确保您的 Kubernetes 集群是通过 kubeadm 安装的,且版本号不低于 1.15.0
* swap 已禁用(如果您参考 www.kuboard.cn 上的文档安装swap已禁用
* 集群使用静态Podapiserver、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 上执行:
``` sh
yum list --showduplicates kubeadm --disableexcludes=kubernetes
# 在列表中找到最新的 1.16 版本号
# 该版本号格式为 1.16.x-0其中 x 是最新的补丁
```
## 升级 master 节点
### 升级第一个 master 节点
假设所有命令都以 root 身份执行
* 在第一个 master 节点上执行如下命令,升级 kubeadm
``` sh
# 将 1.16.x-0 中的 x 替换为最新的补丁版本
yum install -y kubeadm-1.16.x-0 --disableexcludes=kubernetes
```
执行命令 `kubeadm version`,以验证升级结果
::: danger 替换 1.16.x 中的 x
本文中,所有碰到 1.16.x 的地方,都要将其中的 x 替换为您前面查询到的最新补丁号
:::
* 在第一个 master 节点上执行命令 `kubeadm upgrade plan`,输出结果如下所示:
``` {9,24,25,26,27,28,29}
[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
_____________________________________________________________________
```
::: tip
* 请忽略错误 `could not fetch a Kubernetes version from the internet: unable to get URL "https://dl.k8s.io/release/stable.txt"`,在不能获得最新 kubernetes 版本列表的情况下,将使用 kubeadm 的版本作为升级的目标版本(在前面的步骤中,已经从 yum 仓库找到了最新 kubeadm 的版本)
:::
* 执行如下命令以升级:
``` sh
# 替换 x 为最新补丁的版本号
kubeadm upgrade apply v1.16.x
```
::: tip
* `kubeadm upgrade` 同时会自动更新节点上的证书。如果不想更新证书,请使用参数 `--certificate-renewal=false`
:::
输出信息如下所示:
``` {11}
[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.
```
<!-- * 手动升级CNI插件 -->
### 升级其他 master 节点
* 在其他 master 节点上执行命令
``` sh
kubeadm upgrade node
```
::: tip
* 不需要执行 `kubeadm upgrade plan`
* 第一个 master 节点上执行的是 `kubeadm upgrade apply v1.16.x`,此时执行的是 `kubeadm upgrade node`
:::
### 升级 kubelet 和 kubectl
* 在所有的 master 节点上执行如下命令以升级 kubelet 和 kubectl
``` sh
# 替换 x 为最新补丁的版本号
yum install -y kubelet-1.16.x-0 kubectl-1.16.x-0 --disableexcludes=kubernetes
```
* 执行如下命令,以重启 kubelet
``` sh
systemctl daemon-reload
systemctl restart kubelet
```
## 升级 worker 节点
建议逐个升级 worker 节点,或者同一时间点只升级少量的 worker 节点,以避免集群出现资源紧缺的状况。
### 升级 kubeadm
* 在所有的 worker 节点上执行如下命令,升级 kubeadm
``` sh
# 将 1.16.x-0 中的 x 替换为最新的补丁版本
yum install -y kubeadm-1.16.x-0 --disableexcludes=kubernetes
```
### 排空drain节点
* 执行以下命令,将节点标记为 `不可调度的` 并驱逐节点上所有的 Pod
``` sh
# 在可以执行 kubectl 命令的位置执行(通常是第一个 master节点
# $NODE 代表一个变量,实际执行时,请用您的节点名替换
kubectl drain $NODE --ignore-daemonsets
```
输出结果如下所示:
```
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
```
### 升级 kubelet 的配置
* 执行命令
``` sh
kubeadm upgrade node
```
### 升级 kubelet 和 kubectl
* 在所有的 worker 节点执行命令
``` sh
# 替换 x 为最新补丁的版本号
yum install -y kubelet-1.16.x-0 kubectl-1.16.x-0 --disableexcludes=kubernetes
```
* 执行如下命令,以重启 kubelet
``` sh
systemctl daemon-reload
systemctl restart kubelet
```
### 恢复uncordon节点
* 执行如下命令,使节点重新接受调度并投入使用:
``` sh
kubectl uncordon $NODE
```
## 检查集群的状态
在所有节点的 kubelet 本升级以后,执行如下命令以验证所有节点都可用:
``` sh
kubectl get nodes -o wide
```
`STATUS` 字段应该为 `Ready`,版本号也应该显示目标版本号。
## 从错误状态中恢复
如果 `kubeadm upgrade` 执行过程中出现错误且未曾回滚,例如执行过程中意外关机,您可以再次执行 `kubeadm upgrade`。该命令是 [幂等](glossary/idempotent.html) 的,并将最终保证您能够达到最终期望的升级结果。
从失败状态中恢复时,请执行 `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 的配置信息