Docker Runc container lifecycle
The life cycle of a container involves internal program implementation and user-oriented command line interface. The internal container state transition operations of runc, the operation defined by the runc command parameter, and the container operations defined by the docker client are different. For example, for the create of the docker client,
The semantics and runc are completely different. This article analyzes the abstraction, internal implementation and state transition diagram of the container life cycle of runc. It will be easier to understand the container state transition of runc and compare and understand the semantics of container operation commands provided by docker client.
Container life cycle related interfaces
- The most basic required interface
- Start: Initialize the container environment and start an init process, or add the namespace of the existing container and start a setns process; execute the postStart hook; block the write end of the init pipeline, and the user sends a signal to replace the real command
- Exec: Read the init pipeline and notify the init process or setns process to continue execution
- Run: A combination of Start + Exec
- Signal: Send signal to the init process in the container
- Destroy: Kill the process in cgroups, delete the path corresponding to cgroups, and run the hook of postStop
- other
- Set: Update the configuration information of the container, such as modifying cgroups resize, etc.
- Config: Get the configuration information of the container
- State: Get the status information of the container
- Status: Get the current running status of the container: created, running, pausing, paused, stopped
- Processes: Returns a list of all processes in the container
- Stats: statistics on cgroups in containers
- For Linux containers, a unique functional interface is defined and implemented
- Pause: All processes in the free container
- Resume: All processes in the thaw container
- Checkpoint: criu checkpoint
- Restore: criu restore
Internal implementation of interface
- The interface of Start/Run/Exec is exposed to developers as a standard interface in different Os environments. There are many duplicate parts of the interface internal implementation that can be unified, so the internal interface is actually more concise. Here we take the Linux container as an example to illustrate
- For Start/Run/Exec internal implementation, only the following two functions are used. By passing in flags (whether the container is in the stopped state), it is differentiated whether to create the init process or the init process that creates the process by passing in flags (whether the container is in the stopped state)
- start: Create an init process. If status == stopped, create and execute newInitProcess. Otherwise, create and execute newSetnsProcess, wait for the user to send an execution signal (will be on the pipeline write end), and replace it with the user's command
- exec: read the pipeline and send the execution signal
- Start directly using start
- Run actually uses start(doInit = true) first, and then exec
- Exec actually uses start(doInit = false) first, then exec
- For Start/Run/Exec internal implementation, only the following two functions are used. By passing in flags (whether the container is in the stopped state), it is differentiated whether to create the init process or the init process that creates the process by passing in flags (whether the container is in the stopped state)
The correspondence between the command line parameters exposed to the user and the container interface, taking the Linux container as an example
- create -> Start(doInit = true)
- start -> Exec
- run -> Run(doInit = true)
- exec -> Run(doInit = false)
- kill -> Signal
- delete -> Signal and Destroy
- update -> Set
- state -> State
- events -> Stats
- ps -> Processes
- list
- linux specific
- pause -> Pause
- resume -> Resume
- checkpoint -> Checkpoint
- restore -> Restore
Effects of the action sequence of the runc command line on the container state machine
- For the life cycle of a container, there are 4 stable states: stopped, created, running, and paused
- Note that the action in the state transition diagram below is the runc command line parameter action, not the container interface action, and the checkpoint-related restore state is not considered here.
delete |------| /-------------------------------------------------------------| | | / |----- start ---| | | V / | | | |---------| ----------- create ----------> |---------|<---------/ | | stopped | | created |------------| | |---------| <-------- delete(with kill)--- |---------| | | ^ ^ | | | | | | | run | |--------------- delete(-f with kill) ---| exec | | delete(-f with kill) | | | | | | | | | | resume | V | | |---------| -----------------------------> |----------| | | | paused | | running |<----------|-------| |---------| <---------------------------- |----------| | ^ pause ^ | | | | | | | |--exec--| | | | |--------------------------- pause ---------------------------|
Thank you for reading, I hope it can help you. Thank you for your support for this site!