Service Kubernetes服务,集群吊舱处于主/备用状态

Service Kubernetes服务,集群吊舱处于主/备用状态,service,kubernetes,kubernetes-pod,Service,Kubernetes,Kubernetes Pod,很抱歉,我没有这么简短,因为任何这样的尝试都会让我错过问题的一些重要细节 我有一个遗留Java应用程序,它在集群环境中以活动/备用模式工作,通过预定义的端口公开某些RESTful Web服务 如果我的应用程序群集中有两个节点,在任何时间点,只有一个节点处于主动模式,另一个处于被动模式,并且请求总是由应用程序在主动模式下运行的节点提供服务。”“主动”和“被动”只是角色,应用程序本身将在两个节点上运行。主动和被动实例通过相同的预定端口彼此通信 假设我有一个两节点集群,每个节点上运行一个应用程序实例,

很抱歉,我没有这么简短,因为任何这样的尝试都会让我错过问题的一些重要细节

我有一个遗留Java应用程序,它在集群环境中以活动/备用模式工作,通过预定义的端口公开某些RESTful Web服务

如果我的应用程序群集中有两个节点,在任何时间点,只有一个节点处于主动模式,另一个处于被动模式,并且请求总是由应用程序在主动模式下运行的节点提供服务。”“主动”和“被动”只是角色,应用程序本身将在两个节点上运行。主动和被动实例通过相同的预定端口彼此通信

假设我有一个两节点集群,每个节点上运行一个应用程序实例,那么一个实例最初是活动的,另一个是被动的。如果出于某种原因,活动节点因某种原因而出现问题,则另一个节点中的应用程序实例会使用某种心跳机制来识别它,接管控制并成为新的活动节点。当旧的主动角色返回时,它会检测到另一个人已经拥有了新的主动角色,因此它进入被动模式

该应用程序通过使用集群IP,在同一个端点IP上提供RESTful Web服务,而不管哪个节点在“活动”模式下运行该应用程序,集群IP都会借助于活动实例,因此集群IP会切换到在活动模式下运行该应用程序的节点

我正在尝试将此应用程序容器化,并在Kubernetes集群中运行此应用程序,以实现规模和易于部署。我能够集装箱化,并能够将其作为一个吊舱部署在Kubernetes集群中

为了在这里引入主动/被动角色,我正在运行该POD的两个实例,每个实例使用节点关联固定到单独的K8S节点(每个节点标记为主动或被动,POD定义在这些标签上),并使用我的应用程序的集群机制对它们进行集群,而只有一个是主动的,另一个是被动的

我通过使用NodePort使用K8S服务语义对外公开REST服务,并通过主节点上的NodePort公开REST Web服务

以下是我的yaml文件内容:

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
  labels:
    app: myapp-service
spec:
  type: NodePort
  ports:
    - port: 8443
      nodePort: 30403
  selector:
    app: myapp

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: active
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: myapp
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: nodetype
                operator: In
                values:
                - active
      volumes:
        - name: task-pv-storage
          persistentVolumeClaim:
           claimName: active-pv-claim
      containers:
      - name: active
        image: myapp:latest
        imagePullPolicy: Never
        securityContext:
           privileged: true
        ports:
         - containerPort: 8443
        volumeMounts:
        - mountPath: "/myapptmp"
          name: task-pv-storage

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: passive
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: myapp
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: nodetype
                operator: In
                values:
                - passive
      volumes:
        - name: task-pv-storage
          persistentVolumeClaim:
           claimName: active-pv-claim
      containers:
      - name: passive
        image: myapp:latest
        imagePullPolicy: Never
        securityContext:
           privileged: true
        ports:
         - containerPort: 8443
        volumeMounts:
        - mountPath: "/myapptmp"
          name: task-pv-storage
一切似乎都很正常,只是因为两个pod都通过相同的端口公开了web服务,所以K8S服务以随机方式将传入的请求路由到其中一个pod。由于我的REST WebService端点仅在活动节点上工作,因此只有当请求被路由到应用处于活动角色的POD时,服务请求才能通过K8S服务资源工作。如果在任何时间点,K8S服务碰巧将传入请求路由到处于被动角色的应用程序的POD,则该服务不可访问/不提供服务

我如何使K8S服务始终将请求路由到处于活动角色的应用程序的POD中?这在库伯内特斯是可行的还是我的目标太高了


谢谢你抽出时间

实现这一点的一种方法是在pod中添加标签标记为active和standby。然后选择服务中的活动吊舱。这会将流量发送到标记为活动的pod

您可以在此文档中找到另一个示例


您可以将准备就绪探测器与选举容器结合使用。选举将始终从选举池中选出一名主控,如果您确保只有pod标记为就绪。。。只有该pod才会接收流量。

问题是,我不能永远将某个特定pod标记为“主动”,因为如果该pod中的应用程序因某种原因停机,角色可能会变为被动,在这种情况下,另一个pod中的应用程序可能会承担“主动”角色。它实际上取决于集群IP。无论哪个POD激活了群集IP(我的应用程序的群集IP,而不是K8S服务群集IP),该POD都应被视为“活动”并将入口流量路由到该POD。然后,如Radek添加的其他选项,您可以使用liveness probe Thank you@sfgroups,根据Radek的建议,我添加了一个准备就绪探测器,仅当POD是活动POD时,该探测器才会将POD标记为准备就绪,从而解决了问题@msbl3004能否共享代码以检查吊舱的活动状态?太好了!非常感谢@Radek'Goblin'Pieczonka的回答。You make my day:-)我认为这不符合预期,因为准备就绪探测不会永远针对指定端点运行。