深入理解k8s中pod、service、deployment和statefulSet等工作负载--图文篇

一、Pod、Deployment和Service的角色关系

k8s集群中,Deployment、Pod、Service是最重要的三个概念之一。对于新手如何理解它们的职责呢嗯?

下面的图形是对它们关系的形象总结。

Pod 是牛马打工人,永远有负载运行。

Deployment 是创建Pod 和控制副本数的对象,Pod 要岁时随刻满足它的期望状态。所以它就是纪律管理员,Pod数量永远要保证出勤和数量。可以说它天生有强烈的控制欲望。

对于Service服务,它既是一组pod 的流量入口,也是对外发布信息的"网关"。就好比酒店大堂的总接待人。具体任务过来,它会分配给后端某个具体的Pod。


二、Pod、Deployment和Service的Spec配置

Kubernetes 的核心设计思想是 "声明式 API":用户通过 YAML 声明资源应该达到的状态。

所有资源(如 Pod、Deployment、Service、ConfigMap 等)的 YAML 配置中,spec是核心字段之一,定义了资源的 "期望"状态。

以上三种资源最重要的定义部分,都罗列到这张图里了,记得收藏哦!

2.1 Pod中spec定义部分

Pod的完整示例:

bash 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: production-web-app
  labels:
    app: web-app
    tier: frontend
    version: v1.2.3
  annotations:
    kubernetes.io/change-cause: "Deploy version v1.2.3 with security fixes"
    prometheus.io/scrape: "true"
    prometheus.io/port: "8080"
spec:
  # 调度配置
  nodeSelector:
    node-type: optimized-web
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - web-app
        topologyKey: kubernetes.io/hostname
  
  # 安全配置
  serviceAccountName: web-app-sa
  securityContext:
    runAsUser: 1001
    runAsGroup: 1001
    fsGroup: 1001
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
  
  # 存储配置
  volumes:
  - name: app-config
    configMap:
      name: web-app-config
      defaultMode: 0644
  - name: tmp-volume
    emptyDir:
      medium: Memory
      sizeLimit: 128Mi
  - name: tls-secrets
    secret:
      secretName: web-app-tls
      defaultMode: 0600
  
  # 初始化容器
  initContainers:
  - name: init-config
    image: busybox:1.35
    command: ['sh', '-c', 'echo "Waiting for config..." && until [ -f /etc/config/ready ]; do sleep 2; done']
    volumeMounts:
    - name: app-config
      mountPath: /etc/config
    securityContext:
      runAsUser: 1001
      allowPrivilegeEscalation: false
  
  # 主容器
  containers:
  - name: web-app
    image: my-registry/app/web:v1.2.3
    imagePullPolicy: IfNotPresent
    
    # 资源限制
    resources:
      requests:
        cpu: 500m
        memory: 512Mi
        ephemeral-storage: 1Gi
      limits:
        cpu: 1000m
        memory: 1024Mi
        ephemeral-storage: 2Gi
    
    # 端口配置
    ports:
    - name: http
      containerPort: 8080
      protocol: TCP
    - name: metrics
      containerPort: 9090
      protocol: TCP
    
    # 环境变量
    env:
    - name: APP_ENV
      value: "production"
    - name: LOG_LEVEL
      value: "info"
    - name: CONFIG_PATH
      value: "/etc/app/config"
    - name: NODE_NAME
      valueFrom:
        fieldRef:
          fieldPath: spec.nodeName
    - name: POD_IP
      valueFrom:
        fieldRef:
          fieldPath: status.podIP
    
    # 健康检查
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: X-Health-Check
          value: "liveness"
      initialDelaySeconds: 45
      timeoutSeconds: 3
      periodSeconds: 10
      failureThreshold: 3
    
    readinessProbe:
      httpGet:
        path: /readyz
        port: 8080
      initialDelaySeconds: 5
      timeoutSeconds: 2
      periodSeconds: 5
      successThreshold: 1
      failureThreshold: 2
    
    startupProbe:
      httpGet:
        path: /healthz
        port: 8080
      failureThreshold: 30
      periodSeconds: 10
    
    # 生命周期钩子
    lifecycle:
      postStart:
        exec:
          command:
          - "/bin/sh"
          - "-c"
          - |
            echo "Pod $POD_NAME started on $NODE_NAME" > /tmp/startup.log
      preStop:
        httpGet:
          path: /prestop
          port: 8080
    
    # 存储挂载
    volumeMounts:
    - name: app-config
      mountPath: /etc/app/config
      readOnly: true
    - name: tmp-volume
      mountPath: /tmp
    - name: tls-secrets
      mountPath: /etc/tls
      readOnly: true
    
    # 容器安全上下文
    securityContext:
      allowPrivilegeEscalation: false
      runAsNonRoot: true
      runAsUser: 1001
      capabilities:
        drop:
        - ALL
      readOnlyRootFilesystem: true
  
  # Pod 级别配置
  restartPolicy: Always
  terminationGracePeriodSeconds: 60
  dnsPolicy: ClusterFirst
  hostNetwork: false
  hostPID: false
  hostIPC: false
  imagePullSecrets:
  - name: registry-credentials

