我们通常用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/
image-1671527757486

打赏
支付宝 微信
上一篇 下一篇