У меня есть кластер Kubernetes, который распределен по 2 зонам - zone1 и zone2.
У меня есть 2 приложения - веб-приложение и база данных. Конфигурации веб-приложения хранятся в базе данных. И приложение, и база данных развертываются как приложения с отслеживанием состояния.
Идея состоит в том, чтобы развернуть 2 набора реплик для веб-приложения (приложение-0 и приложение-1) и 2 реплики для базы данных (база данных-0 и база данных-1). приложение-0 указывает на базу данных-0, приложение-1 указывает на базу данных-1.
Включена антиаффинность стручка. Поэтому желательно, чтобы приложение-0 и приложение-1 не находились в одной зоне. Также база данных-0 и база-данных-1 не будут находиться в одной зоне.
Я хочу, чтобы приложение 0 и база данных 0 находились в одной зоне. А приложение-1 и база данных-1 находятся в другой зоне. Так что производительность веб-приложения не будет снижена. Это возможно?
Размещение подов в Kubernetes
Ответы (3)
Если вы хотите строго разделить рабочие нагрузки по двум зонам - я бы предложил использовать nodeSelector в зоне узла.
Аналогичный результат возможен с привязкой к поду, но он более сложен и позволяет получить четкое разделение, которое вы описываете. Вам нужно будет использовать правила requiredDuringScheduling / Execution, которых обычно лучше избегать, если они вам действительно не нужны.
Точно так же, как вы использовали правила анти-сродства, чтобы избежать подготовки обоих приложений в одной зоне, вы можете использовать сродство для подготовки app-0 только в зоне, где существует db-0, технически это будет означать, что вы можете полностью отказаться от анти-сродства из приложения. как если бы вы сказали, чтобы он планировал только в зоне db, а db определен для распространения зон с анти-сродством, вы наследуете распределение от части базы данных.
PodAntiAffinity для распространения на зоны
Для вашей базы данных
metadata:
labels:
app: db
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- db
topologyKey: "kubernetes.io/hostname"
Для вашего веб-приложения
metadata:
labels:
app: web-app
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web-app
topologyKey: "kubernetes.io/hostname"
PodAffinity для размещения модулей на узлах
Кроме того, вы добавляете podAffinity
в свое веб-приложение (не в базу данных), чтобы разместить его на узлах с вашей базой данных.
С добавлением podAffinity
для вашего веб-приложения:
metadata:
labels:
app: web-app
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web-app
topologyKey: "kubernetes.io/hostname"
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- db
topologyKey: "kubernetes.io/hostname"
Результат
С PodAntiAffinity
и PodAffinity
вы получите web-app-X, расположенный вместе с db-X.
web-app-1 web-app-2
db-1 db-2
В документации Kubernetes есть пример разместить кеш вместе с приложением на узлах около PodAffinity
и «PodAntiAffinity».
Стабильная сетевая идентификация для StatefulSet
Чтобы обратиться к одному конкретному экземпляру StatefulSet, создать Headless Service с ClusterIP: None
для каждого реплика db. Это позволяет вашим веб-приложениям подключаться к определенному экземпляру.
Доступ к ближайшему экземпляру БД
Теперь ваши веб-приложения могут подключаться к db-0 и db-1 через безголовые сервисы. Позвольте вашим веб-приложениям изначально подключаться к обоим и использовать одно с самым коротким временем отклика - скорее всего, оно находится на том же узле.