2.2 Deployment中spec定义部分

以下是一个包含上述主要配置的 Deployment 完整 YAML:

bash 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  minReadySeconds: 5
  revisionHistoryLimit: 5
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "100m"
            memory: "128Mi"
          limits:
            cpu: "200m"
            memory: "256Mi"

2.3 Service的spec定义部分

Kubernetes 中 Service 是 将运行在一个或一组 Pod 上的网络应用程序公开为网络服务的方法。

以下是一个包含上述主要配置的service完整yaml:

bash 复制代码
apiVersion: v1
kind: Service
metadata:
  name: production-web-service
  namespace: web-production
  labels:
    app: web-application
    environment: production
  annotations:
    # 云厂商特定注解
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
    service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true"
    service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:us-west-2:123456789012:certificate/xxxxxx"
    # 运维相关注解
    prometheus.io/scrape: "true"
    prometheus.io/port: "9090"
spec:
  # 服务类型配置
  type: LoadBalancer
  
  # 选择器 - 关联后端 Pod
  selector:
    app: web-frontend
    component: api-server
    environment: production
    version: v2.1.3
  
  # 端口映射配置
  ports:
  - name: http-web
    protocol: TCP
    port: 80
    targetPort: 8080
    appProtocol: http
    
  - name: https-web
    protocol: TCP
    port: 443
    targetPort: 8443
    appProtocol: https
    
  - name: metrics
    protocol: TCP
    port: 9090
    targetPort: 9090
    appProtocol: http  # 指标端点通常使用 HTTP
    
  - name: grpc-api
    protocol: TCP
    port: 50051
    targetPort: 50051
    appProtocol: grpc
  
  # IP 地址配置
  clusterIP: 10.96.105.150  # 固定 ClusterIP,便于防火墙规则
  loadBalancerIP: 203.0.113.25  # 预留的负载均衡器 IP
  
  # 外部 IP(用于混合云或特定网络场景)
  externalIPs:
  - 192.168.1.200
  - 192.168.1.201
  
  # 会话保持配置
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800  # 3小时会话保持
  
  # 流量策略
  externalTrafficPolicy: Local  # 保留客户端源 IP,流量只路由到本地节点 Pod
  internalTrafficPolicy: Cluster  # 内部流量在集群内所有 Pod 间负载均衡
  
  # 健康检查配置(NodePort 类型相关)
  healthCheckNodePort: 32456  # 自定义健康检查端口
  
  # 负载均衡器源范围限制
  loadBalancerSourceRanges:
  - 203.0.113.0/24
  - 198.51.100.0/24
  - 192.168.0.0/16

三、Statefulset、DaemonSet和Job深入理解

3.1 StatefulSet的Spec配置项

StatefulSet 运行一组 Pod,并为每个 Pod 保留一个稳定的标识。 这可用于管理需要持久化存储或稳定、唯一网络标识的应用。

StatefulSet 用于管理有状态应用,spec 核心字段围绕 "稳定标识""有序部署 / 更新"、"存储持久化" 设计。

bash 复制代码
spec:
  replicas: <int>                  # 期望副本数(默认1)
  selector: <LabelSelector>        # 匹配Pod的标签选择器(必须与template.metadata.labels一致)
  template: <PodTemplateSpec>      # Pod模板(定义Pod的容器、网络、资源等)
  serviceName: <string>            # 关联的Headless Service名称(用于Pod网络标识,必填)
  volumeClaimTemplates: <[]PersistentVolumeClaim>  # PVC模板(为每个Pod创建独立PVC,实现存储持久化)
  updateStrategy:                  # 更新策略(默认RollingUpdate)
    type: <string>                 # 策略类型:RollingUpdate(滚动更新)/OnDelete(手动删除旧Pod才更新)
    rollingUpdate:                 # 当type为RollingUpdate时生效
      partition: <int>             # 分区更新:仅更新序号≥partition的Pod(用于灰度发布)
  revisionHistoryLimit: <int>      # 保留的历史版本数(默认10,用于回滚)
  minReadySeconds: <int>           # 新Pod就绪后,等待多少秒再继续更新(默认0)

