目录
[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 的作用)
[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 无状态特性
要求 :需要完整的登录会话环境
不支持的连接方式 :su、sudo
支持的连接方式:SSH、直接登录
总结
通过 systemd 管理容器提供了传统服务管理的便利性,结合了容器技术的灵活性。关键要点:
-
专用用户:为容器管理创建专用普通用户
-
完整会话:通过 SSH 建立完整登录会话运行 Podman
-
服务生成 :使用
podman generate systemd --new --files生成服务文件 -
持久化配置 :使用
loginctl enable-linger实现开机启动 -
管理分离:使用 systemd 管理后,避免直接使用 podman 命令操作容器