【问题标题】:How to select a specific pod for a service in Kubernetes如何在 Kubernetes 中为服务选择特定的 Pod
【发布时间】:2017-05-01 04:49:40
【问题描述】:

我有一个由 3 个主机组成的 kubernetes 集群,其中每个主机都有一个唯一的 id 标签。 在这个集群上,有一个软件有 3 个实例(副本)。

每个副本都需要与所有其他副本进行通信。此外,还有一个包含所有 pod 的服务,因此这个应用程序是永久可用的。

所以我有:

Instance1 (with labels run: theTool,instanceid: 1)
Instance2 (with labels run: theTool,instanceid: 2)
Instance3 (with labels run: theTool,instanceid: 3)

Service1 (selecting pods with label instanceid=1)
Service2 (selecting pods with label instanceid=2)
Service3 (selecting pods with label instanceid=3)
Service (selecting pods with label run=theTool)

这种方法有效,但我无法扩展或使用滚动更新功能。

我想定义一个包含 3 个副本的部署,其中每个副本都有一个唯一的通用标签(例如 1/3、2/3 等副本 ID)。

在服务中,我可以使用选择器来获取即使在更新后仍然存在的标签。

另一种解决方案可能是选择 pod/deployment,具体取决于运行它的主机。我可以使用 DaemonSet 或仅使用具有关联性的 pod/deployment 来确保每个主机都有我的部署的完全相同的一个副本。

但我不知道如何根据运行所在的主机标签来选择 pod。

使用主机名不是一个选项,因为主机名会在不同的环境中改变。

我搜索了文档,但没有找到与此用例匹配的任何内容。希望这里有人知道如何解决这个问题。

【问题讨论】:

    标签: kubernetes kubernetes-deployment


    【解决方案1】:

    您正在寻找的功能称为StatefulSets,它刚刚以Kubernetes 1.5 发布到测试版(请注意,它以前以不同的名称在测试版中可用,PetSets)。

    在 StatefulSet 中,每个副本都有一个唯一的名称,该名称在重新启动时保持不变。在您的示例中,这些将是 instance-1、instance-2、instance-3。由于实例名称是持久的(即使 pod 是在另一个节点上重新创建的),所以您不需要 service-per-instance。

    文档有更多细节:

    【讨论】:

    • 我成功创建了一个 StatefulSet 但之后我发现目前无法通过名称解析 pod 的 ip。
    • 好的,找到问题了。服务必须是无头的。然后可以使用 ...svc. 来解析 pody
    【解决方案2】:

    您可以将 NodeIP:NodePort 映射到 PodIP:PodPort。您的 pod 正在某个节点(实例/虚拟机)上运行。

    1. 为您的节点分配标签,

      http://kubernetes.io/docs/user-guide/node-selection/

    2. 为你的 pod 写一个服务,例如

    service.yaml:

    apiVersion: v1
    kind: Service
    metadata:
      name: mysql-service
      labels:
        label: mysql-service
    spec:
      type: NodePort
      ports:
      - port: 3306 #Port on which your service is running
        nodePort: 32001 # Node port on which you can access it statically
        targetPort: 3306
        protocol: TCP
        name: http
    
      selector:
        name: mysql-selector   #bind pod here
    
    1. 将节点选择器(在规范字段中)添加到您的 deployment.yaml

    deployment.yaml:

    spec:
      nodeSelector:
        nodename: mysqlnode #labelkey=labelname assigned in first step
    

    有了这个,您将能够使用 Nodeip:Nodeport 访问您的 pod 服务。如果我用 标记节点10.11.20.177

    nodename=mysqlnode

    我将添加节点选择器,

    nodeSelector:
      nodename : mysqlnode 
    

    我在服务 nodePort 中指定,所以现在我可以访问 pod 服务(在容器中运行)

    10.11.20.177:32001
    

    但是这个节点应该在同一个网络中,这样它才能访问 pod。对于外部访问,请使用防火墙配置公开访问 32001。它永远是静止的。 Label 会处理您的动态 pod ip。

    【讨论】:

    • 这种方法的问题是我需要在启动时知道其他 pod 的 IP 或可解析的 dns 名称,以便它们同步。他们需要互相了解。
    猜你喜欢
    • 2020-05-17
    • 2019-01-29
    • 1970-01-01
    • 2016-08-05
    • 2019-11-08
    • 2020-01-20
    • 1970-01-01
    • 2020-10-02
    • 2020-12-25
    相关资源
    最近更新 更多