学习了Replication Controller
和Replica Set
两种资源对象,RC
和RS
的功能基本上是差不多的,唯一的区别就是RS
支持集合的selector
。我们也学习到了用RC
/RS
来控制Pod
副本的数量,也实现了滚动升级Pod
的功能。现在看上去似乎一切都比较完美的运行着,但是我们上节课最后也提到了现在我们推荐使用Deployment
这种控制器了,而不是我们之前的RC
或者RS
,这是为什么呢?
没有对比就没有伤害对吧,我们来对比下二者之间的功能吧,首先RC
是Kubernetes
的一个核心概念,当我们把应用部署到集群之后,需要保证应用能够持续稳定的运行,RC
就是这个保证的关键,主要功能如下:
- 确保
Pod
数量:它会确保Kubernetes
中有指定数量的Pod
在运行,如果少于指定数量的Pod
,RC
就会创建新的,反之这会删除多余的,保证Pod
的副本数量不变。 - 确保
Pod
健康:当Pod
不健康,比如运行出错了,总之无法提供正常服务时,RC
也会杀死不健康的Pod
,重新创建新的。 - 弹性伸缩:在业务高峰或者低峰的时候,可以用过
RC
来动态的调整Pod
数量来提供资源的利用率,当然我们也提到过如果使用HPA
这种资源对象的话可以做到自动伸缩。 - 滚动升级:滚动升级是一种平滑的升级方式,通过逐步替换的策略,保证整体系统的稳定性。
Deployment
同样也是Kubernetes
系统的一个核心概念,主要职责和RC
一样的都是保证Pod
的数量和健康,二者大部分功能都是完全一致的,我们可以看成是一个升级版的RC
控制器,那Deployment
又具备那些新特性呢?
RC
的全部功能:Deployment
具备上面描述的RC
的全部功能- 事件和状态查看:可以查看
Deployment
的升级详细进度和状态 - 回滚:当升级
Pod
的时候如果出现问题,可以使用回滚操作回滚到之前的任一版本 - 版本记录:每一次对
Deployment
的操作,都能够保存下来,这也是保证可以回滚到任一版本的基础 - 暂停和启动:对于每一次升级都能够随时暂停和启动
创建Deployment
[root@master01 ~]# kubectl explain Deployment
KIND: Deployment
VERSION: apps/v1
DESCRIPTION:
Deployment enables declarative updates for Pods and ReplicaSets.
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <Object>
Standard object metadata.
spec <Object>
Specification of the desired behavior of the Deployment.
status <Object>
Most recently observed status of the Deployment.
cat > myapp-deploy.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
labels:
app: myapp
type: deploy
spec:
replicas: 3
selector:
matchLabels:
app: myapp
type: deploy
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: deploy
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
EOF
kubectl apply -f myapp-deploy.yaml
[root@master01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-deploy-696fdb5868-22lnq 1/1 Running 0 52s
myapp-deploy-696fdb5868-2tjqw 1/1 Running 0 52s
myapp-deploy-696fdb5868-c9c4b 1/1 Running 0 52s
[root@master01 ~]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
myapp-deploy 3/3 3 3 67s
[root@master01 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
myapp-deploy-696fdb5868 3 3 3 75s
查看Deployment
[root@master01 ~]# kubectl describe deployments.apps myapp-deploy
Name: myapp-deploy
Namespace: default
CreationTimestamp: Mon, 13 Jan 2020 15:12:50 +0800
Labels: app=myapp
type=deploy
Annotations: deployment.kubernetes.io/revision: 1
kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"labels":{"app":"myapp","type":"deploy"},"name":"myapp-deploy","n...
Selector: app=myapp,type=deploy
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=myapp
type=deploy
Containers:
myapp:
Image: ikubernetes/myapp:v1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: myapp-deploy-696fdb5868 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 7m53s deployment-controller Scaled up replica set myapp-deploy-696fdb5868 to 3
扩展Deployment
[root@master01 ~]# kubectl scale deployment myapp-deploy --replicas=5
deployment.apps/myapp-deploy scaled
[root@master01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-deploy-696fdb5868-22lnq 1/1 Running 0 10m
myapp-deploy-696fdb5868-2tjqw 1/1 Running 0 10m
myapp-deploy-696fdb5868-8f7qq 1/1 Running 0 8s
myapp-deploy-696fdb5868-c9c4b 1/1 Running 0 10m
myapp-deploy-696fdb5868-vlqgk 1/1 Running 0 8s
滚动升级
镜像版本v1-v2
cat > myapp-deploy.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
namespace: default
labels:
app: myapp
type: deploy
spec:
replicas: 5
minReadySeconds: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
selector:
matchLabels:
app: myapp
type: deploy
template:
metadata:
name: myapp-pod
labels:
app: myapp
type: deploy
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v2
ports:
- name: http
containerPort: 80
EOF
[root@master01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-deploy-8644746745-8f7qz 1/1 Running 0 30s
myapp-deploy-8644746745-cf6ln 1/1 Running 0 22s
myapp-deploy-8644746745-gt8fw 1/1 Running 0 15s
myapp-deploy-8644746745-mhp2q 1/1 Running 0 22s
myapp-deploy-8644746745-wqc8t 1/1 Running 0 30s
[root@master01 ~]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
myapp-deploy 5/5 5 5 18m
t@master01 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
myapp-deploy-696fdb5868 0 0 0 18m
myapp-deploy-8644746745 5 5 5 51s
- minReadySeconds:
- Kubernetes在等待设置的时间后才进行升级
- 如果没有设置该值,Kubernetes会假设该容器启动起来后就提供服务了
- 如果没有设置该值,在某些极端情况下可能会造成服务服务正常运行
- maxSurge:
- 升级过程中最多可以比原先设置多出的POD数量
- 例如:maxSurage=1,replicas=5,则表示Kubernetes会先启动1一个新的Pod后才删掉一个旧的POD,整个升级过程中最多会有5+1个POD。
- maxUnavaible:
- 升级过程中最多有多少个POD处于无法提供服务的状态
- 当
maxSurge
不为0时,该值也不能为0 - 例如:maxUnavaible=1,则表示Kubernetes整个升级过程中最多会有1个POD处于无法服务的状态。
rollout升级回滚
[root@master01 ~]# kubectl set image deployment myapp-deploy myapp=ikubernetes/myapp:v3
deployment.apps/myapp-deploy image updated
[root@master01 ~]# kubectl rollout status deployment myapp-deploy
deployment "myapp-deploy" successfully rolled out
[root@master01 ~]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
myapp-deploy 5/5 5 5 33m
[root@master01 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
myapp-deploy-66865f759d 5 5 5 2m16s
myapp-deploy-696fdb5868 0 0 0 33m
myapp-deploy-8644746745 0 0 0 16m
查看Deployment的升级历史
[root@master01 ~]# kubectl rollout history deployment myapp-deploy
deployment.apps/myapp-deploy
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
接回退到当前版本的上一个版本
kubectl rollout undo deployment myapp-deploy
[root@master01 ~]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
myapp-deploy 5/5 5 5 37m
[root@master01 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
myapp-deploy-66865f759d 0 0 0 6m26s
myapp-deploy-696fdb5868 0 0 0 38m
myapp-deploy-8644746745 5 5 5 20m
[root@master01 ~]# kubectl rollout history deployment myapp-deploy
deployment.apps/myapp-deploy
REVISION CHANGE-CAUSE
1 <none>
3 <none>
4 <none>
回退指定版本
kubectl rollout undo deployment myapp-deploy --to-revision=1
[root@master01 ~]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
myapp-deploy 5/5 5 5 46m
[root@master01 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
myapp-deploy-66865f759d 0 0 0 15m
myapp-deploy-696fdb5868 5 5 5 46m
myapp-deploy-8644746745 0 0 0 28m
ot@master01 ~]# kubectl rollout history deployment myapp-deploy
deployment.apps/myapp-deploy
REVISION CHANGE-CAUSE
3 <none>
4 <none>
5 <none>
在执行Deployment
升级的时候最好带上record
参数,便于我们查看历史版本信息
[root@master01 ~]# kubectl apply -f myapp-deploy.yaml --record=true
deployment.apps/myapp-deploy configured
[root@master01 ~]# kubectl rollout history deployment myapp-deploy
deployment.apps/myapp-deploy
REVISION CHANGE-CAUSE
3 <none>
5 <none>
6 kubectl apply --filename=myapp-deploy.yaml --record=true
删除Deployment
kubectl delete deployments.apps myapp-deploy