K8S-Deployment

Deployment 核心概念

Deployment 是 Kubernetes 中管理无状态应用的核心对象,通过声明式配置实现对 Pod 和 ReplicaSet 的自动化管理。其核心功能围绕应用生命周期管理展开:

  • 声明式更新:用户通过 YAML 文件定义期望状态,系统自动调整实际状态至匹配
  • 版本控制:保留历史版本记录,支持滚动更新和快速回滚
  • 扩缩容:动态调整 Pod 副本数量应对负载变化
  • 自愈能力:自动替换故障节点,维持声明副本数

YAML 文件结构解析

典型 Deployment 配置文件包含以下关键字段:

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
关键字段说明

metadata 部分

  • name: 必填字段,定义 Deployment 对象名称
  • labels: 可选标签,用于资源分类和组织

spec 部分核心参数

  • replicas: 指定期望的 Pod 副本数量
  • selector: 标签选择器,确定 Deployment 管理的 Pod 范围
  • template: Pod 模板定义,必须包含匹配 selector 的标签

策略配置扩展

yaml 复制代码
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
  minReadySeconds: 10
  revisionHistoryLimit: 10
  • strategy.type: 更新策略(RollingUpdate/Recreate)
  • maxSurge: 更新期间允许超出副本数的百分比
  • maxUnavailable: 更新期间允许不可用副本比例
  • minReadySeconds: Pod 就绪后等待时间(秒)
  • revisionHistoryLimit: 保留的历史版本数量

操作场景示例

滚动更新触发 修改 Pod 模板中的镜像版本后,自动触发渐进式更新流程:

shell 复制代码
kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1

版本回滚操作 回退到上一个稳定版本:

shell 复制代码
kubectl rollout undo deployment/nginx-deployment

状态监控命令 查看更新进度和状态:

shell 复制代码
kubectl rollout status deployment/nginx-deployment
kubectl get replicasets -l app=nginx

高级配置技巧

资源配额管理 在 Pod 模板中配置资源限制:

yaml 复制代码
resources:
  limits:
    cpu: "500m"
    memory: "512Mi"
  requests:
    cpu: "250m"
    memory: "256Mi"

健康检查配置 添加存活和就绪探针:

yaml 复制代码
livenessProbe:
  httpGet:
    path: /
    port: 80
  initialDelaySeconds: 15
readinessProbe:
  httpGet:
    path: /
    port: 80
  periodSeconds: 5

多容器部署 单个 Pod 中部署多个关联容器:

yaml 复制代码
containers:
- name: nginx
  image: nginx:1.16.1
- name: log-collector
  image: fluentd:latest
bash 复制代码
apiVersion: extensions/v1beta1   #接口版本
kind: Deployment                 #接口类型
metadata:
  name: cango-demo               #Deployment名称
  namespace: cango-prd           #命名空间
  labels:
    app: cango-demo              #标签
