Skip to content

1.Deployment场景实践

场景说明:运⾏⼀个demoapp的应⽤,部署3个副本,然后通过service来实现负载均衡;

  • 创建 Deployment资源,部署三个副本
  • 创建 Service资源,通过标签选择器选择对应的Pod,以实现负载均衡;
  • ⽤ curl命令,或Chrome浏览器验证集群⾼可⽤;

image-20240430151005538

1.1 创建

  • 创建yaml文件
yaml
[root@kube-master yaml]# cat test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: demo-container
        image: registry.cn-zhangjiakou.aliyuncs.com/hsuing/demoapp:v1
        ports:
        - name: http-server
          containerPort: 80
[root@kube-master yaml]# cat test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: demo-container
        image: registry.cn-zhangjiakou.aliyuncs.com/hsuing/demoapp:v1
        ports:
        - name: http-server
          containerPort: 80
  • 查看
shell
[root@kube-master yaml]# kubectl get pod
NAME                               READY   STATUS    RESTARTS         AGE
demo-deployment-6b9fc7dc7f-fnsb2   1/1     Running   0                8s
demo-deployment-6b9fc7dc7f-r4j2l   1/1     Running   0                8s
demo-deployment-6b9fc7dc7f-sqw7c   1/1     Running   0                8s
[root@kube-master yaml]# kubectl get pod
NAME                               READY   STATUS    RESTARTS         AGE
demo-deployment-6b9fc7dc7f-fnsb2   1/1     Running   0                8s
demo-deployment-6b9fc7dc7f-r4j2l   1/1     Running   0                8s
demo-deployment-6b9fc7dc7f-sqw7c   1/1     Running   0                8s

1.2 检查dp状态

检查集群的 Deployment

shell
[root@kube-master yaml]# kubectl get deployments.apps
NAME              READY   UP-TO-DATE   AVAILABLE   AGE
demo-deployment   3/3     3            3           79s
[root@kube-master yaml]# kubectl get deployments.apps
NAME              READY   UP-TO-DATE   AVAILABLE   AGE
demo-deployment   3/3     3            3           79s

每列参数含义

NAME 列出了集群中 Deployment 的名称

READY 显示应⽤程序的可⽤的“副本”数。显示的模式是“就绪个数/期望个数”

UP-TO-DATE 显示为了达到期望状态已经更新的副本数

AVAILABLE 显示应⽤可供⽤户使⽤的副本数

AGE 显示应⽤程序运⾏的时间

💡 说明

期望副本数是根据 .spec.replicas 字段设置 3

检查集群的 ReplicaSet

shell
[root@kube-master yaml]# kubectl get rs
NAME                         DESIRED   CURRENT   READY   AGE
demo-deployment-6b9fc7dc7f   3         3         3       6m35s
[root@kube-master yaml]# kubectl get rs
NAME                         DESIRED   CURRENT   READY   AGE
demo-deployment-6b9fc7dc7f   3         3         3       6m35s

NAME 列出名字空间中 ReplicaSet 的名称

DESIRED 显示应⽤的期望副本个数,即在创建 Deployment 时所定义的值。 此为期望状态

CURRENT 显示当前运⾏状态中的副本个数

READY 显示应⽤中有多少副本可以为⽤户提供服务;

AGE 显示应⽤已经运⾏的时间⻓度

❌ 注意

ReplicaSet 的名称被格式化为[Deployment名称]-[随机字符串]

  • 检查pod 是否为3个
shell
[root@kube-master yaml]# kubectl get pod
NAME                               READY   STATUS    RESTARTS        AGE
demo-deployment-6b9fc7dc7f-fnsb2   1/1     Running   0               11m
demo-deployment-6b9fc7dc7f-r4j2l   1/1     Running   0               11m
demo-deployment-6b9fc7dc7f-sqw7c   1/1     Running   0               11m
[root@kube-master yaml]# kubectl get pod
NAME                               READY   STATUS    RESTARTS        AGE
demo-deployment-6b9fc7dc7f-fnsb2   1/1     Running   0               11m
demo-deployment-6b9fc7dc7f-r4j2l   1/1     Running   0               11m
demo-deployment-6b9fc7dc7f-sqw7c   1/1     Running   0               11m

1.3 创建Service

  • 创建yaml文件
yaml
[root@kube-master yaml]# cat test_svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: demo-service
spec:
  selector:				#类似upstream
    app: demo
  ports:
  - name: http	
    port: 8080			# service对外提供的端⼝
    targetPort: 80		# Pod的端⼝
[root@kube-master yaml]# cat test_svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: demo-service
spec:
  selector:				#类似upstream
    app: demo
  ports:
  - name: http	
    port: 8080			# service对外提供的端⼝
    targetPort: 80		# Pod的端⼝
  • 生成
shell
[root@kube-master yaml]# kubectl apply  -f test_svc.yaml
service/demo-service created
[root@kube-master yaml]# kubectl apply  -f test_svc.yaml
service/demo-service created
  • 查看svc地址
