This article covers essential Docker security concepts, including process isolation, user privileges, and managing Linux capabilities for container security.
Welcome to this comprehensive lesson on Docker security. In this session, we explore essential Docker security concepts that lay the groundwork for understanding security contexts in Kubernetes. We’ll begin by reviewing how Docker isolates container processes using namespaces and how user privileges impact container security.Imagine a host machine with Docker installed. This host runs its own processes, such as the operating system services, the Docker daemon, and an SSH server. Now, consider running an Ubuntu container executing a process that sleeps for one hour. Unlike virtual machines, containers share the host’s Linux kernel and achieve isolation through namespaces. Each container operates within its dedicated namespace, keeping its processes hidden from the host and other containers.For example, when you run the following command to start a container:
Copy
Ask AI
docker run ubuntu sleep 3600
Inside the container, if you list the processes:
Copy
Ask AI
bashps aux
you will observe only the sleep process with a process ID of 1. However, on the host where processes across all namespaces are managed, the same sleep process appears among many with a different process ID:
Copy
Ask AI
bashps auxUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMANDroot 1 0.0 0.0 4528 828 ? Ss 03:06 0:00 sleep 3600
Docker uses namespaces to maintain process isolation. Although the container’s process starts with PID 1 inside its own namespace, it receives a different PID when viewed on the host system.
Docker hosts usually have a root user along with non-root users. By default, Docker starts container processes as the root user. You can verify this by comparing the process list inside and outside the container, as shown below:
To improve security, it is best practice to avoid running container processes as the root user. You can change the user at runtime using the --user option:
Copy
Ask AI
docker run --user=1000 ubuntu sleep 3600
After running this command, inspecting the host process list shows the process running as user ID 1000:
Copy
Ask AI
bashps auxUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND1000 1 0.0 0.0 4528 828 ? Ss 03:06 0:00 sleep 3600
Another method to enforce security is by specifying the user in the Docker image during build-time. For example, you can create a Dockerfile based on the default Ubuntu image and set a non-root user:
Copy
Ask AI
FROM ubuntuUSER 1000
Build the custom image and run a container with the following commands:
Copy
Ask AI
docker build -t my-ubuntu-image .docker run my-ubuntu-image sleep 3600
Verifying the running process confirms that it is executed as user ID 1000:
Copy
Ask AI
bashps auxUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND1000 1 0.0 0.0 4528 828 ? Ss 03:06 0:00 sleep 3600
Even though containers by default run as the root user, Docker restricts the container’s root privileges using Linux capabilities. This ensures that the container’s root does not have the same level of control as the host’s root.
Docker utilizes Linux capabilities to restrict what the container’s root user can do. Unlike a system’s root user, which can perform all actions, the container’s root is limited by a default set of capabilities. This prevents containers from performing operations that might compromise the host system or other containers.If additional privileges are needed, you can grant them with the --cap-add option:
Copy
Ask AI
docker run --cap-add=MAC_ADMIN ubuntu
Conversely, to reduce privileges further, the --cap-drop option can be used. In cases where you require a container to run with all privileges, the --privileged flag is available, although it should be used with caution.That concludes our introduction to Docker security. In upcoming lessons, we will dive deeper into Kubernetes security contexts and explore how these Docker security measures extend into container orchestration environments.