deployment in kubernetes
注: 本文是学习《kubernetes in Action中文版》的学习笔记.
这里主要是了解kubernets如何做到服务的多副本高可用,一个是部署的时候,一个是发布更新的时候。
部署的时候我们最基础的是需要多个副本,然后最好是每个副本都在不同的物理机,rack,或者az里,这样可以最大限度的保证高可用。
所以我们这里就是朝着这个方向去努力。
后面我们再分析kubernetes里pod的资源限制和使用的问题。
ReplicationController
1 | apiVersion: v1 |
ReplicationController 这个现在已经不怎么推荐使用了。它会持续监控正在运行的pod列表,确保pod的数量始终与其标签选择器匹配。
ReplicationController主要有4个部分:
- label select, 这个主要是确定ReplicationController的作用域有哪些pod
- replica count, 指定应运行的pod数量
- pod template: 用于创建新的pod副本
- minReadySeconds: 表示启动多久了算ready成功,默认为0,表示一启动就绪就表示可用了。
我们通常可以使用如下命令来获取ReplicationController的信息
1 | kubectl get rc |
上面的rc就是ReplicationController的缩写。
如果我们要查看pod的rc详细信息
1 | kubectl describe rc kubia |
作者在这个时候把其中一个pod所在服务器的网络给中断了,那rc就会再拉起一个新的pod。但是这个是间隔多久说是大概有一分钟的时间。这个应该是有地方可以配置的,不然这个时间也太长了。
但是我们也不能依赖kubernets的健康检查,我们还是需要负载均衡上做相应的检测和重试。
其他的也不用深入研究了,我们直接去到ReplicaSet吧
ReplicaSet
https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/replicaset/
1 | apiVersion: apps/v1 |
我们可以清楚的看到ReplicaSet比ReplicationController多了一个matchLabels的概念,不需要在selector属性里直接列出pod需要的标签,而是通过matchLabels来指定。
这个matchLabels我个人感觉是是上面的selector属性指定没有区别,ReplicaSet里更有意思的是matchExpressions
1 | apiVersion: apps/v1 |
1 | selector: |
这两个例子里可以看到matchExpressions的语法可以有Exists,In,还有NotIn,DoesNotExists
In: label的值必须与其中的一个指定的values匹配
NotIn: label的值愈任何指定的values不匹配
Exists: pod必须包含一个指定名称的标签(值不重要),使用此运算符时,不应该指定values字段
DoesNotExist:pod不得包含含有指定名称的标签,values属性不得指定。
总体来说现在如果还在用ReplicationController的话就把它替换成ReplicaSet吧。
DaemonSet
前面2个Replica都是用来指定部署pod的个数的,但是很多时候我们需要指定某些pod在一些node上执行,那这个就需要使用DaemonSet。
其实以上这些mesos+marathon也可以完成的。
在kubernets中这个是根据node亲和性来的,并不是只是在DaemonSet中使用
1 | apiVersion: v1 |
其中requiredDuringSchedulingIgnoredDuringExecution 这个是必须要有的key,它对应的value是antarctica-east1和antarctica-west1
而preferredDuringSchedulingIgnoredDuringExecution 这个是尽量要有的,但是没有也没关系。
同时原先书中写的nodeSelector 这个已经不建议使用,因为它的语法表达能力比较弱。上面亲和性的2个语法中operator可以有In,NotIn,Exists,DoesNotExist,Gt,Lt
其中Gt和Lt是这里新加的,根据名字也很容易理解就是大于和小于的意思。
nodeSelector和亲和性可以同时使用,但是同时使用的就是要两者都满足才行。
所以我们以后还是就用亲和性就可以了。
以上都是我们在做首次部署的应该注意的,但是在实际生产环境中,我们还需要注意发布的时候的行为。
在mesos+marathon中我们可以设定更新的时候同时更新百分比。
Deployments
在kubernets里当然也有关于更新的设置。
1 | apiVersion: apps/v1 |
其中strategy.type 这里可以是Recreate和RollingUpdate。
Recreate的含义是在创建新的Pod之前,所有现有的Pod都会被杀死。
RollingUpdate的含义就是滚动升级,其中maxUnavailable表示是最大不可用的数量,这里可以写绝对数字,也可以写百分比,比如33% 这样。当然如果我们写0,那就表示我们必须起新的Pod之后再关闭现有的Pod。
maxSurge这个表示可以启动多少个新的Pod,这里也可以是绝对数字或者是百分比。这里如果写100%,那就是说我会再新启动3个nginx Pod,然后再关闭现有的nginx Pod。
502&504问题
我们在部署的时候可以使用minReadySeconds来指定Pod就绪多久才算成功。我们可以把这个值调整一下,有些Pod可能一health check后就表示就绪了,有些Pod并不是这样的,需要有流量了它才会去建立对应连接和请求。
在kubernets里可以使用启动探针保护慢启动容器
1 | startupProbe: # 启动探测,如果失败就会重启 |
当然我们也可以自定义header来请求
1 | livenessProbe: |
我们再来看看终止的问题:
1 | apiVersion: apps/v1 |
我们可以看到terminationGracePeriodSeconds和preStop这2个。terminationGracePeriodSeconds表示优雅退出,这个默认是30s,最小值为1s,也就是表示无论如何这个nginx超过120s后都会被强制终止。
那这里的preStop又是干什么呢?
需要注意的是,这个terminationGracePeriodSeconds是与 PreStop同步开始的,而且它也不会等待preStop结束。
所以这里就是执行sleep 180s而已,而且并不会执行完毕,因为到120s的时候Pod就被强制终止了。