Kubernetes в основном использовался для приложений без сохранения состояния. Однако в версии 1.3 были введены домашние зоны, а позже они превратились в наборы состояния. Официальная документация описывает государственные наборы как
Statefulsets предназначены для использования с приложениями Stateful и распределенными системами
Одним из лучших вариантов использования для этого является организация услуг по предоставлению данных, такие как MongoDB, Elasticsearch, Redis, Zookeeper и так далее.
Некоторые Особенности Это может быть приписано Statefulsets:
- Стручки с порядковыми индексами
- Стабильные сетевые идентификации
- Заказано и параллельное управление стручками
- Обновления
Одной из очень четкой особенности наборов Stateful является предоставление идентификаторов StablenetWork, которые при использовании с Безголовые службы , может быть еще более мощным.
Не тратя много времени на информацию, легко доступную в документации Kubernetes, давайте сосредоточимся на запуске и масштабировании кластера MongoDB.
Вам нужно иметь бег Kubernetes Cluster с RBAC включен (рекомендуемые). В этом уроке мы будем использовать GKE Cluster Тем не менее, AWS EKS или Microsoft AKS или KOPS, управляемые K8, также являются жизнеспособными альтернативами.
Мы развернем следующие компоненты для нашего кластера MongoDB
1. Демон установил для настройки hostvm 2. Сервисная учетная запись и привязку кластерола для монго 5. Mongo Pods Stateful Set 6.GCP Внутренний LB для доступа к MongoDB извне кластера Kuberntes (необязательно) 7. Доступ к стручкам с использованием Ingress (необязательно)
Важно отметить, что у каждого стручка MongoDB будет работать коляска, чтобы настроить реплику, установленную на лету. Коляска проверяет новые участники каждые 5 секунд.
kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
name: hostvm-configurer
labels:
app: startup-script
spec:
template:
metadata:
labels:
app: startup-script
spec:
hostPID: true
containers:
- name: hostvm-configurer-container
image: gcr.io/google-containers/startup-script:v1
securityContext:
privileged: true
env:
- name: STARTUP_SCRIPT
value: |
#! /bin/bash
set -o errexit
set -o pipefail
set -o nounset
# Disable hugepages
echo 'never' > /sys/kernel/mm/transparent_hugepage/enabled
echo 'never' > /sys/kernel/mm/transparent_hugepage/defrag
apiVersion: v1
kind: Namespace
metadata:
name: mongo
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: mongo
namespace: mongo
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: mongo
subjects:
- kind: ServiceAccount
name: mongo
namespace: mongo
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
---
apiVersion: storage.k8s.io/v1beta1
kind: StorageClass
metadata:
name: fast
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-ssd
fsType: xfs
allowVolumeExpansion: true
---
apiVersion: v1
kind: Service
metadata:
name: mongo
namespace: mongo
labels:
name: mongo
spec:
ports:
- port: 27017
targetPort: 27017
clusterIP: None
selector:
role: mongo
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: mongo
namespace: mongo
spec:
serviceName: mongo
replicas: 3
template:
metadata:
labels:
role: mongo
environment: staging
replicaset: MainRepSet
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: replicaset
operator: In
values:
- MainRepSet
topologyKey: kubernetes.io/hostname
terminationGracePeriodSeconds: 10
serviceAccountName: mongo
containers:
- name: mongo
image: mongo
command:
- mongod
- "--wiredTigerCacheSizeGB"
- "0.25"
- "--bind_ip"
- "0.0.0.0"
- "--replSet"
- MainRepSet
- "--smallfiles"
- "--noprealloc"
ports:
- containerPort: 27017
volumeMounts:
- name: mongo-persistent-storage
mountPath: /data/db
resources:
requests:
cpu: 1
memory: 2Gi
- name: mongo-sidecar
image: cvallance/mongo-k8s-sidecar
env:
- name: MONGO_SIDECAR_POD_LABELS
value: "role=mongo,environment=staging"
- name: KUBE_NAMESPACE
value: "mongo"
- name: KUBERNETES_MONGO_SERVICE_NAME
value: "mongo"
volumeClaimTemplates:
- metadata:
name: mongo-persistent-storage
annotations:
volume.beta.kubernetes.io/storage-class: "fast"
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: fast
resources:
requests:
storage: 10Gi
Важные точки:
- Коляска для Mongo должна быть тщательно настроена с помощью надлежащих переменных среды, указав этикетки, приведенные POD, пространство имен для развертывания и обслуживания.
- Руководство по размеру кеша по умолчанию: «50% ОЗУ минус 1 ГБ, или 256 МБ» Анкет Учитывая, что количество запрошенной памяти составляет 2 ГБ, размер кэша WiredTiger здесь был установлен на 256 МБ
- Межпод анти-аффинность Обеспечивает, чтобы на одном и том же рабочем узле запланировано 2 монго -капсула, что делает его устойчивым к сбоям узлов. Кроме того, рекомендуется сохранить узлы в разных AZ, чтобы кластер был устойчив к сбою зон.
- В настоящее время развернутая учетная запись имеет привилегии администратора. Тем не менее, это должно быть ограничено пространством имен БД.
После того, как мы развертываем оба манифеста, указанные выше, мы можем проверить компоненты, когда следующие
root$ kubectl -n mongo get all NAME DESIRED CURRENT AGE statefulsets/mongo 3 3 3m NAME READY STATUS RESTARTS AGE po/mongo-0 2/2 Running 0 3m po/mongo-1 2/2 Running 0 2m po/mongo-2 2/2 Running 0 1m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE svc/mongo ClusterIP None27017/TCP 3m
Как вы можете видеть, у сервиса нет кластерного IP, и нет внешнего IP, это Безголовный сервис . Эта услуга будет напрямую разрешаться в Pod-Ips для наших государственных наборов.
Чтобы проверить разрешение DNS, мы запустим интерактивную оболочку в нашем кластере
kubectl run my-shell --rm -i --tty --image ubuntu -- bash root@my-shell-68974bb7f7-cs4l9:/# dig mongo.mongo +search +noall +answer ; <<>> DiG 9.11.3-1ubuntu1.1-Ubuntu <<>> mongo.mongo +search +noall +answer ;; global options: +cmd mongo.mongo.svc.cluster.local. 30 IN A 10.56.7.10 mongo.mongo.svc.cluster.local. 30 IN A 10.56.8.11 mongo.mongo.svc.cluster.local. 30 IN A 10.56.1.4
DNS для обслуживания будет Анкет Следовательно, в нашем случае это будет Mongo.mongo .
IPS (10.56.6.17, 10.56.7.10, 10.56.8.11) являются IPS нашего Mongo Stateful Set. Это можно проверить, запустив nslookup над ними изнутри кластера.
root@my-shell-68974bb7f7-cs4l9:/# nslookup 10.56.6.17 17.6.56.10.in-addr.arpa name = mongo-0.mongo.mongo.svc.cluster.local. root@my-shell-68974bb7f7-cs4l9:/# nslookup 10.56.7.10 10.7.56.10.in-addr.arpa name = mongo-1.mongo.mongo.svc.cluster.local. root@my-shell-68974bb7f7-cs4l9:/# nslookup 10.56.8.11 11.8.56.10.in-addr.arpa name = mongo-2.mongo.mongo.svc.cluster.local.
Если ваше приложение развернуто в кластере K8, то оно может получить доступ к узлам —
Node-0: mongo-0.mongo.mongo.svc.cluster.local:27017 Node-1: mongo-1.mongo.mongo.svc.cluster.local:27017 Node-2: mongo-2.mongo.mongo.svc.cluster.local:27017
Если вы хотите получить доступ к узлам монго извне кластера, вы можете развернуть балансировщики внутренней нагрузки для каждой из этих стручков или создать внутренний вход, используя контроллер входа, такой как Nginx или Traefik
apiVersion: v1
kind: Service
metadata:
annotations:
cloud.google.com/load-balancer-type: Internal
name: mongo-0
namespace: mongo
spec:
ports:
-
port: 27017
targetPort: 27017
selector:
statefulset.kubernetes.io/pod-name: mongo-0
type: LoadBalancer
Развернуть еще 2 аналогичные услуги для Mongo-1 и Mongo-2.
Вы можете предоставить IPS внутренней балансировщика нагрузки для мочеиспускания URI.
root$ kubectl -n mongo get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mongo ClusterIP None27017/TCP 15m mongo-0 LoadBalancer 10.59.252.157 10.20.20.2 27017:30184/TCP 9m mongo-1 LoadBalancer 10.59.252.235 10.20.20.3 27017:30343/TCP 9m mongo-2 LoadBalancer 10.59.254.199 10.20.20.4 27017:31298/TCP 9m
Внешние IPS для Mongo-0/1/2 являются IPS недавно созданных балансировщиков нагрузки TCP. Они локальные для ваших подсети или заглядываемых сетей, если таковые имеются.
Трафик в Mongo Stateful Set Pods также может быть направлен с использованием контроллера Ingress, такого как Nginx. Убедитесь, что услуга Ingress является внутренней и не выявлена над публичным IP. Объект Ingress будет выглядеть примерно так:
...
spec:
rules:
- host: mongo.example.com
http:
paths:
- path: '/'
backend:
serviceName: mongo # There is no extra service. This is
servicePort: '27017' # the headless service
Важно отметить, что ваше приложение осведомлено как по крайней мере один узел Mongo, который в настоящее время растет, чтобы оно могло обнаружить все остальные.
Вы можете использовать Robo 3T в качестве клиента Mongo на вашем местном Mac. После подключения к одному из узлов и запуска rs.status () , вы можете просмотреть детали набора реплик и проверить, были ли настроены другие 2 стручки и подключены к набору реплик автоматически.
Теперь мы масштабируем набор Stateful для монго, чтобы проверить, добавляются ли новые стручки Mongo в репликат или нет.
root$ kubectl -n mongo scale statefulsets mongo --replicas=4 statefulset "mongo" scaled root$ kubectl -n mongo get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE mongo-0 2/2 Running 0 25m 10.56.6.17 gke-k8-demo-demo-k8-pool-1-45712bb7-vfqs mongo-1 2/2 Running 0 24m 10.56.7.10 gke-k8-demo-demo-k8-pool-1-c6901f2e-trv5 mongo-2 2/2 Running 0 23m 10.56.8.11 gke-k8-demo-demo-k8-pool-1-c7622fba-qayt mongo-3 2/2 Running 0 3m 10.56.1.4 gke-k8-demo-demo-k8-pool-1-85308bb7-89a4
Видно, что Все четыре стручки развернуты в разных узлах GKE и, таким образом, наша аффинная политика Pod-Anti работает правильно.
Действие масштабирования также автоматически обеспечит постоянный том, который будет действовать как каталог данных для нового стручка.
root$ kubectl -n mongo get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE mongo-persistent-storage-mongo-0 Bound pvc-337fb7d6-9f8f-11e8-bcd6-42010a940024 11G RWO fast 49m mongo-persistent-storage-mongo-1 Bound pvc-53375e31-9f8f-11e8-bcd6-42010a940024 11G RWO fast 49m mongo-persistent-storage-mongo-2 Bound pvc-6cee0f97-9f8f-11e8-bcd6-42010a940024 11G RWO fast 48m mongo-persistent-storage-mongo-3 Bound pvc-3e89573f-9f92-11e8-bcd6-42010a940024 11G RWO fast 28m
Чтобы проверить, добавляется ли POD с именем Mongo-3 в набор реплики или нет, мы запускаем rs.status () Еще раз на том же узле и наблюдайте за разницей.
Дальнейшие соображения:
- Это может быть полезно для МАРЕКА НАЗОНА Pool который будет использоваться для стручков Mongo и обеспечить, чтобы соответствующая аффинность узла упоминается в спецификации для набора Date Daemon Configure и конфигурации HostVM. Это связано с тем, что набор демона изменит некоторые параметры ОС хоста, и эти настройки должны быть ограничены только для стручков MongoDB. Другие приложения могут работать лучше без этих настроек.
- Маркировка пула узлов чрезвычайно проста в GKE, может быть непосредственно из консоли GCP.
- Хотя мы указали ограничения процессора и памяти в спецификации POD, мы также можем рассмотреть возможность развертывания VPA (Вертикальный POD Autoscaler).
- Трафик в наш БД изнутри кластера может контролироваться путем реализации сетевых политик или сервисной сетки, такой как Istio Анкет
Цель этого блога — дать вам достаточно информации, чтобы начать работу с наборами Stateful на Kubernetes и надеемся, что вы найдете это полезным.
Оригинал: «https://dev.to/appfleet/orchestrating-mongodb-over-kubernetes-1o5d»