service - 具有集群 POD 的 Kubernetes 服务处于事件/备用状态

标签 service kubernetes kubernetes-pod

抱歉没有保持简短,因为任何此类尝试都会让我错过问题的一些重要细节。

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

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

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

应用程序设法在同一端点 IP 上提供 RESTful web 服务,而不管哪个节点在“事件”模式下运行应用程序,通过使用集群 IP,它搭载在事件实例上,因此集群 IP 切换到任何节点在事件模式下运行应用程序。

我正在尝试将这个应用程序容器化并在 Kubernetes 集群中运行它,以实现扩展和易于部署。我能够容器化并将其部署为 Kubernetes 集群中的 POD。

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

我通过使用 NodePort 使用 K8S 服务语义在外部公开 REST 服务,并通过主节点上的 NodePort 公开 REST WebService。

这是我的 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 服务以随机方式将传入请求路由到这些 PODS 之一。由于我的 REST WebService 端点仅在主动节点上工作,因此仅当请求被路由到具有主动角色的应用程序的 POD 时,服务请求才通过 K8S 服务资源工作。如果在任何时间点 K8S 服务碰巧将传入请求路由到具有被动角色的应用程序的 POD,则该服务将无法访问/未提供服务。

如何使 K8S 服务始终将请求路由到 POD 且应用程序处于事件角色中?这在 Kubernetes 中是可行的,还是我的目标太大了?

感谢您的时间!

最佳答案

您可以将就绪探针与选举容器结合使用。 Election 总是会从选举池中选出一个 master,如果你确保只有那个 pod 被标记为就绪……只有那个 pod 才会接收流量。

关于service - 具有集群 POD 的 Kubernetes 服务处于事件/备用状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47291581/

相关文章:

android - 启动时启动 Activity

java - MIUI 中的 Internet 连接状态被阻止

kubernetes - 使用 yaml 文件将服务暴露给 minikube

docker - 澄清测试在管道中的位置

工作节点之间的 Kubernetes 卷复制

javascript - 在 javascript 中使用网络天气服务

windows - golang程序不适用于Windows服务

kubernetes - 重命名 Kubernetes 中的部署

Docker 容器在 kubernetes 内工作/不工作

docker - 无法从 pod 容器内访问 kubernetes api