Как добавить начальных пользователей при запуске контейнера Docker RabbitMQ?

В настоящее время я запускаю контейнер RabbitMQ Docker с использованием изображения RabbitMQ по умолчанию из DockerHub. Используя следующие команды.

docker run --restart=always \
-d \
-e RABBITMQ_NODENAME=rabbitmq \
-v /opt/docker/rabbitmq/data:/var/lib/rabbitmq/mnesia/rabbitmq \
-p 5672:5672 \
-p 15672:15672 \
--name rabbitmq rabbitmq:3-management

У меня есть необходимость, когда я хочу предоставлять пользователям по умолчанию и/или виртуальным хостам при первом запуске образа. Например, чтобы создать "тестовый пользователь" по умолчанию.

В настоящее время я должен сделать это вручную, используя плагин управления и добавив пользователей/виртуальных хостов через веб-интерфейс ui. Есть ли способ предоставить настройки по умолчанию при запуске образа RabbitMQ?

Ответы

Ответ 1

Вы можете создать простой файл Docker, который расширяет функциональность основного изображения и создает пользователя по умолчанию. Необходимый файл Docker:

FROM rabbitmq

# Define environment variables.
ENV RABBITMQ_USER user
ENV RABBITMQ_PASSWORD user

ADD init.sh /init.sh
EXPOSE 15672

# Define default command
CMD ["/init.sh"]

И init.sh:

#!/bin/sh

# Create Rabbitmq user
( sleep 5 ; \
rabbitmqctl add_user $RABBITMQ_USER $RABBITMQ_PASSWORD 2>/dev/null ; \
rabbitmqctl set_user_tags $RABBITMQ_USER administrator ; \
rabbitmqctl set_permissions -p / $RABBITMQ_USER  ".*" ".*" ".*" ; \
echo "*** User '$RABBITMQ_USER' with password '$RABBITMQ_PASSWORD' completed. ***" ; \
echo "*** Log in the WebUI at port 15672 (example: http:/localhost:15672) ***") &

# [email protected] is used to pass arguments to the rabbitmq-server command.
# For example if you use it like this: docker run -d rabbitmq arg1 arg2,
# it will be as you run in the container rabbitmq-server arg1 arg2
rabbitmq-server [email protected]

Этот script также инициализирует и выставляет веб-интерфейс RabbitMQ на порт 15672.

Ответ 2

Придумал решение, которое соответствует моим потребностям, оставив его здесь, если кому-то еще это понадобится.

Резюме

Идея состоит в том, чтобы использовать стандартный контейнер rabbitmq с включенным плагином управления и использовать его для создания необходимой конфигурации, затем экспортировать и использовать его для запуска новых контейнеров. В приведенном ниже решении создается производное изображение докеров, но оно также работает, чтобы просто монтировать два файла во время выполнения (например, с помощью компоновки докеров).

Ссылки

Компоненты

  • официальный образ rabbitmq, версия плагина управления (rabbitmq: management)
  • пользовательское изображение на основе оригинала, с этим файлом Docker (с использованием версии 3.6.6):

    FROM rabbitmq:3.6.6-management
    ADD rabbitmq.config /etc/rabbitmq/
    ADD definitions.json /etc/rabbitmq/
    RUN chown rabbitmq:rabbitmq /etc/rabbitmq/rabbitmq.config /etc/rabbitmq/definitions.json
    CMD ["rabbitmq-server"]
    
  • rabbitmq.config просто сообщает rabbitmq загружать определения из json файла
  • definitions.json содержит пользователей, vhosts и т.д. и может быть сгенерирована функцией экспорта веб-интерфейса управления.

Пример rabbitmq.config:

[
  {rabbit, [
    {loopback_users, []}
  ]},
  {rabbitmq_management, [
    {load_definitions, "/etc/rabbitmq/definitions.json"}
  ]}
].

definition.json example:

