Objective
Docker container command
Today, in the Docker, we are able to easily package our applications with containers and deploy them on our servers and run them. However, talking about how to stop the Docker container in the running and terminate the program correctly is a very worthwhile topic to discuss.
Docker command to start container
In fact, docker commands to run a container,in our daily projects,docker command for running containers , this is a problem that we often have to confront and deal with:
Docker container bash command
Scenario A: If we package the program in the container, provide HTTP service, handle all kinds of HTTP requests and return the result, we must hope that when the container is stopped, we can let the program have time to process the request has been processed, docker command from container,and return the results to the client.
Scenario B: Another example is the program we pack in the container, which writes the data to a data file, and we want the program to be able to persist the cached data in memory to the storage device in case the data is lost when the container is stopped.
Scene C: Again, such as the current micro-service architecture, there will be the mechanism of service discovery, that is, each micro-service in the start-up, will take the initiative to register their own address information into the Service discovery module, so that other services can know their existence. When the container is stopped, the micro-service needs to log itself out of the service discovery module immediately to prevent the request from the API gateway from being routed incorrectly to the service that has been stopped.
As in the various scenarios above, it is required that an application packaged in a container can be gracefully terminated (also known as gracefully shutdown), a gracefully shutdown way that allows the program to do some post-processing when the container is stopped, This is also the topic that we need to discuss further.
The difference between Docker stop and Docker kill
The Docker itself provides two ways to terminate the operation of the container, that is,docker stopwithdocker kill.
Docker stop
First of alldocker stop, when we use thedocker stopcommand to stop the container, Docker defaults to allow the application in the container to have 10 seconds to terminate the operation. So when we look at thedocker stopcommand help, we have the following tips:
→docker Stop--help
usage:docker stop [OPTIONS] CONTAINER [CONTAINER ...]
Stop one or more running containers
Options:
--help Print Usage-
t,--time int Seconds to wait for STO P before killing it (default 10)
docker stopwhen the command executes, it sends the system signal sigterm to the process of PID 1 in the container, then waits for the application in the container to terminate execution, if the wait time reaches the set timeout, or the default 10 seconds, will continue to send sigkill system signals to forcibly kill the process. The application in the container can choose to ignore and not process the sigterm signal, but once the timeout is reached, the program is forcibly killed by the system because the Sigkill signal is sent directly to the system kernel and the application has no chance to handle it.docker stopwhen we use the command, the only thing we can control is the timeout period, such as setting the 20 second timeout:
Docker Stop--time=20 Container_name
Docker Kill
Then we look at thedocker killcommand, by default, thedocker killcommand does not give the application in the container any gracefully shutdown opportunities. It directly emits a sigkill system signal to force the operation of the program in the container to be terminated. By lookingdocker killat the command's help, we can see that, in addition to sending the Sigkill signal by default, we also allow us to send some custom system signals:
→docker kill--help
usage:docker kill [OPTIONS] CONTAINER [CONTAINER ...]
Kill one or more running containers
Options:
--help Print usage
-S,--signal string signal to send to th E container (default "KILL")
For example, if we want to send a SIGINT signal to a program in Docker, we can do this:
Docker Kill--signal=sigint Container_name
Unlike the Docker Stop command, wheredocker killthere is no time-out setting, it sends a sigkill signal directly and other signals that the user specifies through the signal parameter.
In fact, it is not difficult to see, Docker Stop command, more similar to the KILL command in the Linux system, both are sending system signal sigterm. Thedocker killcommand, more like a kill-9 or Kill-sigkill command in a Linux system, is used to send a sigkill signal and force the process to terminate.
Receiving and processing signals in a program
Knowing thedocker stopdocker killdifference, we can know that it isdocker killappropriate to force the termination of the program and implement a fast stop container. And if you want the program to be able to gracefully shutdown, itdocker stopis the choice. In this way, we can let the program after receiving the sigterm signal, there is a certain amount of time to process, save the program execution site, graceful exit procedures.
Next we can write a simple go program to achieve signal reception and processing, the program after the start, will always block and listen to the system signal, until the corresponding system signal is detected, output console and exit execution.
Main.go
Package main
import (
"FMT" "
os"
"os/signal"
"Syscall"
)
func Main () {
fmt. PRINTLN ("program started ...")
ch: = Make (chan os. Signal, 1)
Signal. Notify (CH, syscall. Sigterm)
S: = <-ch
if s = = Syscall. sigterm {
FMT. Println ("Sigterm received!")
Do something ...
}
Fmt. Println ("Exiting ...")
}
The next step is to compile the program in a precompiled way so that the program can run under Linux:
Cgo_enabled=0 goos=linux goarch=amd64 Go build-o Graceful
After compiling, we also need to package the program to run in the container. So, we have to have a dockerfile. Here, we choose to use small and lightweight alpine mirrors as the base image, packaging the Go program:
From Alpine:latest
maintainer Timothy
ADD graceful/graceful
CMD ["/graceful"]
A pit to avoid here is the use of the cmd command in Dockerfile.
There are two ways to cmd commands:
InCMD command param1 param2this way, the program is actually run as a shell. When the final program is executed, it runs our program like a/bin/sh-c, which causes/bin/sh to run with PID 1, and our program is just a subprocess that it fork/execs. We mentioned earlier that the sigterm signal of Docker stop is only sent to the process where the PID is 1 in the container, and our program cannot receive and process the signal.
CMD [“executable”,”param1”,”param2”]starting a program in this way is what we want, and when it's done and started, our program will be executed directly, not in the shell, so that our program canPID=1start executing in the same way.
The topic turned back, we started the container build operation, packaging program:
Docker build-t Registry.xiaozhou.net/graceful:latest.
After the packaging of the mirror, only about 6MB:
Λtimothy [workspace/src/graceful]→docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
Registry.xiaozhou.net/graceful Latest B2210a85ca55 hours ago 6.484 MB
To start and run the container:
λtimothy [Workspace/src/graceful]→docker run-d--name Graceful B2210a85
To view the status of a container running:
λtimothy [Workspace/src/graceful]→docker ps-a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fd18eedafd16 b221 "/graceful" 3 seconds ago up 2 seconds Graceful
Viewing the container output, you can see that the program is starting normally:
Λtimothy [Workspace/src/graceful]→docker logs graceful
started ...
We then usedocker stopDafa to see if the program responds to Sigterm signals:
λtimothy [workspace/src/graceful]→docker Stop graceful
graceful
Finally, check the container's log to verify the output:
Λtimothy [Workspace/src/graceful]→docker logs graceful
started ...
Sigterm received!
Exiting ...
Summarize
The above is the full content of this article, with the Docker kill command, you can simply and rudely terminate the Docker container running the program, but to gracefully terminate, we need to use the Docker Stop command, and in the program to spend a little more effort to process the system signal, This guarantees that the program will not be rudely terminated, thus achieving gracefully shutdown. I hope the content of this article for everyone's study or work can help, if there is doubt you can message exchange.