【问题标题】:How to run a service running in a container in systemd, including systemd-notify and logging如何在 systemd 中运行在容器中运行的服务,包括 systemd-notify 和 logging
【发布时间】:2020-12-11 21:37:31
【问题描述】:

我们目前在主机上运行许多不同的服务,并且我们广泛使用 systemd,包括用于消息传递的 systemd-notify 和用于服务管理的自己的前端。

我们希望开始在容器内运行这些服务,以简化依赖管理并同时运行多个版本以进行测试。我们想要:

  • 系统通知
  • 同时记录到 systemd 日志和 syslog
  • 使用 systemctl start / stop 启动和停止服务。

请注意;大多数问题都是关于在 docker 容器中运行 systemd 的。这不是这个问题是关于什么的。相反,我想在 systemd 中运行一个(docker?)容器。

【问题讨论】:

    标签: docker containers systemd


    【解决方案1】:

    我们采用了以下解决方案:

    播客

    我们决定选择Podman。 Podman 是 RunC 的包装器,其 CLI 工具被调整为 Docker 的替代品。然而,因为它不是在守护进程下运行容器(无论如何我更喜欢它),所以几乎不需要任何管道来使 systemd-notify 工作。

    只需在 sytemd 服务文件中指定 Environment=NOTIFY_SOCKET=/run/systemd/notify 即可。

    也请参阅here

    系统通知

    完整示例:

    我正在使用来自 https://github.com/bb4242/sdnotify 的 systemd-notify 测试脚本

    Dockerfile

    FROM python
    
    COPY test.py /
    
    RUN pip install sdnotify
    RUN chmod 755 /test.py
    
    ENTRYPOINT ["/usr/local/bin/python", "test.py"]
    CMD ["run"]
    
    EXPOSE 8080
    

    build.sh - 创建 Podman 容器,需要与 Dockerfile 和 test.py 脚本位于同一文件夹中。

    #!/bin/bash
    IMAGE_NAME=python-test
    CONTAINER_NAME=python-test
    sudo podman build . -t ${IMAGE_NAME}
    sudo podman rm ${CONTAINER_NAME}
    sudo podman create -e PYTHONUNBUFFERED=true -d --name=${CONTAINER_NAME} ${IMAGE_NAME}
    

    通知测试服务

    [Unit]
    Description=A test service written in Python
    
    [Service]
    # Note: setting PYTHONUNBUFFERED is necessary to see the output of this service in the journal
    # See https://docs.python.org/2/using/cmdline.html#envvar-PYTHONUNBUFFERED
    Environment=PYTHONUNBUFFERED=true
    Environment=NOTIFY_SOCKET=/run/systemd/notify
    SyslogIdentifier=notify-test
    NotifyAccess=all
    
    ExecStart=/usr/bin/podman start -a python-test
    ExecStop=/usr/bin/podman stop python-test
    
    # Note that we use Type=notify here since test.py will send "READY=1"
    # when it's finished starting up
    Type=notify
    
    [Install]
    WantedBy=multi-user.target
    

    所以首先安装 podman,并将上面 url 中的 test.py、Dockerfile 和 build.sh 放在一个单独的文件夹中。运行./build.sh

    然后把 .service 文件,和其他 systemd 服务文件放在/usr/lib/systemd/user 中。做sudo systemctl daemon-reload

    现在,可以使用sudo systemctl start notify-testsudo systemctl stop notify-test 启动和停止服务。

    记录

    默认情况下,systemd 会自动将写入 stdout/stderr 的任何内容记录到它自己的日志(可通过 journalctl 访问)和 syslog。

    见:https://www.freedesktop.org/software/systemd/man/systemd.exec.html

    SyslogLevelPrefix= 接受一个布尔参数。如果是真的并且 StandardOutput= 或 StandardError= 设置为 journal 或 kmsg(或 与 +console 组合使用相同的设置),日志行由 以日志级别为前缀的已执行进程将是 使用此日志级别集进行处理,但删除了前缀。如果设置为 false,这些前缀的解释被禁用并且记录 行按原样传递。这仅适用于写入的日志消息 到标准输出或标准错误。有关此前缀的详细信息,请参见 sd 守护进程 (3)。默认为真。

    两个问题:

    问题:当使用 podman 作为ExecStart= 时,日志源默认为可执行文件的名称,即“podman”。

    解决方案:使用 SyslogIdentifier= 指定日志记录的名称,如上面的 .service 文件示例。

    问题:日志行的日志级别之间不会有任何差异。

    解决方案:就像 systemd 文档中描述的 here 一样,在日志行前面加上 (用于调试)、(用于信息)、(用于警告)等以设置 systemd到处都有正确的日志级别,包括系统日志。甚至在 journalctl 工具中免费获取颜色!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-03
      • 1970-01-01
      • 2021-12-29
      • 2021-07-01
      • 2018-11-06
      • 1970-01-01
      • 2019-08-19
      • 2017-03-22
      相关资源
      最近更新 更多