{
 "rabbit_version": "3.6.6",
 "users": [
  {
   "name": "user1",
   "password_hash": "pass1",
   "hashing_algorithm": "rabbit_password_hashing_sha256",
   "tags": ""
  },
  {
   "name": "adminuser",
   "password_hash": "adminpass",
   "hashing_algorithm": "rabbit_password_hashing_sha256",
   "tags": "administrator"
  }
 ],
 "vhosts": [
  {
   "name": "\/vhost1"
  },
  {
   "name": "\/vhost2"
  }
 ],
 "permissions": [
  {
   "user": "user1",
   "vhost": "\/vhost1",
   "configure": ".*",
   "write": ".*",
   "read": ".*"
  }
 ],
 "parameters": [],
 "policies": [],
 "queues": [],
 "exchanges": [],
 "bindings": []
}

Альтернативная версия

Получение нового изображения докеры - это всего лишь одно решение и лучше всего работает, когда мобильность является ключевой, поскольку она позволяет избежать управления файлами на хосте на картинке.

В некоторых ситуациях предпочтительным может быть использование официального изображения и предоставление файлов конфигурации из локального хранилища на хост.

Файлы rabbitmq.config и definitions.json создаются одинаково, а затем монтируются во время выполнения.

Примечания:

  • Я предполагаю, что они были помещены в/etc/so/для этих примеров.
  • файлы должны либо быть читаемыми в мире, либо принадлежащими пользователю или группе rabbitmq (числовой идентификатор внутри контейнера докера равен 999), это должно обрабатываться системным администратором хоста

Пример запуска docker:

    docker run --rm -it \
        -v /etc/so/rabbitmq.config:/etc/rabbitmq/rabbitmq.config:ro \
        -v /etc/so/definitions.json:/etc/rabbitmq/definitions.json:ro \
        rabbitmq:3.6-management
Пример

docker:

    version: '2.1'
    services:
        rabbitmq:
            image: "rabbitmq:3.6-management"
            ports:
                - 5672:5672
                - 15672:15672
            volumes:
                - /etc/so/rabbitmq.config:/etc/rabbitmq/rabbitmq.config:ro
                - /etc/so/definitions.json:/etc/rabbitmq/definitions.json:ro

Ответ 3

Самая новая версия образа RabbitMQ на Dockerhub имеет встроенную функциональность для изменения имени пользователя/пароля по умолчанию с "guest"/"guest" на что-то другое.

Просто установите переменные окружения "RABBITMQ_DEFAULT_USER" и "RABBITMQ_DEFAULT_PASS" при запуске изображения.

Как команда docker, вы должны запустить образ так:

docker run \
-e RABBITMQ_DEFAULT_USER=test-user \
-e RABBITMQ_DEFAULT_PASS=test-user \
-p 5672:5672 \
rabbitmq

Ответ 4

Я хотел бы добавить, что sudo-ответ мне очень помог. Но он все еще пропустил команду, которая будет добавлена ​​в файл Docker.

Файл rabbitmq.config и definitions.json должен принадлежать пользователю и группе rabbitmq. Поэтому после добавления файлов запускайте chown.

Полный файл Docker в моем случае был следующим:

FROM rabbitmq:3-management-alpine
ADD definitions.json /etc/rabbitmq/
ADD rabbitmq.config /etc/rabbitmq/
RUN chown rabbitmq:rabbitmq /etc/rabbitmq/rabbitmq.config /etc/rabbitmq/definitions.json

EXPOSE 4369 5671 5672 15671 15672 25672

CMD ["rabbitmq-server"]

В файле rabbitmq.config имеется следующий контент, являющийся слиянием из конфигурации образа по умолчанию и добавлением добавленных определений:

[
    { rabbit, [
        {loopback_users, []},
        { tcp_listeners, [ 5672 ]},
        { ssl_listeners, [ ]},
        { hipe_compile, false } 
    ]},
    { rabbitmq_management, [
        { load_definitions, "/etc/rabbitmq/definitions.json"},
        { listeners, [
            { port, 15672 },
            { ssl, false } 

        ]}
    ]}
].

Файл определений может быть экспортирован из интерфейса управления на вкладке обзора.

Итак, вы должны создать обычный "пустой" контейнер rabbitmq. Определите, какие пользователи, обмены и очереди вам нравятся. Затем введите интерфейс управления, экспортируйте определения и создайте собственное изображение, используя файл, как описано выше.

Загрузка определений - это самый простой способ получить правильные хэши паролей в файле определений для ваших собственных паролей. Если вы не хотите этого делать, вы должны следовать инструкциям, указанным здесь (https://www.rabbitmq.com/passwords.html), чтобы генерировать правильные хэши.

Ответ 5

В моем случае вышеприведенное решение sleep 5 не сработало, потому что время запуска RabbitMQ было намного больше и не предсказуемо. Отправка решения, которое ожидает, пока RabbitMQ не будет запущен и работает:

  • Dockerfile

    FROM rabbitmq:3-management
    ADD init.sh /
    ADD config_rabbit.sh /
    RUN chmod +x /init.sh /config_rabbit.sh
    ENTRYPOINT ["/init.sh"]
    
  • init.sh

    #!/bin/bash
    
    # Launch config script in background
    # Note there is no RabbitMQ Docker image support for executing commands after server (PID 1) is running (something like "ADD schema.sql /docker-entrypoint-initdb.d" in MySql image), so we are using this trick
    /config_rabbit.sh &
    
    # Launch
    /docker-entrypoint.sh rabbitmq-server
    
  • config_rabbit.sh

    #!/bin/bash
    
    # This script needs to be executed just once
    if [ -f /$0.completed ] ; then
      echo "$0 'date' /$0.completed found, skipping run"
      exit 0
    fi
    
    # Wait for RabbitMQ startup
    for (( ; ; )) ; do
      sleep 5
      rabbitmqctl -q node_health_check > /dev/null 2>&1
      if [ $? -eq 0 ] ; then
        echo "$0 'date' rabbitmq is now running"
        break
      else
        echo "$0 'date' waiting for rabbitmq startup"
      fi
    done
    
    # Execute RabbitMQ config commands here
    
    # Create user
    rabbitmqctl add_user USER PASSWORD
    rabbitmqctl set_permissions -p / USER ".*" ".*" ".*"
    echo "$0 'date' user USER created"
    
    # Create queue
    rabbitmqadmin declare queue name=QUEUE durable=true
    echo "$0 'date' queues created"
    
    # Create mark so script is not ran again
    touch /$0.completed
    

Ответ 6

С RabbitMQ 3.7 и более новым форматом конфигурации rabbitmq.conf(sysctl) следующие настройки устанавливают RabbitMQ с пользователем по умолчанию и очередью в Docker, при желании вы можете добавить следующие команды RUN в файл docker для создания пользователей...

RUN rabbitmqctl add_user {username} {password}
RUN rabbitmqctl set_user_tags {username} administrator
RUN rabbitmqctl set_permissions ...

rabbitmq.conf

# Default user
default_user = testuser
default_pass = testpassword

## The default "guest" user is only permitted to access the server
## via a loopback interface (e.g. localhost).
loopback_users.guest = true

# IPv4
listeners.tcp.default = 5672

## HTTP listener and embedded Web server settings.
management.tcp.port = 15672

# Load queue definitions
management.load_definitions = /etc/rabbitmq/definitions.json

#Ignore SSL
ssl_options.verify               = verify_peer
ssl_options.fail_if_no_peer_cert = true

definitions.json

{
  "rabbit_version": "3.7.11",
  "users": [
    {
      "name": "testuser",
      "password_hash": "txn+nsYVkAaIMvDsH8Fsyb3RWMCMWihRUVCk/wICL1NBKKvz",
      "hashing_algorithm": "rabbit_password_hashing_sha256",
      "tags": "administrator"
    }
  ],
  "vhosts": [ { "name": "test-vhost" } ],
  "permissions": [
    {
      "user": "testuser",
      "vhost": "test-vhost",
      "configure": ".*",
      "write": ".*",
      "read": ".*"
    }
  ],
  "topic_permissions": [],
  "parameters": [],
  "global_parameters": [
    {
      "name": "cluster_name",
      "value": "[email protected]"
    }
  ],
  "policies": [],
  "queues": [
    {
      "name": "testqueue",
      "vhost": "test-vhost",
      "durable": true,
      "auto_delete": false,
      "arguments": {}
    }
  ],
  "exchanges": [],
  "bindings": []
}

Dockerfile

FROM rabbitmq:3.7-management

COPY rabbitmq.conf /etc/rabbitmq
COPY definitions.json /etc/rabbitmq

RUN ls /etc/rabbitmq
RUN cat /etc/rabbitmq/rabbitmq.conf

Команды Dockers для сборки и запуска контейнера...

docker build -t rabbitmq-with-queue .
docker run --rm -it --hostname my-rabbit -p 5672:5672 -p 15672:15672 rabbitmq-with-queue

Ответ 7

Вот пример того, как я добавляю непривилегированного пользователя gg RUN useradd -d /home/gg -m -s /bin/bash gg RUN echo gg:gg | chpasswd RUN echo 'gg ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers.d/gg RUN chmod 0440 /etc/sudoers.d/gg

Ответ 8

Мне пришлось внести несколько изменений в сценарий в принятом ответе, чтобы заставить его работать на основе комментариев выше.

Dockerfile

FROM rabbitmq

# Define environment variables.
ENV RABBITMQ_USER user
ENV RABBITMQ_PASSWORD user

ADD init.sh /init.sh
EXPOSE 15672

# Define default command
CMD ["/init.sh"]

init.sh

#!/bin/sh
( sleep 10 && \
rabbitmqctl add_user $RABBITMQ_USER $RABBITMQ_PASSWORD && \
rabbitmqctl set_user_tags $RABBITMQ_USER administrator && \
rabbitmqctl set_permissions -p / $RABBITMQ_USER  ".*" ".*" ".*" ) & \
rabbitmq-server

Ответ 9

В Куберне, похоже на @sudo answer; можно загрузить файл definitions.json в контейнер через ConfigMap & Объем.

ConfigMap rabbitmq-definitions-configmap определяется как карта конфигурации, созданная из файла, а целью является файл defines.json.

То же самое можно сделать и для файла rabbitmq.config.

Обратите внимание на использование mountPath & subPath, просто использование mountPath не сработало для меня.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: rabbitmq-deployment
spec:
  selector:
    matchLabels:
      app: rabbitmq-deployment
  replicas: 1
  template:
    metadata:
      labels:
        app: rabbitmq-deployment
    spec:
      volumes:
      - name: rabbitmq-definitions
        configMap:
          name: rabbitmq-definitions-configmap
      containers:
      - name: rabbitmq
        image: rabbitmq:3.7.18-management-alpine
        imagePullPolicy: IfNotPresent
        envFrom:
        - configMapRef:
            name: rabbitmq-configmap
        - secretRef:
            name: rabbitmq-secrets
        volumeMounts:
        - name: rabbitmq-definitions
          mountPath: /etc/rabbitmq/definitions.json
          subPath: rabbitmq-definitions

Ответ 10

Вы можете создать новое изображение и использовать командную строку rabbitmqctl.

Например, используя этот файл Docker:

FROM rabbitmq
# rabbitmqctl command requires to start the rabbitmq server 
RUN service rabbitmq-server start
RUN /usr/lib/rabbitmq/bin/rabbitmqctl add_user test-user mypassword
RUN /usr/lib/rabbitmq/bin/rabbitmqctl add_vhost myvhost 
RUN /usr/lib/rabbitmq/bin/rabbitmqctl set_permissions -p /myvhost test-user ".*" ".*" ".*"

И постройте изображение, используя

sudo docker build -t anImageName .

Я не тестировал свой ответ, я не могу использовать докер на работе