ошибка контейнера «не удалось найти пользователя по uid» при создании контейнера ejbca docker в azure

#azure #docker #azure-container-instances #ejbca #containerd

#azure #docker #azure-container-instances #ejbca #контейнер

Вопрос:

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

Я ожидаю следующего результата : события экземпляра контейнера портала Azure завершились успешно

Но я получаю следующую ошибку :

сбой событий экземпляра контейнера портала azure

Failed to start container my-azure-container-resource-name, Error response: to create containerd task: failed to create container e9e48a_________ffba97: guest RPC failure: failed to find user by uid: 10001: expected exactly 1 user matched '0': unknown

Некоторый контекст:

Я запускаю контейнер в экземпляре azure cloud container

Я попытался

  • из шаблона ARM
  • с портала Azure.
  • с подключенным общим файлом
  • с переменной env базы данных
  • без каких-либо переменных env

Локально он работает нормально, используя ту же переменную env (конфигурация базы данных). Раньше он запускался с той же конфигурацией пару недель назад.

Вот несколько журналов, которые я получаю, когда я подключаю группу контейнеров из командной строки az.

 (count: 1) (last timestamp: 2020-11-03 16:04:32 00:00) pulling image "primekey/ejbca-ce:6.15.2.3"
(count: 1) (last timestamp: 2020-11-03 16:04:37 00:00) Successfully pulled image "primekey/ejbca-ce:6.15.2.3"
(count: 28) (last timestamp: 2020-11-03 16:27:52 00:00) Error: Failed to start container aci-pulsy-ccm-ejbca-snd, Error response: to create containerd task: failed to create container e9e48a06807fba124dc29633dab10f6229fdc5583a95eb2b79467fe7cdffba97: guest RPC failure: failed to find user by uid: 10001: expected exactly 1 user matched '0': unknown
  

Извлечение файла dockerfile из dockerhub

Я подозреваю, что проблема может быть связана с командами USER 0 , и USER 10001 мы несколько раз находили в dockerfile.

 COPY dir:89ead00b20d79e0110fefa4ac30a827722309baa7d7d74bf99910b35c665d200 in /
