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 ....
Related
Is it possible for a second Docker container to natively access the internal file system of another container if they're running on the same system?
without mapping volumes, I think it is not possible!
when you run a container Docker create a namespace for that container and this namespace creates a layer of isolation for the processes of that container meaning their PID sequence, hostname, filesystem, ..... are isolated and for them it is like they are the only processes in that machine
if you need more informations refer to this book: https://www.manning.com/books/kubernetes-in-action
You can use shared filesystem mounted as volume in two separate containers.
The following command will create a directory called nginxlogs in your current user’s home directory and bindmount it to /var/log/nginx in the container:
docker run --name=nginx -d -v ~/nginxlogs:/var/log/nginx -p 5000:80 nginx
Then you can perform same operations on another container.
Finally you have to remember that if two separate processes from different containers will try to access files it can cause conflicts.
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.
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
How can i attach a HBA card (which is on my physical server running on centos 7) to a docker container? As I'm doing POC for migration to docker from existing environment this is much needed. It's similar to direct IO in VMware ESXi(Attaching a physical hba to VM can be done via Direct I/O).
Docker isn't a hypervisor, containers aren't VMs, and "attaching devices" to a container doesn't necessarily make sense -- a container is just a process running on your host.
You can expose a device node in /dev to a container using the --device flag to docker run, although exposing a block device inside a container usually leads to other complications (e.g., a normal container can't mount filesystems, so you would need to run it with --privileged, which may or may not be acceptable form a security perspective depending on your environment).
For storage, it is more common to mount devices on the host, and then expose those filesystems to container as Docker volumes (-v /host/path:/container/path).
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