k8s学习(10):RS、Deployment控制器

ReplicaSet

RC(ReplicationController)主要的作用是确保容器应用的副本数始终保持在用户定义的副本数。

k8s官方建议使用RS(ReplicaSet)替代RC,两者功能一样,但RS支持集合式的selector

举个栗子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
name: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: myapp
image: hub.test.com/library/myapp:v1
env:
- name: GET_HOSTS_FROM
value: dns
ports:
- containerPort: 80
1
2
3
4
5
6
7
8
9
10
11
12
# 查看标签
kubectl get pod --show-labels
# 尝试修改标签,看看会不会自动创建新的pod
kubectl label pod frontend-xxx tier=frontend1
# 会提示需要加--overwrite is false
kubectl label pod frontend-xxx tier=frontend1 --overwrite=True
# 再次get看pod状态
kubectl get pods --show-labels
# 删除RS,此时不会删除之前修改过label的pod
kubectl delete rs frontend
# 查看pod,此时只剩下一个pod
kubectl get pod

RS会通过matchLabels匹配template.metadata.labels对应的数值

如果修改pod的标签,会重新创建新的pod;如果删除旧的pod,也会重新创建pod

Deployment

image-20200131012425977

Deployment为Pod和ReplicaSet提供了一个声明式定义(declarative)方法,用来替代以前的RC来方便管理应用,典型应用:

  • 定义Deployment来创建Pod和RS

  • 滚动升级和回滚应用

  • 扩容和缩容

  • 暂停和继续Deployment

举个栗子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: hub.test.com/library/myapp:v1
ports:
- containerPort: 80
1
2
3
4
5
6
7
8
9
# 创建deployment,通过添加record参数可以记录命令,后续可以查看revision的变化
kubectl create -f nginx-deployment.yaml --record
# 查看deployment
kubectl get deploy
# 查看rs
kubectl get rs
# 查看pod
kubectl get pods
# 查看label
  • labels需要写在spec.template.metadata.labels这个位置

这里个人理解一下:

rs有matchLabels和labels相对应,deployment只有labels,应该是deployment省略了

扩容

1
kubectl scale deployment nginx-deployment --replicas=10

如果集群支持horizontal pod autoscaling的话,还可以为Deployment设置自动扩展

1
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80

更新镜像

1
2
3
4
5
6
7
8
9
kubectl set image deployment/nginx-deployment nginx=wangyanglinux/myapp:v2
# 查看pod,发现旧的pod被删除,新的pod被创建
kubectl get pods
# 此时查看rs,会发现多一个rs
kubectl get rs
# 查看pod IP
kubectl get pod -o wide
# 查看pod版本
curl ip

回滚

1
2
3
4
5
6
kubectl rollout undo deployment/nginx-deployment
# 查看rs和pod
kubectl get pods -o wide
kubectl get rs
# 查看pod版本
curl ip

Deployment更新策略

Deployment可以保证在升级时只有一定数量的Pod是down。默认的,它会确保至少有比期望的Pod数量少一个是up状态(最多一个不可用)

Deployment同时也可以确保只创建出超过期望数量的一定数量的Pod。默认的,它会确保最多比期望的Pod数量多一个的Pod是up的(最多一个surge)

未来的k8s版本中,将从1-1变成25%-25%

1
kubectl describe deployment

Rollver(多个rollout并行)

假如你创建了一个有5个replicas的nginx:1.7.9的Deployment,但是当还只有3个pod被创建出来的时候就开始更新nginx至nginx:1.9.1,在这种情况下,Deployment会立即杀掉已创建的3个的nginx:1.7.9的pod,并开始创建nginx:1.9.1的pod。它不会等到所有的5个nginx:1.7.9的Pod都创建完成后才开始改变航道。

回退Deployment

只要Deployment的rollout被出发就会创建一个revision。也就是说当且仅当Deployment的Pod template(如‘.spec.template’)被更改,例如更新template中的label和容器镜像时,就会创建出一个新的revision。其他的更新,如扩容,则不会创建revision。当回退历史revision时,只会回退template,数量不会回退。

1
2
3
4
5
6
7
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
kubectl rollout status deployments nginx-deployment
kubectl get pods
kubectl rollout history deployment/nginx-deployment
kubectl rollout undo deployment/nginx-deployment
kubectl rollout undo deployment/nginx-deployment --to-revision=2 ## 指定历史版本
kubectl rollout pause deployment/nginx-deployment ## 暂停deployment的更新

可以用kubectl rollout status命令查看Deployment是否完成。如果rollout完成,则返回一个0值的Exit Code

1
2
3
4
5
$ kubectl rollout status deploy/nginx
Waiting for rollout to finish:2 of 3 updated replicas are available...
deployment "nginx" successfully rolled out
$ echo $?
0

清理Policy

可以通过设置.spce.revisionHistoryLimit项来指定deployment最多保留多少revision历史记录。默认的会保留所有的revision;如果将该项设置为0,就不允许回退