spec:
  replicas: 3
  selector:
   matchLabels:
    app: cango-demo  #匹配模板中label
   strategy:
    rollingUpdate:  ##由于replicas为3,则整个升级,pod个数在2-4个之间
      maxSurge: 1      #滚动升级时会先启动1个pod
      maxUnavailable: 1 #滚动升级时允许的最大Unavailable的pod个数
  template:         
    metadata:
      labels:
        app: cango-demo  #模板名称必填
    sepc: #定义容器模板,该模板可以包含多个容器
      containers:                                                                   
        - name: cango-demo                                                           #镜像名称
          image: swr.cn-east-2.myhuaweicloud.com/cango-prd/cango-demo:0.0.1-SNAPSHOT #镜像地址
          command: [ "/bin/sh","-c","cat /etc/config/path/to/special-key" ]    #启动命令
          args:                                                                #启动参数
            - '-storage.local.retention=$(STORAGE_RETENTION)'
            - '-storage.local.memory-chunks=$(STORAGE_MEMORY_CHUNKS)'
            - '-config.file=/etc/prometheus/prometheus.yml'
            - '-alertmanager.url=http://alertmanager:9093/alertmanager'
            - '-web.external-url=$(EXTERNAL_URL)'
    #如果command和args均没有写,那么用Docker默认的配置。
    #如果command写了,但args没有写,那么Docker默认的配置会被忽略而且仅仅执行.yaml文件的command(不带任何参数的)。
    #如果command没写,但args写了,那么Docker默认配置的ENTRYPOINT的命令行会被执行,但是调用的参数是.yaml中的args。
    #如果如果command和args都写了,那么Docker默认的配置被忽略,使用.yaml的配置。
          imagePullPolicy: IfNotPresent  #如果不存在则拉取
          livenessProbe:       #表示container是否处于live状态。如果LivenessProbe失败,LivenessProbe将会通知kubelet对应的container不健康了。随后kubelet将kill掉container,并根据RestarPolicy进行进一步的操作。默认情况下LivenessProbe在第一次检测之前初始化值为Success,如果container没有提供LivenessProbe,则也认为是Success;
            httpGet:
              path: /health #如果没有心跳检测接口就为/
              port: 8080
              scheme: HTTP
            initialDelaySeconds: 60 ##启动后延时多久开始运行检测
            timeoutSeconds: 5
            successThreshold: 1
            failureThreshold: 5
          readinessProbe:
            httpGet:
              path: /health #如果没有心跳检测接口就为/
              port: 8080
              scheme: HTTP
            initialDelaySeconds: 30 ##启动后延时多久开始运行检测
            timeoutSeconds: 5
            successThreshold: 1
            failureThreshold: 5
          resources:              ##CPU内存限制
            requests:
              cpu: 2
              memory: 2048Mi
            limits:
              cpu: 2
              memory: 2048Mi
          env:                    ##通过环境变量的方式,直接传递pod=自定义Linux OS环境变量
            - name: LOCAL_KEY     #本地Key
              value: value
            - name: CONFIG_MAP_KEY  #局策略可使用configMap的配置Key,
              valueFrom:
                configMapKeyRef:
                  name: special-config   #configmap中找到name为special-config
                  key: special.type      #找到name为special-config里data下的key
          ports:
            - name: http
              containerPort: 8080 #对service暴露端口
          volumeMounts:     #挂载volumes中定义的磁盘
          - name: log-cache
            mountPath: /tmp/log
          - name: sdb       #普通用法,该卷跟随容器销毁,挂载一个目录
            mountPath: /data/media    
          - name: nfs-client-root    #直接挂载硬盘方法,如挂载下面的nfs目录到/mnt/nfs
            mountPath: /mnt/nfs
          - name: example-volume-config  #高级用法第1种,将ConfigMap的log-script,backup-script分别挂载到/etc/config目录下的一个相对路径path/to/...下,如果存在同名文件,直接覆盖。
            mountPath: /etc/config       
          - name: rbd-pvc                #高级用法第2中,挂载PVC(PresistentVolumeClaim)
​
#使用volume将ConfigMap作为文件或目录直接挂载,其中每一个key-value键值对都会生成一个文件,key为文件名,value为内容,
  volumes:  # 定义磁盘给上面volumeMounts挂载
  - name: log-cache
    emptyDir: {}
  - name: sdb  #挂载宿主机上面的目录
    hostPath:
      path: /any/path/it/will/be/replaced
  - name: example-volume-config  # 供ConfigMap文件内容到指定路径使用
    configMap:
      name: example-volume-config  #ConfigMap中名称
      items:
      - key: log-script           #ConfigMap中的Key
        path: path/to/log-script  #指定目录下的一个相对路径path/to/log-script
      - key: backup-script        #ConfigMap中的Key
        path: path/to/backup-script  #指定目录下的一个相对路径path/to/backup-script
  - name: nfs-client-root         #供挂载NFS存储类型
    nfs:
      server: 10.42.0.55          #NFS服务器地址
      path: /opt/public           #showmount -e 看一下路径
  - name: rbd-pvc                 #挂载PVC磁盘
    persistentVolumeClaim:
      claimName: rbd-pvc1         #挂载已经申请的pvc磁盘

三、企业应用案例 h3 3.1 环境准备 创建my-blue.yaml

bash 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
 name: mydm
spec:
 replicas: 3
 selector:
  matchLabels:
   app: myapp-blue #匹配模板中label
 template:
  metadata:
   labels:
    app: myapp-blue
  spec:
   containers:
   - name: myapp-blue
     image: janakiramm/myapp:v1
     imagePullPolicy: IfNotPresent
     ports:
     - containerPort: 80

创建访问service my-blue-service.yaml

bash 复制代码
apiVersion: v1
kind: Service
metadata:
  name: service-blue
spec:
  selector:
    app: myapp-blue
  type: NodePort 
  ports:
  - port: 80
    nodePort: 30030
    targetPort: 80

提交对应的资源清单

bash 复制代码
[root@k8s-master01 ~]# kubectl apply -f my-blue.yaml
[root@k8s-master01 ~]# kubectl apply -f my-blue-service.yaml
#查看对应的资源
[root@k8s-master01 ~]# kubectl get pod
NAME                      READY   STATUS    RESTARTS        AGE
mydm-7755b9f55f-7h2nb     1/1     Running   0               69s
mydm-7755b9f55f-bj9gf     1/1     Running   0               69s
mydm-7755b9f55f-hjckc     1/1     Running   0               69s
mydm-7755b9f55f-lfvrd     1/1     Running   0               69s
mydm-7755b9f55f-lxzw4     1/1     Running   0               69s
mydm-7755b9f55f-v74w8     1/1     Running   0               69s
[root@k8s-master01 ~]# kubectl get svc
NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service-blue         NodePort    10.10.157.201   <none>        80:30030/TCP     87s

