资讯动态

Docker部署Rocky Linux:打造企业级基础镜像的完整实践

发布时间:2026/9/15 20:51:01 来源:尧图企业网站定制
做运维这些年容器化落地最难的不是把某一个服务跑起来而是怎么把一套稳定、可控、可复现的系统环境固化下来。我最近把公司内部的基础环境从老旧的 CentOS 迁移到了 Docker 里的 Rocky Linux 镜像上顺带把 RHEL 兼容的软件栈、静态 IP 网络、MySQL、Redis 这些常用组件全部标准化成了可以直接复用的基础镜像。这篇文章就是把整套搭建过程和踩过的坑完整记录下来希望能给同样在折腾的人少走点弯路。Rocky Linux 是什么它是 RHEL 的下游二进制兼容发行版CentOS 停止维护后由社区接力做出来的一个替代方案。对做运维、后端、测试的朋友来说用 Docker 部署 Rocky Linux等于拿到了 RHEL 的稳定性和兼容生态又不用承担商业订阅成本非常适合作为企业级基础镜像平台。这篇文章适合三类人刚入门 Docker、想找一个靠谱基础镜像的正在从 CentOS 做迁移、担心兼容性问题的以及要在团队内部统一基础镜像标准、搞镜像资产管理的人。1. 为什么企业级基础镜像要选 Rocky Linux1.1 RHEL 兼容到底意味着什么企业里谈RHEL 兼容背后往往是一堆存量软件和硬件认证要求。RHEL 是 Red Hat 的商业发行版稳定、安全更新及时但每台机器的订阅费用对很多中小公司来说并不便宜。Rocky Linux 基于 RHEL 的源码重新编译对外表现的 ABI应用二进制接口、内核模块接口、软件包版本都保持了一致。对做镜像平台的人来说这个兼容性的价值非常实在业务方交过来的部署文档、软件包、驱动基本都是按照 RHEL 系列写的遇到问题也完全可以照着 RHEL 的故障处理思路去排查团队不用重新学一套体系知识沉淀和工具链都能直接复用。这比单纯能用更高一级的标准是兼容、稳定、可预期。生产环境最怕的不确定性恰恰是 Rocky Linux 这类重建版发行版最擅长解决的。我在实际迁移中验证过原来 CentOS 7/8 上的 shell 脚本、systemd 服务文件、yum/dnf 源配置在 Rocky Linux 上几乎可以无缝迁移少数需要微调的地方也就是 dnf 和 yum 命令差异这种级别。1.2 Rocky Linux 与 CentOS、AlmaLinux 的取舍CentOS 8 在 2021 年底停止维护之后CentOS Stream 变成了滚动发布模式对要长期稳定的生产环境很不友好。当时市面上能续命的 RHEL 兼容版主要就是 Rocky Linux 和 AlmaLinux两个都是基于 RHEL 源码重建功能层面对我来说差别不大。我最终选 Rocky Linux核心原因是迁移路径最顺——原来 CentOS 7/8 的脚本和文档几乎可以原样沿用社区文档活跃Docker Hub 官方镜像更新也及时。发行版定位稳定性更新策略适用场景RHEL商业发行版极高订阅制版本锁定有合规与商业支持需求Rocky LinuxRHEL 重建版高社区维护小版本滚动替代 CentOS统一基础镜像AlmaLinuxRHEL 重建版高社区维护小版本滚动同上团队习惯可延续CentOS Stream介于 RHEL 与 Fedora中滚动更新开发预演不建议生产这里想多说一句如果你团队已经深度使用了 AlmaLinux没必要因为我的选择强行换两个产品在基础镜像这个层面是一条级别的。关键是别再让生产环境去裸奔 CentOS 8 这种停止维护的版本安全漏洞没人管审计也过不去。1.3 Docker 镜像源与版本选择经常有人问Rocky Linux 8.10 镜像位置在哪其实 Docker Hub 上的官方仓库 rockylinux/rockylinux 就是最优先的来源tag 直接对应大版本和具体小版本比如 8、8.10、9、9.3 这样。我用的是 9.x 系列生命周期长、内核新、软件包全。如果你有老系统必须对齐 RHEL 8 生态那就用 8.10有些厂商只认证到 RHEL 8Rocky 8 能帮你避开兼容性坑。版本定了之后拉取很简单docker pull rockylinux/rockylinux:9.3。注意我建议优先用官方仓库坊间还有不少第三方的 Rocky 变体镜像来源不明的镜像有供应链风险在企业环境里这是大忌。基础镜像一旦确定后面所有人的构建都从这同一个源出发供应链的安全性才可控。2. 用 Docker 拉起一个可用的 Rocky Linux 环境2.1 镜像拉取与基础启动装好 Docker 之后的第一步很简单拉镜像、进容器docker pull rockylinux/rockylinux:9.3 docker run -it --name rocky-dev rockylinux/rockylinux:9.3 /bin/bash进去之后先验证系统信息cat /etc/redhat-release cat /etc/os-release你会看到 Rocky Linux 9.3 的版本信息这种开箱即 RHEL的体验就是兼容版发行版的好处。这里有个特别重要的认知要提前说Docker 官方这套基础镜像默认没有 systemdPID 1 是你自己指定的命令所以在容器里直接执行systemctl start xxx是会报错的。很多刚上手的朋友在这里被卡住其实解决方式取决于你的目的。如果只是跑应用Java、Python、Nginx 这一类完全不需要 systemd让应用自己当 PID 1 反而是更规范的容器化做法。如果非得要 systemd比如要装图形环境或者一些强依赖系统服务的软件那就需要用特权模式启动/sbin/init这个我在第 4 章会详细说。顺带提一句 Ubuntu 上装 Docker 的快速方式因为很多人本地测试机是 Ubuntu 的sudo apt update sudo apt install -y docker.io docker-compose-v2 sudo systemctl enable --now docker docker --versionUbuntu 自带的 docker.io 包够用但如果你要 Docker Desktop 的图形界面和插件支持还是去官网下载 deb 包安装更舒服。2.2 容器内系统初始化实践进入容器后我习惯先把系统更新一遍把常见工具装齐dnf -y update dnf install -y vim wget curl tar unzip iproute net-tools dnf-utils如果你在国内yum/dnf 源建议换成本地镜像站速度快很多。做法是把/etc/yum.repos.d/下的 Rocky 源 URL 替换成对应镜像站地址注意 9.x 的官方源路径里会有$releasever这样的变量替换时保留变量即可。源配好后一定要执行dnf clean all dnf makecache否则可能因为缓存了旧元数据导致安装报错。然后设置时区、创建普通用户ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime dnf install -y sudo useradd -m -G wheel deploy echo deploy ALL(ALL) NOPASSWD: ALL /etc/sudoers.d/deploy为什么不直接在 root 下干活企业环境里基础镜像最后是要给很多人共用的留一个普通用户强制走 sudo审计日志才完整。当然如果你只是自己本地调试root 也完全没问题。这里还要记住一个容器特性/etc/hosts和/etc/resolv.conf是 Docker 启动时自动生成的你就算在容器里改了重启之后也会被覆盖。正确做法是在docker run时用--add-host和--dns参数或者走自定义网络配置。2.3 静态 IP 与容器网络的配置思路Rocky Linux 设置静态 IP是个搜索热度很高的词但很多人其实是走错了方向。在容器里改/etc/sysconfig/network-scripts/ifcfg-eth0是没有意义的因为 Docker 容器默认是动态分配 IP重启就变。想要固定 IP正路是下面这几种方法一自定义 bridge 网络 指定 IP。先创建网络再在启动时指定 IPdocker network create --subnet172.20.0.0/16 rocky-net docker run -it --network rocky-net --ip 172.20.0.10 rockylinux/rockylinux:9.3 /bin/bashdocket-compose 里对应这样写services: rocky-app: image: my-rocky-app:latest networks: rocky-net: ipv4_address: 172.20.0.10方法二macvlan 网络。想让容器直接出现在局域网里、可以被其他物理机器直接访问就用 macvlan容器会拥有一个和宿主机同网段的独立 IPdocker network create -d macvlan \ --subnet192.168.1.0/24 \ --gateway192.168.1.1 \ -o parenteth0 macvlan-net docker run --network macvlan-net --ip 192.168.1.80 ...macvlan 的一个坑是宿主机和容器间默认不通这由 macvlan 本身的工作机制决定因为宿主机网卡被虚拟了多个 MAC 后内核会过滤掉发往虚拟 MAC 的帧。需要宿主机访问容器时一般再加一个 bridge 网卡或者用 veth pair或者干脆换 host 网络。生产上很多网络管控严格的场景我反而更推荐 macvlan因为容器 IP 是真实局域网 IP监控、防火墙策略、IP 管理都能走公司现有的那套体系。方法三host 网络。docker run --network host会让容器共享宿主机网络栈没有独立 IP但性能最好适合对网络延迟敏感的服务代价是你不能再用-p做端口映射端口直接由容器进程bind容易跟宿主机已有服务冲突。我的经验是内部微服务之间通信首选自定义 bridge 网络追求性能选 host需要局域网直连选 macvlan。进入容器后建议用ip addr而不是ifconfig来查看网络信息因为 iproute 在最小化镜像里就带着net-tools 反而不一定有。3. 从基础镜像到企业级应用镜像3.1 基础镜像定制EPEL、常用软件、时区与源不要每次起一个容器临时安装软件而是要把环境固化到一个 Dockerfile 里。我放一个生产可用的基础镜像模板FROM rockylinux/rockylinux:9.3 ENV TZAsia/Shanghai \ LANGen_US.UTF-8 RUN dnf -y update \ dnf -y install epel-release \ dnf -y install \ vim wget curl tar unzip \ iproute net-tools dnf-utils \ sudo ntpdate cronie \ fontconfig \ dnf clean all \ ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime RUN useradd -m -G wheel deploy \ echo deploy ALL(ALL) NOPASSWD: ALL /etc/sudoers.d/deploy WORKDIR /data CMD [/bin/bash]构建命令也比较直白docker build -t my-rocky-base:9.3.20250101 .这里一个经验tag 后面带日期比如my-rocky-base:9.3.20250101方便回滚和追踪。别总是覆盖构建latest团队里一旦有人拉错 tag生产环境就是事故现场。再补充几个构建优化技巧dnf clean all一定要放在同一个 RUN 指令末尾这是为了减少镜像层体积缓存清理不会形成多余层。可以在dnf install参数里加--setopttsflagsnodocs跳过安装文档文件能省几十 MB。项目目录下加.dockerignore别把本地的日志、node_modules、*.pyc之类的东西打进构建上下文。3.2 在 Rocky Linux 容器中安装 LibreOffice 之类的重应用很多人觉得基础镜像干净就足够了但企业里经常有文档转换、报表渲染这类需求需要在 Rocky Linux 容器里安装 LibreOffice 这种比较重的桌面级软件。我在实际项目里就干过这事用 LibreOffice 7.4.7.2 的 Linux x86-64 rpm 包来做无头headless文档转换服务。先把 rpm 包下载解压dnf install -y libXinerama libXext cups-libs fontconfig xdg-utils wget https://download.documentfoundation.org/libreoffice/stable/7.4.7.2/.../LibreOffice_7.4.7.2_Linux_x86-64_rpm.tar.gz tar -xzf LibreOffice_7.4.7.2_Linux_x86-64_rpm.tar.gz cd LibreOffice_7.4.7.2_Linux_x86-64_rpm/RPMS rpm -ivh *.rpm踩过的坑主要是缺依赖在最小化 Rockylinux 镜像里libXinerama、libXext、fontconfig这些库默认不一定有装 rpm 的时候会报一堆 libXinerama.so.1 is needed 之类的错误所以先把基础依赖装齐再装 LibreOffice。另外在容器环境里它没法跑图形界面但无头转换完全用不到 GUI写代码时直接用soffice的命令行模式就行soffice --headless --convert-to pdf --outdir /data /data/test.docx中文文档转换乱码是另一个高频问题解决方法是装中文字体并刷新字体缓存dnf install -y wqy-zenhei-fonts fc-cache -f装完之后把这条转换链路写进 Dockerfile做成一个独立的doc-convert服务镜像。这样业务方只需要调用容器里的 HTTTP 接口或者命令行不用关心底层环境这才是基础镜像平台该有的样子——把环境彻底沉淀下来交付给任何团队都是同样的行为。3.3 构建 MySQL 8.0、Redis 主从等常用镜像组合如果是快速跑服务直接用官方mysql:8.0、redis:7镜像是最省事的。但要搭一个统一的镜像平台我建议做两件事数据库和缓存组件可以先用官方镜像业务基础镜像用 Rocky Linux然后在一个自定义网络里把它们编排起来如果你有严格的合规要求也可以把这些组件都封装到 Rocky 基础镜像里统一安全基线和补丁节奏但维护成本会高一些看团队资源取舍。这里给一个 docker-compose 的参考模拟企业内部常见的 MySQL Redis 主从 业务容器组合services: mysql: image: mysql:8.0 container_name: rocky-mysql environment: MYSQL_ROOT_PASSWORD: WeakPassword MYSQL_DATABASE: appdb ports: - 3306:3306 volumes: - mysql-data:/var/lib/mysql networks: rocky-net: ipv4_address: 172.20.0.11 redis-master: image: redis:7 container_name: rocky-redis-master command: [redis-server, --appendonly, yes] ports: - 6379:6379 networks: rocky-net: ipv4_address: 172.20.0.12 redis-slave: image: redis:7 container_name: rocky-redis-slave command: [redis-server, --replicaof, 172.20.0.12, 6379] depends_on: - redis-master networks: rocky-net: ipv4_address: 172.20.0.13 app: build: . container_name: rocky-app depends_on: - mysql - redis-master networks: rocky-net: ipv4_address: 172.20.0.14 volumes: mysql-data: networks: rocky-net: external: true注意networks用的是第 2.3 节里建好的rocky-net外部网络。这样编排的好处是整个环境内部通过固定 IP 互通不依赖域名解析而且外部只暴露真正需要的端口3306、6379。Redis 主从验证也很简单docker exec -it rocky-redis-master redis-cli set site rocky docker exec -it rocky-redis-slave redis-cli get site能从从节点读到rocky说明主从同步正常。这个组合本身不难难的是把它当成平台的一部分去管理镜像 tag 统一命名、每次构建都要做漏洞扫描、关键组件版本锁定这些才是企业级镜像平台和自己玩玩 Docker之间的本质区别。4. 常见问题与排查技巧实录4.1 Docker Desktop 启动失败与虚拟化支持问题Windows 上遇到 Virtualization support not detected是 Docker Desktop 最常见的启动坑。报错全称类似 Docker Desktop failed to start because virtualization support is not enabled on your system。这通常是三个层面的问题。第一系统功能没开启。在 Windows 10/11 里运行dism.exe /Online /Enable-Feature /FeatureName:Microsoft-Hyper-V /All dism.exe /Online /Enable-Feature /FeatureName:VirtualMachinePlatform /All dism.exe /Online /Enable-Feature /FeatureName:Microsoft-Windows-Subsystem-Linux /All然后重启。Windows 11 家庭版也可以用 WSL2 跑 Docker Desktop不一定需要完整 Hyper-V但 VirtualMachinePlatform 必须开。第二BIOS 里虚拟化被禁了。开机进 BIOS/UEFI确认 Intel VT-x 或 AMD SVM 是开启状态。在 Windows 里可以用systeminfo命令看最后面的 Hyper-V 要求那一节如果显示虚拟化已启用说明 BIOS 没问题。第三软件冲突。机器上装了 VMware 或 VirtualBox 的话Hyper-V/WSL2 和它们存在权限冲突一种方案是彻底卸载第三方虚拟机软件另一种是改用 WSL2 后端而非 Hyper-V 后端具体情况取决于 Docker Desktop 的版本。再补一个隐蔽的坑Windows 的安全中心里内核隔离-内存完整性开启时VirtualMachinePlatform 可能无法正常启动。如果上面几步都做了还是失败去Windows 安全中心-设备安全性-内核隔离里关掉内存完整性再重启试试。我自己在几台 Windows 机器上排查过这个设置导致的启动失败比例不低。4.2 容器内 systemd 无法启动问题在默认的 Rocky Linux 容器里执行systemctl start httpd大概率看到这样的错误Failed to connect to bus: No such file or directory原因就是容器 PID 1 不是 systemd。解决方法有两条路。第一条路不需要 systemd 的应用直接把启动命令放在docker run或CMD里用脚本或者二进制作为 PID 1这是最推荐的做法。第二条路确实需要 systemd 来托管服务那就用特权模式启动 initdocker run -d --name rocky-sys \ --privileged \ -v /sys/fs/cgroup:/sys/fs/cgroup:rw \ rockylinux/rockylinux:8.10 \ /sbin/init然后docker exec -it rocky-sys bash在里面就能正常用 systemctl 了。要特别提醒的是--privileged会放开容器所有权限不建议在严格安全的环境里滥用。如果你只是想让 systemctl 能查询服务状态还有一个折中方案systemctl --no-pager status配合容器启动时传入--init之类的工具但归根结底还是得想清楚你到底要不要 systemd。4.3 网络与端口映射问题容器网络问题的排查路径我一般这么做第一先确认端口映射是否生效docker port container。第二检查宿主机端口是否被占用ss -lntp | grep 3306这个命令在宿主机上跑。第三外部访问不通但容器内部正常时绝大多数是宿主机防火墙没放行对应端口放行即可。第四容器能访问外网但 DNS 解析很慢优先检查/etc/resolv.conf如果是 Docker 默认分配的 127.0.0.11可以尝试用--dns 223.5.5.5这类公共 DNS 覆盖注意别把改公共 DNS和网络代理混为一谈容器内直接改 DNS 是最稳定的做法。第五如果docker network connect报 address already in use说明 IP 被占用了用docker network inspect rocky-net查看已分配地址。还有一个特别容易被忽略的问题自定义 bridge 网络的每个网段都有一个--subnet和--gateway容器默认能通过172.20.0.1访问宿主机但宿主机未必能直接访问容器除非做了端口映射。所以排错的时候先分清楚是容器到宿主机不通还是宿主机到容器不通别一上来就乱试。4.4 镜像瘦身与磁盘占用经验镜像越堆越多是必然的关键是定期打理。先看磁盘占用大头docker system df这个命令会展示镜像、容器、卷、构建缓存的占用情况。日常维护三件套docker image prune清理悬空镜像dangling images可加-a清理所有未被容器使用的镜像但我建议至少保留最近几个版本的 tag。docker system prune -a --volumes全量清理连没用的数据卷一起删。这个命令在生产环境要非常谨慎--volumes会把所有未被容器挂载的卷删掉如果有重要的本地数据卷没挂载到运行中的容器会直接丢数据。基础镜像构建时用多阶段构建或dnf clean all别把编译工具链留在运行镜像里。我个人的经验是镜像瘦身别过度安全基线扫描和可追溯性比省那几百 MB 更重要。最痛苦的不是磁盘占用而是镜像包越来越大导致部署拉取变慢。所以我会在构建流水线里加一个docker history image检查让负责构建的人每次都能看到每一层的大小变化及时发现某个 RUN 步骤偷偷装了一堆没用东西的情况。最后再分享一个我自己感受挺深的点。做这套 Rocky Linux 镜像平台最花时间的不是跑起来而是把 systemd、静态 IP、软件源、组件编排这些看起来小事的细节理顺。前期多花点时间把基础镜像的 Dockerfile、网络规划和命名规范定好后面业务团队拿去用的时候就非常省心。我的建议是先在小范围试跑一个业务镜像走通整个流程再逐步推广到全团队。如果遇到问题也欢迎照着我这篇文章的排查思路过一遍大概率能解决大部分常见坑。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价