MongoDB: запуск в Kubernetes з MongoDB Operator та MongoDBCommunity CRD
0 (0)

Автор |  24/07/2026
Click to rate this post!
[Total: 0 Average: 0]

В продовження попереднього посту Valkey: запуск в Kubernetes – Helm, monitoring, ACL – там підняли Valkey/Redis, тепер треба додати MongoDB.

Робиться для нашого нового сервісу, який ще в експерементальній/PoC фазі, але скоріш за все піде в продакшен, тому сетап такий собі “недо-production” – робимо з розрахунком на те, що потім це все діло будемо повноцінно менеджити і моніторити, але поки і не сильно заморочуємось зі всякими security-задачами.

Як і Valkey, запускати MongoDB будемо в Kubernetes, але на відміну з Valkey тут трохи більш і складно і печально, бо:

  • для MongoDB є ентерпрайз-версія, і частина компонентів та документації заточено під неї, що трохи заплутує – бо документації багато
  • нема адекватного і простого Helm-чарту – бо і сама система трохи складніша за Redis (ну – якщо не розгортати Redis Cluster)
    • є чарт Bitnami – але ж ми не вороги собі 🙂

Тому для запуску в Kubernetes вибрав підхід з MCK – MongoDB Controllers for Kubernetes (MCK).

Отже, що будемо робити:

  • у власному Kubernetes Namespace встановимо сам MongoDB Operator
  • в окремому Namespace створимо тестовий MongoDB Replica Set “cluster” – але з одною нодою

Так як для MongoDB будемо використовувати Kubernetes Operator та CRD – то рекомендую почитати пости про те, як воно працює “під капотом” – Kubernetes: Kubernetes API, API Groups, CRD та etcd та Kubernetes: що таке Kubernetes Operator та CustomResourceDefinition.

Install MongoDB Operator

Всі values чудово задокументовані в MongoDB Controllers for Kubernetes Operator Helm Installation Settings.

Всі дефолтні значення можна глянути в репозиторії mongodb/helm-charts/main/charts/mongodb-kubernetes/values.yaml.

Ще може бути цікавим глянути маніфест mongodb-kubernetes.yaml – по суті тут всі ресурси, які створить Helm chart самого оператора.

Поки робимо установку оператора руками в тестовий Kubernetes Namespace – потім перенесемо в автоматизацію Kubernetes.

Додаємо репозиторій:

$ helm repo add mongodb https://mongodb.github.io/helm-charts

Пишемо простий values:

operator:

  env: dev
  
  watchNamespace: test-mongodb-service-ns

  watchedResources:
    - mongodbcommunity

  replicas: 1

  resources:
    requests:
      cpu: 100m
      memory: 128Mi
    limits:
      cpu: 500m
      memory: 512Mi

  createOperatorServiceAccount: true
  createResourcesServiceAccountsAndRoles: true

  enableClusterMongoDBRoles: false
  enablePVCResize: true

Тут:

  • env: від значення в env задається log level
  • watchNamespace: вказуємо Kubernetes Namespace, де буде потім буде MongoDBCommunity – оператор тут створить Roles && RoleBindings, і тільки в цих NS буде моніторити свої Custom Resources
  • watchedResources: будемо користуватись тільки MongoDBCommunity CRD, без Enterprise, Ops Manager, Search тощо – тому тут обмежуємо ресурси
  • enableClusterMongoDBRoles: CRD ClusterMongoDBRole не використовуємо, ролі для MongoDB будемо задавати на рівні MongoDBCommunity
  • enablePVCResize: включаємо можливість збільшення PVC (StorageClass має бути з allowVolumeExpansion)
  • resources: відразу додамо, потім в production підтюнимо значення

Helm-чарт оператора встановить потрібні CRD, ClusterRole та RoleBinding самого оператора в його власному неймспейсі – та RoleBinding і потрібні ServiceAccounts в неймспейсі нашого тестового інстансу MongoDB.

