Supervisor简介
Supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时能自动重启。
它是通过fork/exec
的方式把这些被管理的进程当作supervisor的子进程来启动,这样只要在supervisor的配置文件中,把要管理的进程的可执行文件的路径写进去即可。
也实现当子进程挂掉的时候,父进程
可以准确获取子进程
挂掉的信息的,可以选择是否自己启动和报警。supervisor还提供了一个功能,可以为supervisord
或者每个子进程,设置一个非root
的user
,这个user
就可以管理它对应的进程。
事件背景
给公司用 docker 部署新的 dnmp 开发环境,想用 supervisor 实现对 php 进程和 swoole 进程的监控。但是部署了 dnmp 后,发现对于存活的 php 进程无法正确的监控到,始终报 fatal
,致命错误。
错误分析
在 dnmp 中,由于 supervisor 作为一个独立的容器存在,所以对于监控配置文件 supervisor/conf.d/php-fpm.ini 中运行的 php 命令并无法正常执行(因为只有在php容器中才可执行 php-cli 命令)。
所以,接下来的改写,目的就是吧 supervisor 移植到 php 容器中运行。
参考文献
配置修改过程
php的dockerfile改写
ARG PHP_VERSION
FROM ${PHP_VERSION}
ARG TZ
ARG PHP_EXTENSIONS
ARG CONTAINER_PACKAGE_URL
# 配置清华镜像
RUN if [ $CONTAINER_PACKAGE_URL ] ; then sed -i "s/dl-cdn.alpinelinux.org/${CONTAINER_PACKAGE_URL}/g" /etc/apk/repositories ; fi
# 安装php扩展
COPY ./extensions /tmp/extensions
WORKDIR /tmp/extensions
RUN chmod +x install.sh \
&& sh install.sh \
&& rm -rf /tmp/extensions
# 添加扩展安装执行脚本
ADD ./extensions/install-php-extensions /usr/local/bin/
# 赋予可执行权限
RUN chmod uga+x /usr/local/bin/install-php-extensions
# 安装必要的软件
# supervisor
# bash
# 设置时区
RUN apk update \
&& apk upgrade \
&& apk add supervisor \
&& apk add bash \
&& apk --no-cache add tzdata \
&& cp "/usr/share/zoneinfo/$TZ" /etc/localtime \
&& echo "$TZ" > /etc/timezone \
&& rm -rf /var/cache/apk/*
# Fix: https://github.com/docker-library/php/issues/240
RUN apk add gnu-libiconv libstdc++ --no-cache --repository http://${CONTAINER_PACKAGE_URL}/alpine/edge/community/ --allow-untrusted
ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php
# 安装 composer 并更改它的缓存主页
RUN curl -o /usr/bin/composer https://mirrors.aliyun.com/composer/composer.phar \
&& chmod +x /usr/bin/composer
ENV COMPOSER_HOME=/tmp/composer
# 配置用户组
RUN apk --no-cache add shadow && usermod -u 1000 www-data && groupmod -g 1000 www-data
# 设置工作目录
WORKDIR /var/www
主要修改的内容是:
RUN apk update \
&& apk upgrade \
&& apk add supervisor \
&& apk add bash \
&& apk --no-cache add tzdata \
&& cp "/usr/share/zoneinfo/$TZ" /etc/localtime \
&& echo "$TZ" > /etc/timezone \
&& rm -rf /var/cache/apk/*
docker-composer中 php 的容器编排修改
# php7
php:
build:
context: ./services/php
args:
PHP_VERSION: php:7.4.7-fpm-alpine
CONTAINER_PACKAGE_URL: mirrors.ustc.edu.cn
PHP_EXTENSIONS: pdo_mysql,mysqli,mbstring,gd,curl,opcache,apcu,zip,opcache,redis,swoole
TZ: "Asia/Tokyo"
container_name: php
ports:
- "9001:9001"
expose:
- 9000 # php-fpm
- 9001 # supervisor
- 5200 # swoole laravels
#extra_hosts:
# - "www.site1.com:172.17.0.1"
volumes:
- ..:/var/www/:rw
- ./services/php/php.ini:/usr/local/etc/php/php.ini:ro
- ./services/php/php-fpm.conf:/usr/local/etc/php-fpm.d/www.conf:rw
- ./logs/php:/var/log/php
- ./data/composer:/tmp/composer
# supervisor 文件映射配置
- ./services/supervisor/supervisord.conf:/etc/supervisord.conf:rw
- ./services/supervisor/conf.d:/etc/supervisor/conf.d:rw
- ./logs/supervisor:/var/log/supervisor:rw
restart: always
command:
- /bin/sh
- -c
- |
supervisord -n -c /etc/supervisord.conf
cap_add:
- SYS_PTRACE
environment:
APP_ENV: "developer"
networks:
- default
主要增加了 9001:9001的端口映射,然后在容器内部通过 expose 暴露 9001 的端口。
在 volumes 里面映射了 supervisor 的相关配置文件。
在 command 中加入了supervisor启动脚本:
command:
- /bin/sh
- -c
- |
supervisord -n -c /etc/supervisord.conf
修改supervisor对于php的监听配置
services/supervisor/conf.d/php-fpm.ini
[program:php]
command=/usr/local/bin/php -S 0.0.0.0:80
directory=/var/www/
然后重新 build 容器,最后 up 启动容器就成功了!
测试结果
总结
当前处理方式的弊端
本篇文章处理的方式是将 supervisor 安装进 php 容器中,然后运行命令 command=/usr/local/bin/php -S 0.0.0.0:80
来监听 php 的相关进程。
所以这样做的弊端就是,如果 php 的容器宕机后,由于 supervisor 存在于php容器中,那么 supervisor 也将无法使用,所以supervisor失去了他监控健康进程的意义。
基于当前的环境要求如何改写
可以将 supervisor 继续作为一个独立的容器运行,然后在配置文件command中,通过 docker exec - it xxx xx
等相关配置,来监听别的容器中的相关进程是否健康。