使用 systemd 单元管理容器环境完全指南

目录

[1. systemd 管理容器概述](#1. systemd 管理容器概述)

[传统服务 vs 容器服务](#传统服务 vs 容器服务)

适用场景分析

[2. 场景任务说明](#2. 场景任务说明)

具体需求

[3. 创建专用管理用户](#3. 创建专用管理用户)

为什么需要专用用户?

创建管理用户

[4. Podman 登录会话要求](#4. Podman 登录会话要求)

[重要限制:Podman 需要完整登录会话](#重要限制:Podman 需要完整登录会话)

问题根源解析

正确连接方式

[5. 初始容器运行测试](#5. 初始容器运行测试)

运行容器命令详解

验证容器状态

[6. 生成 systemd 服务文件](#6. 生成 systemd 服务文件)

[systemd 服务文件位置](#systemd 服务文件位置)

生成服务文件的两种模式

[模式 1:不使用 --new 选项](#模式 1:不使用 --new 选项)

[模式 2:使用 --new 选项(推荐)](#模式 2:使用 --new 选项(推荐))

创建服务文件

[7. 管理 systemd 用户服务](#7. 管理 systemd 用户服务)

[重新加载 systemd 配置](#重新加载 systemd 配置)

启动容器服务

检查服务状态

验证容器运行

[8. 重要管理原则](#8. 重要管理原则)

[systemd 与 Podman 命令的冲突](#systemd 与 Podman 命令的冲突)

[9. systemd 系统服务 vs 用户服务对比](#9. systemd 系统服务 vs 用户服务对比)

[10. 配置开机启动(用户服务)](#10. 配置开机启动(用户服务))

用户服务的默认行为问题

启用持久化(linger)

[linger 的作用](#linger 的作用)

[11. Root 用户 systemd 容器管理](#11. Root 用户 systemd 容器管理)

[Root 容器管理的不同之处](#Root 容器管理的不同之处)

[Root 管理的优势](#Root 管理的优势)

[12. 关键概念解析](#12. 关键概念解析)

[1. Rootless 容器](#1. Rootless 容器)

[2. systemd 用户服务](#2. systemd 用户服务)

[3. linger 机制](#3. linger 机制)

[4. Podman 无状态特性](#4. Podman 无状态特性)

总结


1. systemd 管理容器概述

传统服务 vs 容器服务

在传统环境中,系统服务(如 Web 服务器、数据库)通常配置为在系统启动时自动运行,并通过 systemctl 命令进行管理。对于容器化服务,我们同样可以使用 systemd 来管理,实现类似的自动化运维体验。

适用场景分析

小型部署

  • 单个容器主机

  • 无需复杂扩展

  • 适合使用 systemd 管理

大型部署

  • 需要复杂扩展和编排

  • 推荐使用 Kubernetes 等企业级平台(如红帽 OpenShift)


2. 场景任务说明

具体需求

将基于 httpd24 容器镜像的 webserver1 容器配置为:

  • 系统启动时自动启动

  • 挂载 /app-artifacts 目录作为 Web 服务器内容目录

  • 将本地 8080 端口映射到容器端口

  • 通过 systemctl 命令启动和停止


3. 创建专用管理用户

为什么需要专用用户?

普通用户 vs 系统用户

  • 普通用户 :使用 useradd 创建,系统会自动在 /etc/subuid 文件中为容器保留 ID 范围

  • 系统用户 :使用 useradd --system 创建,不会为容器保留 ID 范围,无法运行 Rootless 容器

创建管理用户

bash 复制代码
sudo useradd appdev-adm
sudo passwd appdev-adm

密码设置过程

bash 复制代码
Changing password for user appdev-adm.
New password: redhat
BAD PASSWORD: The password is shorter than 8 characters
Retype new password: redhat
passwd: all authentication tokens updated successfully.

注意:虽然提示密码太短,但仍在 RHEL 学习环境中被接受。


4. Podman 登录会话要求

重要限制:Podman 需要完整登录会话

bash 复制代码
su appdev-adm
podman info

错误输出

bash 复制代码
ERROR[0000] XDG_RUNTIME_DIR directory "/run/user/1000" is not owned by the current user

问题根源解析

  • su 命令:只切换用户身份,不创建完整的登录会话

  • sudo 命令:同样不创建完整登录会话

  • SSH 连接:创建完整的登录会话,满足 Podman 要求

正确连接方式

bash 复制代码
# 退出当前会话
exit
exit

# 通过 SSH 建立完整登录会话
ssh appdev-adm@host

5. 初始容器运行测试

运行容器命令详解

bash 复制代码
podman run -d --name webserver1 -p 8080:8080 -v \
~/app-artifacts:/var/www/html:Z registry.access.redhat.com/ubi8/httpd-24

参数解析

  • -d:后台运行(detached mode)

  • --name webserver1:指定容器名称

  • -p 8080:8080:端口映射(主机端口:容器端口)

  • -v ~/app-artifacts:/var/www/html:Z:卷挂载与 SELinux 上下文

  • registry.access.redhat.com/ubi8/httpd-24:容器镜像

注:端口映射指的是访问主机的8080端口就是在访问容器内部的8080端口

验证容器状态

bash 复制代码
podman ps

输出分析

bash 复制代码
CONTAINER ID IMAGE    COMMAND               CREATED STATUS PORTS    NAMES
cde4a3d8c956 registry.access.redhat.com/ubi8/httpd-24:latest /usr/bin/run-http... 4 seconds ago Up 5 seconds ago 0.0.0.0:8080->8080/tcp webserver1

状态说明

  • STATUS: Up 5 seconds:容器正常运行

  • PORTS: 0.0.0.0:8080->8080/tcp:端口映射生效


6. 生成 systemd 服务文件

systemd 服务文件位置

  • 系统服务/etc/systemd/system/

  • 用户服务~/.config/systemd/user/

生成服务文件的两种模式

模式 1:不使用 --new 选项
bash 复制代码
podman generate systemd --name webserver1

生成的关键配置

bash 复制代码
ExecStart=/usr/bin/podman start webserver1
ExecStop=/usr/bin/podman stop -t 10 webserver1
ExecStopPost=/usr/bin/podman stop -t 10 webserver1

模式特点

  • 启动时:执行 podman start 启动现有容器

  • 停止时:执行 podman stop 停止容器

  • 不删除容器:容器持久存在

模式 2:使用 --new 选项(推荐)
bash 复制代码
podman generate systemd --name webserver1 --new

生成的关键配置

bash 复制代码
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-common --rm --sdnotify=common --replace -d --name webserver1 -p 8080:8080 -v /home/appdev-adm/app-artifacts:/var/www/html:Z registry.access.redhat.com/ubi8/httpd-24
ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id

模式特点

  • 启动时:执行 podman run 创建并启动新容器

  • 使用 --rm 选项:停止时自动删除容器

  • 每次启动都是新容器:确保状态一致性

创建服务文件

bash 复制代码
# 生成服务文件到当前目录
podman generate systemd --name webserver1 --new --files

# 创建用户 systemd 目录
mkdir -p ~/.config/systemd/user/

# 移动服务文件到正确位置
mv container-webserver1.service ~/.config/systemd/user/

7. 管理 systemd 用户服务

重新加载 systemd 配置

bash 复制代码
systemctl --user daemon-reload

作用:让 systemd 识别新添加的服务文件

启动容器服务

bash 复制代码
systemctl --user start container-webserver1.service

检查服务状态

bash 复制代码
systemctl --user status container-webserver1.service

输出分析

bash 复制代码
container-webserver1.service - Podman container-webserver1.service
Loaded: loaded (/home/appdev-adm/.config/systemd/user/container-webserver1.service; disabled; vendor preset: disabled)
Active: active (running) since Thu 2022-04-28 21:22:26 EDT; 18s ago
Docs: man:podman-generate-systemd(1)
Process: 31560 ExecStartPre=/bin/rm -f /run/user/1003/container-webserver1.service.ctr-id (code=exited, status=0/SUCCESS)
Main PID: 31600 (common)

状态说明

  • Loaded:服务文件已加载,但未启用开机启动

  • Active: active (running):服务正在运行

  • Process:显示启动预处理命令执行成功

验证容器运行

bash 复制代码
podman ps

输出

bash 复制代码
CONTAINER ID IMAGE    COMMAND               CREATED    STATUS    PORTS    NAMES
18eb00f42324 registry.access.redhat.com/ubi8/httpd-24:latest /usr/bin/run-http...  28 seconds ago Up 29 seconds ago  0.0.0.0:8080->8080/tcp webserver1

8. 重要管理原则

systemd 与 Podman 命令的冲突

重要警告 :使用 systemd 管理容器后,不要再使用 podman 命令直接启动或停止容器,否则会干扰 systemd 的监控和状态管理。


9. systemd 系统服务 vs 用户服务对比

功能 系统服务 用户服务
单元文件位置 /etc/systemd/system/unit.service ~/.config/systemd/user/unit.service
重载单元文件 systemctl daemon-reload systemctl --user daemon-reload
启动/停止服务 systemctl start UNIT systemctl stop UNIT systemctl --user start UNIT systemctl --user stop UNIT
开机启动 systemctl enable UNIT loginctl enable-linger systemctl --user enable UNIT

10. 配置开机启动(用户服务)

用户服务的默认行为问题

默认情况下,用户服务:

  • 用户登录时启动

  • 用户注销时停止

启用持久化(linger)

bash 复制代码
# 检查当前状态
loginctl show-user appdev-adm

输出Linger=no

bash 复制代码
# 启用 linger
loginctl enable-linger appdev-adm

# 验证配置
loginctl show-user appdev-adm

输出Linger=yes

linger 的作用

  • 启用后:服务在系统启动时启动,系统关闭时停止

  • 禁用后:服务在用户登录时启动,用户注销时停止


11. Root 用户 systemd 容器管理

Root 容器管理的不同之处

如果以 root 用户身份管理容器:

配置项 Root 容器管理 Rootless 用户管理
服务文件位置 /etc/systemd/system/ ~/.config/systemd/user/
管理命令 systemctl(无 --user systemctl --user
linger 配置 不需要 loginctl enable-linger
用户要求 不需要专用用户 需要专用普通用户

Root 管理的优势

  • 服务像传统 systemd 单元一样工作

  • 不需要用户会话管理

  • 更接近传统服务管理体验


12. 关键概念解析

1. Rootless 容器

定义 :普通用户(非 root)运行的容器
优势

  • 提高安全性

  • 不需要特殊权限

  • 用户隔离更好

2. systemd 用户服务

特点

  • 在用户级别运行

  • 需要完整的用户会话

  • 默认依赖用户登录状态

3. linger 机制

作用 :允许用户服务在用户未登录时继续运行
适用场景:需要长期运行的用户服务

4. Podman 无状态特性

要求 :需要完整的登录会话环境
不支持的连接方式susudo
支持的连接方式:SSH、直接登录


总结

通过 systemd 管理容器提供了传统服务管理的便利性,结合了容器技术的灵活性。关键要点:

  1. 专用用户:为容器管理创建专用普通用户

  2. 完整会话:通过 SSH 建立完整登录会话运行 Podman

  3. 服务生成 :使用 podman generate systemd --new --files 生成服务文件

  4. 持久化配置 :使用 loginctl enable-linger 实现开机启动

  5. 管理分离:使用 systemd 管理后,避免直接使用 podman 命令操作容器

相关推荐
石像鬼₧魂石13 小时前
有哪些常见的字典可以用于Hydra的密码破解?
linux·学习·ssh
RXXW_Dor13 小时前
西门子EtherNet/IP 适配器 通过 EtherNet/IP 将第三方控制系统连接到 SIMATIC S7 控制器
linux·网络·tcp/ip
Mr.H012713 小时前
(上册)TCP 服务器核心流程实操指南
linux·服务器·网络·tcp/ip
DeeplyMind14 小时前
Guest → QEMU → Virglrenderer 调用逻辑分析
linux·驱动开发·虚拟化·virtio-gpu·virglrenderer
chenzhou__14 小时前
LinuxC语言并发程序笔记(第二十天)
linux·c语言·笔记·学习
会飞的土拨鼠呀14 小时前
运维工程师需要具备哪些技能
linux·运维·ubuntu
虎头金猫16 小时前
随时随地处理图片文档!Reubah 加cpolar的实用体验
linux·运维·人工智能·python·docker·开源·visual studio
NiKo_W16 小时前
Linux 数据链路层
linux·服务器·网络·内网穿透·nat·数据链路层
dessler16 小时前
MYSQL-物理备份(xtrabackup)使用指南
linux·数据库·mysql