很抱歉没有保持简短,因为任何此类尝试都会让我错过问题的一些重要细节。
我有一个旧版 Java 应用程序,它在集群环境中以主动/备用模式工作,通过预定义端口公开某些 RESTful Web 服务。
如果我的应用程序集群中有两个节点,则在任何时间点只有一个节点处于主动模式,另一个处于被动模式,并且请求始终由应用程序在主动模式下运行的节点提供服务。 “主动”和“被动”只是角色,应用程序本身将在两个节点上运行。主动实例和被动实例通过同一预定端口相互通信。
假设我有一个两节点集群,每个节点上运行一个应用程序实例,那么其中一个实例最初是活动的,另一个实例是被动的。如果由于某种原因,活动节点因某种原因而发生抛掷,其他节点中的应用程序实例会使用某种心跳机制来识别这一点,接管控制权并成为新的活动节点。当旧的主动角色恢复时,它检测到另一个人已经拥有新的主动角色,因此它进入被动模式。
该应用程序设法在同一端点 IP 上提供 RESTful Web 服务,无论哪个节点通过使用集群 IP 以“主动”模式运行该应用程序,该集群 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 服务以随机方式将传入请求路由到其中一个 POD。由于我的 REST WebService 端点仅在活动节点上工作,因此仅当请求路由到应用程序处于活动角色的 POD 时,服务请求才通过 K8S 服务资源工作。如果在任何时间点,K8S 服务碰巧将传入请求路由到应用程序处于被动角色的 POD,则该服务将无法访问/无法提供服务。
如何让 K8S 服务始终将请求路由到应用程序处于活动角色的 POD?这在 Kubernetes 中可行还是我的目标太多了?
感谢您的时间!