supervisor 进程管理

Supervisor (http://supervisord.org) 是一个用 [Python] 写的进程管理工具,可以很方便的用来启动、重启、关闭进程(不仅仅是 Python 进程)。除了对单个进程的控制,还可以同时启动、关闭多个进程,比如很不幸的服务器出问题导致所有应用程序都被杀死,此时可以用 supervisor 同时启动所有应用程序而不是一个一个地敲命令启动。

安装

当前Supervisor的最高版本是3.0,之前尝试使用2.x版本管理实验集群中的若干mdrill进程,发现使用客户端无法有效启动和停止服务器端管理的各个子进程,从网上搜索错误发现2.x版本有一些bug,建议升级到3.0版本。因此我卸载了2.x版本,重新安装了3.0版本,发现3.0版本很好使。3.0版本相对2.x版本,配置文件不同部分的配置项都发生了变化,详见官方文档。

sudo yum install python-setuptools-devel
easy_install supervisor 或 sudo pip install supervisor

如果是 Ubuntu 系统,还可以使用 apt-get 安装

apt-get install supervisor

supervisord 配置

Supervisor 相当强大,提供了很丰富的功能,不过我们可能只需要用到其中一小部分。安装完成之后,可以编写配置文件,来满足自己的需求。为了方便,我们把配置分成两部分:supervisord(supervisor 是一个 C/S 模型的程序,这是 server 端,对应的有 client 端:supervisorctl)和应用程序(即我们要管理的程序)。
首先来看 supervisord 的配置文件。安装完 supervisor 之后,可以运行echo_supervisord_conf
命令输出默认的配置项,也可以重定向到一个配置文件里:

echo_supervisord_conf > /etc/supervisord.conf

去除里面大部分注释和“不相关”的部分,注释符号为分号,我们可以先看这些配置:

[unix_http_server]
file=/tmp/supervisor.sock   ; UNIX socket 文件,supervisorctl 会使用
;chmod=0700                 ; socket 文件的 mode,默认是 0700
;chown=nobody:nogroup       ; socket 文件的 owner,格式: uid:gid
 
;[inet_http_server]         ; HTTP 服务器,提供 web 管理界面
;port=127.0.0.1:9001        ; Web 管理后台运行的 IP 和端口,如果开放到公网,需要注意安全性
;username=user              ; 登录管理后台的用户名
;password=123               ; 登录管理后台的密码
 

[supervisord]

logfile=/tmp/supervisord.log ; 日志文件,默认是 $CWD/supervisord.log logfile_maxbytes=50MB ; 日志文件大小,超出会 rotate,默认 50MB logfile_backups=10 ; 日志文件保留备份数量默认 10 loglevel=info ; 日志级别,默认 info,其它: debug,warn,trace pidfile=/tmp/supervisord.pid ; pid 文件 nodaemon=false ; 是否在前台启动,默认是 false,即以 daemon 的方式启动 minfds=1024 ; 可以打开的文件描述符的最小值,默认 1024 minprocs=200 ; 可以打开的进程数的最小值,默认 200 ; the below section must remain in the config file for RPC ; (supervisorctl/web interface) to work, additional interfaces may be ; added by defining them in separate rpcinterface: sections

[rpcinterface:supervisor]

supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]

serverurl=unix:///tmp/supervisor.sock ; 通过 UNIX socket 连接 supervisord,路径与 unix_http_server 部分的 file 一致 ;serverurl=http://127.0.0.1:9001 ; 通过 HTTP 的方式连接 supervisord ; 包含其他的配置文件

[include]

