首页 > 系统相关 >Docker容器与守护进程运维 --项目四

Docker容器与守护进程运维 --项目四

时间:2024-05-11 11:31:25浏览次数:28  
标签:容器 运维 -- nginx docker root Docker localhost

一、Docker容器配置进阶 

1、容器的自动重启

Docker提供重启策略控制容器退出时或Docker重启时是否自动启动该容器。

容器默认不支持自动重启,要使用 --restart 选项指定重启策略。

作用:容器自动重启;重启策略能够确保关联的多个容器按照正确的顺序启动。

容器重启选项值:

重启策略时的注意事项:

  1. 重启策略只在容器成功启动后才会生效。(容器运行后生效)
  2. 如果手动停止一个容器,那么它的重启策略会被忽略,直到Docker守护进程重启或容器手动重启。(手动停止,暂停重启策略)
  3. Docker Swarm服务的重启策略采用不同的配置方式。(集群采用不同的重启策略)
  4. 重启策略不同于dockerd命令的--live-restore选项,这个选项可使Docker升级中,即使网络和用户输入都终端,容器依然保持运行。
  5. Docker建议使用重启策略,并避免使用进程管理器启动容器:(1)同时使用两者会产生冲突;(2)进程管理器依赖于操作系统,Docker无法监控。

示例:

查看代码
 # 案例1:运行一个始终重启的redis容器,容器退出时Docker重启它
[root@localhost ~]# docker run -d --name testrs --restart=always redis
cdf90c50d38f712020f2bd75e10e20c5ba6aa980747176f7bff4b45d4844ab8a
# 停止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

# 案例4:手动停止容器,重启策略会忽略
[root@localhost /]# docker run -d --name testrs --restart=always redis
[root@localhost /]# docker stop d3debe3f40e3
[root@localhost /]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED             STATUS                     PORTS     NAMES
d3debe3f40e3   redis     "docker-entrypoint.s…"   5 minutes ago       Exited (0) 2 seconds ago             testrs     《————不再重启,策略失效
# 守护进程重启或容器手动重启后,策略恢复
[root@localhost /]# systemctl restart docker
[root@localhost /]# docker ps -a            
CONTAINER ID   IMAGE     COMMAND                  CREATED             STATUS                     PORTS      NAMES
d3debe3f40e3   redis     "docker-entrypoint.s…"   6 minutes ago       Up 1 second                6379/tcp   testrs

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守护进程在升级期间保持容器的运行。

存在的问题:

  1. 只支持Docker 补丁版本升级,不支持主要版本和次要版本的升级。
  2. 升级过程中跳过版本,守护进程可能无法恢复其与容器的连接。

(3)重启时的实时恢复

限定条件:只有Docker守护进程选项未发生变化,实时恢复才能恢复容器。

(4)实时恢复功能对运行容器的影响

守护进程停止,正在运行的容器可能会填满守护进程通常读取的FIFO日志,阻止容器记录更多日志数据。

缓冲区填满,必须重新启动Docker守护进程来刷新。
可以更改/proc/sys/fs/pipe-max=size来修改内核的缓冲区大小。

(5)dockerd启动失败排错

# 执行该命令显示最后200行linux系统日志信息,并滚动刷新
[root@localhost home]# tail -200f /var/log/messages

# 再开一个session,执行命令
[root@localhost /]# systemctl daemon-reload   
[root@localhost /]# systemctl restart docker

# 可以看到日志刷新的信息,即可根据信息提示完成修复
Apr 23 19:32:45 localhost dockerd: unable to configure the Docker daemon with file /etc/docker/daemon.json: invalid character '}' looking for beginning of object key string

3、一个容器中运行多个服务

注意:一个容器可以有多个进程,但为了高效利用Docker,不要让一个容器负责整个应用程序的多个方面,而要通过用户定义网络和共享卷连接多个容器来实现应用程序的多个方面。

容器的主进程负责管理它启动的所有进程。

解决子进程回收:--init选项可以将一个精简的初始化进程作为主进程插入容器,并在容器退出时回收所有的进程。

解决多进程启停最好方式:设置一个上层的进程统一处理这些进程的生命周期(sysinit\upstart\systemd)

在一个容器运行多个服务的方式:

  1. 将所有命令放入包装器脚本中,并提供测试和调试信息,使用CMD指令运行包装器脚本。
  2. 如果有一个主进程需要首先启动并保持运行,但是临时需要运行一些其他进程(可能与主进程交互),可以使用bash脚本的作业控制实现。
  3. 在容器中使用supervisord等进程管理器。

SupervisorLinux/UNIX系统下的一个进程管理工具,守护进程名为supervisord,可以方便地监听、启动、停止、重启一个或多个进程。
该工具管理进程时,如遇到进程被意外杀死,守护进程监听到后,会自动重启

(1)php:7.3-fpm案例

 

查看代码
 # 1.创建项目目录
