Docker (CentOS 7 с SYSTEMCTL): не удалось смонтировать tmpfs и cgroup

(Я новичок в Docker. Затем я изучил несколько руководств по CentOS-7)

В моем CentOS 7.2 я пытался изучить Docker, выполнив следующие шаги.

# docker version

Client:
 Version:      1.10.3
 API version:  1.22
 Go version:   go1.5.3
 Git commit:   20f81dd
 Built:        Thu Mar 10 15:39:25 2016
 OS/Arch:      linux/amd64

Server:
 Version:      1.10.3
 API version:  1.22
 Go version:   go1.5.3
 Git commit:   20f81dd
 Built:        Thu Mar 10 15:39:25 2016
 OS/Arch:      linux/amd64

# docker pull centos:latest
# docker images
centos     latest    778a53015523    12 days ago    196.7 MB

# mkdir ~/docker/centos7-systemd
# cd ~/docker/centos7-systemd
# vi Dockerfile
FROM centos
MAINTAINER "XXXX XXXX" <[email protected]>
ENV container docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]

# docker build --rm -t local/centos7-systemd .
..
Successfully built 1a9f1c4938b3

# docker images
centos                  latest    778a53015523    12 days ago    196.7 MB
local/centos7-systemd   latest    1a9f1c4938b3    8 seconds ago  196.7 MB

Итак, до этого момента все (кажется) в порядке.
Теперь проблема возникает, когда я запускаю:

# docker run -ti -v /sys/fs/cgroup:/sys/fs/cgroup:ro -p 80:80 local/centos7-systemd
Failed to mount tmpfs at /run: Operation not permitted
Failed to mount cgroup at /sys/fs/cgroup/systemd: Operation not permitted
[!!!!!!] Failed to mount API filesystems, freezing.

Что это вообще означает и, что более важно, что происходит и как я могу это решить, пожалуйста?

Спасибо вам всем :)


person 夏期劇場    schedule 14.04.2016    source источник


Ответы (7)


попробуйте запустить контейнер в привилегированном режиме:

docker run -ti --privileged=true -v /sys/fs/cgroup:/sys/fs/cgroup:ro -p 80:80 local/centos7-systemd

это должно решить вашу проблему

person arcticless    schedule 14.04.2016
comment
Это работает на самом деле! Большое спасибо!! (И у вас есть какие-нибудь идеи, когда я запускаю, почему он не работает в фоновом режиме. Вместо этого он держится на моем терминале.) Извините, я не знаю, как это объяснить. Еще раз спасибо :D - person 夏期劇場; 14.04.2016
comment
если вы хотите использовать фоновый режим, вы можете попробовать опцию -d - person hiproz; 31.12.2019
comment
Можете ли вы назвать причину, пожалуйста? - person Tengerye; 23.04.2020
comment
На высоком уровне причина проблемы заключается в аргументах командной строки -v /sys/fs/cgroup:/sys/fs/cgroup:ro направляет докеру монтировать /sys/fs/cgroup с хост-компьютера в ту же dir в докер-контейнере. /sys/fs/cgroup — это управляемая ядром структура каталогов, принадлежащая пользователю root. Что такое /sys/fs/cgroup? Управление ресурсами ядра Linux см. man7.org/linux/man-pages/man7 /cgroups.7.html Зачем монтировать его с хоста в док-контейнер? см. hub.docker.com/_/centos, в котором описаны те же шаги в этом вопросе, которые создают контейнер с поддержкой systemd. - person gaoithe; 13.05.2021
comment
поразительнй ! большое спасибо !!! - person Mário de Sá Vera; 18.06.2021

Более современный подход к этому, после того, как Дэниел Уолш внес серию патчей, заключается в следующем...

docker run -ti --tmpfs /tmp --tmpfs /run -v /sys/fs/cgroup:/sys/fs/cgroup:ro -p 80:80 local/centos7-systemd

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

Хотя в целом мы должны поддерживать принцип «один сервис/процесс для каждого контейнера», некоторые люди хотят запускать контейнеры, поддерживаемые RedHat, что означает использование systemd.

См. https://developers.redhat.com/blog/2016/09/13/running-systemd-in-a-non-privived-container/ для получения дополнительной информации.

Чтобы продемонстрировать урезанный контейнер systemd, что-то вроде этого будет иметь запущенные apache и tomcat; не единый принцип службы/процесса, а просто пример. Очевидно, вам нужно сделать больше с этим изображением, но это основная идея. Я думаю, что я получил это из одного из постов Дэниела где-то, но я не помню сейчас.

FROM centos:7
ENV container docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \
systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
RUN yum -y install httpd tomcat tomcat-javadoc.noarch \
    tomcat-docs-webapp.noarch tomcat-admin-webapps.noarch ; \
    yum clean all
RUN systemctl enable tomcat.service
RUN systemctl enable httpd.service

VOLUME [ "/sys/fs/cgroup" ]
EXPOSE 80 8080
CMD ["/usr/sbin/init"]

