我们通常用Deployment来部署无状态服务,Deployment能够以声明的方式更新Pod和ReplicaSet,所谓“声明”的方式是将一些特定场景的一些列运维步骤固化下来,以便快速准确的执行。
1. 定义一个Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
我们对比之前定义的ReplicaSet,发现处理kind不同之外,其他基本一样。
2. 创建Deployment
kubectl apply -f 文件名.yml
[root@k8s-master1 deployments]# kubectl apply -f 01-create-deployment.yml
deployment.apps/nginx-deployment created
3. 查看Deployment
简单查询:kubectl get deployments
查看更多信息: kubectl get deployments -o wide
查看更多描述信息: kubectl describe deployment 名称
[root@k8s-master1 deployments]# kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 0/2 2 0 61s
[root@k8s-master1 deployments]# kubectl get deployments -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deployment 0/2 2 0 70s nginx nginx:latest app=nginx
[root@k8s-master1 deployments]# kubectl describe deployment nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Tue, 20 Dec 2022 15:06:49 +0800
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 3
Selector: app=nginx
Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:latest
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: nginx-deployment-585449566 (2/2 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 26m deployment-controller Scaled up replica set nginx-deployment-585449566 to 2
Normal ScalingReplicaSet 15m deployment-controller Scaled up replica set nginx-deployment-76f59d996 to 1
Normal ScalingReplicaSet 14m deployment-controller Scaled down replica set nginx-deployment-585449566 to 1
Normal ScalingReplicaSet 14m deployment-controller Scaled up replica set nginx-deployment-76f59d996 to 2
Normal ScalingReplicaSet 14m deployment-controller Scaled down replica set nginx-deployment-585449566 to 0
Normal ScalingReplicaSet 5m9s deployment-controller Scaled up replica set nginx-deployment-585449566 to 1
Normal ScalingReplicaSet 4m48s deployment-controller Scaled down replica set nginx-deployment-76f59d996 to 1
Normal ScalingReplicaSet 4m48s deployment-controller Scaled up replica set nginx-deployment-585449566 to 2
Normal ScalingReplicaSet 4m40s deployment-controller Scaled down replica set nginx-deployment-76f59d996 to 0
[root@k8s-master1 deployments]#
在检查集群中的 Deployment 时,所显示的字段有:
- NAME:列出了名字空间中 Deployment 的名称。
- READY:显示应用程序的可用的“副本”数。显示的模式是“就绪个数/期望个数”。
- UP-TO-DATE:显示为了达到期望状态已经更新的副本数。
- AVAILABLE:显示应用可供用户使用的副本数。
- AGE:显示应用程序运行的时间。
- CONTAINERS:显示容器名称
- IMAGES: 显示容器镜像
- SELECTOR:显示标签选择器
查看上线状态:kubectl rollout status deployment deployment名称
[root@k8s-master1 deployments]# kubectl rollout status deployment nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 0 of 2 updated replicas are available...
Waiting for deployment "nginx-deployment" rollout to finish: 1 of 2 updated replicas are available...
deployment "nginx-deployment" successfully rolled out
查看Deployment创建的ReplicaSet:kubectl get rs
[root@k8s-master1 deployments]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-585449566 2 2 2 2m7s
ReplicaSet名称与Deployment名称匹配上。ReplicaSet 输出中包含以下字段:
- NAME: 列出名字空间中 ReplicaSet 的名称;
- DESIRED: 显示应用的期望副本个数,即在创建 Deployment 时所定义的值。 此为期望状态;
- CURRENT: 显示当前运行状态中的副本个数;
- READY: 显示应用中有多少副本可以为用户提供服务;
- AGE: 显示应用已经运行的时间长度。
注意 ReplicaSet 的名称始终被格式化为[Deployment名称]-[哈希]。 其中的哈希字符串与 ReplicaSet 上的 pod-template-hash 标签一致。可以通过kubectl get rs --show-labels查看到标签信息。
[root@k8s-master1 deployments]# kubectl get rs --show-labels
NAME DESIRED CURRENT READY AGE LABELS
nginx-deployment-585449566 2 2 2 7m25s app=nginx,pod-template-hash=585449566
4. 更新Deployment
方式一:使用kubectl set命令
kubectl set image deployment nginx-deployment nginx=nginx:1.16.1
[root@k8s-master1 deployments]# kubectl set image deployment nginx-deployment nginx=nginx:1.16.1
deployment.apps/nginx-deployment image updated
[root@k8s-master1 deployments]# kubectl rollout status deployment nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deployment" successfully rolled out
[root@k8s-master1 deployments]# kubectl get deployment -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deployment 2/2 2 2 17m nginx nginx:1.16.1 app=nginx
方式二:使用kubectl edit 命令
kubectl edit deployment nginx-deployment
修改信息后,输入:wq保存退出。
[root@k8s-master1 deployments]# kubectl edit deployment nginx-deployment
deployment.apps/nginx-deployment edited
You have new mail in /var/spool/mail/root
[root@k8s-master1 deployments]# kubectl get deployment -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deployment 2/2 1 2 21m nginx nginx:latest app=nginx
[root@k8s-master1 deployments]# kubectl rollout status deployment/nginx-deployment
deployment "nginx-deployment" successfully rolled out
5. 删除Deployment
kubectl delete -f 文件名.yml
[root@k8s-master1 deployments]# kubectl delete -f 01-create-deployment.yml
deployment.apps "nginx-deployment" deleted
6. 回滚Deployment
当Deployment的Pod模板(.spec.template)发生变更时,比如模板的标签或者容器镜像发生变化,会创建新的修订版本,而其他的更新,如Deployment的扩缩容操作不会创建Deployment修订版本。
查看修订版本记录: kubectl rollout history deployment 名称
查看具体某个修订版本的变更记录:kubectl rollout history deployment 名称 --revision=版本号
[root@k8s-master1 deployments]# kubectl rollout history deployment nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>
[root@k8s-master1 deployments]# kubectl rollout history deployment nginx-deployment --revision=2
deployment.apps/nginx-deployment with revision #2
Pod Template:
Labels: app=nginx
pod-template-hash=76f59d996
Containers:
nginx:
Image: nginx:1.16.1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
回滚到上一个版本:kubectl rollout undo deployment 名称
回滚到指定版本:kubectl rollout undo deployment 名称 --to-revision=版本号
[root@k8s-master1 deployments]# kubectl rollout undo deployment nginx-deployment
deployment.apps/nginx-deployment rolled back
[root@k8s-master1 deployments]# kubectl get deployment -owide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deployment 2/2 2 2 9m8s nginx nginx:latest app=nginx
[root@k8s-master1 deployments]# kubectl rollout history deployment nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
2 <none>
4 <none>
5 <none>
[root@k8s-master1 deployments]# kubectl rollout undo deployment nginx-deployment --to-revision=4
deployment.apps/nginx-deployment rolled back
[root@k8s-master1 deployments]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 2/2 1 2 9m52s
[root@k8s-master1 deployments]# kubectl get deployment -owide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deployment 2/2 1 2 9m56s nginx nginx:1.14.2 app=nginx
7. 缩放Deployment
手动缩放:kubectl scale deployment 名称 --replicas=副本数
例如:kubectl scale deployment nginx-deployment --replicas=1
自动缩放:kubectl autoscale deployment 名称 --min=副本数 --max=副本数 --cpu-percent=比例
例如:kubectl autoscale deployment nginx-deployment --min=1 --max=3 --cpu-percent=80
[root@k8s-master1 deployments]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 2/2 2 2 15m
[root@k8s-master1 deployments]# kubectl scale deployment nginx-deployment --replicas=1
deployment.apps/nginx-deployment scaled
[root@k8s-master1 deployments]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 1/1 1 1 16m
[root@k8s-master1 deployments]# kubectl autoscale deployment nginx-deployment --min=1 --max=3 --cpu-percent=80
horizontalpodautoscaler.autoscaling/nginx-deployment autoscaled
You have new mail in /var/spool/mail/root
[root@k8s-master1 deployments]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 1/1 1 1 17m
8. 暂停和恢复Deployment
(1)暂停上线:kubectl rollout pause deployment 名称
例如:kubectl rollout pause deployment nginx-deployment
(2)恢复上线:kubectl rollout resume deployment 名称
例如:kubectl rollout resume deployment nginx-deployment
9. 金丝雀发布(灰度发布)
如果想将最新的应用程序版本发布给一部分用户(或服务器),可以为每个版本创建一个Deployment,此时应用程序的新旧两个版本都将同时获得生产上的流量,具体的执行过程如下:
(1)部署第一个版本的Deployment,该版本包含了2个Pod副本,Service通过label selector 【app:nginx】选择对应的Pod,具体配置内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.16.1
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx
spec:
selector:
app: nginx
ports:
- name: nginx-port
protocol: TCP
port: 80
nodePort: 32600
targetPort: 80
type: NodePort
(2)假设此时想要发布新的版本nignx:latest,那么可以创建第二个Deployment,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment-canary
labels:
app: nginx
track: canary
spec:
replicas: 1
selector:
matchLabels:
app: nginx
track: canary
template:
metadata:
labels:
app: nginx
track: canary
spec:
containers:
- name: nginx
image: nginx:latest
由于Service的LabelSeletor是 app:nginx ,而由nginx-deployment和nginx-deployment-canary创建的Pod都带有标签 app:nginx ,所以Service的流量将会在两个deployment之间分配,分配的比例根据deployment的replicas配置。
当确定新版本没有问题之后,可以将nginx-deployment的镜像标签修改为新版本的镜像标签,并在完成对nginx-deployment的滚动更新之后,删除nginx-deployment-canary这个Deployment。
(3)测试过程
修改新版本nginx对应pod中,nginx的index.html 文件内容
[root@k8s-master1 deployments]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-7f785d94f5-8crb9 1/1 Running 0 6m32s
nginx-deployment-7f785d94f5-xdw2t 1/1 Running 0 6m32s
nginx-deployment-canary-5c9598bbb4-vjrlk 1/1 Running 0 3m33s
[root@k8s-master1 deployments]#
[root@k8s-master1 deployments]# kubectl exec -it pod nginx-deployment-canary-5c9598bbb4-vjrlk
root@nginx-deployment-canary-5c9598bbb4-vjrlk:/etc/nginx/conf.d# cd /usr/share/nginx/html/
root@nginx-deployment-canary-5c9598bbb4-vjrlk:/usr/share/nginx/html# ls
50x.html index.html
root@nginx-deployment-canary-5c9598bbb4-vjrlk:/usr/share/nginx/html# echo 'canary deploy' > index.html
[root@k8s-master1 deployments]# kubectl get service -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d1h <none>
nginx-service NodePort 10.102.214.102 <none> 80:32600/TCP 10m app=nginx
通过浏览访问:http://192.168.253.111:32600/