В образе контейнера EJBCA-ce, я думаю, они пытаются предоставить пользователя, отличного от root
, для запуска сервера EJBCA. Согласно документации Docker:
Инструкция USER устанавливает имя пользователя (или 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 &> /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 opengcs.
О проекте говорят:
Open Guest Compute Service - это проект Linux с открытым исходным кодом, направленный на дальнейшее развитие производственной реализации контейнера Linux Hyper-V в 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
.
Как вы указали, если он работал с той же конфигурацией пару недель назад, моим лучшим гостем является то, что, возможно, они переключили ваши контейнеры с чистой реализации среды выполнения Linux containerd
на реализацию, основанную на 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.
person
jccampanero
schedule
19.11.2020