[root@localhost ~]# mkdir php-nginx-supervisord && cd php-nginx-supervisord/

# 2.创建nginx子目录和supervisor子目录,并准备配置文件
[root@localhost php-nginx-supervisord]# mkdir nginx
[root@localhost php-nginx-supervisord]# mkdir supervisor
[root@localhost php-nginx-supervisord]# touch nginx/nginx.conf
[root@localhost php-nginx-supervisord]# mkdir nginx/conf.g
[root@localhost php-nginx-supervisord]# touch nginx/conf.g/site.conf
[root@localhost php-nginx-supervisord]# mkdir supervisor/conf.d/
[root@localhost php-nginx-supervisord]# touch supervisor/conf.d/supervisord.conf
# 查看目录结构
[root@localhost php-nginx-supervisord]# tree
.
├── nginx
│   ├── conf.g
│   │   └── site.conf
│   └── nginx.conf
└── supervisor
    └── conf.d
        └── supervisord.conf
4 directories, 3 files

# 3.编写supervisord.conf文件内容
[root@localhost php-nginx-supervisord]# vi supervisor/conf.d/supervisord.conf 
[supervisord]
gfile=/tmp/supervisord.log ; # 日志
logfile_maxbytes=50MB ; # 最大50M日志
logfile_backups=10 ; # 轮循日志备份10个
loglevel=info ; # 日志等级记录info的
pidfile=/tmp/supervisord.pid ;pid
nodaemon=true ; # 在前台启动
minfds=102400 ; # 文件描述符限制
minprocs=2000 ; # 进程数

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket

[program:nginx]
command=/usr/sbin/nginx -g 'daemon off';  # 前台启动nginx
autostart=true ; # 随着supervisor自动启动
startsecs=10 ; # 启动10s后算正常启动
autorestart=true ; # 程序退出后自动重启
startretries=3 ; # 启动失败自动重试次数
stdout_logfile_maxbytes=20MB ;stdout   # 日志文件大小最大20Mb
stdout_logfile=/var/log/nginx/out.log

[program:php7-fpm]
command=/usr/local/sbin/php-fpm
autostart=true ; # 随着supervisor自动启动
startsecs=10 ; # 启动10s后算正常启动
autorestart=true ; #程序退出后自动重启
startretries=3 ; # 启动失败自动重试次数
stdout_logfile_maxbytes=20MB ;stdout 日志文件大小最大20Mb

# 4.尝试登录这个php容器,判断系统版本
[root@localhost php-nginx-supervisord]# docker run -ti php:7.3-fpm /bin/bash
# 进入容器检查信息
root@16fddccbb4ce:/var/www/html# cat /etc/issue
Debian GNU/Linux 11 \n \l
root@16fddccbb4ce:/var/www/html# cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
# 由此得知为debian 11版本的系统

# 5.准备debian11换源文件sources.list
[root@localhost php-nginx-supervisord]# touch sources.list
[root@localhost php-nginx-supervisord]# vi sources.list 
deb http://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb http://mirrors.aliyun.com/debian-security/ bullseye-security main
deb-src http://mirrors.aliyun.com/debian-security/ bullseye-security main
deb http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib

# 6.准备nginx.conf文件
[root@localhost php-nginx-supervisord]# vi nginx/nginx.conf 
#一个主进程和多个工作进程
worker_processes  1;
events {
    #每个工作进程最大的并发数(一个工作进程可以有多少个线程)
    worker_connections  1024;
}
#http服务器设置
http {
    #设定mime类型,类型由mime.type文件定义
    include       mime.types;
    #长连接超时时间
    keepalive_timeout  65;
    #配置虚拟主机
    server {
        #虚拟主机使用的端口
        listen       80;
        #虚拟主机域名
        server_name  localhost;
        #定义web根路径
        location / {
            #根目录路径
            root   html;
            #索引页
            index  index.html index.htm;
        }
    }
}   

# 6.编写Dockerfile文件内容
[root@localhost php-nginx-supervisord]# vi Dockerfile
FROM php:7.3-fpm
COPY sources.list /etc/apt/
RUN apt-get clean && apt-get update && apt-get -y install nginx supervisor procps net-tools && mkdir -p /var/log/supervisor
COPY nginx /etc/nginx
COPY supervisor /etc/supervisor
WORKDIR /var/www
RUN usermod -u 1000 www-data
EXPOSE 80
CMD ["/usr/bin/supervisord"]