/bin/sh -c rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
CMD ["/bin/bash"]
USER 0
COPY dir:893e424bc63d1872ee580dfed4125a0bef1fa452b8ae89aa267d83063ce36025 in /opt/primekey
COPY dir:756f0fe274b13cf418a2e3222e3f6c2e676b174f747ac059a95711db0097f283 in /licenses
USER 10001
CMD ["/opt/primekey/wildfly-14.0.1.Final/bin/standalone.sh" "-b" "0.0.0.0"
MAINTAINER PrimeKey Solutions AB
ARG releaseTag
ARG releaseEdition
  

Шаблон ARM

 {
      "type": "Microsoft.ContainerInstance/containerGroups",
      "apiVersion": "2019-12-01",
      "name": "[variables('ejbcaContainerGroupName')]",
      "location": "[parameters('location')]",
      "tags": "[variables('tags')]",
      "dependsOn": [
        "[resourceId('Microsoft.DBforMariaDB/servers', variables('ejbcaMariadbServerName'))]",
        "[resourceId('Microsoft.DBforMariaDB/servers/databases', variables('ejbcaMariadbServerName'), variables('ejbcaMariadbDatabaseName'))]"
      ],
      "properties": {
        "sku": "Standard",
        "containers": [
          {
            "name": "[variables('ejbcaContainerName')]",
            "properties": {
              "image": "primekey/ejbca-ce:6.15.2.3",
              "ports": [
                {
                  "protocol": "TCP",
                  "port": 443
                },
                {
                  "protocol": "TCP",
                  "port": 8443
                }
              ],
              "environmentVariables": [

                {
                  "name": "DATABASE_USER",
                  "value": "[concat(parameters('mariadbUser'),'@', variables('ejbcaMariadbServerName'))]"
                },
                {
                  "name": "DATABASE_JDBC_URL",
                  "value": "[variables('ejbcaEnvVariableJdbcUrl')]"
                },
                {
                  "name": "DATABASE_PASSWORD",
                  "secureValue": "[parameters('mariadbAdminPassword')]"
                }
              ],
              "resources": {
                "requests": {
                  "memoryInGB": 1.5,
                  "cpu": 2
                }
              }
              ,
               "volumeMounts": [
                 {
                   "name": "certificates",
                   "mountPath": "/mnt/external/secrets"
                 }
               ]
            }
          }
        ],
        "initContainers": [],
        "restartPolicy": "OnFailure",
        "ipAddress": {
          "ports": [
                {
                  "protocol": "TCP",
                  "port": 443
                },
                {
                  "protocol": "TCP",
                  "port": 8443
                }
          ],
          "type": "Public",
          "dnsNameLabel": "[parameters('ejbcaContainerGroupDNSLabel')]"
        },
        "osType": "Linux",
         "volumes": [
           {
             "name": "certificates",
             "azureFile": {
               "shareName": "[parameters('ejbcaCertsFileShareName')]",
               "storageAccountName": "[parameters('ejbcaStorageAccountName')]",
               "storageAccountKey": "[parameters('ejbcaStorageAccountKey')]"
             }
           }
         ]
      }
    }

  

Он отлично работает на моем локальном компьютере в Linux (ubuntu 20.04)

 docker run -it --rm -p 8080:8080 -p 8443:8443 -h localhost -e DATABASE_USER="mymaridbuser@my-db" -e DATABASE_JDBC_URL="jdbc:mariadb://my-azure-domain.mariadb.database.azure.com:3306/ejbca?useSSL=true" -e DATABASE_PASSWORD="my-pwd" primekey/ejbca-ce:6.15.2.3
  

Комментарии:

1. Похоже, что Azure не использует пользователей для Docker, или, возможно, они используют другую среду выполнения контейнера, а не сам Docker. Возможно, вы можете использовать этот образ из Azure market place, потому что, если это не сработает, вы можете получить поддержку от Bitnami: azuremarketplace.microsoft.com/en-us/marketplace/apps /…

Ответ №1:

Я думаю, что в образе контейнера EJBCA-ce они пытаются предоставить пользователя, отличного от root запуска сервера EJBCA. Согласно документации Docker:

Инструкция ПОЛЬЗОВАТЕЛЯ задает имя пользователя (или UID) и, при необходимости, группу пользователей (или GID) для использования при запуске образа и для любых инструкций RUN, CMD и ENTRYPOINT, которые следуют за ним в файле Dockerfile

В Dockerfile них ссылаются на двух пользователей root , соответствующих UID 0 , и еще одного с UID 10001 .

Как правило, в системах Linux и UNIX UID могут быть организованы в разных диапазонах: это во многом зависит от конкретной операционной системы и практики управления пользователями, но очень вероятно, что первой учетной записи пользователя, созданной в системе Linux, будет присвоен UID 1001 или 10001 , как в этом случае. Пожалуйста, посмотрите, например, Запись UID в Википедии или в этой статье.

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

Пользователь с UID 10001 будет фактически настроен в вашем контейнере с помощью скрипта, который запускается в CMD Dockerfile , /opt/primekey/bin/start.sh , с помощью этого фрагмента кода:

 if ! whoami amp;> /dev/null; then
  if [ -w /etc/passwd ]; then
    echo "${APPLICATION_NAME}:x:$(id -u):0:${APPLICATION_NAME} user:/opt:/sbin/nologin" >> /etc/passwd
  fi
fi
  

Пожалуйста, имейте в виду, что APPLICATION_NAME в этом контексте принимает значение ejbca и что пользователь, который запускает этот скрипт, как указано в Dockerfile , является 10001 . Это будет значение, указанное командой id -u в этом коде.

Вы можете проверить это, если запустите свой контейнер локально:

 docker run -it -p 8080:8080 -p 8443:8443 -h localhost primekey/ejbca-ce:6.15.2.3
  

И инициализируйте bash его:

  docker exec -it container_name /bin/bash
  

Если вы запустите whoami , он сообщит вам ejbca .

Если вы запустите id его, он выдаст вам следующий вывод:

 uid=10001(ejbca) gid=0(root) groups=0(root)
  

Вы также можете проверить существование пользователя /etc/passwd в:

 bash-4.2$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
ejbca:x:10001:0:ejbca user:/opt:/sbin/nologin
  

Причина, по которой Пьер не получил этот вывод, заключается в том, что он запустил контейнер, перезаписав предоставленный CMD и, как следствие, не выполнив start.sh сценарий, ответственный за создание пользователя, как упоминалось выше.

По какой-либо причине, и именно здесь мои знания подводят меня, когда Azure пытается запустить ваш контейнер, он терпит неудачу, потому USER 10001 что идентифицированный в Dockerfile не существует.

Я думаю, это может быть связано с использованием containerd вместо docker .

Ошибка, о которой сообщает Azure, похоже, связана с Microsoft project opengcs.

Они говорят о проекте:

Open Guest Compute Service — это проект Linux с открытым исходным кодом для дальнейшей разработки качественной реализации Linux Hyper-V container в Windows (LCOW). Он предназначен для запуска внутри пользовательской ОС Linux для поддержки полезной нагрузки контейнера Linux.

И:

Основное внимание в LCOW v2 в качестве замены LCOW v1 уделяется координации и работе, которая была проделана в containerd / containerd и его интерфейсе Runtime V2. Чтобы увидеть нашу прокладку на стороне хоста контейнера, пожалуйста, посмотрите здесь Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1.

Ошибка, которую вы видите в консоли, вызвана spec.go файлом, который вы можете найти в их базе кода, когда они пытаются установить пользователя, от имени которого должен быть запущен процесс контейнера:

 func setUserID(spec *oci.Spec, uid int) error {
    u, err := getUser(spec, func(u user.User) bool {
        return u.Uid == uid
    })
    if err != nil {
        return errors.Wrapf(err, "failed to find user by uid: %d", uid)
    }
    spec.Process.User.UID, spec.Process.User.GID = uint32(u.Uid), uint32(u.Gid)
    return nil
}
  

Этот код выполняется другим фрагментом кода — вы можете увидеть полный код функции здесь:

 parts := strings.Split(userstr, ":")
switch len(parts) {
case 1:
    v, err := strconv.Atoi(parts[0])
    if err != nil {
        // evaluate username to uid/gid
        return setUsername(spec, userstr)
    }
    return setUserID(spec, int(v))
  

И getUser функция:

 func getUser(spec *oci.Spec, filter func(user.User) bool) (user.User, error) {
    users, err := user.ParsePasswdFileFilter(filepath.Join(spec.Root.Path, "/etc/passwd"), filter)
    if err != nil {
        return user.User{}, err
    }
    if len(users) != 1 {
        return user.User{}, errors.Errorf("expected exactly 1 user matched '%d'", len(users))
    }
    return users[0], nil
}
  

Как вы можете видеть, это именно те ошибки, о которых сообщает Azure.

В качестве резюме, я думаю, что они предоставляют решение Windows LCOW, которое соответствует спецификации формата изображения OCI, подходящей для запуска контейнеров containerd .

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

Возможным обходным путем может быть создание пользовательского образа на основе официального, предоставленного PrimeKey, и создание пользователя 10001 , как также указал Пьер.

Для выполнения этой задачи сначала создайте новый пользовательский Dockerfile интерфейс . Вы можете попробовать, например:

 FROM primekey/ejbca-ce:6.15.2.3

USER 0

RUN echo "ejbca:x:10001:0:ejbca user:/opt:/sbin/nologin" >> /etc/passwd

USER 10001
  

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

С помощью этого Dockerfile вы можете создать свой образ с docker помощью или docker compose с соответствующим docker-compose.yaml файлом, что-то вроде:

 version: "3"

services:
  ejbca:
    image: <your repository>/ejbca
    build: .
    ports:
      - "8080:8080"
      - "8443:8443"
  

Пожалуйста, настройте его так, как считаете нужным.

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

Комментарии:

1. @MarcBouvier Я обновил ответ информацией, связанной с кодом, который, как я думаю, Microsoft использует в реализации контейнеров Azure. Как указано в ответе, они, вероятно, переключили ваши контейнеры с реализации среды выполнения Linux containerd на реализацию, основанную на Windows и в указанном программном обеспечении, и именно поэтому ваши контейнеры теперь выходят из строя. Боюсь, что четкого решения вашей проблемы нет. Мой лучший совет — попробуйте некоторые из предложенных обходных путей или обратитесь в службу поддержки Microsoft.

2. Вот ответ от службы поддержки Azure. Похоже, это соответствует вашей гипотезе. «Для изображения требуется несколько пользователей hub.docker.com/layers/primekey/ejbca-ce/6.15.2.3/images/… который не поддерживается во время выполнения контейнера «. Они предлагают «закрепить подписку на развертывание только в контейнерной инфраструктуре» в качестве резолюции.

3. Я углубился в детали ваших новых входных данных. Спасибо за такой подробный ответ. Позвольте мне принять ваш ответ, когда разрешение запроса в службу поддержки подтвердит ваш ответ.

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

5. Все в порядке, @MarcBouvier. Я очень рад слышать, что вы наконец смогли развернуть ejbca. Кстати, отличный продукт!

Ответ №2:

Пользователь с UID 10001 не существует в вашем изображении. Это не мешает USER работе команды в вашем Dockerfile или недопустимости самого изображения, но, похоже, вызывает проблемы с контейнером Azure.

Я не могу найти документ или какую-либо ссылку на то, почему он не работает в Azure (будет обновлен, если это так), но добавление пользователя в изображение должно решить проблему. Попробуйте добавить что-то подобное в свой Dockerfile, чтобы создать пользователя с UID 10001 (это должно быть сделано от имени пользователя root, то есть с пользователем 0 ) :

 useradd -u 10001 myuser
  

Дополнительные примечания для просмотра пользователя 10001 не существует:

 # When running container, not recognized by system
$ docker run docker.io/primekey/ejbca-ce:6.15.2.3 whoami
whoami: cannot find name for user ID 10001

# Not present in /etc/passwd
$ docker run docker.io/primekey/ejbca-ce:6.15.2.3 cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin