-
install SELinux-dockersock if you need to allow containers to access
docker.sock
-
add the z: or Z: option to any host->container volume mappings (i.e.
-v /host-dir:/container_dir:Z
as part of arun
command or asoptions: ["z"]
or["Z"]
in a yaml config file)
The following (and summary above) reflects the results of my efforts to give a Jenkins container (that is, a container running Jenkins) a spin while running in an SELinux environment, which is the default for CentOS and RHEL 7. For those not familiar with SELinux, there are plenty of resources out there to explain it in great depth. Suffice it to say that it is a rich and robust Mandatory Access Control security layer that, by design, places a lot of restrictions on what can be accessed by a user/application. In this particular case, there were two SELinux gotchas that interfered with my attempt to give Jenkins a try this way, although the issues and their solutions apply more broadly to running Docker under SELinux in general.
Following is the run command that the Jenkins website provides as the starting point for a Python app building tutorial:
docker run \
--rm \
-u root \
-p 8080:8080 \
-v jenkins-data:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$HOME":/home \
jenkinsci/blueocean
-
The first thing to note is that this docker command looks to bind the host
/var/run/docker.sock
resource to an identical path in the container. This is so that the container can act as a client to the docker daemon it is running under. Jenkins wants this so that it can spin up its own containers as part of its processing. However, and for good reason, SELinux locks/var/run/docker.sock
down. But if you need it (as the Jenkins container does), you'll need to install SELinux-dockersock, which will allow containers to access that socket. -
When mapping a host directory to a container, as this docker command does for the user's home directory (which is where the tutorial files are placed), you need to flag the mapping with
:z
or:Z
to have docker re-label the host directory so that the container has full access to it. The:z
flag is more permissive, in that it allows the bound directory to be shared across multiple containers.:Z
locks the bound directory to that specific container (private and unshared). On a system running under SELinux, you can readily see what happens if you do not use one of the two flags:
luberda@localhost git-jekyll-docker]$ docker run --rm -it --name mycontainer -v ~/host_test:/tmp/container_test docker.io/centos:7
[root@5391ab6e565a /]# ls -ldZ /tmp/container_test
drwxr-xr-x. root root system_u:object_r:svirt_sandbox_file_t:s0:c117,c400 /tmp/container_test
[root@5391ab6e565a /]# cd /tmp/container_test
bash: cd: /tmp/container_test: Permission denied
With the flag (in this case, :Z
), we now have access to the bound directory:
[luberda@localhost git-jekyll-docker]$ docker run --rm -it --name mycontainer -v ~/host_test:/tmp/container_test:Z docker.io/centos:7
[root@da4d0addb286 /]# ls -ldZ /tmp/container_test
drwxr-xr-x. root root system_u:object_r:svirt_sandbox_file_t:s0:c28,c471 /tmp/container_test
[root@da4d0addb286 /]# cd /tmp/container_test
[root@da4d0addb286 container_test]#
So our revised version of the Jenkins tutorial command is:
docker run \
--rm \
-u root \
-p 8080:8080 \
-v jenkins-data:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$HOME":/home:Z \
jenkinsci/blueocean
In short, so that Dan Walsh doesn't have to weep, or perhaps not as much, just because you wanted to give Jenkins a test drive, you can thus stopdisablingSELinux.
One other thing to note: it has been variously observed that it is a very bad idea to mount system directories such as /etc
, /home
, /usr
, and /var
using either :z
or :Z
(and especially the latter). Doing so risks breaking things, possibly rendering your host system inoperable. So probably don't do that.
Hello, the :z and :Z labels are not available when using a docker swarm service. Do you have a recommended method for using bind mounts with Docker Swarm Services?