SONiC系列:supervisor技术详解

news/2025/1/15 19:51:30/

文章目录

  • 概念
    • supervisor简介
    • supervisor特性
  • 主要组件
    • debian仓库里的版本
    • 核心组件——supervisord
    • 核心组件——supervisorctl
  • 配置详解
    • systemctl系统服务
    • supervisord服务端
    • supervisorctl客户端
    • 子进程配置
  • 案例
    • 测试项目
      • 安装supervisor
      • 修改配置
      • 守护一个shell
      • 查看子进程动态
    • SONiC实战
    • 设置交换机IP
    • 等待确认pmon启动
      • 修改supervisor配置
      • 修改热管理代码
      • 配置子进程日志输出
  • 附录
    • 修改运行中的docker容器
  • 参考资料

概念

supervisor简介

supervisor是一个守护套件,用于守护没有独立进程的工具,比如python、bash等等。它可以像系统服务一样守护多个进程,配置依赖关系、shell优先级、环境变量、开机自启、禁止或允许shell启动、print转发logger等等,功能丰富而强大。fancontrol、thermalctld、psud、syseepromd、xcvrd等等都用此套件来保证脚本程序持续运行和异常恢复。

在这里插入图片描述

在debian系统中,此守护套件被systemd守护,依赖supervisor维护的shell如此被多层守护,重重守护,保障用户的shell长久运行。它与launchd、daemontools和runit等程序有一些相同的目标。与其中一些程序不同,它并不意味着作为init的“1号进程”来运行。相反,它旨在用于控制与项目或客户相关的流程,并旨在像启动时的任何其他程序一样启动。

supervisor特性

  1. 方便:传统方式,开发者需要为每个进程实例编写rc.d脚本。这很不方便。rc.d脚本包含进程初始化、自动启动、管理等公共管理表格,它们的编写和维护可能很困难。此外,rc.d脚本无法自动重新启动崩溃的进程,许多程序在崩溃时也无法正常重新启动。Supervisord将流程作为其子流程启动,并且可以配置为在崩溃时自动重新启动它们。它还可以自动配置为在自己的调用中启动进程。

  2. 精准:在UNIX上,通常很难获得进程的准确上下文状态。Pid文件经常不可靠。supervisord将进程作为子进程启动,因此它总是知道其子进程的真实上行/下行状态,并且可以方便地查询这些数据。

  3. 可委托:需要控制流程状态的用户通常只需要这样做。他们不希望或不需要对运行进程的机器进行全面的shell访问。侦听“低”TCP端口的进程通常需要作为根用户启动和重新启动(UNIX的一个错误功能)。通常情况下,允许“正常”人员停止或重新启动这样的进程是完全可以的,但为他们提供shell访问权限通常是不切实际的,并且为他们提供root访问权限或sudo访问权限通常也是不可能的。也很难(正确地)向他们解释为什么存在这个问题。如果supervisord以root用户身份启动,则可以允许“普通”用户控制此类过程,而无需向他们解释问题的复杂性。Supervisorctl允许对机器进行非常有限的访问,本质上允许用户通过从简单的shell或web UI发出“停止”、“启动”和“重新启动”命令来查看流程状态并控制Supervisorord控制的子流程。

  4. 进程分组:进程通常需要分组启动和停止,有时甚至需要按“优先级顺序”启动和停止。通常很难向人们解释如何做到这一点。Supervisor允许您为进程分配优先级,并允许用户通过supervisorctl客户端发出命令,如“start all”和“restart all”,后者按预先分配的优先级顺序启动进程。此外,进程可以分为“进程组”,一组逻辑相关的进程可以作为一个单元停止和启动。

主要组件

debian仓库里的版本

supervisor是一个C/S模型的软件。supervisord是S端,supervisorctl是C端。查询版本,运行apt policy supervisor显示:

supervisor:Installed: (none)Candidate: 4.2.1-1ubuntu1Version table:4.2.1-1ubuntu1 500500 http://archive.ubuntu.com/ubuntu jammy/universe amd64 Packages

检查依赖,运行apt depends supervisor显示:

supervisorbashPreDepends: init-system-helpers (>= 1.54~)Depends: lsb-baseDepends: python3-pkg-resourcesDepends: <python3:any>python3Suggests: supervisor-doc

核心组件——supervisord