docker build -t apache ./
docker run --tmpfs /tmp --tmpfs /run -it -v /sys/fs/cgroup:/sys/fs/cgroup:ro -p 8081:80 -p 8080:8080 --name apache apache
person Trenton D. Adams    schedule 06.02.2019
comment
За это нужно много голосов. Вы хотите по возможности избегать работы в привилегированном режиме. - person udondan; 06.01.2020
comment
и в случае, если вы находитесь в хост-системе, которая не является BSD (т.е. изначально не имеет systemd cgroup basedir), вы должны просто скопировать ее в tar-шар из любой системы, подобной BSD, в локальный каталог и заменить на нее! например, он работает на Mac. - person Mário de Sá Vera; 18.06.2021

У меня такая же проблема с Docker для Windows (1.12.3)...

$ docker logs bareos
systemd 219 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
Detected virtualization docker.
Detected architecture x86-64.

Welcome to CentOS Linux 7 (Core)!

Set hostname to <bareos>.
Failed to install release agent, ignoring: No such file or directory
Failed to create root cgroup hierarchy: No such file or directory
Failed to allocate manager object: No such file or directory
[!!!!!!] Failed to allocate manager object, freezing.

В последнем boot2docker нет systemd. У нас не может быть systemd в контейнере Docker, если его нет на хосте. Поскольку важной папкой для этого является /sys/fs/cgroup/systemd.

Итак, наконец, я создаю виртуальную машину default в VitualBox на основе Alpine Linux и default docker-machine с драйвером generic.

person Michel Buczynski    schedule 09.11.2016

Как я уже сказал здесь, вы не обязаны использовать параметр --privileged=true (что может быть опасно, ИМХО), вы просто забыли добавить -v /run к своей команде docker run.

Итак, ваша последняя команда запуска, которая должна работать, будет:

docker run -ti -v /sys/fs/cgroup:/sys/fs/cgroup:ro -v /run -p 80:80 local/centos7-systemd
person Anthony O.    schedule 19.09.2018

Если вам не нужно запускать контейнер на переднем плане, вы можете запустить в автономном режиме, чтобы избежать этой ошибки. Например:

docker run -d --name=my_container_name image_id

Затем вы можете использовать что-то вроде этого, чтобы получить оболочку в контейнере:

docker exec -ti my_container_name /bin/bash

Если у вас нет команды на переднем плане в CMD Dockerfile, вызывающей немедленный выход из контейнера, вы можете добавить команду, которая поддерживает его работу, например:

docker run -d --name=my_container_name image_id tail -f /dev/null

Подробнее о последнем примере см. в SO answer.

person Nagev    schedule 29.04.2019

MacOS X не требует монтирования тома cgroups в контейнере

$docker run -it -p 80:80 ${ImageID}

После запуска многих экземпляров контейнера Мой Mac застрял в

[!!!!!!] Failed to mount API filesystems, freezing.

ссылка В настоящее время режим bash у меня работает нормально

$docker run -it -p 80:80 ${ImageID} /bin/bash

person patilnitin    schedule 25.04.2017

Хотя вы можете запустить systemd внутри контейнера, я не думаю, что это хорошая идея. Вот почему:

  1. #P2#
    #P3#
  2. #P4# <блочная цитата> #P5# #P6#
  3. Этот сообщение в блоге был связан в качестве примера того, как заставить его работать, но вы можете видеть, что контейнер по-прежнему нужно запускать от имени пользователя root:

    EXPOSE 80
    CMD [ "/sbin/init" ]
    

    Хотя это, конечно, не уникально для этих контейнеров, это все же менее безопасно:

  4. В качестве еще одного доказательства того, что это не очень хорошая идея, даже собственные Dockerfiles Red Hat CentOS не делают этого. Например (источник):

    FROM centos:centos7
    
    # RHSCL httpd24 image.
    #
    # Volumes:
    #  * /opt/rh/httpd24/root/var/www - Datastore for httpd
    #  * /var/log/httpd24 - Storage for logs when $HTTPD_LOG_TO_VOLUME is set
    # Environment:
    #  * $HTTPD_LOG_TO_VOLUME (optional) - When set, httpd will log into /var/log/httpd24
    
    EXPOSE 80
    EXPOSE 443
    
    COPY run-*.sh /usr/local/bin/
    RUN mkdir -p /var/lib/httpd24
    COPY contrib /var/lib/httpd24/
    
    RUN rpmkeys --import file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 && \
        yum -y --setopt=tsflags=nodocs install https://www.softwarecollections.org/en/scls/rhscl/httpd24/epel-7-x86_64/download/rhscl-httpd24-epel-7-x86_64.noarch.rpm && \
        yum install -y --setopt=tsflags=nodocs gettext hostname bind-utils httpd24 httpd24-mod_ssl && \
        yum clean all
    
    # When bash is started non-interactively, to run a shell script, for example it
    # looks for this variable and source the content of this file. This will enable
    # the SCL for all scripts without need to do 'scl enable'.
    ENV BASH_ENV=/var/lib/httpd24/scl_enable \
        ENV=/var/lib/httpd24/scl_enable \
        PROMPT_COMMAND=". /var/lib/httpd24/scl_enable"
    
    
    VOLUME ["/opt/rh/httpd24/root/var/www"]
    VOLUME ["/var/log/httpd24"]
    
    ENTRYPOINT ["/usr/local/bin/run-httpd24.sh"]
    CMD ["httpd", "-DFOREGROUND"]
    

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

person bmaupin    schedule 18.03.2019