我如何更好地控制我的服务分配给我的部署的 NodePorts?

How do I get more control over the NodePorts my Service assigns to my Deployment?

我有一个包含 5 个副本的 Deployment。都有ssh和telnet。它们不应该是负载平衡的。我希望每个人都能从可预测的 5 个列表中 select。

这是我的部署

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
spec:
  selector:
    matchLabels:
      app: myapp
  replicas: 5
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myapp:1.0
        ports:
        - name: ssh
          protocol: TCP
          containerPort: 22
        - name: telnet
          protocol: TCP
          containerPort: 23

这是我的服务,出于说明目的,nodePort 值无效。

apiVersion: v1
kind: Service
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  type: NodePort
  ports:
  - name: ssh
    port: 22
    nodePort: [30022, 30122, 30222, 30322, 30422, 30522]
  - name: telnet
    port: 23
    nodePort: [30023, 30123, 30223, 30323, 30423, 30523]

我希望能够完成两件事:

  1. 每个 pod 副本实例只会从 [30022, 30122, 30222, 30322, 30422, 30522] 获得一个 ssh 端口,从 [30023, 30123, 30223, 30323, 30423, 30523] 获得一个 telnet 端口
  2. 获取 ssh 端口 30022 的 pod 副本实例也获取 telnet 端口 30023。获取 ssh 端口 30122 的 pod 副本实例获取 telnet 端口 30123,依此类推。

谢谢!

考虑到"Replica"的概念,意思就是要和其他的一样; 克隆.

根据您的问题,您需要具有基于模板的唯一对象,因此 DeploymentStatefulSet 都无济于事,因为它们依赖于 ReplicaSet

至于 StatefulSet 标签方法,我宁愿说它更像是一种 多对一 关系,这意味着整个 Service 将链接到特定的 pod。这意味着 NodePort 服务中映射的所有端口都将服务于集合中的特定 pod。如果我的理解是正确的,您宁愿在公开端口和 pods.

之间建立 一对一 关系

由于服务就像一个负载均衡器,将传入的请求路由到每个后端(来自部署的副本)上完全相同的目标(端口),您需要的那种唯一性最好分别处理,如DeploymentStatefulSet 及其相应的 NodePort 服务,并根据您的需要映射您的端口 每个案例

这种方法当然有很高的操作开销,但可以应对您的用例所需的唯一性级别。

您可以使用 StatefulSet 而不是部署:

Like a Deployment, a StatefulSet manages Pods that are based on an identical container spec. Unlike a Deployment, a StatefulSet maintains a sticky identity for each of their Pods. These pods are created from the same spec, but are not interchangeable: each has a persistent identifier that it maintains across any rescheduling.

StatefulSets 的一个特别有用的功能是您将为每个 pod 获得一个可预测生成的唯一标签:

When the StatefulSet controller creates a Pod, it adds a label, statefulset.kubernetes.io/pod-name, that is set to the name of the Pod. This label allows you to attach a Service to a specific Pod in the StatefulSet. [source]

然后您将创建 5 个不同的服务,每个 pod 一个,格式如下:

apiVersion: v1
kind: Service
metadata:
  name: myapp-${n}
  labels: { ... } # whatever you want
spec:
  type: NodePort
  selector: 
    statefulset.kubernetes.io/pod-name: myapp-${n} # assuming you keep the name
                                                   # "myapp" and just switch kind
                                                   # from Deployment to StatefulSet
  ports:
  - name: ssh
    port: 22
    nodePort: 30${n}22
  - name: telnet
    port: 23
    nodePort: 30${n}23

通过 4.

${n} 替换为 0