You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何实现Kubernetes中两个Pod的双向同节点绑定与故障重调度?

实现Kubernetes Pod双向紧密绑定(互相跟随调度)

你目前的配置只实现了单向的Pod亲和性,要达到双向绑定、任一Pod重新调度后另一方自动跟随的效果,需要调整两个Deployment的亲和性规则,同时启用运行时的规则检查。以下是具体的实现方案:

核心思路

要实现双向绑定,需要满足两个核心条件:

  1. 双向Pod亲和性:两个Pod都必须配置亲和性规则,要求调度到对方所在的节点。
  2. 运行时规则校验:默认的亲和性规则只在调度阶段生效,运行时不会检查规则是否被破坏。我们需要改用requiredDuringSchedulingRequiredDuringExecution类型的规则,让Kubernetes在运行时持续检查,一旦规则被打破就驱逐Pod并重新调度。

修改后的Deployment清单

第一个应用(first-app)的配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: first-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: first-app
  template:
    metadata:
      labels:
        app: first-app
    spec:
      containers:
      - name: first-app
        imagePullPolicy: IfNotPresent
        image: image1
      nodeSelector:
        nodegroup: etl
      affinity:
        # 保留原有反亲和性(避免同应用多Pod挤在同一节点,replicas=1时可忽略)
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: "app"
                operator: In
                values:
                - first-app
            topologyKey: "kubernetes.io/hostname"
        # 添加指向second-app的双向亲和性,启用运行时校验
        podAffinity:
          requiredDuringSchedulingRequiredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: "app"
                operator: In
                values:
                - second-app
            topologyKey: "kubernetes.io/hostname"

第二个应用(second-app)的配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: second-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: second-app
  template:
    metadata:
      labels:
        app: second-app
    spec:
      containers:
      - name: second-app
        imagePullPolicy: IfNotPresent
        image: image1
      nodeSelector:
        nodegroup: etl
      affinity:
        # 保留原有反亲和性
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: "app"
                operator: In
                values:
                - second-app
            topologyKey: "kubernetes.io/hostname"
        # 修改为指向first-app的双向亲和性,启用运行时校验
        podAffinity:
          requiredDuringSchedulingRequiredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: "app"
                operator: In
                values:
                - first-app
            topologyKey: "kubernetes.io/hostname"

关键配置说明

  1. 双向Pod亲和性:两个Deployment都新增了指向对方的podAffinity规则,确保调度时会优先选择对方Pod所在的节点。如果其中一个Pod先启动,另一个会自动跟进到同一节点;如果同时启动,调度器会尝试将它们放在同一符合nodeSelector的节点上。
  2. 运行时校验:将亲和性规则的类型从requiredDuringSchedulingIgnoredDuringExecution改为requiredDuringSchedulingRequiredDuringExecution,这个配置会让Kubernetes在Pod运行期间持续检查亲和性规则是否满足。一旦其中一个Pod被重新调度到其他节点,另一个Pod就会违反规则,kubelet会将其驱逐,Deployment会自动创建新的Pod并调度到对方所在的新节点。

注意事项

  • 可用性权衡:当Pod被驱逐重新调度时,会有短暂的服务不可用窗口。如果你的应用需要高可用性,可以考虑结合PodDisruptionBudget来控制驱逐行为,或者调整replicas数量(但多副本的双向绑定会增加调度复杂度)。
  • 节点选择范围:确保nodeSelector限定的节点池中有足够的节点,避免出现无节点可调度的情况。
  • 测试验证:可以通过以下步骤验证效果:
    • 删除first-app的Pod,观察它是否重新调度到second-app所在的节点;
    • 直接删除Pod所在的节点,观察两个Pod是否都重新调度到同一个新节点。

内容的提问来源于stack exchange,提问作者programmingtech

火山引擎 最新活动