3.2 扩缩容 修改对应的yaml文件中的replicas的数量

bash 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
 name: mydm
spec:
 replicas: 5
 selector:
  matchLabels:
   app: myapp-blue #匹配模板中label
 template:
  metadata:
   labels:
    app: myapp-blue
  spec:
   containers:
   - name: myapp-blue
     image: janakiramm/myapp:v1
     imagePullPolicy: IfNotPresent
     ports:
     - containerPort: 80

3.3 滚动更新 修改对应的yaml文件中的image信息

bash 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
 name: mydm
spec:
 replicas: 3
 selector:
  matchLabels:
   app: myapp-blue #匹配模板中label
 template:
  metadata:
   labels:
    app: myapp-blue
  spec:
   containers:
   - name: myapp-blue
     image: janakiramm/myapp:v2
     imagePullPolicy: IfNotPresent
     ports:
     - containerPort: 80

3.4 回滚 查看历史版本

bash 复制代码
[root@k8s-master01 ~]# kubectl  rollout history deployment name

回滚操作

bash 复制代码
[root@k8s-master01 ~]# kubectl rollout undo deployment name --to-revision=1

自定义更新策略配置详解

maxSurge与maxUnavailable类型说明

maxSurge

定义与期望副本数相比,允许超出副本数的最大比例或绝对值。数值越大,副本更新速度越快,但可能短暂占用更多资源。

maxUnavailable

定义与期望副本数相比,允许不可用副本的最大比例或绝对值。数值越小,服务稳定性越高,更新过程更平滑,但可能延长更新时间。

设置类型

按数量配置

  • maxUnavailable取值范围为[0, 副本数],例如副本数为10时,可设为3表示最多允许3个副本不可用。
  • maxSurge取值范围为[0, 副本数],例如设为2表示最多允许同时新增2个副本。
  • 两者不能同时为0,否则会导致更新无法进行。

按比例配置

  • maxUnavailable取值范围为[0%, 100%],计算时向下取整。例如10个副本的5%为0.5,实际按0处理。
  • maxSurge取值范围为[0%, 100%],计算时向上取整。例如10个副本的5%为0.5,实际按1处理。
  • 两者不能同时为0%,需至少保证一个参数允许更新动作。
配置案例

案例1:快速更新(侧重速度)

yaml 复制代码
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 30%  # 允许快速扩容30%副本
    maxUnavailable: 10%  # 仅允许10%副本不可用

案例2:平滑更新(侧重稳定性)

yaml 复制代码
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 1  # 每次仅新增1个副本
    maxUnavailable: 0  # 确保所有副本始终可用

案例3:混合配置(平衡速度与稳定性)

yaml 复制代码
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 20%  # 按比例扩容,向上取整
    maxUnavailable: 1  # 按数量控制,最多1个副本不可用

注意事项

  • 生产环境中建议优先保证稳定性(maxUnavailable设为较低值)。
  • 测试环境可适当调高maxSurge以加速迭代。
  • 按比例配置时需注意副本总数,避免因取整规则导致更新停滞。
bash 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-v1
spec:
  replicas: 3
  selector:
   matchLabels:
    app: myapp
    version: v1
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
   metadata:
    labels:
     app: myapp
     version: v1
   spec:
    containers:
    - name: myapp
      image: janakiramm/myapp:v1
      imagePullPolicy: IfNotPresent
      ports:
      - containerPort: 80
相关推荐
eight *3 小时前
docker部署elk+filebeat日志收集分析系统
elk·docker·容器
小股虫3 小时前
分布式事务:在增长中台,我们如何做到“发出去的内容”和“记录的数据”不打架?
分布式·微服务·云原生·架构·团队建设·方法论
自己的九又四分之三站台4 小时前
docker安装pgvector、age和postgis
运维·docker·容器
忧郁蓝调264 小时前
Redis不停机数据迁移:基于 redis-shake 的跨实例 / 跨集群同步方案
运维·数据库·redis·阿里云·缓存·云原生·paas
java1234_小锋4 小时前
ZooKeeper集群中服务器之间是怎样通信的?
分布式·zookeeper·云原生
幺零九零零5 小时前
Docker底层-IPC Namespace(进程间通信隔离)
运维·docker·容器
easy_coder5 小时前
从“未知故障”到“自治诊断”:基于双路召回与RAG的智能诊断系统构建
人工智能·云原生·云计算
eddy-原6 小时前
ELKStack 与 Kubernetes 核心基础知识点综合作业
云原生·容器·kubernetes
V胡桃夹子6 小时前
Docker快速部署apollo
运维·docker·容器
ygqygq27 小时前
Kubernetes Gateway API 与 Envoy Gateway 部署使用指南
kubernetes·gateway·envoy·ingress