一、Docker容器配置进阶
1、容器的自动重启
Docker提供重启策略控制容器退出时或Docker重启时是否自动启动该容器。
容器默认不支持自动重启,要使用 --restart
选项指定重启策略。
[root@localhost ~]# docker run --help
--restart string Restart policy to apply when a container exits (default "no")
容器重启策略选项值:
选项值 | 功能 |
---|---|
no | 容器退出时不重启,默认设置 |
on-failure[:max-retries] | 容器以非0状态退出时重启,max-retries指定重启的次数 |
always | 不管退出状态始终重启,无限次 |
unless-stopped | 不管退出状态始终重启,(Docker守护进程启动时,容器处于运行状态才生效) |
# 案例1:运行一个始终重启的redis容器,容器退出时Docker重启它
[root@localhost ~]# docker run -d --name testrs --restart=always redis
cdf90c50d38f712020f2bd75e10e20c5ba6aa980747176f7bff4b45d4844ab8a
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cdf90c50d38f redis "docker-entrypoint.s…" 7 seconds ago Up 6 seconds 6379/tcp testrs
# 停止Docker后,容器立马重启
[root@localhost ~]# systemctl stop docker
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cdf90c50d38f redis "docker-entrypoint.s…" 2 minutes ago Up Less than a second 6379/tcp testrs
# 案例2:设置容器最大重启次数
# 设置非0状态最大重启十次
[root@localhost ~]# docker run -dti --restart=on-failure:10 redis bash
fe8f308023cfde7a738ba5a22098dbe8d5f35697db85094a2dc7778a7293f1d5
# 另一个终端执行
[root@localhost ~]# systemctl stop docker
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fe8f308023cf redis "docker-entrypoint.s…" 20 seconds ago Up Less than a second 6379/tcp serene_pascal
# 案例3:已经运行或创建的容器,用 docker update 更改重启策略
[root@localhost ~]# docker update --restart=on-failure:3 fe8f308
fe8f308
作用:容器自动重启;重启策略能够确保关联的多个容器按照正确的顺序启动。
使用重启策略时的注意事项:
- 重启策略只在容器成功启动后才会生效。(容器运行后生效)
- 如果手动停止一个容器,那么它的重启策略会被忽略,直到Docker守护进程重启或容器手动重启。(手动停止,暂停重启策略)
- Docker Swarm服务的重启策略采用不同的配置方式。(集群采用不同的重启策略)
- 重启策略不同于dockerd命令的
--live-restore
选项,这个选项可使Docker升级中,即使网络和用户输入都终端,容器依然保持运行。 - Docker建议使用重启策略,并避免使用进程管理器启动容器:(1)同时使用两者会产生冲突;(2)进程管理器依赖于操作系统,Docker无法监控。
2、在Docker停止时保持容器继续运行
默认情况下,Docker守护进程终止时,正在运行的容器会关闭。
实时恢复(Live Restore):管理员配置守护进程,让容器在守护进程不可用时依然运行。
实时恢复的作用:减少因Docker守护进程崩溃、计划停机或升级导致的容器停机时间。
(1)启用实时恢复功能
第一种方式是在Docker守护进程配置文件中设置:
sighup(挂断)信号在控制终端或者控制进程死亡时向关联会话中的进程发出,默认进程对SIGHUP信号的处理时终止程序,所以我们在shell下建立的程序,在登录退出连接断开之后,会一并退出。
nohup,故名思议就是忽略SIGHUP信号,一般搭配& 一起使用,&表示将此程序提交为后台作业或者说后台进程组。
[root@localhost ~]# vi /etc/docker/daemon.json
{
"live-restore":true
}
# 配置生效方法一:
# 修改配置后重启守护进程生效
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker
# 配置生效方法二:
# 重新加载Docker守护进程,避免容器停止
[root@localhost ~]# systemctl reload docker
# 案例1:
# 1.启动两个容器
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1dd65fa55b80 top "/bin/sh -c 'exec to…" 5 weeks ago Up 38 seconds test_exec_entry
52a7de98ccc7 test_shell_entry "/bin/sh -c 'top -b'" 5 weeks ago Up 52 seconds test:
# 2.停止docker守护进程
[root@localhost ~]# systemctl stop docker
Warning: Stopping docker.service, but it can still be activated by:
docker.socket
[root@localhost ~]# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: inactive (dead) since Wed 2022-05-11 00:23:16 CST; 8s ago
Docs: https://docs.docker.com
Process: 1697 ExecReload=/bin/kill -s HUP $MAINPID (code=exited, status=0/SUCCESS)
Process: 1853 ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock (code=exited, status=0/SUCCESS)
Main PID: 1853 (code=exited, status=0/SUCCESS)
# 3.查看容器是否依然运行
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1dd65fa55b80 top "/bin/sh -c 'exec to…" 5 weeks ago Up About a minute test_exec_entry
52a7de98ccc7 test_shell_entry "/bin/sh -c 'top -b'" 5 weeks ago Up 2 minutes test
# 案例2:apache容器测试实时恢复
# 1.修改守护进程配置文件,启动实时恢复
[root@localhost ~]# vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://nxwgbmaq.mirror.aliyuncs.com"],
"live-restore":true
}
# 2.重启守护进程
[root@localhost ~]# systemctl restart docker
# 3.运行一个apache容器
[root@localhost ~]# docker pull httpd
[root@localhost ~]# docker run --rm -d -p 8080:80 httpd
27c266f2fbc9bb5dd67e442a99b82db440d135506b9d912d624331baae675ca9
# 4.重新加载Docker守护进程
[root@localhost ~]# systemctl reload docker
# 5.查看当前容器
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27c266f2fbc9 httpd "httpd-foreground" About a minute ago Up About a minute 0.0.0.0:8080->80/tcp, :::8080->80/tcp inspiring_robinson 《————容器依然运行
# 6.kill结束进程
[root@localhost ~]# ps -e | grep dockerd
5052 ? 00:00:01 dockerd 《————查看获取进程号
[root@localhost ~]# kill -SIGHUP 5052 《————向进程发送sighup信号
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
27c266f2fbc9 httpd "httpd-foreground" 2 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp, :::8080->80/tcp inspiring_robinson 《————容器依然运行
# 7.访问apache验证服务是否正常
[root@localhost ~]# curl 127.0.0.1:8080
<html><body><h1>It works!</h1></body></html>
另一种恢复方式:在手动启动dockerd进程时指定--live-restore选项。
不建议使用这种方式,因为不会设置systemd或其他进程管理器的环境,会导致意外发生。
(2)升级期间的实时恢复
实时恢复功能支持Docker守护进程在升级期间保持容器的运行。
存在的问题:
- 只支持Docker 补丁版本升级,不支持主要版本和次要版本的升级。
- 升级过程中跳过版本,守护进程可能无法恢复其与容器的连接。
(3)重启时的实时恢复
限定条件:只有Docker守护进程选项未发生变化,实时恢复才能恢复容器。
(4)实时恢复功能对运行容器的影响
守护进程停止,正在运行的容器可能会填满守护进程通常读取的FIFO日志,阻止容器记录更多日志数据。
缓冲区填满,必须重新启动Docker守护进程来刷新。
可以更改/proc/sys/fs/pipe-max=size来修改内核的缓冲区大小。
[root@localhost ~]# cat /proc/sys/fs/pipe-max-size
1048576
3、一个容器中运行多个服务
注意:一个容器可以有多个进程,但为了高效利用Docker,不要让一个容器负责整个应用程序的多个方面,而要通过用户定义网络和共享卷连接多个容器来实现应用程序的多个方面。
容器的主进程负责管理它启动的所有进程。
解决子进程回收: