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»