In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >
Share
Shulou(Shulou.com)05/31 Report--
This article mainly explains the "docker source code analysis Libcontainer", the article explains the content is simple and clear, easy to learn and understand, the following please follow the editor's ideas slowly in depth, together to study and learn "docker source code analysis Libcontainer" bar!
1. Brief introduction of Libcontainer 1.1 linux container related technologies
To understand Libcontainer, you must first understand some of the basic technologies used by linux container. Linux container is a kernel virtualization technology that provides lightweight virtualization to isolate processes and resources. This is the core of docker container technology, and docker is an implementation of linux container. The basic technologies used by linux container include namespace, cgroup, chroot, veth, union FS, iptables and netfilter, TC, quota, setrlimit. Here is a brief summary of these basic technologies:
1. Namespace: used for resource isolation to achieve lightweight virtualization, including six kinds of namespace,UTS namespace that provide isolation between hostnames and domain names; IPC namespace provides isolation of inter-process communication; Network namespace provides network isolation including network devices, network stacks, ports, etc.; Mount namespace provides isolation of file systems; and User namespace provides isolation between user permissions.
2. Cgroups: implement resource restrictions to limit and record the physical resources used by task groups. It can also be used for priority allocation to control the priority of running tasks by the number of CPU time slices allocated and the disk IO broadband size. Used for resource statistics, counting the resource usage of the system, such as CPU usage time, memory usage and so on. For task control, you can perform operations such as suspending, controlling, and so on.
3. Chroot: change the root directory for the file system you see in container. It has three advantages: increasing the security of the system and limiting the rights of users; establishing a system directory isolated from the original system, which is very important for the container; and switching the root location of the system.
4. Veth: forwards a packet sent from the network user space (network namespace) to another user space. That is, the communication between the container and the host is realized.
5. Union FS: superimposed file systems, including aufs, a file system that supports federated mounts.
6. Iptables,netfilter: it is mainly used to filter ip packets.
7. TC: mainly used for traffic isolation and bandwidth limitation.
8. Quota: used to limit the size of disk reads and writes, and to limit the amount of free space available to users.
9. Setrlimit: you can limit the number of processes opened in container, the number of files opened, and so on.
1.2 introduction to Libcontainer
Based on the related technologies of linux container above, docker basically implements the first five technologies and makes a layer of encapsulation with libcontainer. In other words, docker encapsulates some of the technologies of linux container through libcontainer, which makes Docker have the advantages of continuous deployment and testing, cross-cloud platform support, environment standardization and version control, high resource utilization and isolation, container cross-platform and mirroring, easy to understand and use, and application image repository. Libcontainer is essentially a package for container management in Docker, which is based on the Goto language and controls the container by managing namespace, Cgroups, capabilities, file system and so on. Libcontainer can be used to create and lifecycle manage containers. When it comes to Libcontainer, you should mention that execdriver,execdriver encapsulates all the methods that operate on OS resources, such as namespace, cgroups, and so on, and Libcontainer is the default implementation of execdriver. Execdriver loads the command information to generate the container configuration container, then calls libcontainer to load the container configuration container, creates the real docker container, completes the creation of the container and manages the container's life cycle.
2. Execdriver workflow
The workflow of Execdriver is shown in figure 2.1:
Figure 2.1 Workflow of execdriver
2.1 introduction to configuration Information
Execdriver first gets the command information submitted by Docker daemon, and the submitted command information contains important information needed to configure containers such as namespace and cgroup. The corresponding command structure source code is shown in figure 2.2, which contains the basic configuration needed to generate the container, such as namespace-related isolation between hostname and domain name; IPC provides isolation of inter-process communication; Network provides network isolation including network devices, network stacks, ports, etc.; Mount provides file system isolation. Resource contains information about cgroup, and ProcessConfig represents information about processes running in the container.
Some of the parameters in figure 2.2 are briefly explained, where ContainerPid indicates that the pid;ID of the process in the container is the container ID, which represents the unique identity of the container; Mount is a kind of namespace used for file system isolation; Network is also a kind of namespace used for network isolation; ProcessConfig describes the information of processes running in the container; Resource provides information related to cgroup, and the deployment of the Resource structure will be analyzed in detail later. Rootfs is the root directory system of the container; WorkingDir is the working path of the container as its name implies; and TmpDir is the directory where temporary docker files are stored.
Figure 2.2 command structure
Cgroups is used to implement resource restrictions, which can limit and record the physical resources used by task groups. Cgroups-related information is contained in resource, and resource contains information about all resources configured by driver. The definition of resource structure is shown in figure 2.3, where memory represents the storage capacity used, and also defines the information required by cgroup such as CPU usage.
Figure 2.3 resource structure
ProcessConfig contains information about the processes running in the container. The source code related to the definition of the ProcessConfig structure is shown in figure 2.4.
Graph 2.4ProcessConfig structure
2.2 main process analysis
The corresponding source code of the workflow shown in figure 2.1 is in the run function of deamon/execdriver/native/driver.go, and the screenshot of the run function is shown in figure 2.5. the function of the container, err: = d.createContainer (c, hooks) statement is to call the createContainer function to create a container configuration. The parameter c passed in to the function indicates execdriver.Command, which is the command structure mentioned above, that is, the createContainer function creates the relevant container configuration based on the command parameter.
Figure 2.5 partial function body of Run function
As mentioned above, the createContainer function creates the relevant container configuration based on the command parameter. Let's take a look at the internal structure of the createContainer function. Figure 2.6 is a partial structure of the createContainer function. Where container = execdriver.InitContainer (c) you can see that the InitContainer function is called to generate the container configuration container with the passed execdriver.Command parameter. A series of createXXX () methods populate the template based on the container obtained by the InitContainer function and configure the required fields such as IPC, Pid, network, and so on. CreateIpc () means that configuring Ipc provides isolation for inter-process communication; createPid () means configuring Pid;createUTS () means configuring UTS to provide isolation between hostnames and domain names; and createNetwork () configuring Network provides network isolation including network devices, network stacks, ports, and so on.
Figure 2.6 partial function body of createContainer function
From the internal structure of the source code of the createContainer function, you can see that the createContainer function first calls the InitContainer function to generate a variable called container, and the InitContainer function generates the container configuration container through the passed execdriver.Command parameters. Figure 2.7 is the internal structure of the execdriver.InitContainer function. In the InitContainer function, you will return a container configuration container based on the hostname hostname, cgroup, devices, rootfs and other information of the command configuration container. The container returned at this time is actually a Config object, indicating the container configuration. Later, the createXXX () method in the createContainer function configures the required fields such as IPC, Pid, network, etc., according to the container container configuration returned by the InitContainer function.
Fig. 2.7 partial function body of InitContainer function
So far, we have analyzed the container, err: = d.createContainer (c, hooks) statement in deamon/execdriver/native/driver.go 's run function. The result of this statement is simply to generate a container container configuration. Next, in the run function, execdriver calls libcontainer to load the generated container configuration container, creating a real Docker container.
3. The principle of Libcontainer implementation
In the run function of deamon/execdriver/native/driver.go, once the container container configuration is successfully generated, the work is left to libcontainer. The main work of libcontainer is:
1. Create the process object that libcontainer needs to use to build the container, that is, Process. The corresponding source code is shown in figure 3.1. Process specifies the configuration and IO of the process object in the container, which specifies several parameters and assigns values to them. Args represents a series of instructions to be run; Env specifies the environment variable for the process object; Cwd changes the process's working directory to the container's rootfs; and User sets UID and GID for running processes in the container.
Figure 3.1 Building Process
two。 Next, in the run function, the err: = setupPipes (container, & c.ProcessConfig, p, pipes); statement calls the setupPipes function to set the output pipeline of the container. The setupPipes function is the output pipeline function of the setting container, and its function body is defined in the setupPipes function of deamon/execdriver/native/driver.go. The setupPipes function mainly configures the output pipeline of the container through execdriver.Pipes, and its main function is to convert the output of the container into standard input, standard output and standard error.
3. Use the Factory factory class to create a logical container Container with container ID and container configuration container. The corresponding source code in the run function is: d.factory.Create (c.ID, container), where c is execdriver.Command,c.ID, container ID,container is the container configuration mentioned many times before. In the process of generating a logical container, the items of the container configuration container are populated into the configuration item config of the logical container Container object.
4. Next, the startup container is used, and the statement corresponding to the startup container is cont.Start (p), where cont is the Container logical container generated by the d.factory.Create (c.ID, container) function, and the parameter p is the process object Process needed by the previously generated container.
5. The following code, p.Wait (), is process.Wait (), which means to wait for all the work of Process to be done until the physical container is created. The source code corresponding to the Wait function of Processd is shown in figure 3.2.
Figure 3.2 Wait () function of Process
6. The final cont.Destroy () indicates Container.Destory (), which means that the container can be destroyed if necessary.
Through the above analysis of the main work of libcontainer, we find that the focus of libcontainer is the implementation of Process, Container and Factory. Factory is used to create a logical container object; Container is a logical container that contains container configuration information; and Process is used for process configuration and IO management in physical containers. Let's parse the three logical entities in libcontainer in detail.
3.1 Factory create logical container
The role of Factory is to create a new container with the given container ID and start the initial process in that container. And the accepted container ID is a character composed of only letters, numbers and underscores, and the length must be between 1 and 1024. The container ID cannot coincide with the ID of an existing container, and containers created using the Factory of the same path (and file system) must have a different identity. Finally, a new container is returned with a running process.
Errors that may occur in this process are: IdInUse indicates that container ID has been occupied by other containers; InvalidIdFormat indicates incorrect format of container ID; ConfigInvalid indicates useless configuration information; and Systemerror indicates system error. As soon as an error occurs, any part of the container that has been created will be cleared, ensuring the atomicity of the container creation. Unless all the containers are created successfully, none of them will be created.
The Factory object contains three functions, which are:
1. Create () function: the input parameters are a container ID and a configuration parameter of Config type, and the accepted container ID is a character composed of only letters, numbers and underscores, and the length must be between 1 and 1024. The container ID cannot coincide with the ID of an existing container, and containers created using the Factory of the same path (and file system) must have a different identity. Create and return a Container class based on the two parameters passed in, including container ID, container working directory, container configuration, initialization instructions and parameters, and Cgroup manager information. In this function, the Container is created. There may be errors such as path does not exist, container has stopped, system failure, and so on.
2. Load () function: the input parameter is the container ID of a container that has been successfully Create, and the information of the container is returned. If the container has already Create and indicates that the id directory exists, the state.json will be read directly from the id directory to load the container information. The errors that may occur are pipe connection errors and system failures.
3. The StartInitialization () function is the container initialization function, which is the internal API that Libcontainer calls during the re-execution of the container.
4. Type () function: returns the container-managed type, such as lxc or libcontainer, etc.
At this point, the Factory object has finished creating and initializing the container. Next, take a look at the logical container Container that contains container configuration information.
3.2 logical container Container
The Container object is equivalent to the logical container, which mainly includes container configuration, control, status display and other functions. Where ID represents the ID of the container. Status indicates the status of processes in the container. The status of the container includes: Running indicates that the container exists and is running; Pausing indicates that the container exists and the process is being stopped; Paused indicates that the container exists but all processes are stopped; Checkpointed indicates that the container exists and the container state has been saved to disk; Destoryed indicates that the container does not exist.
The Container object has a series of container-related function operations, including:
ID (): returns the ID of the container, which represents the unique identity of the container
Status (): returns the state of the process in the container, either running or stopped. The error that may be thrown is ContainerDestroyed, indicating that the container does not exist and has been destroyed; Systemerror indicates a system error.
State (): returns the status information of the container, including container ID, configuration information, initial process ID, process startup time, cgroup file path, namespace path, etc. The error that may occur is Systemerror, which is a system error.
Config (): returns the configuration information of the container
Processes (): returns the PID of the container, which is the namespace used to invoke the process. Some PID may no longer be related to processes in the container, unless the state of the container is PAUSED, which ensures that each PID is valid.
Stats (): returns container statistics, including statistics in cgroup and Nic devices.
Set (): sets the resource configuration of the container, such as the file paths of cgroup subsystems, and so on.
Start (): starts a process in the container and returns an error if the process fails to start. The lifecycle of a process can be tracked according to the previous Process structure. There are two main tasks: create an instance of ParentProcess and execute ParentProcess.start () to start the physical container. ParentProcess is an interface that is implemented as an initProcess object. InitProcess is used to create the ParentProcess required for a container in preparation for the creation of a physical container. Execute initProcess.start () with the logical container Container, and the real physical container, the Docker container, is generated.
Destory (): destroys the container after all running processes are finished.
3.3The Process object
Process is divided into two categories, one is Process and the other is ParentProcess. Process is used for the configuration of processes in the container and the management of IO. Its parameters include: Args represents a series of instructions to be run; Env specifies the environment variables of the process object; Cwd changes the working directory of the process to the rootfs of the container; User sets UID and GID;Stdin io.Reader for standard input for running processes in the container; Stdout io.Writer for standard output; Stderr io.Writer for standard error ConsolePath represents the path to the console of the container; Capabilities represents the permissions required for processes in the container to run; and ops represents the ParentProcess object. ParentProcess handles container startup and includes a series of function actions:
Pid (): returns the pid of a running process, which can be obtained from the started container process through the pipeline.
Start (): starts the execution process in the container.
Terminate (): sends a SIGKILL signal to end the process.
StartTime (): gets the start time of the process.
Signal (): sends a signal to the process.
Wait (): waits for the end of the program execution and returns the finished program status.
Thank you for reading, the above is the content of "docker source code analysis Libcontainer", after the study of this article, I believe you have a deeper understanding of the problem of docker source code analysis Libcontainer, the specific use of the situation also needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.