PID mapping between docker and host - docker

How docker namespace is different from Host namespace and how the pid can be mapped between these two? Can anyone give me an idea that helps to make easy way of mapping pid's between host n docker using source code?

You can find the mapping in /proc/PID/status file. It contains a line like:
NSpid: 16950 24
Which means that 16950 on the host is 24 inside the container.

As I mentioned in "Running docker securely":
Currently, Docker uses five namespaces to alter processes view of the system: Process, Network, Mount, Hostname, Shared Memory.
The fact that, by default, as I mentioned in your previous question "Docker Namespace in kernel level" the container pid are isolated from the host (unless you run them with --pid host) is by design.
If you are using --pid=host, then those container pids are visible from the host, but not easily matched to a particular container, not until issue 10163 and --pid=container:id is resolved.
Update May 2016: issue 10163 and --pid=container:id is actually resolved by PR 22481 for docker 1.12, allowing to join another container's PID namespace.

Related

Is docker container completely isolated with outside of the docker container?

I wonder whether things like shell script execution can affect on the outside of the container. For example, let's say I want to save some file at the host machine from inside of the container, not using docker volumes or mount. Is that can be done? Or let's say I want to kill a process which is running on the host machine with shell commands from inside of the container. Is that can be done?
No, that is not possible, a docker container environment is completely isolated from the host, the only way to change some files in the host is by mounting a volume from the host to the container, you can kill an external PID but it's not a common practice.
Docker takes advantage of Linux namespaces to provide the isolated workspace we call a container. When a container is deployed, Docker creates a set of namespaces for that specific container, isolating it from all the other running containers. The various namespaces created for a container include:
PID Namespace: Anytime a program starts, a unique ID number is assigned to the namespace that is different than the host system. Each container has its own set of PID namespaces for its processes.
MNT Namespace: Each container is provided its own namespace for mount directory paths.
NET Namespace: Each container is provided its own view of the network stack avoiding privileged access to the sockets or interfaces of another container.
UTS Namespace: This provides isolation between the system identifiers; the hostname and the NIS domain name.
IPC Namespace: The inter-process communication (IPC) namespace creates a grouping where containers can only see and communicate with other processes in the same IPC namespace.
Containers allow developers to package large or small amounts of code and their dependencies together into an isolated package. This model then allows multiple isolated containers to run on the same host, resulting in better usage of hardware resources, and decreasing the impact of misbehaving applications on each other and their host system.
I hope it may help you.
You cannot modify host files without mounting them inside the container, though you can mount entire root inside (e.g -v /:/host). As for killing host processes, it is possible if you ran the container with host PID mode: docker run --pid=host ....

How to find a process's pid in docker host namespace from inside a container in which it is running

I have a process running inside a container. I want to know this process's pid in docker host namespace from inside the container. I have a docker client installer inside the container from which I can execute a few commands but I do not have full privileges since I'm doing so from inside the container. Is there a way to find this pid?
The purpose of this approach was to make sure that only one instance of a process is running at time on a docker host. So the idea is to store the pid of the process at docker host level, so that it can be checked before starting a new instance.
I found another way to do so by using container id. You can do docker ps from inside the container and it will list all the containers running on docker host. Moreover container id does not change with namespace unlike pid. That solves my problem.

Docker pid namespace and Host

When we run the same process in docker and in host system, how it differentiates one from the other, from the perspective of audit logs?
Can I view the process running in docker in host system?
You would not run the same process (same pid) in docker and in host, since the purpose of a container is to provide isolation (both processes and filesystem)
I mentioned in your previous question "Docker Namespace in kernel level" that the pid of a process run in a container could be made visible from the host.
But in term of audit log, you can configure logging drivers in order to follow only containers, and ignore processes running directly on host.
For instance, in this article, Mark configures rsyslog to isolate the Docker logs into their own file.
To do this create /etc/rsyslog.d/10-docker.conf and copy the following content into the file using your favorite text editor.
# Docker logging
daemon.* {
/var/log/docker.log
stop
}
In summary this will write all logs for the daemon category to /var/log/docker.log then stop processing that log entry so it isn’t written to the systems default syslog file.
That should be enough to clearly differentiate the host processes logs (in regular syslog) from the ones running in containers (in /var/log/docker.log)
Update May 2016: issue 10163 and --pid=container:id is closed by PR 22481 for docker 1.12, allowing to join another container's PID namespace.

Docker Namespace in kernel level

How to differentiate pid 1,17 etc of docker containers with host's 1,17 etc pid's and what all the kernel changes are happening when we create a new process inside the docker container?
How the process inside the docker can be seen in the host?
How to differentiate pid 1,17 etc of docker containers with host's 1,17
By default, those pid are in different namespace.
Since issue 10080 and --pid host, the container pids can stay in the host's pid namespace.
There also issue 10163: "Allow shared PID namespaces", requesting a --pid=container:id
what all the kernel changes are happening when we create a new process inside the docker container
Note and update May 2016: issue 10163 and --pid=container:id is now resolved by PR 22481 for docker 1.12, allowing to join another container's PID namespace.
No changes on the kernel level, only the use of:
cgroups or control groups. A key to running applications in isolation is to have them only use the resources you want.
union file systems to provide the building blocks for containers

Sensu-Client inside Docker container

I created a customize Docker image based on ubuntu 14.04 with the Sensu-Client package inside.
Everything's went fine but now I'm wondering how can I trigger the checks to run from the hosts machine.
For example, I want to be able to check the processes that are running on the host machine and not only the ones running inside the container.
Thanks
It depends on what checks you want to run. A lot of system-level checks work fine if you run sensu container with --net=host and --privileged flags.
--net=host not just allows you to see the same hostname and IP as host system, but also all the tcp connections and interface metric will match for container and host.
--privileged gives container full access to system metrics like hdd, memory, cpu.
Tricky thing is checking external process metrics, as docker isolates it even from privileged container, but you can share host's root filesystem as docker volume ( -v /:/host) and patch check to use chroot or use /host/proc instead of /proc.
Long story short, some checks will just work, for others you need to patch or develop your own way, but sensu in docker is one possible way.
an unprivileged docker container cannot check processes outside of it's container because docker uses kernel namespaces to isolate it from all other processes running on the host. This is by design: docker security documentation
If you would like to run a super privileged docker container that has this namespace disabled you can run:
docker run -it --rm --privileged --pid=host alpine /bin/sh
Doing so removes an important security layer that docker provides and should be avoided if possible. Once in the container, try running ps auxf and you will see all processes on the host.
I don't think this is possible right now.
If the processes in the host instance are running inside docker, you can mount the socket and get the status from the sensu container
Add a sensu-client to the host machine? You might want to split it out so you have granulation between problems in the containers VS problems with your hosts
Else - You would have to set up some way to report from the inside - Either using something low level (system calls etc) or set up something from outside to catch the the calls and report back status.
HTHs
Most if not all sensu plugins hardcode the path to the proc files. One option is to mount the host proc files to a different path inside of the docker container and modify the sensu plugins to support this other location.
This is my base docker container that supports modifying the sensu plugins proc file location.
https://github.com/sstarcher/docker-sensu

Resources