#kubernetes #deployment #continuous-deployment #azure-aks
#kubernetes #развертывание #непрерывное развертывание #azure-aks
Вопрос:
Итак, у меня есть 4 узла. 1 — System, 1 — Dev, 1 — Qa и 1 — UAT.
Моя привязка заключается в следующем:
apiVersion: apps/v1
kind: Deployment
metadata:
name: auth
namespace: dev
labels:
app: auth
environment: dev
app-role: api
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: auth
template:
metadata:
labels:
app: auth
environment: dev
app-role: api
tier: backend
annotations:
build: _{Tag}_
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- auth
topologyKey: kubernetes.io/hostname
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: environment
operator: In
values:
- dev
containers:
- name: companyauth
image: company.azurecr.io/auth:_{Tag}_
imagePullPolicy: Always
env:
- name: ConnectionStrings__DevAuth
value: dev
ports:
- containerPort: 80
imagePullSecrets:
- name: ips
Я намерен убедиться, что в моем производственном кластере, который имеет 3 узла в 3 разных зонах доступности. Что все модули будут запланированы на другом узле / зоне доступности. Однако, похоже, что если у меня уже есть модули, запланированные на узле, то при выполнении развертывания они не будут перезаписывать уже существующие модули.
Доступно 0/4 узлов: 1 узел (ы) не соответствует привязке / анти-привязке pod, 3 узла (ов) не соответствуют селектору узлов.
Однако, если я удалю podAffinity, он будет работать нормально и перезапишет текущий узел новым модулем из развертывания. Каков правильный способ сделать это, чтобы гарантировать, что мое развертывание в моем производственном кластере всегда будет иметь модуль, запланированный на другом узле в другой зоне доступности, а также иметь возможность обновлять существующие узлы?
Комментарии:
1. Не могли бы вы поделиться своими манифестами развертывания / Pod и конфигурацией узла (метки и т. Д.)? Опубликованная привязка предназначена для Pod, Deployment, что-нибудь еще? Похоже, что у вашего модуля нет метки with
app: auth
, и ни у одного из ваших узлов нетenvironment: dev
метки. Пожалуйста, предоставьте вышеуказанную информацию для дальнейшего изучения.2. @PjoterS Я обновил до полного файла развертывания. Первое развертывание работает, но последующие развертывания не работают, если я не удалю привязку к pod.
Ответ №1:
Ваша цель может быть достигнута с помощью только PodAntiAffinity.
Я протестировал это с моим GKE
тестовым кластером, но он должен работать аналогично Azure
.
Текущая проблема
В вашей текущей настройке вы установили podAntiAffinity
with nodeAffinity
.
Pod anti-affinity
может помешать планировщику найти новый модуль на том же узле, что и модули с теми же метками, если селектор меток в новом модуле совпадает с меткой в текущем модуле.
В вашей Deployment
настройке новые модули будут иметь такие метки, как:
app: auth
environment: dev
app-role: api
tier: backend
PodAntiAffinity
был настроен так, чтобы не разрешать развертывание нового модуля, если уже есть модуль с меткой: app: auth
.
NodeAffinity
был настроен для развертывания только на узле с меткой environment: dev
.
Подводя итог, ваша ошибка:
0/4 nodes are available: 1 node(s) didn't match pod affinity/anti-affinity, 3 node(s) didn't match node selector.
1 узел (ы) не соответствовал привязке / анти-привязке pod
ваша настройка позволяет развертывать только на узле с меткой environment: dev
и только на одном модуле с меткой app: auth
.
Как вы упомянули
если у меня уже есть модули, запланированные на узле, то при выполнении развертывания они не будут перезаписывать уже существующие модули.
PodAntiAffinity
поведение сработало и не позволило развернуть новый модуль с меткой app: auth
, поскольку он уже был.
3 узла не соответствуют селектору узлов.
NodeAffinity
позволяет развертывать модули только на узле с меткой environment: dev
. Другие узлы, вероятно, имеют метки типа environment: system
, environment: uat
, environment: qa
которые не соответствуют environment: dev
метке, поэтому не совпадают node selector
.
Решение
Самый простой способ — удалить NodeAffinity
.
Пока TolpologyKey
установлено значение kubernetes.io/hostname
in PodAntiAffinity
, этого достаточно.
topologyKey использует метку по умолчанию, прикрепленную к узлу, для динамической фильтрации по имени узла.
Для получения дополнительной информации, пожалуйста, ознакомьтесь с этой статьей.
Если вы опишете свой nodes
и grep
их, kubernetes.io/hostname
вы получите уникальное значение:
$ kubectl describe node | grep kubernetes.io/hostname
kubernetes.io/hostname=gke-affinity-default-pool-27d6eabd-vhss
kubernetes.io/hostname=gke-affinity-default-pool-5014ecf7-5tkh
kubernetes.io/hostname=gke-affinity-default-pool-c2afcc97-clg9
Тесты
apiVersion: apps/v1
kind: Deployment
metadata:
name: auth
labels:
app: auth
environment: dev
app-role: api
tier: backend
spec:
replicas: 3
selector:
matchLabels:
app: auth
template:
metadata:
labels:
app: auth
environment: dev
app-role: api
tier: backend
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- auth
topologyKey: kubernetes.io/hostname
containers:
- name: nginx
image: nginx
imagePullPolicy: Always
ports:
- containerPort: 80
После развертывания этого YAML.
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
auth-7fccf5f7b8-4dkc4 1/1 Running 0 9s 10.0.1.9 gke-affinity-default-pool-c2afcc97-clg9 <none> <none>
auth-7fccf5f7b8-5qgt4 1/1 Running 0 8s 10.0.2.6 gke-affinity-default-pool-5014ecf7-5tkh <none> <none>
auth-7fccf5f7b8-bdmtw 1/1 Running 0 8s 10.0.0.9 gke-affinity-default-pool-27d6eabd-vhss <none> <none>
Если вы увеличите количество реплик до 7, модули больше не будут развернуты. Все новые модули будут заблокированы в Pending
состоянии, в antiPodAffinity
котором они работали (у каждого узла уже есть модуль с меткой app: dev
).
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
auth-7fccf5f7b8-4299k 0/1 Pending 0 79s <none> <none> <none> <none>
auth-7fccf5f7b8-4dkc4 1/1 Running 0 2m1s 10.0.1.9 gke-affinity-default-pool-c2afcc97-clg9 <none> <none>
auth-7fccf5f7b8-556h5 0/1 Pending 0 78s <none> <none> <none> <none>
auth-7fccf5f7b8-5qgt4 1/1 Running 0 2m 10.0.2.6 gke-affinity-default-pool-5014ecf7-5tkh <none> <none>
auth-7fccf5f7b8-bdmtw 1/1 Running 0 2m 10.0.0.9 gke-affinity-default-pool-27d6eabd-vhss <none> <none>
auth-7fccf5f7b8-q4s2c 0/1 Pending 0 79s <none> <none> <none> <none>
auth-7fccf5f7b8-twb9j 0/1 Pending 0 79s <none> <none> <none> <none>
Аналогичное решение было описано в блоге High-Availability Deployment of Pods on Multi-Zone Worker Nodes.
Ответ №2:
Ваше правило привязки к узлу требует, чтобы для планирования рассматривался только узел разработчика. В сочетании с вашим podAntiAffinityRule это означает, что можно запланировать только один модуль (тот, который находится на узле разработки).
Чтобы получить равномерное планирование между узлами, вам придется добавить дополнительные узлы разработчика или удалить правило nodeAffinity.
Комментарии:
1. Итак, как мне гарантировать, что в моем производственном кластере я всегда получаю равномерное планирование узлов в пуле узлов (иначе запланируйте каждый модуль в другой зоне доступности)? Но также убедитесь, что каждое последующее развертывание, кроме первого, способно перезаписывать / обновлять исходное развертывание?