22

(I'm a Docker beginner. Then I followed some tutorials for CentOS-7)

In my CentOS 7.2, I tried to learn Docker by following the steps below.

# 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" <xxxx@xxxx.com>
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

So up to this point, everything (seems) ok.
Now the problem comes when I run:

# 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.

What does this even mean, and more importantly, what is happening and how can I solve this, please?

Thank you all :)

donjuedo
  • 2,475
  • 18
  • 28
夏期劇場
  • 17,821
  • 44
  • 135
  • 217

6 Answers6

36

The more modern approach to this, after Daniel Walsh contributed a series of patches, is this...

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

Essentially starting in a privileged container is a bad idea for security reasons. Since Daniel contributed patches to make it unnecessary we are able to start without escalating privileges.

While it's true that we should maintain the "single service/process per container" principle in general, some people want to run RedHat supported containers, which means the use of systemd.

See https://developers.redhat.com/blog/2016/09/13/running-systemd-in-a-non-privileged-container/ for more information

To demonstrate a stripped down systemd container, something like this would have an apache and tomcat running; not the single service/process principle, but just an example. You'd obviously need to do more to this image, but this is the basic idea. I think I got this from one of Daniel's posts somewhere, but I don't recall now.

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
Trenton D. Adams
  • 1,805
  • 2
  • 16
  • 20
  • 5
    This needs to be upvoted by a lot. You want to avoid running in privileged mode when possible. – udondan Jan 06 '20 at 08:24
  • and in case you are in a host system that is not BSD (ie does not have systemd cgroup basedir originally) you should just copy it in a tar ball from any BSD like system to a local dir and replace for that ! it works in a Mac for example. – Mário de Sá Vera Jun 18 '21 at 11:14
29

try to run your container in privileged mode:

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

this should solve your problem

arcticless
  • 664
  • 5
  • 14
  • This works actually! Thank you so much!! (And do you have any idea when i run, why it doesn't run in the background. Instead it is holding on my terminal.) Sorry i don't know how to explain this. Thanks again :D – 夏期劇場 Apr 14 '16 at 09:04
  • 1
    if you want use backgroud mode ,you can try -d option – hiproz Dec 31 '19 at 08:45
  • Can you give the reason please? – Tengerye Apr 23 '20 at 13:30
  • At a high level the reason there is a problem is the command-line arguments " -v /sys/fs/cgroup:/sys/fs/cgroup:ro " direct docker to mount /sys/fs/cgroup from the host machine into the same dir in docker container. /sys/fs/cgroup is a kernel controlled dir structure owned by root. What is /sys/fs/cgroup? Linux kernel resource control see https://man7.org/linux/man-pages/man7/cgroups.7.html Why mount it from host into docker container? see https://hub.docker.com/_/centos which describes the same steps in this question which create a systemd enabled container. – gaoithe May 13 '21 at 17:06
2

I got the same problem with Docker for 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.

The latest boot2docker doesn't have systemd. We can't have systemd in a Docker container, if the host doesn't have it. Since the important folder for that is /sys/fs/cgroup/systemd.

So finally, I create a default vm in VitualBox based on Alpine Linux and a default docker-machine with the generic driver.

2

MacOS X doesn't require to mount cgroups volume in container

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

After running many container instances, My mac stuck into

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

reference Currently bash mode is working fine for me

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

patilnitin
  • 1,151
  • 10
  • 14
2

As I said here, you are not forced tu use the --privileged=true parameter (which can be dangerous IMHO), you just forgot to add -v /run to your docker run command.

So your final run command which should work would be:

docker run -ti -v /sys/fs/cgroup:/sys/fs/cgroup:ro -v /run -p 80:80 local/centos7-systemd
Anthony O.
  • 22,041
  • 18
  • 107
  • 163
2

If you don't need to run the container in the foreground, you can start it in detached mode to avoid this error. For example:

docker run -d --name=my_container_name image_id

Then you can use something like this to get a shell into the container:

docker exec -ti my_container_name /bin/bash

If you don't have a command in the foreground in the Dockerfile CMD, causing the container to immediately exit, you can add a command that keeps it running, e.g.:

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

See the SO answer for more details on the last example.

Nagev
  • 10,835
  • 4
  • 58
  • 69