Створюємо неймспейси:

$ kk create ns test-mongodb-operator-ns

$ kk create ns test-mongodb-service-ns

Деплоїмо оператор:

$ helm upgrade --install mongodb-kubernetes-operator \
  mongodb/mongodb-kubernetes \
  --namespace test-mongodb-operator-ns \
  --create-namespace \
  -f operator-values.yaml

Перевіряємо поди:

$ kk get pod
NAME                                           READY   STATUS    RESTARTS   AGE
mongodb-kubernetes-operator-6b4cb5955b-wk9q5   1/1     Running   0          28s

Для створення інстансів MongoDB у watchNamespace оператор створює там ServiceAccount – перевіряємо, що він є і з цим ServiceAccount є права на створення Kubernetes StatefulSet:

$ kk auth can-i create statefulsets.apps \
  --namespace test-mongodb-service-ns \
  --as system:serviceaccount:test-mongodb-operator-ns:mongodb-kubernetes-operator
yes

Перевіряємо MongoDBCommunity CustomResourceDefinition:

$ kk get crd mongodbcommunity.mongodbcommunity.mongodb.com
NAME                                            CREATED AT
mongodbcommunity.mongodbcommunity.mongodb.com   2026-07-22T13:36:50Z

По-дефолту Operator шле MongoDB product telemetry – можна відключити з:

operator:
  telemetry:
    enabled: false

Оператор готовий – можемо запускати саму MongoDB.

Деплой MongoDB Community instance

Сам CRD можна подивитись тут – mongodbcommunity.mongodb.com_mongodbcommunity.yaml.

З ним ми вже власне описуємо саме наш MongoDB, тому це вже робимо в іншому неймспейсі test-mongodb-service-ns, в якому буде сам наш сервіс, який буде цю MongoDB використовувати.

Kubernetes Secrets та паролі поки робимо руками, потім вже нормально – з AWS Secrets Manager та External Secrets Operator.

Створюємо сікрет з паролем для root на цьому інстансі MongoDB:

$ kk -n test-mongodb-service-ns create secret generic agents-mainframe-mongodb-admin-password \
  --from-literal=password='test-mongodb-admin-password'

Створюємо маніфест mongodb-community.yaml:

apiVersion: mongodbcommunity.mongodb.com/v1
kind: MongoDBCommunity
metadata:
  name: agents-mainframe-mongodb
spec:
  type: ReplicaSet
  members: 1
  version: "8.0.13"

  security:
    authentication:
      modes:
        - SCRAM

  users:
    - name: admin
      db: admin
      passwordSecretRef:
        name: agents-mainframe-mongodb-admin-password
      scramCredentialsSecretName: agents-mainframe-mongodb-admin-scram
      roles:
        - name: root
          db: admin

Тут:

  • members: кількість MongoDB-процесів у MongoDB Replica Set (не плутати з Kubernetes ReplicaSet)
  • authentication.modes: SCRAM – стандартна аутентифікація по логіну-паролю
  • users: описуємо RBAC – задаємо ім’я root user
    • в passwordSecretRef передаємо та ім’я Kubernetes Secret, в якому зберігається його пароль (той, що створили вище)
    • scramCredentialsSecretName: ім’я Kubernetes Secret для MongoDB Operator, див. нижче
    • в roles – задаємо значення root, всі ролі є в документації Built-In Roles

Деплоїмо:

$ kk -n test-mongodb-service-ns apply -f mongodb-community.yaml
mongodbcommunity.mongodbcommunity.mongodb.com/agents-mainframe-mongodb created

Перевіряємо Pods:

$ kk -n test-mongodb-service-ns get pod
NAME                         READY   STATUS    RESTARTS   AGE
agents-mainframe-mongodb-0   2/2     Running   0          2m30s

Перевіряємо стан CustomResource:

$ kk -n test-mongodb-service-ns get mongodbcommunity agents-mainframe-mongodb
NAME                       PHASE     VERSION
agents-mainframe-mongodb   Running   8.0.13

