工作负载推荐配置

ACK集群中配置工作负载(Deployment、StatefulSet、DaemonSet、Job、CronJob等)时,您需考虑多种因素,以确保应用可以稳定、可靠地运行。

声明每个PodRequestsLimits

在 Kubernetes 集群中,节点上调度过多 Pod 会导致负载过高,无法正常提供服务。配置Pod时,建议声明其所需的requestslimits,以便集群在部署Pod时可以根据资源需求找到合适的节点。

下方示例中,Nginx Pod的资源配置为:

  • CPU请求:1核;内存请求:1024Mi

  • CPU限制:2核;内存限制:4096Mi

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
    resources: # 资源声明
      requests:
        memory: "1024Mi"
        cpu: "1000m"
      limits:
        memory: "4096Mi"
        cpu: "2000m"

Kubernetes采用静态资源调度机制。每个节点的剩余资源的计算公式为节点剩余资源 = 节点总资源 - 已分配资源。手动运行资源密集型程序时,Kubernetes无法感知其实际资源使用量。因此公式中基于已分配资源进行计算,而非实际使用资源。

此外,所有Pod都应声明resources。如果Pod未声明resources,调度到节点后,Kubernetes不会为其预留资源。这可能导致节点上调度过多Pod,进而引发资源争用问题。

推荐使用ACK提供的资源画像功能,基于资源使用量的历史数据获得容器粒度的资源规格推荐,简化容器requestslimits的配置复杂度。

启动时等待下游服务,不要直接退出

有些应用可能存在一些外部依赖,例如需要从数据库(DB)读取数据或者依赖另外一个服务的接口。应用启动时,外部依赖可能无法完全满足。在传统手动运维中,通常采用“依赖不满足即退出”的方式(即failfast)。但在Kubernetes中,大多运维操作是自动化的,无需人工干预。例如部署应用时系统会自动选择节点并启动应用,应用失败时系统会自动重启,负载增加时可以通过HPA(Horizontal Pod Autoscaler)实现自动扩容。

假设有两个应用AB,A依赖B,并且它们运行在同一节点上。如果该节点因某种原因重启,重启后A先启动,而B尚未启动,此时A的依赖无法满足。如果A按照传统方式直接退出,即使B启动后,A也不会自动恢复,需要人工干预。

Kubernetes集群中,建议在启动时检查依赖。如果依赖不满足,可以通过轮询等待,而不是直接退出。这一功能可以通过Init Container实现。

配置restart policy

Pod 运行期间,进程退出是一种常见现象。代码缺陷或内存占用过多等问题都可能导致应用程序进程退出,从而导致 Pod 终止。您可以为 Pod 配置restartPolicy,确保在 Pod 退出后能够自动重启。`

apiVersion: v1
kind: Pod
metadata:
  name: nginx-test
spec:
  restartPolicy: OnFailure 
  containers:
  - name: nginx
    image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6

restartPolicy可选值如下:

  • Always:总是自动重启。

  • OnFailure:异常退出时自动重启(进程退出状态非0)。

  • Never:从不重启。

配置健康检查探针

为应对应用死锁、启动缓慢或服务失效等异常,配置探针赋予了 Kubernetes 故障自愈与流量管控能力。它能自动重启异常容器并仅向就绪实例分发请求,是保障服务高可用性与稳定性的关键机制。

  • startupProbe (启动探针):用于启动较慢的应用(如Java)检测是否完成启动。启动探测成功前,就绪探针和存活探针不会被执行,防止应用启动缓慢而被Kubelet误判为失败并重启。

  • readinessProbe (就绪探针):用于业务流量控制,仅当检测通过后才将 Pod IP 加入 Service 的 Endpoints 列表,确保外部请求只分发给具备处理能力的容器。

  • livenessProbe(存活探针):负责监测容器的存活状态,在检测到死锁或崩溃时由 kubelet 触发自动重启以实现故障自愈。

以下为一个Nginx无状态(Deployment)应用配置健康检查探针的参考示例。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment-demo
spec:
  replicas: 1                 # 生产环境建议配置2以上保证高可用
  selector:
    matchLabels:
      app: nginx-demo
  template:
    metadata:
      labels:
        app: nginx-demo 
    spec:
      containers:
      - name: nginx
        image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 500m
            memory: 1Gi
          limits:
            cpu: 500m
        # --- 健康检查探针 ---
        # 启动探针 (Startup Probe): 确保容器内应用已完成启动
        startupProbe:
          httpGet:
            path: / # Nginx默认根路径可访问即代表启动成功
            port: 80
          # 给予应用足够长的启动时间。总超时 = failureThreshold * periodSeconds,即 30 * 10 = 300 秒
          failureThreshold: 30
          periodSeconds: 10
        # 就绪探针 (Readiness Probe): 判断容器是否准备好接收流量
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5  # 容器启动后5秒开始探测
          periodSeconds: 5        # 每5秒探测一次
          timeoutSeconds: 2       # 探测超时时间
          successThreshold: 1     # 1次成功即标记为就绪
          failureThreshold: 3     # 连续3次失败即标记为不就绪
        # 存活探针 (Liveness Probe): 判断容器是否“存活”,用于实现故障自愈。
        # 此配置应比readinessProbe更宽松,以避免因短暂抖动导致不必要的重启。
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 15 # 在容器启动15秒后开始第一次探测,给予应用充分的初始化后稳定时间。
          periodSeconds: 10       # 探测频率低于readinessProbe,以减少对系统资源的消耗。
          timeoutSeconds: 3       # 超时时间可略长于readinessProbe。
          successThreshold: 1     # 1次成功即代表存活。
          failureThreshold: 3     # 连续3次失败(3*10=30秒)后,Kubelet将重启该容器。

如需在生产环境配置零中断滚动部署,请参考实现零中断滚动部署

每个进程一个容器

部分开发者习惯将容器当作虚拟机(VM)使用,并在一个容器中运行多个进程,例如监控进程、日志进程、sshd 进程,甚至整个 Systemd。这种做法会带来以下问题:

  • 判断 Pod 的整体资源占用会更加复杂,也不利于正确配置 Requests 和 Limits。

  • 如果容器内仅运行单个进程,当该进程中断时,外部容器引擎能够立即感知并重启容器。若容器内运行多个进程,即使其中一个进程崩溃,外部容器引擎也无法感知,可能导致容器无法正常工作。

Kubernetes支持多个进程的协同工作。例如,Nginx 和 PHP-FPM 可通过 Unix Domain Socket 通信,您可创建一个包含2个容器的 Pod,并将 Unix Domain Socket 存放于两者的共享 Volume 中。

确保不存在单点故障(Single Point of Failure)

如果应用仅有一个实例,当该实例发生故障时,尽管 Kubernetes 能够自动重启实例,但在这期间不可避免地会出现短暂的服务中断。即使在更新应用或发布新版本时,也可能出现类似的服务中断情况。

在 Kubernetes 中,应尽量避免直接管理 Pod,而是通过 Deployment 或 StatefulSet 来管理,并确保应用至少运行两个以上的 Pod 实例。这种做法能够有效提升系统的高可用性,避免因单个实例故障导致的服务中断。

相关文档