files = relative/directory/*.ini ; 可以是 *.conf 或 *.ini

我们把上面这部分配置保存到 /etc/supervisord.conf(或其他任意有权限访问的文件),然后启动 supervisord(通过 -c 选项指定配置文件路径,如果不指定会按照这个顺序查找配置文件:$CWD/supervisord.conf, $CWD/etc/supervisord.conf, /etc/supervisord.conf):

supervisord -c /etc/supervisord.conf   或  supervisord 

program 配置

上面我们已经把 supervisrod 运行起来了,现在可以添加我们要管理的进程的配置文件。可以把所有配置项都写到 supervisord.conf 文件里,但并不推荐这样做,而是通过 include 的方式把不同的程序(组)写到不同的配置文件里。
为了举例,我们新建一个目录 /etc/supervisor/ 用于存放这些配置文件,相应的,把 /etc/supervisord.conf 里 include 部分的的配置修改一下,支持自定义路径:

[include]
files = /etc/supervisor/*.conf

现在编写一份配置文件来管理这个进程,自定义栗子如下:

[program:flume]
directory = /export/flume/apache-flume-1.6.0-bin/
command = nohup bin/flume-ng agent -c conf -f conf/flume.conf -n agent -Dflume.root.logger=INFO,console > /dev/null 2>&1 &
autostart = true
startsecs = 5
autorestart = true
startretries = 3
user = root
redirect_stderr = true
stdout_logfile_maxbytes = 20MB
stdout_logfile_backups = 10
stdout_logfile = /export/flume/logs/sup_flume_stdout.log
;IT will stop all processes including child process
stopasgroup=true

栗子如下:

[program:usercenter]
directory = /home/leon/projects/usercenter       ; 程序的启动目录
command = gunicorn -c gunicorn.py wsgi:app         ; 启动命令,可以看出与手动在命令行启动的命令是一样的
process_name=%(program_name)s       ; process_name expr (default %(program_name)s)
numprocs=1           ; number of processes copies to start (def 1)
autostart = true     ; 在 supervisord 启动的时候也自动启动
startsecs = 1        ; 启动 1 秒后没有异常退出,就当作已经正常启动了
autorestart = true   ; 程序异常退出后自动重启
startretries = 3     ; 启动失败自动重试次数,默认是 3
user = leon          ; 用哪个用户启动
redirect_stderr = true          ; 把 stderr 重定向到 stdout,默认 false
stdout_logfile_maxbytes = 20MB  ; stdout 日志文件大小,默认 50MB
stdout_logfile_backups = 10     ; stdout 日志文件备份数
; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
stdout_logfile = /data/logs/usercenter_stdout.log
;这一配置项的作用是:如果supervisord管理的进程px又产生了若干子进程,使用supervisorctl停止px进程,停止信号会传播给px产生的所有子进程,确保子进程也一起停止。这一配置项对希望停止所有进程的需求是非常有用的。
stopasgroup=true
 
; 可以通过 environment 来添加需要的环境变量,一种常见的用法是修改PYTHONPATH ;process environment additions      
; environment=PYTHONPATH=$PYTHONPATH:/path/to/somewhere  

有几个配置项值得解释一下,可以根据需要自行设置。

  1. stopasgroup=true。这一配置项的作用是:如果supervisord管理的进程px又产生了若干子进程,使用supervisorctl停止px进程,停止信号会传播给px产生的所有子进程,确保子进程也一起停止。这一配置项对希望停止所有进程的需求是非常有用的。
  2. autostart=true。这一配置项的作用是:当启动supervisord的时候会将该配置项设置为true的所有进程自动启动。
  3. 一份配置文件至少需要一个 [program:x]部分的配置,来告诉 supervisord 需要管理那个进程。[program:x]语法中的 x 表示 program name,会在客户端(supervisorctl 或 web 界面)显示,在 supervisorctl 中通过这个值来对程序进行 start、restart、stop 等操作。

启动supervisor进程后,可以配置通过web界面查看,效果如下:

效果图

确保配置无误后可以在每台主机上使用下面的命令启动supervisor的服务器端supervisord
【启动supervisord】

supervisord -c /etc/supervisord.conf   或  supervisord 

【停止supervisord】

supervisorctl shutdown

【重新加载配置文件】

supervisorctl reload

【进程管理】

  1. 启动supervisord管理的所有进程
supervisorctl start all
  1. 停止supervisord管理的所有进程
supervisorctl stop all
  1. 启动supervisord管理的某一个特定进程
supervisorctl start program-name // program-name为[program:xx]中的xx
  1. 停止supervisord管理的某一个特定进程
supervisorctl stop program-name  // program-name为[program:xx]中的xx
  1. 重启所有进程或所有进程
supervisorctl restart all // 重启所有supervisorctl reatart program-name // 重启某一进程,program-name为[program:xx]中的xx
  1. 查看supervisord当前管理的所有进程的状态
supervisorctl status

使用 supervisorctl 客户端命令

Supervisorctl 是 supervisord 的一个命令行客户端工具,启动时需要指定与 supervisord 使用同一份配置文件,否则与 supervisord 一样按照顺序查找配置文件

supervisorctl -c /etc/supervisord.conf

上面这个命令会进入 supervisorctl 的 shell 界面,然后可以执行不同的命令了:

> status    # 查看程序状态
> stop usercenter   # 关闭 usercenter 程序
> start usercenter  # 启动 usercenter 程序
> restart usercenter    # 重启 usercenter 程序
> reread    # 读取有更新(增加)的配置文件,不会启动新添加的程序
> update    # 重启配置文件修改过的程序

上面这些命令都有相应的输出,除了进入 supervisorctl 的 shell 界面,等同于直接在 bash 终端运行:

$ supervisorctl status
$ supervisorctl stop usercenter
$ supervisorctl start usercenter
$ supervisorctl restart usercenter
$ supervisorctl reread
$ supervisorctl update

【其他】

除了 supervisorctl 之外,还可以配置 supervisrod 启动 web 管理界面,这个 web 后台使用 Basic Auth 的方式进行身份认证。
除了单个进程的控制,还可以配置 group,进行分组管理。
经常查看日志文件,包括 supervisord 的日志和各个 pragram 的日志文件,程序 crash 或抛出异常的信息一半会输出到 stderr,可以查看相应的日志文件来查找问题。

  • 遇到问题及解决方案

在使用命令supervisorctl start all启动控制进程时,遇到如下错误

unix:///tmp/supervisor.sock no such file

出现上述错误的原因是supervisord并未启动,只要在命令行中使用命令sudo supervisord启动supervisord即可。

  • 遗留问题

当集群规模扩大后,登录到每台主机使用supervior控制进程也是很麻烦的,能不能用一台主机作为客户端,同时连接集群中的所有主机,以一种中心化的方式统一管理集群中的所有进程?之前一直使用的方式是使用交互式工具expect。supervisor本身有没有提供一种机制实现集群中所有进程的中央化管理?

目前测试成功的是使用一台主机作为客户端(supervisorctl),控制另一台服务器(supervisord)主机上的状态。方法是在服务器端配置[inet_http_server]部分,开启TCP端口监听。客户端配置[supervisorctl]部分,指定服务器端的serverurl,连接服务器端监听的端口。但是一个客户端只能连接一个服务器,无法指定多个服务器。

作者:lj
链接:https://wordpress.5978917.com
来源:宁夏大飞网络科技有限公司
著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

堡垒机 jumpserver 的安装和使用流程

1.jumpserver是一款由python编写, Django开发的开源跳板机/堡垒机系统, 助力互联网企业高效 用户、资产、权限、审计 管理。jumpserver实现了跳板机应有的功能,基于ssh协议来管理,客户端无需安装agent。

Jumpserver特点:

1)完全开源,GPL授权 

2)Python编写,容易再次开发 

3)实现了跳板机基本功能,身份认证、访问控制、授权、审计 、批量操作等。

4)集成了Ansible,批量命令等 

5)支持WebTerminal 

6)Bootstrap编写,界面美观 

7)自动收集硬件信息 

8)录像回放 

9)命令搜索 

10)实时监控 

11)批量上传下载

安装流程:

1.首先关闭selinux和设置防火墙条件(或者关闭)

setfenforce 0

/etc/init.d/iptables stop 

2.安装依赖包:

yum -y install epel-release

yum clean all && yum makecache

yum -y update

yum -y install git python-pip mysql-devel gcc automake autoconf python-devel vim sshpass lrzsz readline-devel

3.下载jumpserver

a.解压:tar zxf jumpserver-0.3.0.tar.gz 

           cd jumpserver-0.3.0-beta/install

b.执行快速安装脚本:pip install -r requirements.txt

c.查看安装的包:pip freeze

d.安装mysql数据库

   建立数据库:create database jumpserver;

   建立用户:grant all on jumpserver.* to 用户名@’ip’ identified by “密码”;

                      flush privileges;

e.安装jumpserver:

 python install.py

请输入您服务器的IP地址,用户浏览器可以访问 [192.168.9.1]:  192.168.9.1                  //jumpserver访问地址         

是否安装新的MySQL服务器? (y/n) [y]: n                               //由于本机已经提前安装了mysql,所以这里就不需要更新了

请输入数据库服务器IP [127.0.0.1]: 192.168.9.1       //输入本机的ip地址,以连接mysql。最好提前测试下用这个账号权限是否能正常连接

请输入数据库服务器端口 [3306]: 3306

请输入数据库服务器用户 [root]: root                   //使用上面授权信息

请输入数据库服务器密码: 123456

请输入使用的数据库 [jumpserver]: jumpserver

连接数据库成功

请输入SMTP地址: smtp.sina.com                   //接着进行发件邮箱设置(需要登陆到自己的邮箱下,将POP3/SMTP服务功能开启)     

请输入SMTP端口 [25]: 25                         //这个邮箱设置一定要正确通过,否则后续添加用户时就不能正常发送邮件!

请输入账户: zabbix_ljlj@sina.com

请输入密码: c652810

请登陆邮箱查收邮件, 然后确认是否继续安装          //登陆邮箱,会收到一封”Jumpserver Mail Test!”的邮件,说明邮件测试通过

是否继续? (y/n) [y]: y

开始写入配置文件

开始安装Jumpserver, 要求环境为 CentOS 6.5 x86_64

开始更新jumpserver

创建数据库中的表。。。。。。

请输入管理员用户名 [admin]: admin              //设置web管理员用户名和管理员密码

请输入管理员密码: [5Lov@wife]: admin

请再次输入管理员密码: [5Lov@wife]: admin

Starting jumpsever service:                                [确定]

安装成功,请访问web, 祝你使用愉快。

请访问 https://github.com/ibuler/jumpserver查看文档

安装过程中可能要的问题(一般发生在邮箱验证之后):

1.开始写入配置文件

Traceback (most recent call last):

  File “/root/jumpserver-0.3.0-beta/install/next.py”, line 19, in

    from juser.user_api importdb_add_user, get_object, User

  File “/root/jumpserver-0.3.0-beta/juser/user_api.py”, line 3, in

    from Crypto.PublicKey importRSA

  File “/usr/lib64/python2.6/site-packages/Crypto/PublicKey/RSA.py”, line 75, in

    from Crypto.Util.number importgetRandomRange, bytes_to_long, long_to_bytes

  File “/usr/lib64/python2.6/site-packages/Crypto/Util/number.py”, line 56, in

    if_fastmath is not None and not _fastmath.HAVE_DECL_MPZ_POWM_SEC:

AttributeError: ‘module’object has no attribute ‘HAVE_DECL_MPZ_POWM_SEC’

原因:是python的pycrypto模块问题,需要卸载重装:

[root@jumpserver install]

# pip uninstall pycrypto

[root@jumpserver install]

# easy_install pycrypto

2.Traceback (most recent call last):

  File “install.py”, line 8, in

    importMySQLdb

  File “/usr/lib64/python2.6/site-packages/MySQLdb/__init__.py”, line 19, in

    import_mysql

ImportError: libmysqlclient.so.18: cannot openshared object file: No such fileor directory

解决办法:

查找这个libmysqlclient.so.18库文件,由于本机之前部署了mysql,所以可以查到这个文件(如果没有的话,可以安装mysql来获取这个文件)

[root@jumpserver install]

# find / -name libmysqlclient.so.18

/usr/local/src/mysql-5.6.34/libmysql/libmysqlclient.so.18

/usr/local/src/mysql-5.6.34/libmysql/CMakeFiles/CMakeRelink.dir/libmysqlclient.so.18

/usr/local/mysql/lib/libmysqlclient.so.18

[root@jumpserver install]

# ln -s /usr/local/mysql/lib/libmysqlclient.so.18 /usr/lib/libmysqlclient.so.18

[root@jumpserver install]

# vim /etc/ld.so.conf

include ld.so.conf.d/*.conf

/usr/lib/

/usr/local/mysql/lib/

[root@jumpserver install]

# ldconfig

然后再次执行上面的install.py脚本就OK了

3.django.db.utils.OperationalError: (1366, “Incorrect string value: ‘\\xE6\\x9C\\xBA\\xE6\\x88\\xBF’ for column ‘name’ at row 1”)

问题原因:网上查找同类问题,应该是mysql数据编码的问题,django连接的数据库编码字符集要求utf8,不然报错

修改配置文件:

[client]

default-character-set = utf8

[mysqld]

character-set-server = utf8

[mysql]

default-character-set = utf8

重新启动数据库,再次执行安装脚本即可

4.还有可能出现的问题:

如果出现启动失败的话,直接在项目目录下执行 ./service.sh start