# 7.基于Dockerfile构建镜像
[root@localhost php-nginx-supervisord]# docker build -t php-nginx-supervisord .
[+] Building 134.0s (14/14) FINISHED                                               
 => [internal] load build definition from Dockerfile                          0.0s
 => => transferring dockerfile: 350B                                          0.0s
 => [internal] load .dockerignore                                             0.0s
 => => transferring context: 2B                                               0.0s
 => [internal] load metadata for docker.io/library/php:7.3-fpm                0.0s
 => CACHED [1/9] FROM docker.io/library/php:7.3-fpm                           0.0s
 => [internal] load build context                                             0.0s
 => => transferring context: 902B                                             0.0s
 => [2/9] COPY sources.list /etc/apt/                                         0.0s
 => [3/9] RUN apt-get clean && apt-get update                                34.9s
 => [4/9] RUN apt-get -y install nginx supervisor procps net-tools           85.5s
 => [5/9] RUN mkdir -p /var/log/supervisor                                    0.3s 
 => [6/9] COPY nginx /etc/nginx                                               0.0s 
 => [7/9] COPY supervisor /etc/supervisor                                     0.0s 
 => [8/9] WORKDIR /var/www                                                    0.0s 
 => [9/9] RUN usermod -u 1000 www-data                                        0.3s 
 => exporting to image                                                       12.9s 
 => => exporting layers                                                      12.9s
 => => writing image sha256:801d960db6395bde049fe7f3ffcec0de1a8e3b918a219b27  0.0s
 => => naming to docker.io/library/php-nginx-supervisord                      0.0s

# 8.基于该镜像启动容器
[root@localhost php-nginx-supervisord]# docker images
REPOSITORY              TAG       IMAGE ID       CREATED              SIZE
php-nginx-supervisord   latest    62a3c736e277   About a minute ago   516MB
[root@localhost php-nginx-supervisord]# docker run -tid -p 8080:80 php-nginx-supervisord
44e42a4ae258ebe1f37a0b940afda5462f79260686477c89270cd8103ac61adf

