Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What is the implementation principle of Docker exec?

2025-02-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly explains "what is the implementation principle of Docker exec". Interested friends may wish to have a look at it. The method introduced in this paper is simple, fast and practical. Next, let the editor take you to learn "what is the implementation principle of Docker exec"?

I used the docker exec command to get into the container. After learning about the isolation mechanism of Linux Namespace, you should naturally think of a question: how does docker exec get into the container?

In fact, the isolated space created by Linux Namespace is invisible, but the Namespace information of a process does exist on the host machine and exists as a file.

For example, you can see that the process number (PID) of the currently running Docker container is 25686 with the following instruction:

$docker inspect-- format'{{.State.Pid}} '4ddf4638572d25686

At this point, you can see all the Namespace files corresponding to this 25686 process by looking at the proc file of the host:

$ls-l / proc/25686/nstotal 0lrwxrwxrwx 1 root root 0 Aug 13 14:05 cgroup-> cgroup: [4026531835] lrwxrwxrwx 1 root root 0 Aug 13 14:05 ipc-> ipc: [4026532278] lrwxrwxrwx 1 root root 0 Aug 13 14:05 mnt-> mnt: [4026532276] lrwxrwxrwx 1 root root 0 Aug 13 14:05 net-> net: [4026532281] lrwxrwxrwx 1 root root 0 Aug 13 14:05 pid-> pid: [4026532279] lrwxrwxrwx 1 root root 0 Aug 13 14:05 pid_for_children-> pid: 4026532279] lrwxrwxrwx 1 root root 0 Aug 13 14:05 user-> user: [4026531837] lrwxrwxrwx 1 root root 0 Aug 13 14:05 uts-> uts: [4026532277]

As you can see, each Linux Namespace of a process has a corresponding virtual file under its corresponding / proc/ [process number] / ns and is linked to a real Namespace file.

With such a file that can "hold" all Linux Namespace, we can do something meaningful with Namespace, such as adding to an existing Namespace.

This means that a process can choose to join the existing Namespace of a process, so as to achieve the purpose of "entering" the container where the process is located, which is the principle of docker exec implementation.

This operation relies on a Linux system call called setns (). Its calling method, I can use the following paragraph Mini Program to explain to you:

# define _ GNU_SOURCE#include # define errExit (msg) do {perror (msg); exit (EXIT_FAILURE);} while (0) int main (int argc, char * argv []) {int fd;fd = open (argv [1], O_RDONLY); if (setns (fd, 0) = =-1) {errExit ("setns");} execvp (argv [2], & argv [2]); errExit ("execvp");

The function of this code is very simple: it receives a total of two parameters, the first parameter is argv [1], that is, the path of the Namespace file to which the current process is to be added, such as / proc/25686/ns/net;, and the second parameter is the process you want to run in this Namespace, such as / bin/bash.

The core operation of this code is to open the specified Namespace file through the open () system call and give the file's descriptor fd to setns () for use. After setns () is executed, the current process is added to the Linux Namespace corresponding to this file.

Now you can compile and execute this program and add it to the Network Namespace of the container process (PID=25686):

$gcc-o set_ns set_ns.c$. / set_ns / proc/25686/ns/net / bin/bash$ ifconfigeth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:02inet addr:172.17.0.2 Bcast:0.0.0.0 Mask:255.255.0.0inet6 addr: fe80::42:acff:fe11:2/64 Scope:LinkUP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:12 errors:0 dropped:0 overruns:0 frame:0TX packets:10 errors:0 Dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:0RX bytes:976 (976.0 B) TX bytes:796 (796.0 B) lo Link encap:Local Loopbackinet addr:127.0.0.1 Mask:255.0.0.0inet6 addr: 1Plat128 Scope:HostUP LOOPBACK RUNNING MTU:65536 Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000RX bytes:0 (0.0B) TX bytes:0 (0.0B)

As shown above, when we execute the ifconfig command to check the network devices, I will find that there are fewer network cards I can see: only two. My host has at least four network cards. What's going on?

In fact, the two NICs I saw after setns () are the NICs in the Docker container I started earlier. In other words, my newly created / bin/bash process, because it has joined the Network Namepace of the container process (PID=25686), it sees the same network devices as in this container, that is, the network device view of the / bin/bash process has also been modified.

Once a process is added to another Namespace, it will also be reflected in the Namespace file of the host.

On the host, you can use the ps instruction to find the / bin/bash process executed by the set_ns program, and its real PID is 28499:

# ps aux on the host machine | grep / bin/bashroot 28499 0.0 19944 3612 pts/0 S 14:15 0:00 / bin/bash

At this point, if you follow the method described earlier and look at the Namespace of this PID=28499 process, you will find this fact:

$ls-l / proc/28499/ns/netlrwxrwxrwx 1 root root 0 Aug 13 14:18 / proc/28499/ns/net-> net: [4026532281] $ls-l / proc/25686/ns/netlrwxrwxrwx 1 root root 0 Aug 13 14:05 / proc/25686/ns/net-> net: [4026532281]

In the / proc/ [pid] / ns/net directory, this PID=28499 process is exactly the same as the Network Namespace file pointed to by our previous Docker container process (PID=25686). This shows that the two processes share this Network Namespace called net: [4026532281].

In addition, Docker specifically provides a parameter that allows you to launch one container and "add" to the Network Namespace of another container. This parameter is-net, such as:

$docker run-it-net container:4ddf4638572d busybox ifconfig

In this way, our newly launched container will be added directly to the ID=4ddf4638572d container, that is, the Network Namespace of the application container (PID=25686) we created earlier. So, the network card information returned by ifconfig here is exactly the same as the result returned by Mini Program before me, you can also give it a try.

If I specify-net=host, it means that the container will not enable Network Namespace for the process. This means that the container removes the "wall" of Network Namespace, so it will directly share the host's network stack like other ordinary processes on the host. This provides a channel for the container to directly operate and use the host network.

At this point, I believe you have a deeper understanding of "what is the implementation principle of Docker exec?" you might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report