supervisor的服务器部分被命名为supervisord。 它负责在自己的调用下启动子程序,响应客户的命令,重新启动崩溃或退出的子进程,记录子进程的stdout和stderr输出,并生成和处理与子进程生命周期内各点相对应的 “事件”。 这通常位于/etc/supervisord.conf中。 这个配置文件是一个 "Windows-INI "风格的配置文件。 保持这个文件的安全是很重要的,因为它可能包含未加密的用户名和密码。

运行 Supervisor 时会启动一个进程 supervisord,它负责启动所管理的进程,并将所管理的进程作为自己的子进程来启动,而且可以在所管理的进程出现崩溃时自动重启,其可执行文件位于:/usr/local/bin/supervisord,主要由python3实现。

核心组件——supervisorctl

Supervisor的命令行客户端被称为supervisorctl。 它为supervisord所提供的功能提供了一个类似shell的接口。 通过supervisorctl,用户可以连接到不同的supervisord进程,获得由supervisord控制的子进程的状态,停止和启动子进程,并获得supervisord的运行进程列表。 服务器可以断言客户端的用户在允许他执行命令之前应该出示认证凭证。 客户端进程通常使用与服务器相同的配置文件,但任何带有[supervisorctl]部分的配置文件都可以使用。

这是命令行管理工具,同时支持交互模式,可以用来执行 stop、start、restart 等命令,来对这些子进程进行管理,类似systemctl。supervisor是所有进程的父进程,管理着启动的子进程,supervisor以子进程的PID来管理子进程,当子进程异常退出时supervisor可以收到相应的信号量。有些比较重要的功能设计还有欠缺,比如不停服务更新配置文件systemctl reload nginx,nginx会在不停止服务的情况下装载/etc/nginx.conf并更新,supervisor就没有类似的协议与受控进程间通讯。

配置详解

systemctl系统服务

supervisor自身依靠systemctl托管,其配置文件位于/lib/systemd/system/supervisor.service,典型的配置文件内容如下所示:

[Unit]
Description=Supervisor process control system for UNIX
Documentation=http://supervisord.org
After=network.target[Service]
ExecStart=/usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown
ExecReload=/usr/bin/supervisorctl -c /etc/supervisor/supervisord.conf $OPTIONS reload
KillMode=process
Restart=on-failure
RestartSec=50s[Install]
WantedBy=multi-user.target 

supervisord服务端

supervisord是服务端,也是核心服务,它具体实现了对子进程的守护,根据守护进程的配置记录子进程的日志等等,它的配置文件位于:/etc/supervisor/supervisor.conf,详细说明如下:

