Подключение к экземпляру MongoCryptD в среде докеров с помощью Mongoose

Я искал в Интернете, но нигде не мог найти свой ответ. Я пытаюсь запустить веб-службу API, используя структуру NestJS.

Я запускаю docker-compose, который запускает сервер API, экземпляр MongoDB и экземпляр mongocryptd, чтобы разрешить шифрование на уровне поля на стороне клиента в моем приложении.

Я могу подключиться к экземпляру MongoDB, но не к экземпляру mongocryptd.

Файл Docker-Compose:

version: "3.7"
services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
      labels:
        env: dev
      args:
        APP: appname
        APP_PORT: 3000
    ports:
      - "3000:3000"
    command: ["sh", "-c", "npm run start:app:dev"]
    volumes:
      - .:/app

  mongodb:
    build:
      context: .
      dockerfile: docker/MongoEP-Dockerfile
      labels:
        env: dev
      args:
        MONGO_PACKAGE: mongodb-enterprise
        MONGO_REPO: repo.mongodb.com
    image: mongo-enterprise:4.2.5
    command: ["--auth"]
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: usr
      MONGO_INITDB_ROOT_PASSWORD: pwd
    ports:
      - "27017:27017"
    volumes: ["/private/var/services/mongodb:/data/db"]

  mongocryptd:
    build:
      context: .
      dockerfile: docker/MongoEP-Dockerfile
      labels:
        env: dev
      args:
        MONGO_PACKAGE: mongodb-enterprise
        MONGO_REPO: repo.mongodb.com
    image: mongo-enterprise:4.2.5
    entrypoint: mongocryptd
    restart: always
    ports:
      - "27020:27020"
    volumes: ["/private/var/services/mongodb:/data/db"]

Используемый файл dockerfile является официальным файлом dockerfile mongo, но снабжен аргументами для создания корпоративной версии образа, которая включает корпоративные функции.

При попытке подключиться к базе данных из приложения я запускаю:

MongooseModule.forRoot(`mongodb://usr:pwd@mongodb:27017`, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      useFindAndModify: false,
      retryAttempts: 2,
      autoEncryption: {
        keyVaultNamespace,
        kmsProviders,
        extraOptions: {
          mongocryptdURI: `mongodb://mongocryptd:27020`,
          mongocryptdBypassSpawn: true
        }
      } as any
    })

** Это версия NestJS для предоставления конфигураций. это похоже на мангуст - первый аргумент - это URI, а второй - объект настроек


Без параметров автошифрования я могу подключиться без проблем. Это означает, что мой адрес базы данных правильный. С параметрами autoEncyption я получаю MongooseServerSelectionError: connect ECONNREFUSED 172.25.0.4:27020 (адрес mongocryptd). Это означает, что IP правильный (DNS разрешен), но в соединении отказано. Как я показал ранее, порт (27020) публикуется файлом docker-compose, и я даже пытался добавить шаг EXPOSE в саму сборку.

НО когда я сопоставляю сеть контейнеров с хостом (network_mode: "host"), приложение может подключаться без проблем (конечно, меняя DNS-подключения на localhost: 27017 и 27020). Так что это должно означать, что это проблема, связанная с докером.

Дополнительные вещи, которые я пробовал, && резюме того, что я пробовал:

  • Прикрепите том для замены /etc/mongod.conf.orig со следующими сетевыми конфигурациями:
net:
  port: 27017
  bindIp: 0.0.0.0
  bindIpAll: true
  • Вместо присоединения тома замените его ^ на этапе сборки перед запуском службы монго.
  • Я также попытался изменить bindIp на конкретный IP-адрес приложения, который был предоставлен сетью докеров.
  • Все типы строк подключения с учетными данными пользователя и без них, источником аутентификации и базой данных по умолчанию.
  • Порт 27020 публикуется в docker-compose и отображается в файле docker.

У меня закончились идеи. Любая помощь приветствуется! :)

РЕДАКТИРОВАТЬ:

После дополнительной отладки я вижу, что mongod работает с --bind_ip_all по умолчанию, поэтому изменение файла conf не должно иметь эффекта. Пробовал также запустить mongocryptd с точкой входа mongods docker-entrypoint.sh вместо ее переопределения.


person Asaf Kfir    schedule 19.04.2020    source источник
comment
Вы можете поделиться своим обновленным файлом докеров? Я также сталкиваюсь с этой проблемой. Благодарность!   -  person Ben Luk    schedule 12.09.2020
comment
@BenLuk просто добавьте эти строки, чтобы установить процесс mongocrypt в тот же контейнер: ``` RUN wget -qO - mongodb.org/static/pgp/server-4.2.asc | apt-key add - \ && echo deb repo.mongodb.com/apt/debian stretch/ mongodb-предприятие/4.2 основной | tee /etc/apt/sources.list.d/mongodb-enterprise.list RUN apt-get update \ && apt-get install --no-install-recommends -y mongodb-enterprise-cryptd \ && rm -rf /var/ lib/apt/списки/* ```   -  person Asaf Kfir    schedule 21.09.2020


