用Docker部署Rocky Linux:从零搭建企业级基础镜像平台
干运维这些年我越来越依赖一套玩法本地跑一个和线上完全一致的基础环境验证完再推上去。而 Rocky Linux 在这套流程里出镜率尤其高——RHEL 兼容的二进制接口、开源免费、生命周期长再加上 Docker 的镜像化能力基本上就是企业级基础镜像平台的“标准答案”。这篇文章我打算把从零开始用 Docker 部署 Rocky Linux 的完整路径梳理一遍怎么准备环境、怎么拉镜像起容器、怎么让容器拿到固定 IP、怎么把配置固化成一个可复用的基础镜像最后再串几个真实业务场景LibreOffice、MySQL、Redis、GitLab。不管你是刚接触容器的运维新人还是想把内部基础镜像规范化的负责人看完都能直接动手复现。1. 思路拆解为什么偏偏是 Rocky Linux1.1 RHEL 兼容的关键价值先聊一个很多人会问的问题CentOS 不是也能用吗为什么非要换成 Rocky Linux答案就四个字上游对齐。CentOS Stream 已经变成 Fedora 和 RHEL 之间的“滚动预览版”不再适合当作生产基础镜像而 Rocky Linux 是由 CentOS 原联合创始人 Gregory Kurtzer 发起的社区项目目标就是做 RHEL 的 1:1 兼容重建包括内核参数、ABI、软件包版本、目录结构都对齐。这里有个容易被忽略的细节所谓“兼容”不是嘴上说说。RHEL 的软件包经过红帽严格测试Rocky Linux 直接用同一套源码重新编译所以你在 RHEL 上能跑的商业软件、自研程序、数据库驱动在 Rocky Linux 上基本都能跑。对于容器场景来说这意味着你用 Rocky Linux 镜像做出来的容器可以直接拿到基于 RHEL 的认证环境里运行不需要额外适配。1.2 企业基础镜像平台要解决什么问题把视角拉高一点企业里“基础镜像平台”不是简单拉个镜像就完事它至少要有这几个能力可预期镜像的包版本、内核配置、时区、语言环境都是确定的不能每次构建出来都不一样。可复用做好的基础镜像能被团队反复引用新同事入职不需要再从头配置一遍环境。可审计谁在什么时间用什么 Dockerfile 构建了什么镜像都能追溯。可更新上游出了安全补丁基础镜像能快速重建并推送。用 Docker 跑 Rocky Linux恰好能把这几件事全部落地。Rocky Linux 提供官方 Docker 镜像体积小、依赖少你基于它做的所有扩展镜像都天然继承 RHEL 兼容性。再加上 Docker 的分层机制基础层只需构建一次交给团队的每个人复用就行。2. 环境准备先把 Docker 跑起来2.1 Windows 下的 Docker Desktop 安装细节如果你用的是 Windows 开发机最省事的方式是装 Docker Desktop。但这一步有个高频坑装完启动报错Virtualization support not detected。这通常不是 Docker 本身的问题而是 Windows 的虚拟化功能没开全。安装前先检查三件事BIOS/UEFI 里开启了 Intel VT-x 或 AMD-V。Windows 功能里启用了“虚拟机平台”和“Hyper-V”Win10/11 专业版及以上。如果装了第三方杀毒软件先把它的内核隔离功能临时关掉否则虚拟化检测会被拦截。确认没问题后再装 Docker Desktop安装包下载后一路 Next最后重启一次系统。启动后用命令行验证docker version docker run hello-world能正常打印版本信息并跑通 hello-world说明 Docker 环境就绪了。Windows 下我习惯把镜像存放目录改到非系统盘因为 WSL2 的 vhdx 虚拟磁盘文件会越涨越大长期挤占 C 盘很痛苦。可以在 Docker Desktop 设置里把磁盘镜像位置改到 D 盘或 E 盘。2.2 Ubuntu 服务器上的 Docker Engine 安装生产环境还是推荐在 Linux 上装原生 Docker Engine。以 Ubuntu 22.04/24.04 为例官方推荐用 apt 仓库安装sudo apt update sudo apt install -y ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod ar /etc/apt/keyrings/docker.asc echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin装完默认不会开机自启执行sudo systemctl enable --now docker然后把当前用户加进 docker 组省得每次敲命令都加 sudosudo usermod -aG docker $USER newgrp docker这里有一个非常值得养成的习惯刚装完 Docker第一时间设置日志轮转。默认的 json-file 日志驱动会把容器所有 stdout 日志堆在一个文件里不限制的话一个大流量的容器半年能吃掉几十 GB 磁盘。我一般在/etc/docker/daemon.json里写死{ log-driver: json-file, log-opts: { max-size: 10m, max-file: 3 }, registry-mirrors: [https://docker.m.daocloud.io] }然后重启 Dockersudo systemctl restart docker2.3 镜像加速配置解决拉取慢的问题这一节内容很重要。国内网络环境直接连 Docker Hub 拉镜像经常超时必须配置镜像加速器。上面daemon.json里我已经写了registry-mirrors字段这里展开解释一下。registry-mirrors是 Docker 官方支持的镜像加速机制你拉镜像时 Docker 会优先从配置的镜像站拉取失败再回源 Docker Hub。可以配置多个Docker 会按顺序尝试。我自己用的比较稳的是 DaoCloud 公共镜像源你也可以在阿里云容器镜像服务控制台申请一个专属加速地址格式大致为https://你的ID.mirror.aliyuncs.com。配置完记得重启 Docker然后用docker info查看 Registry Mirrors 是否生效docker info | grep -A 10 Registry Mirrors如果看到你配置的地址说明加速已经生效。再拉一次镜像试试速度基本上几百 MB 的镜像也能在合理时间内拉完。3. 核心实操拉取 Rocky Linux 镜像并启动容器3.1 版本选择与镜像拉取Rocky Linux 官方在 Docker Hub 发布了多个仓库最常用的是rockylinux和rockylinux/rockylinux。前者是精简版类似 CentOS 的 base 镜像后者带一些额外工具日常做基础镜像推荐前者。版本方面Rocky Linux 9 是目前的主力版本8 还在维护期但已经接近生命周期尾部。除非你的应用有强制的兼容性要求否则直接上 9。拉镜像命令很简单docker pull rockylinux:9也可以拉指定小版本比如rockylinux:9.3这样能保证镜像内容完全可复现。做企业基础镜像时我非常建议把 tag 精确到小版本而不是跟着9这种浮动 tag 走。原因很简单今天拉rockylinux:9和三个月后拉的rockylinux:9软件源、内核包很可能已经更新过导致“同一套代码在不同时间构建出不同镜像”这在审计和排障时非常头疼。3.2 创建第一个交互式容器镜像拉下来先跑一个交互式容器试一试docker run -it --name rocky-dev rockylinux:9 /bin/bash进入容器后第一件事看版本cat /etc/rocky-release正常情况下会输出 Rocky Linux release 9.x。再看一眼默认用户Rocky Linux 官方镜像默认就是 root包管理器是 dnf/yum 都可用在 9 里 yum 是 dnf 的软链。基础镜像为了控制体积很多常用命令都没装。比如vim、net-tools、passwd这些都不存在需要自己装。第一次进容器我一般会系统性地装一轮工具dnf install -y vim enhanced-passwd sudo tar gzip findutils diffutils dnf install -y iproute iputils procps-ng hostnameiproute提供ip命令iputils提供pingprocps-ng提供ps。这些在容器排障时都是刚需不装的话很多诊断命令根本跑不了。3.3 容器内软件源与基础配置容器内的 Rocky Linux 默认带了 BaseOS 和 AppStream 源但有些常用软件比如htop、ncdu在默认源里没有需要额外启用 EPELExtra Packages for Enterprise Linux。EPEL 是 Fedora 社区为 RHEL 系列维护的扩展软件包仓库在容器里安装方式如下dnf install -y epel-release装完确认一下仓库列表dnf repolist能看到epel仓库说明启用成功。这时候再装一些扩展工具就没问题了。还有一件事容易被忽略容器内的时区默认是 UTC日志时间戳会跟宿主机差几个小时。直接改dnf install -y tzdata ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime echo Asia/Shanghai /etc/timezone如果想在以后所有构建里都用这个时区这一步要写进 Dockerfile而不是只在手工容器里改。4. 网络配置给 Rocky 容器设置静态 IP4.1 自定义网络与静态 IP 的完整操作Docker 容器默认通过 bridge 网络分配动态 IP每次重建容器 IP 都会变。但企业环境里容器经常要当固定节点用比如作为内部 DNS 客户端、接入防火墙白名单、或者和其他服务做点对点通信这时候就需要静态 IP。Docker 本身不支持在默认 bridge 网络上指定静态 IP必须先用自定义网络。操作分三步第一步创建自定义 bridge 网络指定网段docker network create --driver bridge --subnet172.20.0.0/24 --gateway172.20.0.1 rocky-net第二步用--ip参数启动容器docker run -it --name rocky-static --network rocky-net --ip 172.20.0.10 rockylinux:9 /bin/bash第三步在容器内验证 IPip addr show看到172.20.0.10说明静态 IP 生效。这个 IP 在容器存在的整个生命周期内都会保持不变除非你显式删除容器或改网络。卡在动态 IP 反复变化这个问题上的人很多核心原因就是没弄懂 Docker 的网络模型。默认 bridge 网络是 Docker 自动管理的它只知道“这个网段有多少 IP 可用”不关心哪个容器用哪个 IP自定义网络的本质是让 Docker 把 IP 分配权交给你所以才能指定固定值。4.2 网络规划与宿主机联通性验证静态 IP 配好之后还要确认两件事容器和宿主机能否互相访问。容器能否访问外网。容器访问宿主机和外网在默认 bridge 和自定义 bridge 下都能通过 NAT 实现只要宿主机本身能上网就没问题。验证方式ping -c 3 172.20.0.1 # 宿主机网关 ping -c 3 223.5.5.5 # 公网 IP如果 ping 不通公网 IP先检查容器内 DNScat /etc/resolv.conf看看 nameserver 是不是 127.0.0.11Docker 内嵌 DNS。再用curl测试域名解析比如curl -I https://www.baidu.com。这里有个实操心得自定义网络的子网不要和公司内部网段冲突。比如办公楼无线网是192.168.1.0/24你再建一个192.168.1.0/24的 Docker 网络宿主机路由表会打架排查起来非常费劲。我一般习惯用172.20.0.0/16或10.88.0.0/16这类 RFC 1918 私有地址里比较冷门的段避免冲突。4.3 容器内使用 systemd-networkd 配置网络的方式通过 Docker--ip指定静态 IP 是最推荐的方式但有些场景会在容器里装 systemd希望通过 systemd-networkd 或 NetworkManager 在容器内部配置 IP。这种方案适合特权模式privileged的 systemd 容器操作如下先安装必要组件dnf install -y systemd systemd-networkd然后创建 network 配置文件cat /etc/systemd/network/10-static.network EOF [Match] Nameeth0 [Network] Address172.20.0.10/24 Gateway172.20.0.1 DNS223.5.5.5 EOF启用并启动systemctl enable systemd-networkd systemctl restart systemd-networkd但我要提醒一句如果你只是想让容器有个固定 IP没必要走容器内配置这条路。Docker 的--ip参数已经能在网络层做绑定容器内再配置一套 netowrk 反而可能和 Docker 的 NAT 规则冲突折腾半天甚至会把网络搞断。这种容器内配置 IP 的方式只在调试系统网络服务或者模拟物理机行为时有意义。5. 固化配置构建可复用的 Rocky Linux 基础镜像5.1 手工配置后 commit 的适用场景与性能影响手工在容器里配好环境后直接docker commit生成一个新镜像这是最快的“固化”方式docker commit rocky-dev rockylinux-custom:9.3-base但 commit 只适合做临时快照不适合当长期基础设施。原因有几个commit 会把容器当前层的所有改动打包包括临时文件、缓存、可能误装的调试工具镜像体积越来越大。commit 无法复现构建过程别人拿到镜像后不知道里面改了什么审计无从谈起。你无法保证 commit 出来的镜像每个文件都有正确的权限和元数据有些临时改动会污染镜像。所以我的建议是commit 用来快速存个档没问题但正式发布的基础镜像必须走 Dockerfile 构建。5.2 用 Dockerfile 构建规范化基础镜像的完整示例Dockerfile 的好处是把“怎么构建”写成了代码任何人拿到文件都能重建一遍还能和 Git 版本管理配合。下面是一个我实际在用的 Rocky Linux 9 基础镜像 Dockerfile覆盖了时区、语言环境、常用工具、EPEL、清理缓存这几个关键点FROM rockylinux:9.3 LABEL maintaineryour-teamexample.com ENV TZAsia/Shanghai \ LANGen_US.UTF-8 \ LC_ALLen_US.UTF-8 RUN dnf install -y epel-release \ dnf install -y \ vim \ tar \ gzip \ findutils \ diffutils \ sudo \ iproute \ iputils \ procps-ng \ hostname \ tzdata \ glibc-langpack-en \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ echo Asia/Shanghai /etc/timezone \ dnf clean all \ rm -rf /var/cache/dnf CMD [/bin/bash]构建命令docker build -t rockylinux-base:9.3 .构建时几个注意事项dnf clean all一定要加否则基础层会带着一堆包管理缓存体积白白多出几百 MB。语言包glibc-langpack-en要显式安装否则容器内中文环境或者特定 locale 会报错。如果不用ENV TZ环境变量只改/etc/localtime在某些情况下还是会回退到 UTC两个都要做才能把时区彻底锁定。构建完之后用docker images看一下镜像体积Rocky Linux 9.3 基础镜像也就 200 MB 左右加了这些工具一般能控制在 400 MB 以内。如果超过这个量多半是缓存没清干净或者装了一些开发依赖建议重新审查。5.3 需要 systemd 的场景与 privileged 模式说明容器通常不需要 systemd因为一个容器最好只跑一个主进程。但有些场景例外比如你要在容器里跑多个服务或者要模拟完整的 RHEL 系统行为这时候需要 systemd 作为 1 号进程。Rocky Linux 官方也提供了 systemd 镜像 tag但默认镜像里没有需要手动装FROM rockylinux:9.3 RUN dnf install -y systemd \ dnf clean all \ rm -rf /var/cache/dnf STOPSIGNAL SIGRTMIN3 CMD [/sbin/init]启动这类容器时必须加--privileged和对应的 cgroup 挂载参数否则 systemd 起不来docker run -d --name rocky-systemd \ --privileged \ -v /sys/fs/cgroup:/sys/fs/cgroup:rw \ rockylinux-systemd:9.3--privileged相当于给容器开了“上帝模式”让容器内的 systemd 能操作 cgroup、挂载文件系统、管理设备。但权限越大安全隐患越大生产环境建议只在确实需要 systemd 的镜像里使用普通应用容器坚决不开。6. 场景落地在 Rocky 基础容器里装企业应用6.1 在容器内安装 LibreOffice文档转换服务实战先从一个具体例子看基础镜像怎么落地。很多人需要在服务器上跑文档格式转换最常见的就是 LibreOffice 把 docx 转 PDF 或把 xlsx 转 CSV。在 Rocky Linux 容器里部署 LibreOffice 比想象中简单。官方源里自带 LibreOffice但版本可能比较旧。如果想装指定版本比如 7.4.7.2可以下载对应 RPM 包本地安装。流程如下# 进入容器或基于基础镜像构建 dnf install -y libXinerama fontconfig freetype urw-base35-fonts curl -O https://archive.org/download/libreoffice_7.4.7.2_linux_x86-64_rpm/...实际生产我建议不要手动下载散装 RPM直接用 AppStream 源里的版本因为官方源里的包经过了依赖测试装起来不会缺库。以 Rocky 9 为例dnf install -y libreoffice-headless libreoffice-writer libreoffice-calcheadless 模式就是无界面运行完全适合容器场景。装完测试转换libreoffice --headless --convert-to pdf /data/input.docx --outdir /data/output/如果报缺少字体再装一下cjkuni-uming-fonts这类中文字体包否则中文文档转 PDF 会出现乱码方框。6.2 在 Rocky 容器里部署 MySQL 8.0MySQL 官网对 RHEL 系操作系统支持很好Rocky Linux 容器里装 MySQL 8.0 可以直接用官方仓库dnf install -y https://dev.mysql.com/get/mysql80-community-release-el9-1.noarch.rpm dnf install -y mysql-community-server装完初始化数据目录mysqld --initialize-insecure --usermysql注意--initialize-insecure表示 root 用户初始无密码适合容器内先初始化再通过环境变量配置密码的场景。启动服务mysqld --usermysql 然后设置 root 密码并允许远程连接mysql -uroot -e ALTER USER rootlocalhost IDENTIFIED BY YourPass123; CREATE USER root% IDENTIFIED BY YourPass123; GRANT ALL PRIVILEGES ON *.* TO root% WITH GRANT OPTION; FLUSH PRIVILEGES;不过更推荐的方式是把 MySQL 用官方mysql:8.0镜像单独跑而不是打包进 Rocky 基础镜像。只有在内部审计要求所有组件都基于统一系统镜像时才需要把 MySQL 装进 Rocky 容器里。6.3 Redis 主从、GitLab 的容器化部署思路Redis 主从和 GitLab 这两个场景分别代表轻量和重量两种风格。Redis 主从如果要在 Rocky 容器里做先编译装两个 Redis 实例然后配置主从复制replicaof指向主的 IP。但说实话Redis 本身不依赖特定系统环境直接用官方镜像更干净。在 Rocky 容器里装 Redis 的价值在于当你的基础设施强制要求所有中间件跑在统一操作系统上时保证 Redis 的 glibc 版本、内核参数和业务容器一致方便运维统一管理。GitLab 则是完全相反的情况——它依赖的组件非常多PostgreSQL、Redis、Gitaly、Sidekiq要在一个 Rocky 容器里全装起来极其痛苦。生产上不要自己造轮子用官方gitlab/gitlab-ce镜像配合 Docker Compose 部署。如果强调 RHEL 兼容可以考虑用gitlab/gitlab-ce基于 RHEL 构建的版本它原生基于红帽系镜像基础系统环境和 Rocky Linux 是同源的。容器化部署思路的共性就是先分清楚哪些应用应该留在基础镜像平台里哪些应该独立成容器服务。原则很简单单一职责。系统工具、时区、语言、JDK/运行时这些沉淀到基础镜像具体业务数据库、缓存、文档服务各自跑独立容器用 Docker 网络互相通信。7. 问题排查实录用 Rocky Docker 最常踩的坑7.1 yum/dnf 源报错镜像源失效与缓存问题Rocky Linux 容器里最经典的问题就是 dnf 安装软件时报Error: Failed to download metadata for repo baseos。排查顺序第一步看网络通不通curl -I https://mirror.rockylinux.org第二步排除 DNS 问题cat /etc/resolv.conf第三步检查系统时间。容器时间如果和真实世界差太多TLS 证书校验会失败也会表现为元数据下载失败date -R如果是公司内网环境还要检查是否需要走 HTTP 代理。在容器里配置代理直接写环境变量export http_proxyhttp://proxy.example.com:8080 export https_proxyhttp://proxy.example.com:80807.2 systemd 容器起不来或被信号杀死用 systemd 镜像启动容器最常见的问题有两种。一种是启动后 systemd 崩溃日志表现为不断重启。解决方法是确认启动命令是/sbin/init并且加了--privileged和 cgroup 挂载。WSL2 或较老的内核上可能还需要额外加-v /sys/fs/cgroup:/sys/fs/cgroup:rw另一种是容器 stop 时卡住systemd 不响应对 SIGTERM 的处理。Dockerfile 里要加STOPSIGNAL SIGRTMIN3这样 Docker 发送的不是 SIGTERM 而是 SIGRTMIN3systemd 会正确触发关机流程容器能在 10 秒内正常停止。7.3 静态 IP 配置后容器无法上网配了--network rocky-net --ip 172.20.0.10之后容器内能 ping 通网关但上不了外网大概率是内核的 IP 转发没开或者宿主机的 iptables 规则被清过。检查宿主机sysctl net.ipv4.ip_forward输出为 0 就临时开启echo 1 /proc/sys/net/ipv4/ip_forward永久生效写在/etc/sysctl.d/99-docker.confnet.ipv4.ip_forward 1之后执行sysctl -p。改完再重启 Docker自定义网络的 NAT 就能正常工作了。7.4 Docker Desktop 虚拟化检测失败这是 Windows 用户的高频问题Docker Desktop 启动时提示Virtualization support not detected。按以下顺序排查BIOS 确认虚拟化开关已开Intel 叫 VT-xAMD 叫 SVM。Windows 功能里把“虚拟机平台”和“适用于 Linux 的 Windows 子系统”勾上。命令行跑systeminfo看最后一行的 Hyper-V 要求是否显示“已检测到虚拟机监控程序”。如果用了第三方安全软件临时退出后重启 Docker Desktop。实际操作中很多人卡在第 2 步勾完功能后不重启电脑Docker 照样报错。一定要先重启再打开 Docker Desktop顺序错了怎么点都是白搭。7.5 常见问题速查表现象可能原因解决方法dnf 安装软件超时未配置镜像加速或网络受限配置 registry-mirrors检查代理容器时间比宿主机晚 8 小时时区未设置安装 tzdata设置 Asia/Shanghaiping 不通公网 IP内核 IP 转发未开启确认 net.ipv4.ip_forward1pull 镜像很慢Docker Hub 默认源不稳定配置公共镜像加速器commit 后镜像体积暴涨缓存未清理构建后执行 dnf clean all静态 IP 不生效使用了默认 bridge 网络必须使用自定义 bridge 网络systemd 容器一直重启缺少 privileged 或 cgroup 挂载添加 --privileged 和 -v /sys/fs/cgroupLibreOffice 转 PDF 中文乱码缺少中文字体安装 cjkuni-uming-fonts7.6 几个容易忽略的细节补充最后补充三个我踩过坑之后才记住的小细节。第一个容器内改 DNS。默认/etc/resolv.conf里是 Docker 内嵌的 127.0.0.11有时候应用不认这个地址需要自定义 DNS。在 Docker run 时直接指定docker run --dns 223.5.5.5 --dns 8.8.8.8 ...第二个基础镜像里尽量别装编译链gcc、make 这类。基础镜像的定位是运行时环境不是构建环境。需要编译的代码应该用多阶段构建构建阶段用带编译器的镜像运行阶段再拷贝产物到 Rocky 基础镜像。第三个镜像 tag 一定要有规律。我推荐格式是rockylinux-base:9.3-日期比如rockylinux-base:9.3-20250601。这样别人看到 tag 就知道是哪天构建的线上用的什么版本也一目了然。我在实际使用中发现Docker 部署 Rocky Linux 最有价值的点不只是“把 RHEL 兼容系统跑在容器里”这件事本身而是它让我能把底层的系统一致性彻底标准化。以前团队里每人一套环境出了 bug 先扯一小时的“我这边是好的”现在直接从统一的基础镜像拉一个容器环境一模一样排障效率高了一个量级。如果你也想在公司内部推进类似的基础镜像平台从 Rocky Linux 入手是个非常稳妥的起点——兼容性有保障社区活跃工具链完善踩坑也有人替你踩过了。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →