Kubernetes Deployment 使用介绍

84

通常,Pod 不会被直接创建和管理,而是由更高级别的控制器,例如 Deployment 来创建和管理。 这是因为控制器提供了更强大的应用程序管理功能。

应用管理:Deployment 是 Kubernetes 中的一个控制器,用于管理应用程序的部署和更新。它允许你定义应用程序的期望状态,然后确保集群中的副本数符合这个状态。

自愈能力:Deployment 可以自动修复故障,如果 Pod 失败,它将启动新的 Pod 来替代。这有助于确保应用程序的高可用性。

滚动更新:Deployment 支持滚动更新,允许你逐步将新版本的应用程序部署到集群中,而不会导致中断。

副本管理:Deployment 负责管理 Pod 的副本,可以指定应用程序需要的副本数量,Deployment 将根据需求来自动调整。

声明性配置:Deployment 的配置是声明性的,你只需定义所需的状态,而不是详细指定如何实现它。Kubernetes 会根据你的声明来管理应用程序的状态。

1. 部署 deployment

1.1 创建 deployment 资源文件

#go-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  # deployment 唯一名称
  name: hellok8s-go-http
spec:
  replicas: 2 # 副本数量
  selector:
    matchLabels:
      app: hellok8s # 管理template下所有 app=hellok8s的pod,(要求和template.metadata.labels完全一致!!!否则无法部署deployment)
  template: # template 定义一组容器
    metadata:
      labels:
        app: hellok8s
    spec:
      containers:
        - image: leigg/hellok8s:v1
          name: hellok8s

1.2 使用kubectl 访问 api-server 执行创建

[root@kube-01 data]# kubectl apply -f go-deployment.yaml
deployment.apps/hellok8s-go-http created

1.3 显示该 Deployment 的相关信息

[root@kube-01 data]# kubectl describe deployment hellok8s-go-http
Name:                   hellok8s-go-http
Namespace:              default
CreationTimestamp:      Fri, 28 Mar 2025 16:47:20 +0800
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=hellok8s
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=hellok8s
  Containers:
   hellok8s:
    Image:        leigg/hellok8s:v1
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   hellok8s-go-http-6645bf8bd4 (2/2 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  116s  deployment-controller  Scaled up replica set hellok8s-go-http-6645bf8bd4 to 2
[root@kube-01 data]# 

1.4 列出该 Deployment 创建的 Pod

[root@kube-01 data]# kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
hellok8s-go-http-6645bf8bd4-8ggmk   1/1     Running   0          6m24s
hellok8s-go-http-6645bf8bd4-frl6v   1/1     Running   0          6m24s
nginx-pod                           1/1     Running   0          122m

1.5 展示某一个 Pod 信息

[root@kube-01 data]# kubectl describe pod hellok8s-go-http-6645bf8bd4-8ggmk
Name:         hellok8s-go-http-6645bf8bd4-8ggmk
Namespace:    default
Priority:     0
Node:         kube-03/192.168.80.203
Start Time:   Fri, 28 Mar 2025 16:47:20 +0800
Labels:       app=hellok8s
              pod-template-hash=6645bf8bd4
Annotations:  cni.projectcalico.org/containerID: 79faf397d84c82f812c96d1a9f28cf68f3eb8f00fbb259362b98a53da698d123
              cni.projectcalico.org/podIP: 10.233.69.115/32
              cni.projectcalico.org/podIPs: 10.233.69.115/32
Status:       Running
IP:           10.233.69.115
IPs:
  IP:           10.233.69.115
Controlled By:  ReplicaSet/hellok8s-go-http-6645bf8bd4
Containers:
  hellok8s:
    Container ID:   docker://468e7698c259a9dd108d93f702492fde80fdbd2de338e1c0a9d314682e55246e
    Image:          leigg/hellok8s:v1
    Image ID:       docker-pullable://leigg/hellok8s@sha256:bcfb541375d6feb2f50531e480cd2981b73ed340fb835a81eec087aa59688406
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Fri, 28 Mar 2025 16:47:44 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-bdk9v (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  kube-api-access-bdk9v:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  7m59s  default-scheduler  Successfully assigned default/hellok8s-go-http-6645bf8bd4-8ggmk to kube-03
  Normal  Pulling    7m58s  kubelet            Pulling image "leigg/hellok8s:v1"
  Normal  Pulled     7m35s  kubelet            Successfully pulled image "leigg/hellok8s:v1" in 23.378462223s (23.378468191s including waiting)
  Normal  Created    7m35s  kubelet            Created container hellok8s
  Normal  Started    7m35s  kubelet            Started container hellok8s
[root@kube-01 data]#

2. 修改 deployment

2.1 编辑deployment资源文件

Copy之前的go-deployment.yaml,创建一个新的go-deployment-latest.yaml,来更新 Deployment。

下面的 YAML 文件指定该 Deployment 镜像更新为 leigg/hellok8s:latest

#go-deployment-latest.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  # deployment 唯一名称
  name: hellok8s-go-http
spec:
  replicas: 2 # 副本数量
  selector:
    matchLabels:
      app: hellok8s # 管理template下所有 app=hellok8s的pod,(要求和template.metadata.labels完全一致!!!否则无法部署deployment)
  template: # template 定义一组容器
    metadata:
      labels:
        app: hellok8s
    spec:
      containers:
        - image: leigg/hellok8s:latest # 更新镜像
          name: hellok8s

2.2 应用新的 YAML

kubectl apply -f go-deployment-latest.yaml

2.3 通过增加副本数来扩缩应用

你可以通过应用新的 YAML 文件来增加 Deployment 中 Pod 的数量。 下面的 YAML 文件将 replicas 设置为 4,指定该 Deployment 应有 4 个 Pod:

2.4 删除Deployee

kubectl delete deployment hellok8s-go-http

滚动更新(Rolling Update)

k8s 1.15 版本起支持滚动更新,即先创建新的 pod,创建成功后再删除旧的 pod,确保更新过程无感知,大大降低对业务影响。

在 deployment 的资源定义中, spec.strategy.type 有两种选择:

  • RollingUpdate: 逐渐增加新版本的 pod,逐渐减少旧版本的 pod。(常用)

  • Recreate: 在新版本的 pod 增加前,先将所有旧版本 pod 删除(针对那些不能多进程部署的服务)

另外,还可以通过以下字段来控制升级 pod 的速率:

  • maxSurge: 最大峰值,用来指定可以创建的超出期望 Pod 个数的 Pod 数量。

  • maxUnavailable: 最大不可用,用来指定更新过程中不可用的 Pod 的个数上限。

如果不设置,deployment 会有默认的配置。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hellok8s-go-http
spec:
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  replicas: 3
省略其他熟悉的配置项。。。

存活探针 (livenessProb)

存活探测器来确定什么时候要重启容器。 例如,存活探测器可以探测到应用死锁(应用程序在运行,但是无法继续执行后面的步骤)情况。 重启这种状态下的容器有助于提高应用的可用性,即使其中存在缺陷。

apiVersion: apps/v1
kind: Deployment
metadata:
  # deployment唯一名称
  name: hellok8s-go-http
spec:
  replicas: 2 # 副本数量
  selector:
    matchLabels:
      app: hellok8s # 管理template下所有 app=hellok8s的pod,(要求和template.metadata.labels完全一致!!!否则无法部署deployment)
  template: # template 定义一组pod
    metadata:
      labels:
        app: hellok8s
    spec:
      containers:
        - image: leigg/hellok8s:v1
          name: hellok8s
          # 存活探针
          livenessProbe:
            # http get 探测指定pod提供HTTP服务的路径和端口
            httpGet:
              path: /healthz
              port: 3000
            # 3s后开始探测
            initialDelaySeconds: 3
            # 每3s探测一次
            periodSeconds: 3

还有其他探测方式,比如 TCP、gRPC、Shell 命令。

参考官方文档: https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/

就绪探针 (readiness)

就绪探测器可以知道容器何时准备好接受请求流量,当一个 Pod 内的所有容器都就绪时,才能认为该 Pod 就绪。

这种信号的一个用途就是控制哪个 Pod 作为 Service 的后端。若 Pod 尚未就绪,会被从 Service 的负载均衡器中剔除。

如果一个 Pod 升级后不能就绪,就不应该允许流量进入该 Pod,否则升级完成后导致所有服务不可用。

apiVersion: apps/v1
kind: Deployment
metadata:
  # deployment唯一名称
  name: hellok8s-go-http
spec:
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  replicas: 3 # 副本数量
  selector:
    matchLabels:
      app: hellok8s # 管理template下所有 app=hellok8s的pod,(要求和template.metadata.labels完全一致!!!否则无法部署deployment)
  template: # template 定义一组pod
    metadata:
      labels:
        app: hellok8s
    spec:
      containers:
        - image: leigg/hellok8s:v1
          name: hellok8s
          # 就绪探针
          readinessProbe:
            # http get 探测pod提供HTTP服务的路径和端口
            httpGet:
              path: /healthz
              port: 3000
            initialDelaySeconds: 1 # 1s后开始探测
            periodSeconds: 5 # 每5s探测一次
            timeoutSeconds: 1 # 单次探测超时,默认1
            failureThreshold: 3 # 探测失败时,k8s的重试次数,默认3,达到这个次数后 停止探测,并打上未就绪的标签

底层控制器 ReplicaSet

实际上,Pod 的副本集功能并不是由 Deployment 直接提供的,而是由 Deployment 管理的 ReplicaSet 控制器来提供的。

ReplicaSet 是一个相比 Deployment 更低级的控制器,它负责维护一组在任何时候都处于运行状态且符合预期数量的 Pod 副本的稳定集合。 然而由于 ReplicaSet 不具备滚动更新和回滚等一些业务常用的流水线功能,所以通常情况下,我们更推荐使用 Deployment 或 DaemonSet 等其他控制器 而不是直接使用 ReplicaSet。通过 https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/replicaset/了解更多 ReplicaSet 细节。

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  # 按你的实际情况修改副本数
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
        - name: php-redis
          image: gcr.io/google_samples/gb-frontend:v3