之前,我们介绍了[kubernetes][2] 1.2.0的新特性,还不清楚的童鞋查看[这里][1]。
本文讨论的是使用 kubernetes 1.2.0 的注意事项,包括对周边组件的要求(比如docker的兼容性)、目前已知的bug(kubernetes和docker 1.9)和如何平稳升级。
## Part I 升级注意事项
1.使用kubernetes 1.2.0 推荐使用Docker v1.9.1,但仍然支持v1.8.3和v1.10。如果你使用的Docker版本太低,请先升级Docker。但Docker v1.9.1存在一些问题,下面我们详细讨论。
2.如果内核支持CPU hardcapping,并且容器设置了CPU limit,那么CPU hardcapping选项将默认启用。可以通过调整CPU limit或者只设置CPU request来避免hardcapping。如果内核不支持CPU Quota,NodeStatus会包含一个“无法使用CPU limit”的警告。
3.这条注意事项只在你使用 Go 语言 client(/pkg/client/unversioned)创建Job时适用,比如使用 ”k8s.io/kubernetes/pkg/apis/extensions”.Job 来定义 GO 变量。这种做法并不常用,如果你不明白这里在讨论什么,那你暂时无须关注这个问题。如果你使用Go语言client创建Job,并且重新发布了"k8s.io/kubernetes/",那么需要设置job.Spec.ManualSelector = true,或者设置job.Spec.Selector = nil。否则你创建的 jobs 可能被驳回,具体操作点击这里查看。
4.Deployment(apiVersion extensions/v1beta1)在v1.1中是Alpha版,默认不集成到release中。由于我们对API做了向后不兼容的变更,所以在v1.1中创建的Deployment对象将无法在v1.2中使用。具体变更如下:
a)升级到v1.2之前,务必删除所有Alpha版本的Deployment资源,包括Deployment管理的ReplicationController和Pod。升级到v1.2之后,创建Beta版本的Deployment资源。不删除Deployment资源的话,由于选择器API的变更,可能导致deployment controller错误地匹配和删除其他pods。
b)进行Deployment相关的操作时,客户端(kubectl)和服务器端的版本必须匹配(均为1.1或者1.2)。
c) API行为变更:①Deployment创建ReplicaSets而不是ReplicationController;②scale subresource的状态结构体中增加了一个字段 targetSelector,该字段支持基于集合(set-based)的选择器,但格式必须是序列化后的结果。
d)规格(Spec)变更:①Deployment对象的选择器更加通用(支持基于集合的选择器,而在v1.1中支持基于比较的选择器);②.spec.uniqueLabelKey字段已被删除,用户将不能自定义unique label key,它的默认值也由"deployment.kubernetes.io/podTemplateHash"变成了"pod-template-hash";③.spec.strategy.rollingUpdate.minReadySeconds字段被.spec.minReadySeconds代替。
5.DaemonSet(apiVersion extensions/v1beta1)在v1.1中是Alpha版本,默认不包含在release中。由于我们对API做了向后不兼容的变更,所以在v1.1中创建的DaemonSet对象将无法在v1.2中使用。具体变更如下:
a) 升级到v1.2之前,务必删除所有Alpha版本的DaemonSet资源。如果你不想破坏原有的Pod,可以使用命令kubectl
delete daemonset –cascade=false。升级到v1.2之后,创建Beta版本的Deployment资源。
b) 进行DaemonSet相关的操作时,客户端(kubectl)和服务器端的版本必须匹配(均为1.1或者1.2)。
c) API行为变更:①即便节点设置了.spec.unschedulable=true,DaemonSet
pod也会在该节点上创建,即便节点Ready状态为False,pod也不会被删除。②允许 更新Pod
template。如果对DaemonSet进行rolling update,可以更新pod
template,然后把pod一个个删除,新的pod将根据新的pod template创建。
d) 规格(Spec)变更: ①DaemonSet对象的选择器更加通用(支持基于集合的选择器,而在v1.1中支持基于比较的选择器)。
6.如果要在https运行etcd,则需要将下面的参数传递给kube-apiserver(而不是 –etcd-config):
a) –etcd-certfile, --etcd-keyfile (如果使用client cert auth)
b) –etcd-cafile(如果不使用system roots)
7.Kubernetes v1.2将增加对protocol buffer的支持, API也将直接支持YAML格式。作为准备,在当前release中,每个HTTP spec的 Content-Type和Accept headers都会被处理。所以,你通过客户端发送请求给API时,如果Content-Type或Accept headers无效,将会返回415或406错误。目前唯一已知会影响到的客户端是curl,一个错误的做法是:使用-d 发送JSON,但是不设置Content-Type(希望使用默认的"application/x-www-urlencoded")。如果你使用的其他的客户端,那么需要检查确认发送了正确的 accept和 content type headers,或者不做任何设置(默认为JSON)。以curl为例:curl -H "Content-Type: application/json" -XPOST -d '{"apiVersion":"v1","kind":"Namespace","metadata":{"name":"kube-system"}}'
8.由于数据的存储格式发生变化,Kubernetes要求influxdb的版本为0.9(之前为0.8)。
9.将术语"minions"替换为"nodes"。如果运行kube-up时,你指定了NUM_MINIONS或MINION_SIZE,那么在1.2中,则需要指定NUM_NODES或NODE_SIZE。
## Part II Kubernetes中现存的问题
1.处于Paused状态的deployments不能被resize,也不会清空旧的ReplicaSets。
2.最小的内存limit是4MB,这里是docker的限制。
3.最小的CPU limits是10m,这里是Linux内核的限制。
4.对于paused deployments," kubectl rollout undo"(比如 rollback)操作会挂起,因为paused deployments不能被回滚(该结果符合预期),该命令会等待回滚时间返回结果。在回滚之前,用户应该使用" kubectl rollout resume"命令恢复一个deployment。
5." kubectl edit"操作会为每个资源代打开一次编辑器,因此编辑器会被打开很多次。
6.在使用 autoscaling/v1 API创建HPA对象时,如果不指定targetCPUUtilizationPercentage,使用kubectl读取该字段会显示extensions/v1beta1中指定的默认值。
7.如果一个挂载了存储卷的节点或者kubelet意外崩溃,存储卷仍然属于那个节点。由于单个存储卷只能被挂载到一个节点上(比如GCE PDs以RW模式挂载),则必须手动卸载以后才能挂载到其它节点上。
8.如果一个存储卷已经被挂载到某个节点上,则后续再次尝试挂载到该节点的操作(i.e. 由于kubelet重启)都将失败。解决方法有两个,或者手动卸载该存储卷,或者删除所有相关联的pod,该动作将自动触发卸载。
9.在规模非常大的集群中,在某些时间段,可能出现一些节点无法注册到API Server的问题,原因可能多种多样,比如网络问题、宕机等。正常情况下,使用kube-up脚本启动集群时,任意一个节点出现NotReady的情况(即便集群运行正常),kube-up也会返回失败。这里我们添加了变量ALLOWED_NOTREADY_NODES,它定义了最多允许NotReady节点的个数,即如果NotReady节点的个数超出设定的值时,kube-up才会返回失败。
10."kubectl rolling-update"命令只支持Replication Controllers,不支持Replica Sets。如果要rolling update Replica Sets,推荐使用 Deployment 1.2中的"kubectl rollout"命令。
11.在线升级Kubelet到1.2是,如果不清空运行在节点上的pods的话,kubelet管理的所有container都将重启。
## Part III Docker中现存的问题(v1.9.1)
1.docker ps操作有时候非常慢,进而影响到kubelet的性能。
2.Docker daemon重启可能失败。在重启时,必须删除docker checkpoints。
3.Pod IP分配相关的问题。在重启docker daemon之前删除docker checkpoint有助于缓解这个问题,但是尚未验证是否能够完全解决该问题。
4.由于内核死锁,Docker daemon可能出现无响应的情况(极少出现)。
[1]:http://mp.weixin.qq.com/s?__biz=MzIwNzA1MTA5OA==&mid=628878734&idx=1&sn=81d3c6b24b54afb168412544751a7d88&scene=21#wechat_redirect
[2]:https://www.tenxcloud.com/
有疑问加站长微信联系(非本文作者)