# 9.测试web服务
访问:http://192.168.200.103:8080/
登录容器查看进程:
[root@localhost php-nginx-supervisord]# docker exec -ti 5b6d610e032e /bin/bash
root@5b6d610e032e:/var/www# ps auxf        
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         41  0.0  0.1   4100  3456 pts/1    Ss   08:57   0:00 /bin/bash
root         51  0.0  0.1   6700  2816 pts/1    R+   08:58   0:00  \_ ps auxf
root          1  0.3  1.2  29492 24156 pts/0    Ss+  08:57   0:00 /usr/bin/python3 /usr/bin/supervi
root          7  0.4  1.1  73228 22332 pts/0    S    08:57   0:00 php-fpm: master process (/usr/loc
www-data     15  0.0  0.4  73228  8784 pts/0    S    08:57   0:00  \_ php-fpm: pool www
www-data     16  0.0  0.4  73228  8784 pts/0    S    08:57   0:00  \_ php-fpm: pool www
root         49  0.0  0.0   8532  1424 ?        Ss   08:58   0:00 nginx: master process /usr/sbin/n
nobody       50  0.0  0.1   8988  2576 ?        S    08:58   0:00  \_ nginx: worker process

(2)centos镜像案例

# 案例:将supervisord和配置和要管理的应用程序(nginx和tomcat)打包到一个镜像中,一个容器运行多个服务
# 1.创建dockerfile目录
[root@hecs-hqs-01 ~]# mkdir web-supervisord
[root@hecs-hqs-01 web-supervisord]# cd web-supervisord/

# 2.编写Dockerfile
[root@hecs-hqs-01 web-supervisord]#  vi Dockerfile            《————dockerfile目录
FROM centos:7
MAINTAINER [email protected]
COPY CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo
COPY nginx_install.sh /tmp/nginx_install.sh
RUN sh /tmp/nginx_install.sh; \rm -rf /usr/local/src/*
RUN sed -i -e '/worker_processes/a daemon off;' /usr/local/nginx/conf/nginx.conf;
COPY jdk-8u162-linux-x64.tar.gz /usr/local/src/jdk-8u162-linux-x64.tar.gz
COPY tomcat_install.sh /tmp/tomcat_install.sh
RUN sh /tmp/tomcat_install.sh; \rm -rf /usr/local/src/*
COPY supervisor_install.sh /tmp/supervisor_install.sh
COPY supervisord.conf /etc/supervisord.conf
COPY start_tomcat.sh /usr/local/tomcat/bin/mystart.sh
RUN sh /tmp/supervisor_install.sh; \rm -rf /tmp/*.sh
CMD ["supervisord", "-c", "/etc/supervisord.conf"]

# 3.默认源下载慢且总有问题,更换为163的yum源
[root@hecs-hqs-01 web-supervisord]# vi CentOS-Base.repo 
[base]
name=CentOS-$releasever - Base
baseurl=http://mirrors.163.com/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

#released updates
[updates]
name=CentOS-$releasever - Updates
baseurl=http://mirrors.163.com/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
baseurl=http://mirrors.163.com/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
 
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
baseurl=http://mirrors.163.com/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 


# 4.准备nginx安装脚本
[root@hecs-hqs-01 web-supervisord]# vi nginx_install.sh
yum install -y wget tar gcc gcc-c++ make pcre pcre-devel zlib zlib-devel openssl openssl-devel
cd /usr/local/src
wget 'http://nginx.org/download/nginx-1.12.2.tar.gz'
tar -zxvf nginx-1.12.2.tar.gz
cd nginx-1.12.2
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-stream --with-stream_ssl_module
make
make install
exit 0

# 5.准备tomcat安装脚本
[root@hecs-hqs-01 web-supervisord]# vi tomcat_install.sh
yum install -y wget tar
cd /usr/local/src/
tar -zxvf jdk-8u162-linux-x64.tar.gz
mv jdk1.8.0_162 /usr/local/
#/usr/local/jdk1.8.0_162/bin/java -version
#配置java环境变量
echo 'JAVA_HOME=/usr/local/jdk1.8.0_162/' >>/etc/profile
echo 'PATH=$PATH:$JAVA_HOME/bin' >>/etc/profile
echo 'CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPATH' >>/etc/profile
source /etc/profile
wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.78/bin/apache-tomcat-8.5.78.tar.gz
tar -zxvf apache-tomcat-8.5.78.tar.gz
mv apache-tomcat-8.5.78 /usr/local/tomcat


# 6.下载jdk
# 官网下载地址:https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html 需要注册才能下载
[root@hecs-hqs-01 web-supervisord]# ls


# 7.准备supervisor安装脚本
[root@hecs-hqs-01 web-supervisord]# vi supervisor_install.sh 
yum -y install epel-release
yum -y install python2-pip
pip install supervisor


# 8.准备supervisor配置文件
[root@hecs-hqs-01 web-supervisord]# vi supervisord.conf 
[unix_http_server]
file=/tmp/supervisor.sock ; the path to the socket file

[supervisord]
logfile=/tmp/supervisord.log ; # 日志
logfile_maxbytes=50MB ; # 最大50M日志
logfile_backups=10 ; # 轮循日志备份10个
loglevel=info ; # 日志等级记录info的
pidfile=/tmp/supervisord.pid ;pid
nodaemon=true ; # 在前台启动
minfds=102400 ; # 文件描述符限制
minprocs=2000 ; # 进程数
 
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket

[program:nginx]
command=/usr/local/nginx/sbin/nginx ; # 前台启动nginx
autostart=true ; # 随着supervisor自动启动
startsecs=10 ; # 启动10s后算正常启动
autorestart=true ; # 程序退出后自动重启
startretries=3 ; # 启动失败自动重试次数
stdout_logfile_maxbytes=20MB ;stdout # 日志文件大小最大20Mb
stdout_logfile=/usr/local/nginx/logs/out.log

[program:tomcat]
command=sh /usr/local/tomcat/bin/mystart.sh ; # 前台启动tomcat
autostart=true ; # 随着supervisor自动启动
startsecs=10 ; # 启动10s后算正常启动
autorestart=true ; #程序退出后自动重启
startretries=3 ; # 启动失败自动重试次数
stdout_logfile_maxbytes=20MB ;stdout 日志文件大小最大20Mb
stdout_logfile=/usr/local/tomcat/logs/catalina.out

# 9.tomcat启动脚本准备
# 由于supervisor无法使用source,需要编写个脚本来启动
[root@hecs-hqs-01 web-supervisord]# vi start_tomcat.sh
source /etc/profile
/usr/local/tomcat/bin/catalina.sh run


# 10.构建镜像
[root@hecs-hqs-01 web-supervisord]# docker build -t web-supervisor .
[root@localhost web-supervisord]# docker images
REPOSITORY         TAG       IMAGE ID       CREATED         SIZE
web-supervisor     latest    5198c5737571   7 minutes ago   1.44GB

# 11.启动容器测试
[root@localhost web-supervisord]# docker run -d web-supervisor /bin/bash -c 'supervisord -c /etc/supervisord.conf'
a326e2589794c4b2a19c23d177f2c418d0583c87605342fd7445694dc40e2219



# 6.基于镜像启动容器和测试web服务
docker exec -it 76782ab /bin/bash
ifconfig

curl 127.0.0.1
curl 127.0.0.1:8080

 

4、容器健康检查机制

进程级的健康检查:最简单的,检验进程是否运行。重启策略可以根据检查情况重启已停止的容器。这个检查不足:无法发现应用程序问题。

Docker提供了健康检查机制,可以通过Dockerfile文件在镜像中注入,也可以在启动容器时通过相应选项实现。

(1)在Dockerfile中使用HEALTHCHECK指令

可以在Dockerfile中使用HEALTHCHECK指令声明健康检测配置,用于判断容器主进程的服务状态是否正常,反映容器的实际健康状态。

Dockerfile构建镜像时,加入了HEALTHCHECK指令,基于这样镜像启动的容器,就具备了健康状态检查能力,能自动进行健康检查。

Dockerfile中,只能出现一次HEALTHCHECK指令,出现多次,仅最后一次生效。

一旦有一次健康检查成功,Docker就会确认容器为健康状态。

HEALTHCHECK指令格式:

1.设置检查容器健康状况的命令.

HEALTHCHECK [选项] CMD <命令> 

# 选项:
    --interval:设置容器运行后开始健康检查的时间间隔,默认30s。
    --timeout:设置允许健康检查命令允许的最长时间,默认30s。超时即失败。
    --start-period:设置容器启动的初始化时间。(启动过程中的健康检查失败不报错)
    --retries:设置允许连续重试的次数,默认3次。(连续检查失败后视为不健康)

# CMD指令后的命令:指定执行健康检查的具体命令。可以使用shell格式或exec格式。

# 返回值:CMD指令后面的“命令” 执行完毕返回值表示容器的运行状况。
    0:成功。容器是健康且可用的。
    1:失败。容器不健康,不能正常工作。
    2:保留值。暂时不要使用。

# 示例:每5分钟健康检查一次,访问web服务器主页,每次检查3秒以内
HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ || exit 1       # || 表示上一条命令执行失败后,才执行下一条命令,退出返回值为1,告诉docker健康检查失败

 

2.表示禁止从基础镜像继承HEALTHCHECK指令设置

HEALTHCHECK NONE 

 

 

(2)启动容器时通过相应选项实现健康检查

可以在执行 docker run 或 docker create 命令启动创建容器时指定容器的健康检查策略。

##选项
[root@localhost ~]# docker run --help
      --health-cmd string                  # 指定和运行健康检查
      --health-interval duration           # 设置容器运行后开始健康检查的时间间隔(单位:ms/s/m/h),默认是0s
      --health-retries int                 # 设置连续失败需要报告的次数
      --health-start-period duration       # 设置容器启动的初始化时间(单位:ms/s/m/h),默认是0s                                   
      --health-timeout duration            # 设置允许健康检查命令允许的最长时间(单位:ms/s/m/h),默认是0s
      --no-healthcheck                     # 禁用容器健康检查指令

(3)案例:测试容器的健康检查功能

容器启动,开始执行健康检查命令,并周期执行,如果返回0,容器处于健康状态。如果返回非0值,容器不健康。

案例1:dockerfile中实现健康检查案例

查看代码
 # 改写上面的php-nginx-supervisord案例
[root@localhost php-nginx-supervisord]# vi Dockerfile
FROM php:7.3-fpm
COPY sources.list /etc/apt/
RUN apt-get clean && apt-get update
RUN apt-get -y install nginx supervisor procps net-tools
RUN mkdir -p /var/log/supervisor
COPY nginx /etc/nginx
COPY supervisor /etc/supervisor
WORKDIR /var/www
RUN usermod -u 1000 www-data
EXPOSE 80
HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ || exit 1  ##每5分钟健康检查一次,访问web服务器主页,每次检查3秒以内
CMD ["/usr/bin/supervisord"]
# 构建镜像、启动容器
[root@localhost php-nginx-supervisord]# docker build -t php-nginx-supervisord . 
[root@localhost php-nginx-supervisord]# docker run -tid -p 8080:80 php-nginx-supervisord
# 查看容器状态
[root@localhost php-nginx-supervisord]# docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED         STATUS                            PORTS                                             NAMES
7bcf645de0ee   php-nginx-supervisord   "docker-php-entrypoi…"   2 seconds ago   Up 2 seconds (health: starting)   9000/tcp, 0.0.0.0:8080->80/tcp, :::8080->80/tcp   nervous_bartik
[root@localhost php-nginx-supervisord]# docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED         STATUS                   PORTS                                             NAMES
7bcf645de0ee   php-nginx-supervisord   "docker-php-entrypoi…"   3 minutes ago   Up 3 minutes (healthy)   9000/tcp, 0.0.0.0:8080->80/tcp, :::8080->80/tcp   nervous_bartik

案例2:启动容器时设置选项实现健康检查

查看代码
 # 1.下载busybox镜像
[root@localhost ~]# docker pull busybox


# 2.创建容器设置健康检查,检查间隔20s,失败重复1次;并立即查看容器的健康检查状态
[root@localhost ~]#  docker run --rm --name test-health -d \
> --health-cmd 'stat /etc/passwd || exit 1' \
> --health-interval 20s --health-retries 1 \
> busybox sleep 1d; 

[root@localhost ~]#  docker inspect  --format '{{.State.Health.Status}}' test-health
d8fa5965abc02ec8d01722f98257ba2b8f76d50af05890dc8c6e1a18573ee6a3
starting       《————容器启动后的健康状态为Starting

# 3.延迟20s时间,再次查看容器的健康检查状态
[root@localhost ~]# sleep 20s;docker inspect  --format '{{.State.Health.Status}}' test-health
healthy        《————容器处于健康状态

# 4.删除容器的/etc/passwd文件,模拟健康问题
[root@localhost ~]# docker exec test-health rm /etc/passwd

# 5.延迟20s时间,再次查看容器的健康检查状态
[root@localhost ~]# sleep 20s;docker inspect  --format '{{.State.Health.Status}}' test-health
unhealthy     《————容器处于不健康状态
# 进一步查看容器的详情
[root@localhost ~]# docker inspect  --format '{{json .State.Health}}' test-health
{"Status":"unhealthy","FailingStreak":6,"Log":[{"Start":"2022-05-12T04:06:13.855633253+08:00","End":"2022-05-12T04:06:13.899152317+08:00","ExitCode":1,"Output":"stat: can't stat '/etc/passwd': No such file or directory\n"},{"Start":"2022-05-12T04:06:33.910019299+08:00","End":"2022-05-12T04:06:33.953470925+08:00","ExitCode":1,"Output":"stat: can't stat '/etc/passwd': No such file or directory\n"},{"Start":"2022-05-12T04:06:53.956520997+08:00","End":"2022-05-12T04:06:53.998897439+08:00","ExitCode":1,"Output":"stat: can't stat '/etc/passwd': No such file or directory\n"},{"Start":"2022-05-12T04:07:14.002929368+08:00","End":"2022-05-12T04:07:14.045233889+08:00","ExitCode":1,"Output":"stat: can't stat '/etc/passwd': No such file or directory\n"},{"Start":"2022-05-12T04:07:34.050748795+08:00","End":"2022-05-12T04:07:34.090015044+08:00","ExitCode":1,"Output":"stat: can't stat '/etc/passwd': No such file or directory\n"}]}
# 上述信息中报错:stat: can't stat '/etc/passwd': No such file or directory\n,符合前面模拟的健康问题

# 6.查看容器的当前状态
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND      CREATED         STATUS                     PORTS     NAMES
d8fa5965abc0   busybox   "sleep 1d"   5 minutes ago   Up 5 minutes (unhealthy)             test-health

5、运行时选项覆盖Dockerfile指令

Dockerfile中的FROMMAINTAINERRUNADD这四个指令在运行时是不能被覆盖的,其他的指令在执行docker run(或docker create)命令时都会被相应地覆盖。

从镜像运行一个容器时,可以指定一个新的命令来覆盖Dockerfile的CMD指令。

如果镜像的Dockerfile还声明了ENTRYPOINT指令,则Dockerfile的CMD指令或容器运行时指定的命令均作为参数追加到ENTRYPOINT指令中。

(1)覆盖CMD指令

[root@localhost ~]# docker history ubuntu
IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT
ff0fea8310f3   7 weeks ago   /bin/sh -c #(nop)  CMD ["bash"]                 0B           《——————默认命令
<missing>      7 weeks ago   /bin/sh -c #(nop) ADD file:1d3b09cf9e041d608…   72.8MB  

# 语法
[root@localhost ~]# docker run --help
Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

# 不覆盖的案例:使用CMD的默认命令
[root@localhost ~]# docker run -tid ubuntu 
d6adcb9ca10de89dcb1a1f8ab49b33a715b502e4aa4f1ec240774a7f4d2aa9f5

# 覆盖案例
[root@localhost ~]# docker run -tid ubuntu top            《————top替换默认的bash
0485fee218e64e858ca5b2214b9349b523a3bd41d1ad86c08877240635fa0d32

注意:

如果镜像的Dockerfile还声明了ENTRYPOINT指令,则Dockerfile的CMD指令或容器运行时指定的命令均作为参数追加到ENTRYPOINT指令中。

(2)覆盖ENTRYPOINT指令

使用 --entrypoint选项可以覆盖定义镜像的 Dockerfile 中的 ENTRYPOINT 指令设置。

镜像的 ENTRYPOINT 指令定义容器启动时要执行的命令,在启动容器时不容易被覆盖。

注意:运行时使用--entrypoint 选项将清除镜像胡任何默认命令。

查看代码
# 案例
[root@localhost ~]# docker pull redis
[root@localhost ~]# docker history redis
IMAGE          CREATED        CREATED BY                                      SIZE      COMMENT
7614ae9453d1   4 months ago   /bin/sh -c #(nop)  CMD ["redis-server"]         0B        
<missing>      4 months ago   /bin/sh -c #(nop)  EXPOSE 6379                  0B        
<missing>      4 months ago   /bin/sh -c #(nop)  ENTRYPOINT ["docker-entry…   0B        
<missing>      4 months ago   /bin/sh -c #(nop) COPY file:df205a0ef6e6df89…   374B      
<missing>      4 months ago   /bin/sh -c #(nop) WORKDIR /data                 0B        
<missing>      4 months ago   /bin/sh -c #(nop)  VOLUME [/data]               0B        
<missing>      4 months ago   /bin/sh -c mkdir /data && chown redis:redis …   0B        
...省略

# 默认自动运行redis-server的容器中,再运行一个shell
[root@localhost ~]# docker run -ti --entrypoint /bin/bash redis
root@484cb9c42858:/usr/local/bin# ls
docker-entrypoint.sh  redis-benchmark  redis-check-rdb	redis-sentinel
gosu		      redis-check-aof  redis-cli	redis-server
root@bd7640ba7206:/data# exit
exit

# 传递更多参数给ENTRYPOINT
# 默认传递--help给redis-server
[root@localhost ~]# docker run -ti  redis --help
Usage: ./redis-server [/path/to/redis.conf] [options] [-]
       ./redis-server - (read config from stdin)
       ./redis-server -v or --version
       ./redis-server -h or --help
...省略
# 传递--help给redis-cli
[root@localhost ~]# docker run -ti --entrypoint redis-cli redis --help
redis-cli 6.2.6
Usage: redis-cli [OPTIONS] [cmd [arg [arg ...]]]
  -h <hostname>      Server hostname (default: 127.0.0.1).
  -p <port>          Server port (default: 6379).
  -s <socket>        Server socket (overrides hostname and port).
...省略

# 传递空字符串重置容器的入口命令
[root@localhost ~]# docker run -ti --entrypoint="" redis bash
root@5cb647f12d63:/data# exit
exit

(3)覆盖EXPOSE传入端口指令

EXPOSE指令定义对外提供服务的初始传入端口,这些端口可用于容器中的进程。

###选项
[root@localhost ~]# docker run --help
      --expose []                     # 对外暴露容器的一个端口或一个端口范围
      --link []                       # 添加到其他容器的连接                           
  -p, --publish []                    # 将容器的一个端口或端口范围发布到主机                          
  -P, --publish-all                     # 将所有的端口发布到主机随机端口
                             
# 案例:
[root@localhost ~]# mkdir expose-test  && cd expose-test/
[root@localhost expose-test]# vi default.conf
server {
    listen       81;
    listen  [::]:81;
    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
[root@localhost expose-test]# vi Dockerfile
FROM nginx
ADD default.conf /etc/nginx/conf.d/
# 构建镜像
[root@localhost expose-test]# docker build -t expose-test .

# 运行容器
[root@localhost expose-test]# docker run -tid --expose 81 -P expose-test
[root@localhost expose-test]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED              STATUS              PORTS                                                                              NAMES
cfd19ef475fd   expose-test   "/docker-entrypoint.…"   2 seconds ago        Up 2 seconds        0.0.0.0:49155->80/tcp, :::49155->80/tcp, 0.0.0.0:49154->81/tcp, :::49154->81/tcp   determined_allen
# 访问网页发现49154端口才可以访问到网页

 

(4)覆盖ENV指令

linux中的容器,Docker自动设置了如下环境变量(默认值):

  • HOME(用户主目录):根据USER值设置
  • HOSTNAME(主机名):默认为容器名
  • PATH(执行文件的默认路径):常用目录
  • TERM(终端):若容器分配了伪TTY,则为xterm。

可以使用若干 -e 选项设置任何环境变量,并可以覆盖上述默认环境变量或Dockerfile中ENV指令定义的环境变量。

# 选项
[root@localhost ~]# docker run --help
  -e, --env []                      # 设置环境变量
      --env-file []                 # 读取文件中环境变量
                                       environment variables

# 案例
[root@localhost ~]# export today=Sunday
[root@localhost ~]# echo $today
Sunday
[root@localhost ~]# docker run -t -e "deep=purple" \
> -e today \
> --rm alpine env
# 输出如下信息
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=40951973766d
TERM=xterm
deep=purple
today=Sunday
HOME=/root

(5)HEALTHCHECK和WORDDIR指令

覆盖HEALTHCHECK的相关选项:

查看代码
[root@localhost ~]# docker run --help
      --health-cmd string                  # 指定和运行健康检查
      --health-interval duration           # 设置容器运行后,健康检查的时间间隔(单位:ms/s/m/h),默认是0s
      --health-retries int                 # 设置连续失败需要报告的次数
      --health-start-period duration       # 设置容器启动的初始化时间(单位:ms/s/m/h),默认是0s
                                       
      --health-timeout duration            # 设置允许健康检查命令允许的最长时间(单位:ms/s/m/h),默认是0s
      --no-healthcheck                     # 禁用容器健康检查指令

容器中运行二进制文件的默认工作目录是根目录(/),Dockerfile中可以使用WORDDIR指令自定义工作目录。还可以使用 -w选项覆盖WORKDIR指令设置。

查看代码
 #选项
[root@localhost ~]# docker run --help
  -w, --workdir string                 Working directory              # 修改容器的工作目录
                                       inside the container
# 案例:
[root@localhost expose-test]# docker run -tid -w /usr/local nginx
[root@localhost expose-test]# docker exec -ti 59362a6f79d4 /bin/bash
root@59362a6f79d4:/usr/local# pwd
/usr/local                《————工作目录为/usr/local

(6)USER

容器默认用户是root(UID=0),Dockerfile的USER指令可以指定容器运行第一个进程时的默认用户。

启动容器的时候,可以使用 -u(--user)选项指定新的默认用户覆盖镜像的USER指令。

查看代码
 # 选项
[root@localhost ~]# docker run --help
  -u, --user string                    Username or UID            # 指定容器运行第一个进程的默认用户,可以使用用户名、UID、组名、GID参数
                            语法:<name|uid>[:<group|gid>])

# 案例
[root@localhost expose-test]# docker run -ti -u daemon ubuntu 
daemon@8aeca4a93520:/$
[root@localhost expose-test]# docker run -ti -u mail  ubuntu
mail@137b5fdfa150:/$ 

(7)VOLUME指令

Dockerfile中可以使用 VOLUME 指令定义一个或多个与镜像关联的卷。

容器启动时可以使用 -v 、--mount--volume-from选项来指定挂载卷。详见:docker存储管理

标签:容器,运维,--,nginx,docker,root,Docker,localhost
From: https://www.cnblogs.com/sleep24/p/18180730

相关文章

  • 小程序无法使用TextEncoderDecoder问题
    不知道为什么用网友给的FastestSmallestTextEncoderDecoder这个在小程序一直引入不到里面的方法找网友要了两个js包就能用https://github.com/123456789xzxz/miniprogram/blob/main/miniprogram-text-decoder.jshttps://github.com/123456789xzxz/miniprogram/blob/main/minipr......
  • 配置管理与IT资产管理:差异与协同共生
    在信息技术日新月异的今天,高效、可靠的IT服务管理成为企业竞争力的关键一环。ITIL4 作为业界公认的IT服务管理框架,为我们提供了一套全面而系统的实践指南。在这一框架下,配置管理和IT资产管理作为两大核心实践,虽各有侧重,却又相辅相成,共同构建起IT服务的坚实基石。本文将深入探讨这......
  • jenkins plugin 开发简单说明
    属于一个简单的学习,基于了官方提供的脚手架,运行一个简单测试插件,了解下开发流程基于脚手架的简单项目创建使用archetype会提示选择的模版mvn-Uarchetype:generate-Dfilter="io.jenkins.archetypes:"构建mvncleanverifymvncleanpa......
  • tar文件header的格式和构造
    Header定义//standardarchiveformat-standardtar-ustarstructTarHeader{charname[100];//0-99charmode[8];//100-107charuid[8];//108-115chargid[8];//116-123charsize[12];//124-135charm......
  • MySQL索引
    1、索引的概述索引是一种用于快速查询和检索数据的数据结构,其本质可以看成是一种排序好的数据结构。索引的作用就相当于书的目录。打个比方:我们在查字典的时候,如果没有目录,那我们就只能一页一页的去找我们需要查的那个字,速度很慢。如果有目录了,我们只需要先去目录里查找字的位......
  • Fibocom L830 是一款移动通信模块,通常用于嵌入式设备或物联网(IoT)应用中。它提供了蜂窝
    驱动程序下载FibocomL830是一款移动通信模块,通常用于嵌入式设备或物联网(IoT)应用中。它提供了蜂窝连接功能,支持4GLTE网络,并具有全球覆盖的能力。这种模块通常被嵌入到各种设备中,例如智能手表、智能家居设备、工业设备等,以便这些设备可以通过蜂窝网络进行通信和远程控制。关于......
  • 单例模式的两种实现方式(初始化时创建以及运行时创建)
    单例模式删除析构函数通常意味着单例对象应该一直存活直到程序结束。在单例模式中,这通常是可取的,因为单例对象的生命周期通常与应用程序的生命周期相同。但是这样的话需要有一个函数来回收资源。以下例子:使用双重检查锁实现(线程安全)实现模板来创建单例#include<iostream>......
  • MySQL如何快速获取binlog的开始时间和结束时间
    之前写过一篇文章MySQL如何获取binlog的开始时间和结束时间[1],文章里面介绍了如何获取MySQL数据库二进制日志(binlog)的开始时间与结束时间的一些方法。实际应用当中,我们可能还会遇到效率/性能方面的问题。最近对这个问题做了一些研究,这里就介绍一下如何快速获取MySQL二进制日志(bi......
  • Fan Jin Passing Civil Exam
    ThisstoryisadaptedfromFanJinPassingCivilExam《范进中举》Thepointofviewofthestory:thethirdpersonpointofviewThepointofviewoftheadaptedstory:firstpersonpointofviewTheadaptedstoryMynameisFanJin,anordinaryfarmer'sson......
  • VLC.中文参数
    VLC相关参数中文说明VLC(VideoLANClient)是一款自由、开源的跨平台多媒体播放器。以下是VLC播放器中一些常见参数的中文说明:--intf或-I:设置VLC的界面模式。--no-osd:禁止显示OSD(On-ScreenDisplay)。--loop:循环播放文件。--sout或-sout:设置输出模块,用于播放网络流或其他设......