shell
[root@kube-master yaml]# kubectl get svc -owide
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE     SELECTOR
demo-service   ClusterIP   192.168.15.149   <none>        8080/TCP         2m11s   app=demo
[root@kube-master yaml]# kubectl get svc -owide
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE     SELECTOR
demo-service   ClusterIP   192.168.15.149   <none>        8080/TCP         2m11s   app=demo
  • 验证集群的可用性
shell
[root@kube-master yaml]# curl 192.168.15.149:8080
hsuing demoapp v1.1 !! ClientIP: 172.25.244.192, PodName: demo-deployment-bf8f88dbc-b5dmc, PodIP: 172.30.0.142!
[root@kube-master yaml]# curl 192.168.15.149:8080
hsuing demoapp v1.1 !! ClientIP: 172.25.244.192, PodName: demo-deployment-bf8f88dbc-b5dmc, PodIP: 172.30.0.142!

1.4 ⽔平伸缩

水平扩展/收缩的功能比较简单,修改replicas对应的副本数即可。比如将Pod 的副本调整到5个,那么Deployment所管理的ReplicaSet则会自动创建一个新的Pod出来,这样就实现水平扩展

shell
kubectl scale deployment demo-deployment --replicas=4

#或者通过edit方式修改
 kubectl edit deployments.apps demo-deployment
 
#或者 通过patch
kubectl patch deployments.apps demo-deployment -p '{"spec":{"replicas":4}}'
deployment.apps/demo-deployment patched
kubectl scale deployment demo-deployment --replicas=4

#或者通过edit方式修改
 kubectl edit deployments.apps demo-deployment
 
#或者 通过patch
kubectl patch deployments.apps demo-deployment -p '{"spec":{"replicas":4}}'
deployment.apps/demo-deployment patched

💡 说明

在deployment 管理下,删除其中一个pod之后,dp回自动补齐副本数

2. Deployment操作

2.1 创建

bash
#创建资源对象
# 根据yaml配置文件一次性创建service和rc
kubectl create -f my-service.yaml -f my-rc.yaml

# 根据<directory>目录下所有.yaml、.yml、.json文件的定义进行创建操作
kubectl create -f <directory>

# 使用命令行创建pod资源
kubectl run nginx --image=nginx:1.16 --port=80 --replicas=3

[root@kube-master ~]# kubectl create deployment deployapp --image=nginx:1.16 --replicas=3
deployment.apps/deployapp created
#创建资源对象
# 根据yaml配置文件一次性创建service和rc
kubectl create -f my-service.yaml -f my-rc.yaml

# 根据<directory>目录下所有.yaml、.yml、.json文件的定义进行创建操作
kubectl create -f <directory>

# 使用命令行创建pod资源
kubectl run nginx --image=nginx:1.16 --port=80 --replicas=3

[root@kube-master ~]# kubectl create deployment deployapp --image=nginx:1.16 --replicas=3
deployment.apps/deployapp created

2.2 查看

shell
[root@kube-master ~]# kubectl get pod
NAME                         READY   STATUS    RESTARTS      AGE
deployapp-7749464894-grrds   1/1     Running   0             3m1s
deployapp-7749464894-jb2xx   1/1     Running   0             3m1s
deployapp-7749464894-nhq4w   1/1     Running   0             3m1s

#查看pod的ip
[root@kube-master ~]# kubectl get pod -owide
NAME                         READY   STATUS    RESTARTS      AGE     IP              NODE          NOMINATED NODE   READINESS GATES
deployapp-7749464894-grrds   1/1     Running   0             3m8s    172.17.74.70    kube-node03   <none>           <none>
deployapp-7749464894-jb2xx   1/1     Running   0             3m8s    172.30.0.137    kube-node01   <none>           <none>
deployapp-7749464894-nhq4w   1/1     Running   0             3m8s    172.23.127.68   kube-node02   <none>           <none>
[root@kube-master ~]# kubectl get pod
NAME                         READY   STATUS    RESTARTS      AGE
deployapp-7749464894-grrds   1/1     Running   0             3m1s
deployapp-7749464894-jb2xx   1/1     Running   0             3m1s
deployapp-7749464894-nhq4w   1/1     Running   0             3m1s

#查看pod的ip
[root@kube-master ~]# kubectl get pod -owide
NAME                         READY   STATUS    RESTARTS      AGE     IP              NODE          NOMINATED NODE   READINESS GATES
deployapp-7749464894-grrds   1/1     Running   0             3m8s    172.17.74.70    kube-node03   <none>           <none>
deployapp-7749464894-jb2xx   1/1     Running   0             3m8s    172.30.0.137    kube-node01   <none>           <none>
deployapp-7749464894-nhq4w   1/1     Running   0             3m8s    172.23.127.68   kube-node02   <none>           <none>

2.3 扩展Pod副本

shell
#扩展,从3到5
kubectl scale deployment deployapp --replicas=5