Ответы (1)


  1. Убедитесь, что mongocryptd работает (ps awwxu и т. д.)
  2. Убедитесь, что вы можете подключиться к нему из bash в том же контейнере, где он работает, используя mongo.
  3. Убедитесь, что вы можете подключиться к нему из хост-системы, используя mongo.
  4. Проверьте журналы mongocryptd (в основном это mongod с некоторыми дополнительными функциями).
person D. SM    schedule 19.04.2020
comment
1. Я могу убедиться, что он работает под пользователем root, используя ps awwxu. 2. Я получаю сообщение об ошибке отказа в подключении - это потому, что я не запускаю процесс mongod в этом контейнере, а только mongocryptd. Я пытался запустить как mongod, так и mongocryptd из одного и того же контейнера (запустить обычный образ mongo, открыть оболочку, запустить mongocryptd), но получаю ту же ошибку отказа в соединении. 3. Опять же, mongod не запущен. 4. Логи пустые. Я вижу только журналы запуска [listener] Listening on 127.0.0.1 & [listener] waiting for connections on port 27020 - person Asaf Kfir; 20.04.2020
comment
Я повторно запустил mongocryptd и mongo из одного и того же контейнера и просканировал порты с помощью Nmap. И 27017, и 27020 указаны как открытые. Я не получаю отказ в подключении при использовании mongo CLI, и я могу подключиться из приложения, если я не указываю возможность использовать mongocryptd в настройках подключения (ключ autoEncryption из приведенного выше примера). Когда я повторно добавляю ключ шифрования, он пытается подключиться к mongocryptd, и я получаю ту же ошибку ECONNREFUSED. Опять же, при использовании режима хост-сети все работает. - person Asaf Kfir; 20.04.2020
comment
Выполните шаги, оболочка mongo может напрямую подключаться к процессу mongocryptd и, по крайней мере, запускать на нем ismaster. - person D. SM; 20.04.2020
comment
Есть что-то, что я, вероятно, не совсем понимаю. Для уточнения - должен ли mongocryptd полностью заменять mongod? Или я должен запустить оба? Потому что они слушают на разных портах. Это также означает, что я, вероятно, ошибаюсь, запуская их в отдельных контейнерах? (Как я уже сказал, при запуске обоих в одном контейнере это тоже не работает, но, по крайней мере, я буду знать, как отлаживать дальше). - person Asaf Kfir; 20.04.2020
comment
mongod и mongocryptd выполняют разные функции. Вы можете запускать их в одном контейнере или в разных контейнерах. - person D. SM; 20.04.2020
comment
Спасибо за все ответы. Я могу подключиться к команде Mongo(), когда оба процесса находятся в одном контейнере, Mongo("localhost:27020", { keyVaultNamespace: "encryption.__dataKey", kmsProviders: { local: { key: BinData(0, "masterkey") } } }) . Соединение отображается в логах mongocryptd. Я не могу выполнять какие-либо операции шифрования с базой данных, такой как db.getMongo().getKeyVault();. Кроме того, я не могу подключиться к mongocryptd вне этого контейнера через драйвер Mongo()/nodejs. - person Asaf Kfir; 21.04.2020
comment
В вашем вопросе не говорится, как настроены mongod и mongocryptd (аргументы командной строки и файлы конфигурации). В целях сетевого подключения mongocryptd ничем не отличается от mongod с той лишь разницей, что это номер порта по умолчанию. Убедитесь, что ваш IP-адрес привязки правильно установлен в конфигурации сервера для обоих демонов, убедитесь, что вы подключаетесь к правильному IP-адресу. Если вы используете localhost, убедитесь, что процесс прослушивает как ipv4, так и ipv6. - person D. SM; 21.04.2020
comment
Я сделал это. Они настроены с конфигурациями по умолчанию (и я также пытался передать настройки файла conf, описанные выше). В настоящее время я не мог решить эту проблему. Мое лучшее предположение заключается в том, что у mongocryptd нет возможности привязаться к другому IP-адресу, отличному от localhost (не принимает его в файле .conf, и нет возможности передать его в качестве аргумента команды). Через 3 дня я просто сдался и установил пакет mongodb-enterprise-cryptd внутри контейнера приложения. Он работает безупречно, но это не оптимальное решение. - person Asaf Kfir; 21.04.2020
comment
Вы правы, mongocryptd не распознает --bind_ip. - person D. SM; 22.04.2020