1. 为什么选择RHEL9作为Docker运行环境
红帽企业Linux 9(RHEL9)作为企业级操作系统的标杆,其稳定性与安全性使其成为运行容器化应用的理想平台。相较于社区发行版,RHEL9提供了长达10年的生命周期支持,这对于需要长期维护的生产环境至关重要。我在实际企业部署中发现,RHEL9的SELinux策略与容器隔离机制配合得尤为紧密,能有效防止容器逃逸等安全风险。
系统内核方面,RHEL9默认搭载5.14内核,这个版本对cgroups v2的支持已经相当成熟。特别值得注意的是,RHEL9中的Podman虽然可以作为Docker的替代方案,但考虑到企业现有CI/CD流程通常基于Docker构建,直接使用Docker仍然是更务实的选择。以下是RHEL9相较于其他发行版在容器支持方面的优势对比:
| 特性 | RHEL9 | Ubuntu LTS | CentOS Stream |
|---|---|---|---|
| 内核版本 | 5.14+ | 5.15+ | 5.14+ |
| 默认容器工具 | Podman | Docker | Podman |
| 企业级支持周期 | 10年 | 5年 | 5年 |
| SELinux集成度 | 完全集成 | 可选安装 | 完全集成 |
| 安全更新响应时间 | <24小时 | <72小时 | <48小时 |
提示:虽然RHEL9默认使用Podman,但通过官方软件仓库仍然可以完整安装Docker CE版本,两者可以共存于同一系统。
2. RHEL9环境准备与依赖处理
2.1 系统注册与订阅管理
在RHEL9上安装软件前,必须确保系统已正确注册并附加合适的订阅。这个步骤常被新手忽略,导致后续安装失败。执行以下命令完成基础准备:
bash复制# 注册系统到Red Hat账户
sudo subscription-manager register --username <你的红帽账号> --password <密码>
# 附加订阅池(需根据实际订阅调整)
sudo subscription-manager attach --pool=<订阅池ID>
# 启用必要仓库
sudo subscription-manager repos --enable=codeready-builder-for-rhel-9-$(arch)-rpms
我曾遇到过一个典型问题:当企业使用内部卫星服务器管理订阅时,需要先将系统注册到卫星服务器而非红帽官方。这种情况下需要额外配置:
bash复制sudo subscription-manager register --org <组织ID> --activationkey <激活密钥>
2.2 关键依赖包安装
RHEL9默认采用dnf作为包管理器,安装Docker前需要确保这些基础依赖:
bash复制sudo dnf install -y device-mapper-persistent-data lvm2 \
libseccomp-devel iptables-services \
container-selinux policycoreutils-python-utils
这里有个容易踩坑的地方:RHEL9默认使用nftables而非传统的iptables,但Docker仍然依赖iptables服务。解决方案是同时启用两种防火墙后端:
bash复制sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
sudo systemctl enable --now iptables
3. Docker CE在RHEL9上的安装配置
3.1 官方仓库配置与安装
不同于其他Linux发行版,红帽不直接提供Docker官方仓库。我们需要手动添加Docker CE仓库:
bash复制sudo dnf config-manager --add-repo=https://download.docker.com/linux/rhel/docker-ce.repo
安装时特别注意版本选择策略。生产环境建议锁定特定版本而非使用latest标签:
bash复制sudo dnf install -y docker-ce-3:20.10.17-3.el9 docker-ce-cli-1:20.10.17-3.el9
经验之谈:在金融行业部署时,我们发现20.10.17版本与RHEL9的兼容性最佳,较新的23.x版本偶尔会出现cgroup v2适配问题。
3.2 存储驱动选择与优化
RHEL9默认采用overlay2存储驱动,但需要手动配置/etc/docker/daemon.json来优化性能:
json复制{
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true",
"overlay2.size=20G"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
对于使用LVM的服务器,我推荐将/var/lib/docker挂载到独立逻辑卷。这样可以避免容器日志和镜像占满根分区:
bash复制sudo lvcreate -n docker -L 100G rhel
sudo mkfs.xfs /dev/rhel/docker
echo "/dev/rhel/docker /var/lib/docker xfs defaults 0 0" | sudo tee -a /etc/fstab
sudo mount -a
4. 生产环境关键配置实践
4.1 安全加固措施
企业环境中必须加强Docker守护进程的安全配置。以下是我的安全检查清单:
-
禁用特权容器(在daemon.json中添加):
json复制"default-ulimits": { "nofile": { "Name": "nofile", "Hard": 64000, "Soft": 64000 } }, "no-new-privileges": true -
配置用户命名空间隔离:
bash复制sudo echo "dockremap:165536:65536" >> /etc/subuid sudo echo "dockremap:165536:65536" >> /etc/subgid -
启用实时入侵检测:
bash复制sudo ausearch -k docker | sudo auditctl -w /usr/bin/docker -k docker
4.2 网络性能调优
RHEL9的firewalld与Docker网络需要特别协调。建议创建独立的Docker区域:
bash复制sudo firewall-cmd --permanent --new-zone=docker
sudo firewall-cmd --permanent --zone=docker --add-interface=docker0
sudo firewall-cmd --permanent --zone=docker --set-target=ACCEPT
sudo firewall-cmd --reload
对于高吞吐量场景,需要调整内核网络参数:
bash复制echo "net.core.rmem_max=4194304" | sudo tee -a /etc/sysctl.conf
echo "net.core.wmem_max=4194304" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
5. 典型问题排查指南
5.1 SELinux冲突解决
当容器日志中出现"Permission denied"且常规chmod无效时,大概率是SELinux上下文问题。快速诊断命令:
bash复制sudo ausearch -m avc -ts recent
sudo sealert -l <审计日志ID>
常见修复方案是调整文件上下文而非禁用SELinux:
bash复制sudo semanage fcontext -a -t container_file_t "/path/to/file(/.*)?"
sudo restorecon -Rv /path/to/file
5.2 存储驱动故障处理
当docker info显示Storage Driver: overlay2但无法启动容器时,尝试重建存储元数据:
bash复制sudo systemctl stop docker
sudo rm -rf /var/lib/docker/overlay2/*
sudo systemctl start docker
我曾遇到过一个棘手案例:XFS文件系统未启用d_type支持导致overlay2失效。检测方法:
bash复制xfs_info /var/lib/docker | grep ftype=1
如果显示ftype=0,必须重新格式化分区:
bash复制sudo mkfs.xfs -n ftype=1 /dev/your_device
6. 企业级运维实践
6.1 自定义系统服务单元
RHEL9使用systemd管理Docker服务,建议创建自定义服务文件以增加监控指标:
ini复制# /etc/systemd/system/docker.service.d/override.conf
[Service]
ExecStartPre=/usr/bin/chcon -R -t svirt_sandbox_file_t /var/lib/docker
ExecStartPost=/usr/bin/curl -X POST http://monitor.example.com/docker/started
TimeoutStartSec=300
6.2 集中式日志收集
整合journald与Docker日志的配置示例:
bash复制sudo mkdir -p /etc/docker/plugins
echo "{
"log-driver": "journald",
"log-opts": {
"tag": "docker/{{.Name}}"
}
}" | sudo tee /etc/docker/daemon.json
在日志服务器上使用如下journald过滤器:
ini复制# /etc/systemd/journald.conf
ForwardToSyslog=yes
MaxLevelSyslog=debug