StatefulSet 对于需要满足以下一个或多个需求的应用程序很有价值。

  • 稳定的、唯一的网络标识符。
  • 稳定的、持久的存储。
  • 有序的、优雅的部署和扩缩。
  • 有序的、自动的滚动更新。

3.2 DaemonSet的Spec配置项

DaemonSet 用于在集群所有(或指定)节点上运行一个 Pod 副本。

bash 复制代码
spec:
  selector: <LabelSelector>        # 匹配Pod的标签选择器(必须与template.metadata.labels一致)
  template: <PodTemplateSpec>      # Pod模板(定义要在节点上运行的容器)
  updateStrategy:                  # 更新策略(默认RollingUpdate)
    type: <string>                 # 策略类型:RollingUpdate(滚动更新)/OnDelete(手动删除旧Pod才更新)
    rollingUpdate:                 # 当type为RollingUpdate时生效
      maxUnavailable: <int/string> # 更新过程中允许不可用的最大Pod数(默认1,支持百分比如"20%")
  minReadySeconds: <int>           # 新Pod就绪后,等待多少秒再继续更新(默认0)
  revisionHistoryLimit: <int>      # 保留的历史版本数(默认10)
  # 节点选择相关(控制DaemonSet在哪些节点上运行)
  nodeSelector: <map[string]string>  # 节点标签选择器(仅在匹配标签的节点上运行)
  affinity: <Affinity>              # 节点亲和性/反亲和性(更复杂的节点选择逻辑)
  tolerations: <[]Toleration>       # 容忍节点污点(允许在有污点的节点上运行,如master节点)

需要强调的是:Spec核心字段围绕 "节点选择"、"更新策略" 设计。


3.3 Job的Spec配置项

Job 用于运行一次性任务,Pod 成功完成后终止。

bash 复制代码
spec:
  parallelism: <int>               # 并行运行的Pod数(默认1,0表示暂停任务)
  completions: <int>               # 任务需要成功完成的总Pod数(默认1)
  activeDeadlineSeconds: <int>     # 任务超时时间(超过此时长未完成则终止所有Pod,单位秒)
  backoffLimit: <int>              # 失败重试次数(默认6,重试间隔指数增长)
  selector: <LabelSelector>        # 匹配Pod的标签选择器(若手动指定Pod标签,需配置此选项)
  manualSelector: <bool>           # 是否允许手动指定selector(默认false,自动生成)
  template: <PodTemplateSpec>      # Pod模板(任务容器定义,需确保容器正常退出(exit 0))
  ttlSecondsAfterFinished: <int>   # 任务完成后,自动清理Pod的时间(单位秒,需开启TTLAfterFinished特性)

需要注意的是spec核心字段是围绕 "任务完成条件""并行控制" 设计。

四、总结

核心差异点:

  • StatefulSet 强调 serviceName 和 volumeClaimTemplates(有状态标识与持久化);
  • DaemonSet 强调 nodeSelector/tolerations(节点选择);
  • Job 强调 parallelism/completions(任务并行与完成条件);
  • CronJob 强调 schedule/concurrencyPolicy(定时规则与并发控制)。

实际运维中,需结合业务场景(如无状态 / 有状态、常驻 / 一次性 / 定时任务)选择合适控制器,并合理配置上述spec字段。

相关推荐
NightReader8 小时前
minikube 的 kubernetes 入门教程-kubeSphere
云原生·容器·kubernetes
会飞的土拨鼠呀8 小时前
docker-compose 安装MySQL8.0.39
adb·docker·容器
10岁的博客10 小时前
无Dockerfile构建:云原生部署新姿势
云原生
朱包林10 小时前
Prometheus监控K8S集群-ExternalName-endpoints-ElasticStack采集K8S集群日志实战
运维·云原生·容器·kubernetes·prometheus
能不能别报错10 小时前
K8s学习笔记(十三) StatefulSet
笔记·学习·kubernetes
罗不俷10 小时前
【Kubernetes】(二十)Gateway
容器·kubernetes·gateway
虫师c13 小时前
云原生微服务:Kubernetes+Istio 魔法学院实战指南
微服务·云原生·kubernetes·istio·服务网格
一只游鱼14 小时前
linux部署docker(国内镜像)
云原生·eureka
今天头发还在吗14 小时前
【Docker】在项目中如何实现Dockerfile 文件编写
java·docker·容器