很抱歉我不能简短地描述问题,因为这样做会让我错过一些重要的细节。
我有一个传统的Java应用程序,它在集群环境中以活动/备用模式工作,通过预定义端口公开某些RESTful Web服务。
如果我的应用程序集群中有两个节点,那么任何时候只有一个节点处于活动模式,另一个节点处于被动模式,并且请求总是由处于活动模式下运行应用程序的节点提供。'活动'和'被动'只是角色,应用程序本身将在两个节点上运行。活动实例和备用实例之间通过相同的预定端口进行通信。
假设我有一个具有两个节点的集群,每个节点上都运行着我的应用程序的一个实例,那么一个实例最初将是活动状态,而另一个实例则是备用状态。如果由于某种原因活动节点崩溃了,另一个节点中的应用程序实例使用某种心跳机制识别出此情况,接管控制并成为新的活动实例。当旧的活动实例重新启动时,它会检测到另一个实例已经拥有新的活动角色,因此会进入被动模式。
该应用程序通过使用集群IP,在无论哪个节点下运行应用程序处于“活动”模式时,都能够在相同的端点IP上提供RESTful Web服务。
我正在尝试将此应用程序容器化并在Kubernetes集群中运行以实现规模和部署的便利性。我能够容器化并将其部署为Kubernetes集群中的一个POD。
为了在这里引入活动/备用角色,我运行了两个此POD的实例,每个实例钉住不同的K8S节点,并使用我的应用程序的集群机制将它们聚集在一起,其中只有一个是活动状态,另一个是备用状态。
我使用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?这在Kubernetes中可行吗,还是我要求过高?
感谢您的时间!