; supervisor config file[unix_http_server]          ; Web管理配置 
file=/var/run/supervisor.sock   ; socket文件路径
;chmod=0700                 ; socket 文件的权限,也是默认值
;chown=nobody:nogroup       ; socket 所属用户及组
;username=user              ; 用户名
;password=123               ; 密码;[inet_http_server]         ; 是否启用web管理端,默认关闭,如果启用则可以通过web端口管理服务配置、在线查看子进程的日志。还需docker容器开放此端口。
;port=127.0.0.1:9001        ; 监听的IP及端口
;username=user              ; 用户名
;password=123               ; 密码[supervisord] ;supervisord 全局配置
logfile=/var/log/supervisor/supervisord.log ; supervisor 日志路径,默认值是$CWD/supervisord.log
logfile_maxbytes=50MB       ; 单个日志文件最大数
logfile_backups=10          ; 保留多少个日志文件(默认10个)
loglevel=info               ; 日志等级,默认为info; 还可以设置debug、warn、trace
pidfile=/var/run/supervisord.pid ; pid 文件路径
nodaemon=false              ; 启动是否丢到前台,设置为false ,表示以daemon 的方式启动
minfds=1024                 ; 最小文件打开数,对应系统limit.conf 中的nofile ,默认最小为1024,最大为4096
minprocs=200                ; 最小的进程打开数,对应系统的limit.conf 中的nproc,默认为200
childlogdir=/var/log/supervisor  ; 受托管的子进程的日志文件路径
;umask=022                  ; (进程创建文件使用的权限的掩码)
;user=chrism                ; 启动supervisord服务的用户,默认为root,设置为其它普通用户可提升系统安全性
;identifier=supervisor      ; 服务标识,默认值为'supervisor'
;directory=/tmp             ; 后台服务的工作目录
;nocleanup=true             ; 启动时不要清理临时文件,默认为false,即启动时清理临时文件
;childlogdir=/tmp           ; 子进程日志目录,默认值是$TEMP。此配置为空则子进程的日志丢失
;environment=KEY=value      ; 子进程环境变量键值对,还可在子进程配置中分别配置。
;strip_ansi=false           ; 转义字符在日志中是否用转义字符串表示。默认值为false,即不转义,日志消息若有换行,则日志文件体现出换行。如果希望每条消息仅占用一行或者日志文件是一张表格,则应设置为true。; 以下部分必须保留在配置文件中,RPC(supervisorctl/web接口)才能工作,可以通过在单独的rpcinterface:部分中定义额外的接口来添加
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface; [include]部分只能包含“文件”设置。此设置可以列出多个文件(用空格或换行符分隔)。它还可以包含通配符。
; 文件名被解释为相对于此文件。包含的文件*不能包含文件本身。
[include]
files = /etc/supervisor/conf.d/*.conf;[group:thegroupname]          ; 服务组管理,可以将多个服务名写到这里管理(组名自定义)
;programs=progname1,progname2  ; 上面include配置好的服务名,比如hello-cat1等等
;priority=999                  ; 相对启动优先级,默认值是999,数值越大,级别越低。

supervisorctl客户端

一个最简单的配置文件,适用于CS两端在同一个系统的情况,无须登录密码直接操作。

[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; supervisord服务端socket文件路径
;serverurl=http://127.0.0.1:9001 ; 用于访问局域网其它supervisord服务端,实现CS分离
;username=chris              ; 登录账号
;password=123                ; 登录密码
;prompt=mysupervisor         ; 命令行提示符,也叫前导符
;history_file=~/.sc_history  ; 读取历史文件,如果存在,可批量执行操作。

supervisor安装成功后系统环境中存在supervisorctl工具,常用命令如下所示:

子进程配置

根据supervisord的include配置节,所有位于/etc/supervisor/conf.d/的以.conf为后缀的文本文件都能被supervisord识别。子进程配置详解如下所示:

[program:theprogramname]       ; 定义一个守护进程 ,比如下面的elasticsearch 
command=/bin/cat               ; 启动程序使用的命令,可以是绝对路径或者相对路径
;process_name=%(program_name)s ; 一个python字符串表达式,用来表示supervisor进程启动的这个的名称,默认值是%(program_name)s
;numprocs=1                    ; Supervisor启动这个程序的多个实例,如果numprocs>1,则process_name的表达式必须包含%(process_num)s,默认是1
directory=/tmp                 ; supervisord在生成子进程的时候会切换到该目录
;umask=022                     ; umask for process (default None)
;priority=999                  ; 权重,可以控制程序启动和关闭时的顺序,权重越低:越早启动,越晚关闭。默认值是999
autostart=true                 ; 如果设置为true,当supervisord启动的时候,进程会自动启动
autorestart=true               ; 设置为随 supervisord 重启而重启,值可以是false、true、unexpected。false:进程不会自动重启
;startsecs=10                  ; 程序启动后等待多长时间后才认为程序启动成功,默认是10秒
;startretries=3                ; supervisord尝试启动一个程序时尝试的次数。默认是3
;exitcodes=0,2                 ; 一个预期的退出返回码,默认是0,2。
;stopsignal=QUIT               ; 当收到stop请求的时候,发送信号给程序,默认是TERM信号,也可以是 HUP, INT, QUIT, KILL, USR1, or USR2
;stopwaitsecs=10               ; 在操作系统给supervisord发送SIGCHILD信号时等待的时间
;user=chrism                   ; 如果supervisord以root运行,则会使用这个设置用户启动子程序
;redirect_stderr=true          ; 如果设置为true,进程则会把标准错误输出到supervisord后台的标准输出文件描述符
stdout_logfile=/a/path         ; 把进程的标准输出写入文件中,如果stdout_logfile没有设置或者设置为AUTO,则supervisor会自动选择一个文件位置
stdout_logfile_maxbytes=1MB    ; 标准输出log文件达到多少后自动进行轮转,单位是KB、MB、GB。如果设置为0则表示不限制日志文件大小
stdout_logfile_backups=10      ; 标准输出日志轮转备份的数量,默认是10,如果设置为0,则不备份
;stdout_capture_maxbytes=1MB   ; 当进程处于stderr capture mode模式的时候,写入FIFO队列的最大bytes值,单位可以是KB、MB、GB
;stdout_events_enabled=false   ; 如果设置为true,当进程在写它的stderr
;stderr_logfile=/a/path        ; 把进程的错误日志输出一个文件中,除非redirect_stderr参数被设置为true
;stderr_logfile_maxbytes=1MB   ; 错误log文件达到多少后自动进行轮转,单位是KB、MB、GB。如果设置为0则表示不限制日志文件大小
;stderr_logfile_backups=10     ; 错误日志轮转备份的数量,默认是10,如果设置为0,则不备份
;stderr_capture_maxbytes=1MB   ; 当进程处于stderr capture mode模式的时候,写入FIFO队列的最大bytes值,单位可以是KB、MB、GB
;stderr_events_enabled=false   ; 如果设置为true,当进程在写它的stderr到文件描述符的时候,PROCESS_LOG_STDERR事件会被触发
environment=A=1,B=2            ; 一个k/v对的list列表
;serverurl=AUTO                ; 是否允许子进程和内部的HTTP服务通讯,如果设置为AUTO,supervisor会自动的构造一个url

案例

上述所有配置并非都对sonic项目有用。接下来根据最迫切的调试需求演示怎么方便地查看print输出。

测试项目

安装supervisor

此示例在WSL上运行:sudo apt install supervisor,如下图所示:

在这里插入图片描述

修改配置

编辑/etc/supervisor/supervisord.conf

在这里插入图片描述
查看网页如下图所示:

在这里插入图片描述

守护一个shell

  1. 在home目录下新建一个名为hello-supervisor.sh的文件,代码如下:

    # !/bin/bashecho timer running
    while true
    doecho hello at $(date +%F%T)sleep 1
    done
    
  2. 新增hello1的工作目录:mkdir -p /var/supervisor/hello1

  3. 新增守护配置,运行vim /etc/supervisor/conf.d/hello1.conf
    在这里插入图片描述

查看子进程动态

两种方式,一种是运行命令:tail -f /var/supervisor/hello1/out.log,如下图所示:

在这里插入图片描述

另一种方式是在网页上查看:

在这里插入图片描述

在这里插入图片描述

网页能启动能停止但不能配置,日志界面不自动滚屏,需手动操作。如有需要,可打开浏览器调试界面,在控制台输入以下代码:

setInterval(function() {window.scrollTo(0, document.body.scrollHeight);
}, 1000);

滚动条每隔1秒向下滚动1次:

在这里插入图片描述

SONiC实战

以pmon容器为例。其它容器操作方法一样。

设置交换机IP

交换机MGMT网口在开机启动时为动态IP,为简化网络访问,在登录成功、切换root账号后输入:ifconfig eth0 192.168.0.3

等待确认pmon启动

  1. 运行:journalctl -fu pmon,等待日志出现如下图所示:
    在这里插入图片描述

  2. 运行docker ps,记住ID

在这里插入图片描述

修改supervisor配置

  1. 打开supervisor的web服务,编辑/etc/supervisor/supervisord.conf,找到[unix_http_server],追加代码

    [inet_http_server]
    port=:9010
    username=pmon
    password=pmon

    如下图所示:
    在这里插入图片描述

  2. 退出并重启pmon容器,运行:systemctl restart pmon,在浏览器中打开:http://192.168.0.3:9010,效果如下图所示:
    在这里插入图片描述

修改热管理代码

为查看日志输出效果修改/usr/local/bin/thermalctld。当前热管理在正常工作时不输出日志,使测试看不到效果。

  1. 以60为关键字进行搜索,全部改成10,如下图所示:
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

  2. 查找关键字:def run,分别追加代码print('executed som policies.')print('wait {} seconds'.format(self.wait_time)),如下图所示:
    在这里插入图片描述

配置子进程日志输出

以thermalctld为例,

  1. 新建thermalctld工作目录,运行:mkdir -p /var/log/supervisor/thermalctld/

  2. 编辑/etc/supervisor/conf.d/supervisord.conf,如下图所示:
    在这里插入图片描述

  3. 退出容器,重启pmon,运行:systemctl restart pmon

附录

修改运行中的docker容器

首先须知,docker镜像不等于docker容器,它们是两个东西。docker镜像可随时随意修改,但docker容器不可以。docker容器来自于在docker镜像的基础来运行的docker run命令。修改运行中的docker容器的需求来自于它人创建的docker镜像过于封闭,比如开放SSH登录端口等等。下面以修改pmon容器为例说明如何修改运行中的docker容器。 这里需要采用非常规方法在容器启动后修改端口映射设置。容器的端口映射在系统镜像构建的时候已设置,且已设置开启机自动启动。

  1. 根据上面的ID,进入目录:cd /var/lib/docker/containers/3a101c79de35bed8ae3f930685f25790ebd3bdc13b148d788ee2d558a4b5caca
    在这里插入图片描述

  2. 复制hostconfig.json内容到json格式化工具
    在这里插入图片描述

  3. 修改之后复制回去保存,以同样的方法修改config.v2.json

  4. 运行docker restart pmon。docker自动重新压缩配置文件。

参考资料

  1. linux command: man supervisor
  2. http://supervisord.org/
  3. https://github.com/Supervisor/supervisor/issues/1406
作者:曹威
链接:https://blog.csdn.net/caoshiying/article/details/130028462
时间:2021-04-04
版本:1.0

http://www.ppmy.cn/news/41661.html

相关文章

物业企业如何加快向现代服务业转型

近年来&#xff0c;随着人民生活水平的提高&#xff0c;人们对住宅质量提出更高的要求&#xff0c;在此前提下&#xff0c;全国各地涌现出了一些运用现代的计算机、控制与通信技术建设的智能化住宅小区。但是许多智能化住宅小区都存在建好了智能硬件环境却没有智能化的软件在上…

Cadence Allegro 导出Unused Blind/Buired Via Report报告详解

⏪《上一篇》   🏡《上级目录》   ⏩《下一篇》 目录 1,概述2,Unused Blind/Buired Via Report作用3,Unused Blind/Buired Via Report示例4,Unused Blind/Buired Via Report导出方法4.1,方法14.2,方法2B站关注“硬小二”浏览更多演示视频

【Java面试八股文宝典之MySQL篇】备战2023 查缺补漏 你越早准备 越早成功!!!——Day22

大家好&#xff0c;我是陶然同学&#xff0c;软件工程大三即将实习。认识我的朋友们知道&#xff0c;我是科班出身&#xff0c;学的还行&#xff0c;但是对面试掌握不够&#xff0c;所以我将用这100多天更新Java面试题&#x1f643;&#x1f643;。 不敢苟同&#xff0c;相信大…

代码随想录_二叉树_leetcode530 501

leetcode 530 二叉搜索树的最小绝对差 530. 二叉搜索树的最小绝对差 给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 差值是一个正数&#xff0c;其数值等于两值之差的绝对值。 示例 1&#xff1a; 输入&#xff1a;root [4,2,6…

手撕深度学习中的优化器

深度学习中的优化算法采用的原理是梯度下降法&#xff0c;选取适当的初值params&#xff0c;不断迭代&#xff0c;进行目标函数的极小化&#xff0c;直到收敛。由于负梯度方向时使函数值下降最快的方向&#xff0c;在迭代的每一步&#xff0c;以负梯度方向更新params的值&#…

竞赛无人机搭积木式编程——以2022年TI电赛送货无人机一等奖复现为例学习(7月B题)

在学习本教程前&#xff0c;请确保已经学习了前4讲中无人机相关坐标系知识、基础飞行控制函数、激光雷达SLAM定位条件下的室内定点控制、自动飞行支持函数、导航控制函数等入门阶段的先导教程。 同时用户在做二次开发自定义的飞行任务时&#xff0c;可以参照第5讲中2021年国赛植…

编程的核心目的:计算数据

编程的核心目的是通过程序设计实现对数据的计算。计算数据涉及到对数据的获取、变量类型的定义、算术和逻辑运算、条件和循环控制等广泛的计算机科学概念和技术。 对数据的获取可以通过硬编码、用户输入等方式实现。变量类型的定义则是程序中的数据类型、这些类型确保数据的安…

【软考备战·希赛网每日一练】2023年4月10日

文章目录一、今日成绩二、错题总结第一题第二题三、知识查缺题目及解析来源&#xff1a;2023年04月10日软件设计师每日一练 一、今日成绩 二、错题总结 第一题 解析&#xff1a; 本题属于专业英语&#xff0c;大体了解意思即可。 题目大意&#xff1a; 第二题 解析&#xff1a…