Kubernetes 从1.9到1.10升级记录
2018-08-17
Kubernetes 1.11已经发布一个多月了。我们线上的版本都是按照比官方最新版本低一个版本的节奏。 因此可以开始考虑将团队线上环境的Kubernetes集群从1.9升级到1.10了。 本文记录了在测试环境中的演练过程。
1.准备 #
当前Kubernetes 1.10的小版本是1.10.6。 在升级之前一定要多读几遍官方的升级须知Kubernetes 1.10 - Action Required Before Upgrading。
其中针对我们对Kubernetes的使用情况,有几个需要我们注意的地方:
--pod-infra-container-image
Pod的pause镜像由3.0升级到了3.1,即k8s.gcr.io/pause-amd64:3.1
,这个需要提前准备- 通过kubelet的配置文件
--config
指定的参数和原来kubelet命令行参数的有很多有不同的默认值,在切换到--config
时一定要注意这一点 - kubelet的cadvisor端口被废弃了,它的默认值在Kubernetes 1.12将变成0,在1.13将会被彻底移除
Kubernetes 1.10所需的外部依赖和一些组件的版本:
- etcd 3.1.12
- 以下docker版本在Kubernetes 1.10上进行过验证:docker 1.11.2, 1.13.1, 17.03.x (支持的最小docker版本是1.11)
- CNI 0.6.0和Kubernetes 1.9依赖的版本相同
- CSI更新到了0.2.0
- dashboard 1.8.3
- heapster 1.5.0
- kube-dns 1.14.8
- flannel 0.10.0
- kube-state-metrics 1.3.1
2.使用ansible升级Kubernetes #
2.1 master节点 #
我们的集群有3个master节点,在使用ansible升级master节点(kube-apiserver
, kube-scheduler
, kube-controller-manager
)时,通过修改ansible role的inventory文件,只先升级第一个master节点,当测试没有问题后再升级剩余两个master节点。master节点的升级十分顺利,对ansible role的修改也不大。
2.2 node节点 #
同样也是先选择一个node节点升级做测试,如果这个节点上有业务Pod正在运行,可以先将这个节点排干(drain),将业务容器转移到其他的node节点上。 测试环境中的升级十分顺利,算上下载二进制文件,半个小时就完成了集群的升级,各个核心组件成功升级到了1.10.6。
注意提前准备
--pod-infra-container-image
到k8s.gcr.io/pause-amd64:3.1
2.3 Kubelet动态配置 #
Kubelet动态配置(Dynamic Kubelet Configuration beta)特性,在Kubernetes 1.10进入Beta阶段,可以在Node不下线的情况下改变Kubelet的配置。从Kubernetes 1.11开始kubelet的绝大多数命令行flag参数都被标记为DEPRECATED,而官方推荐我们使用--config
指定配置文件,并在配置文件中指定原来这些flag所配置的内容。
因此,我们决定在这次将Kubernetes升级到1.10的过程中为kubelet启用--config
指定配置文件,需要在我们的ansible role中加入相关的配置task。
config.yaml:
1apiVersion: kubelet.config.k8s.io/v1beta1
2kind: KubeletConfiguration
3address: {{ k8s_node_address }}
4authentication:
5 anonymous:
6 enabled: true
7authorization:
8 mode: AlwaysAllow
9cgroupDriver: cgroupfs
10cgroupsPerQOS: true
11clusterDNS:
12- 10.96.0.10
13clusterDomain: cluster.local
14containerLogMaxFiles: 5
15containerLogMaxSize: 10Mi
16contentType: application/vnd.kubernetes.protobuf
17cpuCFSQuota: true
18cpuManagerPolicy: none
19cpuManagerReconcilePeriod: 10s
20enableControllerAttachDetach: true
21enableDebuggingHandlers: true
22enforceNodeAllocatable:
23- pods
24eventBurst: 10
25eventRecordQPS: 5
26evictionHard:
27 imagefs.available: 15%
28 memory.available: 100Mi
29 nodefs.available: 10%
30 nodefs.inodesFree: 5%
31evictionPressureTransitionPeriod: 5m0s
32failSwapOn: false
33fileCheckFrequency: 20s
34hairpinMode: promiscuous-bridge
35healthzBindAddress: 127.0.0.1
36healthzPort: 10248
37httpCheckFrequency: 20s
38imageGCHighThresholdPercent: 85
39imageGCLowThresholdPercent: 80
40imageMinimumGCAge: 2m0s
41iptablesDropBit: 15
42iptablesMasqueradeBit: 14
43kubeAPIBurst: 10
44kubeAPIQPS: 5
45makeIPTablesUtilChains: true
46maxOpenFiles: 1000000
47maxPods: 110
48nodeStatusUpdateFrequency: 10s
49oomScoreAdj: -999
50podPidsLimit: -1
51port: 10250
52registryBurst: 10
53registryPullQPS: 5
54resolvConf: /etc/resolv.conf
55rotateCertificates: true
56runtimeRequestTimeout: 2m0s
57serializeImagePulls: true
58staticPodPath: {{ kube_pod_manifest_dir }}
59streamingConnectionIdleTimeout: 4h0m0s
60syncFrequency: 1m0s
61volumeStatsAggPeriod: 1m0s