Сервис Kubernetes с кластерными POD в активном / резервном режиме
Извиняюсь за то, что не стал так коротким, поскольку любая такая попытка заставила бы меня упустить некоторые важные детали моей проблемы
У меня есть унаследованное Java-приложение, которое работает в активном / ждущем режиме в кластерной среде для предоставления определенных RESTful WebServices через предопределенный порт.
Если в моем кластере приложений есть два узла, то в любой момент времени только один будет в активном режиме, а другой - в пассивном, а запросы всегда обслуживаются узлом, а приложение работает в активном режиме. "Active" и "Passive" - это просто роли, приложение как таковое будет работать на обоих узлах. Активный и пассивный экземпляры взаимодействуют друг с другом через один и тот же заранее определенный порт.
Предположим, у меня есть кластер из двух узлов, на каждом узле которого работает один экземпляр приложения, тогда один экземпляр изначально будет активным, а другой пассивным. Если по какой-то причине активный узел по какой-то причине идет на бросок, экземпляр приложения в другом узле идентифицирует это, используя некоторый механизм биения, берет на себя управление и становится новым активным. Когда старый активный возвращается, он обнаруживает, что другой парень владеет новой активной ролью, следовательно, он переходит в пассивный режим.
Приложению удается предоставить веб-сервисы RESTful на одном IP-адресе конечной точки независимо от того, на каком узле запущено приложение в "активном" режиме, с помощью IP-адреса кластера, который привязывается к активному экземпляру, поэтому IP-адрес кластера переключается на какой-либо узел запуск приложения в активном режиме.
Я пытаюсь создать контейнер для этого приложения и запустить его в кластере Kubernetes для масштаба и простоты развертывания. Я могу контейнировать и развернуть его как POD в кластере Kubernetes.
Чтобы добавить сюда роль Active/Passive, я запускаю два экземпляра этого POD, каждый из которых прикреплен к отдельным узлам K8S с использованием сходства узлов (каждый узел помечен как активный или пассивный, а определения POD прикреплены к этим меткам). и кластеризацию их, используя механизм кластеризации моего приложения, тогда как только один будет активным, а другой пассивным.
Я раскрываю службу REST извне, используя семантику службы K8S, используя NodePort, и выставляя REST WebService через NodePort на главном узле.
Вот мое содержимое файла 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 открывают веб-службу через один и тот же порт, а служба K8S перенаправляет входящие запросы на один из этих PODS случайным образом. Поскольку мои конечные точки REST WebService работают только на активном узле, запросы на обслуживание работают через ресурс службы K8S, только когда запрос направляется на POD с приложением в активной роли. Если в какой-то момент времени служба K8S направляет входящий запрос на POD с приложением в пассивной роли, служба недоступна / не обслуживается.
Как сделать так, чтобы служба K8S всегда перенаправляла запросы на POD с приложением в активной роли? Это что-то выполнимое в Кубернетесе или я стремлюсь к слишком большому?
Спасибо за ваше время!
3 ответа
Вы можете использовать проверку готовности в сочетании с контейнером выбора. Выбор всегда будет выбирать одного мастера из пула выборов, и если вы убедитесь, что только тот модуль помечен как готовый... только этот модуль будет получать трафик.
Немного опоздал. Вы можете сделать это, развернув одно и то же приложение как два разных развертывания приложений с двумя службами с разными IP-адресами (или портами), а затем также развернуть балансировщик нагрузки с пользовательской конфигурацией для отправки трафика в одно приложение, а второе в качестве резервной копии. Весь трафик идет сначала к вашему балансировщику нагрузки. Вы также можете проверить, поддерживает ли какой-либо входной контроллер kubernetes опцию резервного копирования.
Одним из способов достижения этого является добавление метки тега в модуль как активный и резервный. затем выберите активный модуль в вашем сервисе. это отправит трафик на модуль, помеченный как активный.
https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
Вы можете найти другой пример в этом документе.
https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/