#查看
[root@kube-master ~]# kubectl get pod
NAME                         READY   STATUS    RESTARTS      AGE
deployapp-7749464894-dkp72   1/1     Running   0             87s
deployapp-7749464894-grrds   1/1     Running   0             6m22s
deployapp-7749464894-jb2xx   1/1     Running   0             6m22s
deployapp-7749464894-nhq4w   1/1     Running   0             6m22s
deployapp-7749464894-wdbw9   1/1     Running   0             87s
#扩展,从3到5
kubectl scale deployment deployapp --replicas=5

#查看
[root@kube-master ~]# kubectl get pod
NAME                         READY   STATUS    RESTARTS      AGE
deployapp-7749464894-dkp72   1/1     Running   0             87s
deployapp-7749464894-grrds   1/1     Running   0             6m22s
deployapp-7749464894-jb2xx   1/1     Running   0             6m22s
deployapp-7749464894-nhq4w   1/1     Running   0             6m22s
deployapp-7749464894-wdbw9   1/1     Running   0             87s

2.4 缩减Pod副本

shell
kubectl scale deployment deployapp --replicas=3
kubectl scale deployment deployapp --replicas=3

2.5 发布应用

通过Service将应用发布出来,而后集群中的应用就可以通过ServiceIP或域名来访问该复制均衡

shell
--port: 集群内访问service的端口

--target-port: pod容器提供的端口

kubectl expose deployment deployapp --port=8888 --target-port=80

#查看service
[root@kube-master ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)          AGE
deployapp    ClusterIP   192.168.132.134   <none>        8888/TCP         111s
kubernetes   ClusterIP   192.168.0.1       <none>        443/TCP          29h
nginx        NodePort    192.168.253.94    <none>        8080:32498/TCP   6h51m
--port: 集群内访问service的端口

--target-port: pod容器提供的端口

kubectl expose deployment deployapp --port=8888 --target-port=80

#查看service
[root@kube-master ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)          AGE
deployapp    ClusterIP   192.168.132.134   <none>        8888/TCP         111s
kubernetes   ClusterIP   192.168.0.1       <none>        443/TCP          29h
nginx        NodePort    192.168.253.94    <none>        8080:32498/TCP   6h51m

2.6 更新

bash
kubectl set image deployment/deployapp nginx=nginx:1.18

kubectl get pod
kubectl set image deployment/deployapp nginx=nginx:1.18

kubectl get pod

2.7 回滚

bash
查看版本信息
$ kubectl rollout history deployment deployapp

查看更新状态:
$ kubectl rollout status deployment deployapp

终止升级
$ kubectl rollout pause deployment/deployapp

继续升级
$ kubectl rollout resume deployment/deployapp

回滚到上一个版本
$ kubectl rollout undo deployments deployapp

回滚到指定版本
$ kubectl rollout undo deployments deployapp --to-revision=1
查看版本信息
$ kubectl rollout history deployment deployapp

查看更新状态:
$ kubectl rollout status deployment deployapp

终止升级
$ kubectl rollout pause deployment/deployapp

继续升级
$ kubectl rollout resume deployment/deployapp

回滚到上一个版本
$ kubectl rollout undo deployments deployapp

回滚到指定版本
$ kubectl rollout undo deployments deployapp --to-revision=1

3. Deployment升级过程

以下是Deployment进行滚动升级的基本步骤:

  1. 更新Deployment配置

    • 首先,你需要更新Deployment的yaml配置文件,例如更改镜像标签到新版本的应用程序镜像。
  2. 提交变更

    • 应用这些更改,通过kubectl apply命令或API调用将新的配置应用到集群中。
  3. 启动滚动更新

    • Kubernetes Deployment控制器检测到配置变化后,会开始执行滚动更新策略。默认情况下,它采用滚动更新(RollingUpdate)策略。
  4. 逐步替换Pod

    • 滚动更新策略会按照ReplicaSet中的Pod副本数量和指定的

      .spec.strategy.rollingUpdate.maxUnavailable
      .spec.strategy.rollingUpdate.maxUnavailable

      .spec.strategy.rollingUpdate.maxSurge
      .spec.strategy.rollingUpdate.maxSurge

      参数来逐步创建新版本Pod,并同时删除旧版本Pod。

      • maxUnavailable 定义了可以有多少个Pod不可用(未就绪)而不会影响服务的整体可用性。
      • maxSurge 则指定了可以比期望副本数多创建多少个Pod,以加速升级过程。
  5. 健康检查

    • 在每个新Pod被创建之后,Kubernetes会根据定义的livenessProbe和readinessProbe来检查新Pod是否已经启动并准备好接收流量。
  6. 流量转移

    • 当新Pod通过健康检查并标记为“就绪”时,Service会逐渐将流量从旧Pod转移到新Pod。
  7. 完成升级

    • 一旦所有旧Pod都被新Pod替换并且新版本的所有Pod都已准备就绪,则升级过程结束。
  8. 回滚机制

    • 如果在升级过程中出现问题,可以通过回滚Deployment到之前的修订版来恢复到之前的工作状态。
  9. 清理旧版本

    • 一旦验证新版本的应用程序正常工作,可以逐步删除旧版本的Pod副本,以释放资源。