Kubernetes的设计解读
新一代副本控制器replica set
replica set 可以被认为是升级版的replication controller。区别在于,replica set引入了对基于子集的selector查询条件,而replication controller仅支持基于值相等的selector条件查询。
社区引入replica set的目的就是为了取代replication controller。replica set主要用途是被Deployment用于进行pod的创建、更新和删除。
下面来看使用案例:
需要注意的是,在spec.selector
这里使用了基于子集的selector查询条件(该replica set对应pod的label键为tier属性对应的值为fronted)。
创建完成后可以通过kubrctl get replicaset -o wide
完成查询。
Deployment
Deployment多用于为pod和replica set提供更新,并且可以方便的观察其所属的replica set或者pod数量以及其状态变化。
换言之,Deployment是为了应用的更新而设计的。熟悉kubectl的知道有这样一条命令kubectl rolling-update
,它和Deployment的区别在于:kubectl rolling-update
是由命令行工具本身实现更新逻辑,而Deployment则将这一负担转移到服务器端,由专门的controller来负责这部分工作。
创建一个Deployment
{
"apiVersion":"apps/v1",
"kind":"Deployment",
"metadata":{
"name":"nginx-deployment"
},
"spec":{
"replicas":3,
"selector":{
"matchLabels":{
"app":"nginx"
}},
"template":{
"metadata":{
"labels":{
"app":"nginx"
}
},
"spec":{
"containers":[{
"name":"nginx",
"image":"nginx:1.9.1",
"ports":[{
"containerPort":80
}]
}]
}}}}
其中设置Deployment的版本号apiVersion
可以使用kubectl api-versions
进行查询。
[root@master ~]# vi nginx-deployment.json
[root@master ~]# kubectl create -f nginx-deployment.json --record
deployment.apps/nginx-deployment created
创建完成后,查询Deployment状态:
[root@master ~]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 47s
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-56f8998dbc-fhf42 1/1 Running 0 53s
nginx-deployment-56f8998dbc-gwfrf 1/1 Running 0 53s
nginx-deployment-56f8998dbc-zs8ff 1/1 Running 0 53s
正如前文所介绍的,Deployment的使命在于更新pod template。下面就以更新镜像版本为例来看一下这个操作是怎么发生的。
我们修改上面的json文件,把镜像版本的1.9.1
修改成为latest
。然后使用kubectl apply
命令。
[root@master ~]# kubectl apply -f nginx-deployment.json
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
deployment.apps/nginx-deployment configured
再来查看Deployment和Pod的变化:
[root@master ~]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 2m58s
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-786b576769-cmq6b 1/1 Running 0 34s
nginx-deployment-786b576769-g4mzs 1/1 Running 0 36s
nginx-deployment-786b576769-zwdcn 1/1 Running 0 33s
说明:除了
kubectl apply
之外,也可以选用kubectl edit
直接修改。
==Deployment在进行pod template更新时,会保证有相当数量的副本是可以提供服务的,以实现灰度升级的平滑切换。==默认情况下,在更新过程中最多只有1个副本不提供服务。另一方面,Deployment还会保证同一时刻不会有过多的副本同时运行,默认情况下允许运行的副本数最多比预期值多一个。
关于这一点,使用kubectl describe
可以知道。
[root@master ~]# kubectl describe deployment nginx-deployment
Name: nginx-deployment
Namespace: default
......
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 6m37s deployment-controller Scaled up replica set nginx-deployment-56f8998dbc to 3
Normal ScalingReplicaSet 4m11s deployment-controller Scaled up replica set nginx-deployment-786b576769 to 1
Normal ScalingReplicaSet 4m9s deployment-controller Scaled down replica set nginx-deployment-56f8998dbc to 2
Normal ScalingReplicaSet 4m9s deployment-controller Scaled up replica set nginx-deployment-786b576769 to 2
Normal ScalingReplicaSet 4m8s deployment-controller Scaled down replica set nginx-deployment-56f8998dbc to 1
Normal ScalingReplicaSet 4m8s deployment-controller Scaled up replica set nginx-deployment-786b576769 to 3
Normal ScalingReplicaSet 4m7s deployment-controller Scaled down replica set nginx-deployment-56f8998dbc to 0
从上面可以看出,一共有两个replica set。Deployment首先创建了一个新的replica set(nginx-deployment-786b576769),逐步让他与旧的replica set(nginx-deployment-56f8998dbc)相互替换副本,每次新的replica set增加1个,老的replica set减少1个并逐渐减少到0。
默认情况下,所有Deployment的更新记录都被保存在系统中,假设我们将镜像版本号错误的写成了1.91
而不是1.9.1
:
[root@master ~]# cp nginx-deployment.json bad-nginx-deployment.json
[root@master ~]# vi bad-nginx-deployment.json
[root@master ~]# kubectl apply -f bad-nginx-deployment.json
deployment.apps/nginx-deployment configured
那么在Deployment试图更新时,会出现下面的情况:
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-786b576769-cmq6b 1/1 Running 0 20m
nginx-deployment-786b576769-g4mzs 1/1 Running 0 20m
nginx-deployment-786b576769-zwdcn 1/1 Running 0 20m
nginx-deployment-84fdd4f88c-78ghm 0/1 ImagePullBackOff 0 30s
为什么只有一个ImagePullBackOff
,也是说明了是逐个递减的。此时我们需要回滚到上一个稳定的版本中:
[root@master ~]# kubectl rollout history deployment.apps/nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 kubectl create --filename=nginx-deployment.json --record=true
2 kubectl create --filename=nginx-deployment.json --record=true
3 kubectl create --filename=nginx-deployment.json --record=true
然后选择期望的历史版本作为--to-revision
的参数,进行回滚操作:
[root@master ~]# kubectl rollout undo deployment.apps/nginx-deployment --to-revision=2
deployment.apps/nginx-deployment rolled back
此外,还可以采用kubectl rollout pause
以及kubectl rollout resume
来暂停或者恢复kubectl rollout的过程。