Перевіряємо аутентифікацію:

$ kk -n test-mongodb-service-ns exec -it \
  agents-mainframe-mongodb-0 \
  -c mongod \
  -- mongosh \
  --username admin \
  --password \
  --authenticationDatabase admin
Enter password: ***************************
Warning: Could not access file: EACCES: permission denied, mkdir '/data/db/.mongodb'
Current Mongosh Log ID: 6a60ce6f6671cfc48fce5f46
Connecting to:          mongodb://<credentials>@127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&authSource=admin&appName=mongosh+2.5.8

...
Error: Could not open history file.
REPL session history will not be persisted.

...

agents-mainframe-mongodb [direct: primary] test> 

В логах є помилка “EACCES: permission denied, mkdir ‘/data/db/.mongodb‘” – але це від MongoDB Shell, не самого демона mongod: далі і є як раз “Error: Could not open history file.“.

Тому ігноруємо.

І через db.runCommand() пробуємо запустити якусь команду, наприклад – connectionStatus:

agents-mainframe-mongodb [direct: primary] test> db.runCommand({ connectionStatus: 1 })
{
  authInfo: {
    authenticatedUsers: [ { user: 'admin', db: 'admin' } ],
    authenticatedUserRoles: [ { role: 'root', db: 'admin' } ]
  },
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1784729214, i: 1 }),
    signature: {
      hash: Binary.createFromBase64('cVOqP4fgjvw/kg8m6SnhJ03AB1A=', 0),
      keyId: Long('7665352957805723654')
    }
  },
  operationTime: Timestamp({ t: 1784729214, i: 1 })
}

Все працює.

MongoDB Operator та Kubernetes Secrets для MongoDBCommunity

Ще з цікавого, що можна глянути і корисно знати – Kubernetes Secrets, які створюються самим MongoDB Operator, коли ми деплоїмо ресурс MongoDBCommunity:

$ kk -n test-mongodb-service-ns get secret
NAME                                                     TYPE     DATA   AGE
agents-mainframe-mongodb-admin-admin                     Opaque   4      19m
agents-mainframe-mongodb-admin-password                  Opaque   1      26m
agents-mainframe-mongodb-admin-scram-scram-credentials   Opaque   6      21m
agents-mainframe-mongodb-agent-password                  Opaque   1      21m
agents-mainframe-mongodb-config                          Opaque   1      21m
agents-mainframe-mongodb-keyfile                         Opaque   1      21m

Тут agents-mainframe-mongodb-admin-password ми робили руками і передавали в CR manifest в полі passwordSecretRef, а інші:

  • agents-mainframe-mongodb-admin-scram-scram-credentials: це Secret для самого оператору – salt, sha-ключі
    • ім’я створюється зі значення в scramCredentialsSecretName нашого маніфесту CR, до якого оператор додає суфікс “-scram-credentials
  • agents-mainframe-mongodb-admin-admin: тут Operator генерує connection string для підключення в форматі mongodb://<username>:<password>@<host>:<port>/<database>?<options>"
    • ім’я генерується з <MongoDBCommunity name>-<auth database>-<username>
    • містить дві connection sring – connectionString.standard та connectionString.standardSrv: другий використовує Kubernetes DNS замість імен подів – користуємось ним
  • agents-mainframe-mongodb-agent-password: внутрішній пароль MongoDB Agent, створений оператором – агент використовує цей пароль для керування mongod на цьому інстансі MongoDB, нам не цікавий
  • agents-mainframe-mongodb-config: automation configuration для MongoDB Agent – бажаний стан deployment, replica set, users та інші параметри – оновлюється оператором при змінах в MongoDBCommunity, нам, в принципі, не цікавий

Власне – на цьому і все.

Можна готуватись до запуску в Dev/Staging/Prod:

По бекапам – просто EBS snapshots недостатньо/ненадійно, варіанти:

Loading