03 | Namespace of basic principles of container technology

When interviewing or interviewing others in the past, a frequently asked question is: how do you understand the container according to your resume that you are familiar with container technology? A fairly good answer is: the container technology itself is not a new technology. The container is essentially a special process on the host operating system. The Namespace and Cgroup technologies are used to realize the isolation and restriction of resources, realize the container image, and solve the problem of application distribution. So far, it can be said that the understanding of containers is quite comprehensive.

Docker installation: I didn't want to write about a lot of things that need to be searched online and don't need to understand, but I read a lot of articles about the installation process. It's a little pit, so I'd better write about it. The installation process is operated on ubuntu, because CentOS7 will not be maintained in the future. I heard that ebay production environment systems also use ubuntu.

step1: update Ubuntu apt get source

 sudo apt-get update
 sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \

Step 2: add Docker official GPG key

 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

step3: address of the warehouse where Docker stable version is installed

 echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

step4: installing Docker

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

It usually runs automatically after installing Docker, but many people want to use this Docker as a test or staging environment for a long time, so it is estimated that there will be problems directly. The default storage directory of Docker is / var/lib/docker /. The disk of some hosts is very small, especially the virtual machine. It takes a period of time to fill up the system disk and has to be moved away, which is very troublesome. It's better to do it in one step, Put the data storage directory on a larger disk, such as / data/docker /.

step5: edit the / lib/systemd/system/docker.service file and add -- data root = / data / docker after the ExecStart option to customize the data directory. The results are as follows:

ExecStart=/usr/bin/dockerd -H fd:// --data-root=/data/docker --containerd=/run/containerd/containerd.sock --log-level warn --log-opt max-size=100m --log-opt max-file=5

Then reload systemd and restart the Docker process.

systemctl daemon-reload
systemctl restart docker

step6: verify that the container has been installed successfully

# docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

Using Docker to run an Nginx container: Docker is used as a tool. In fact, there is nothing complicated. As long as you master Dockerfile, you can use some basic commands. Next, based on Nginx, make our image and run it.

Step 1: write Dockerfile

# Specify your basic image here. It is recommended to write a fixed version number, otherwise the default latest update may lead to incompatibility of your code
FROM nginx:1.21.3

# Default directory after entering the container
WORKDIR /usr/share/nginx/html

# Change the index.html content to what we want
RUN echo "This is my first image base nginx!" > index.html

Step 2: generate Docker image

docker build -t my_nginx:v1.0 -f Dockerfile .

step3: view the generated image and use it to start the container

# docker images
my_nginx     v1.0      5d0547b2cc8d   3 hours ago              133MB

# docker run -d 5d0547b2cc8d

# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS     NAMES
6961dd4fce83   5d0547b2cc8d   "/docker-entrypoint...."   18 minutes ago   Up 18 minutes   80/tcp    strange_jepsen

step4: check the container IP address and use the container IP to access the nginx service. Here we introduce the use of the nsenter command. The scenario is that there is no ifconfig command in our nginx image, but we want to check the IP address. At this time, we can enter the Namespace of the container through the nsenter command and adjust the container with the command on the host.

[root@iZ2zec5wzaupsrdu55oeaiZ docker]# docker inspect 6961dd4fce83 | grep -i pid
            "Pid": 30176,
            "PidMode": "",
            "PidsLimit": null,
[root@iZ2zec5wzaupsrdu55oeaiZ docker]# nsenter -t 30176 -n ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet  netmask  broadcast
        ether 02:42:ac:12:00:02  txqueuelen 0  (Ethernet)
        RX packets 18  bytes 1256 (1.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 14  bytes 1386 (1.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet  netmask
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@iZ2zec5wzaupsrdu55oeaiZ docker]# curl
This is my first image base nginx!

Turn to the topic and elaborate on Namespace: Namespace is not a new technology. It is a function of the kernel. Docker can realize resource isolation by calling the Namespace function of the kernel. This function isolates kernel resources, so that container processes can run in a separate Namespace, and can only access the resources of the current container Namespace.

There are many resource types under Linux, so Namespace is divided into the following categories to limit resources:

  • PID namespace: used to isolate the process ID.
  • Network namespace: isolate the network interface. In the virtual net namespace, users can have their own independent IP, route, port, etc.
  • Mount namespace: file system mount point isolation.
  • IPC namespace: isolation of semaphores, message queues, and shared memory.
  • UTS namespace: isolation of host name and domain name.
  • User namespace: isolation of users and groups.

The isolation of various resources is listed above. Let's take PID namespace as an example to see how it is implemented in the Linux operating system. The system call to create a process in the Linux system is clone(), as shown in the following code:

int pid = clone(main_function, stack_size, SIGCHLD, NULL); 

But once we pass in clone_ According to the newpid parameter, the newly created process enters an independent space. In this space, its own PID is 1. From the outside, it is a normal process. The process number may be xxx, but certainly not 1, because process 1 is the systemd process of the operating system. The following code realizes process isolation:

int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL); 

Generally speaking, after a process is started, Namespace will give it a package, and then the process will play freely in its own small world. However, Qi Tian Da Sheng is unable to escape the five finger mountain of the Tathagata. For developers, it is still a process on the operating system.

For most people, we only need to know how Docker implements process isolation. If we need to dig deeper in the future, we can look for it according to the Namespace function of the operating system.

Tags: Docker Container

Posted on Thu, 18 Nov 2021 10:36:45 -0500 by saviiour