我有一个由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个副本的部署,其中每个副本都有一个唯一的通用标签(例如副本ID,如1/3,2/3等)。
在服务中,我可以使用选择器来获取即使在更新后也会存在的标签。
另一种解决方案可能是选择pod / deployment,具体取决于运行它的主机。我可以使用DaemonSet或只使用具有亲和力的pod /部署来确保每个主机都具有我部署的完全一个副本。
但我不知道如何根据运行它的主机标签选择一个pod。
使用主机名不是一个选项,因为主机名将在不同的环境中发生变化。
我搜索了文档,但没有找到与此用例相匹配的内容。希望有人知道如何解决这个问题。
答案 0 :(得分:8)
您正在寻找的功能称为StatefulSets,它刚刚使用Kubernetes 1.5发布到测试版(请注意,它以前在alpha中以不同的名称提供,PetSet)。
在StatefulSet中,每个副本都有一个唯一的名称,该名称在重新启动后保持不变。在您的示例中,这些将是instance-1,instance-2,instance-3。由于实例名称是持久的(即使在另一个节点上重新创建了pod),因此您不需要每个实例的服务。
文档包含更多详细信息:
答案 1 :(得分:0)
您可以使用PodIP:PodPort映射NodeIP:NodePort。您的pod正在某个节点(实例/ VM)上运行。
为您的节点分配标签,
为您的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
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
。它永远是静止的。标签将照顾您的动态pod ips。