CentOS部署Docker完整指南:安装、镜像加速与生产实践

发布时间:2026/9/30 8:05:09
CentOS部署Docker完整指南:安装、镜像加速与生产实践 2026年1月我还在给一批CentOS 7.9的存量机器部署Docker。按理说CentOS Linux 7已经停止维护好一阵子了可真实生产环境里就是有大量老系统在跑也还有不少新项目因为“跟现有环境保持一致”继续用7.x。这半年帮人装Docker、修Docker、排查Docker踩过的坑比过去三四年加起来都多。这篇就按我自己的实操顺序把CentOS上从选型、安装、配置镜像加速、跑常用容器到网络排查、磁盘扩容、系统备份的完整过程都梳理一遍。内容不一定多高深但都是可以直接照抄的适合正在给虚拟机或物理机装Docker、准备跑MySQL/Redis/GitLab这类常用服务的同学。1. 动手前先选型2026年到底该装哪一套CentOS1.1 版本选择存量7.9、稳定8 Stream还是直接换Rocky Linux很多人上来就问“CentOS怎么下载”其实真正该先想的是“你到底需要哪个CentOS”。现在官方下载页面能拿到的版本很清楚了CentOS 7.92009是最后一个7.x小版本属于生命周期已经结束的存量系统镜像站里还能下载但装完必须马上换归档源否则yum直接报404CentOS Stream是另一个分支8/9/10都已经发布Stream 10就是滚动更新的前沿版本适合想长期追新、喜欢RHEL系但又愿意冒险的用户。我个人的建议分三种情况。新装机、公司没有历史包袱的直接用Rocky Linux或AlmaLinux它们和CentOS二进制兼容装Docker的方式几乎一样如果必须装原版CentOS优先选Stream 9或Stream 10只有一种情况建议老老实实用7.9那就是手头的老应用只敢在CentOS 7上跑、又没法快速迁移。网上总能看到“ubuntu和centos的区别”这类对比简单说就是包管理不同、软件版本策略不同。Ubuntu用apt软件包新CentOS用yum/dnf软件包老但稳定。装Docker这件事两边都支持只是源路径和服务名略有差异后面我会提到Ubuntu用户要注意什么。1.2 软件源先换成国内源装完系统第一件事就是这个无论你装的是7.9、8还是Stream第一件事永远是换yum源。CentOS 7的仓库已经进了vault归档默认源早就失效了CentOS 8更是老早停更Stream版本如果不换源访问境外repo慢到你怀疑人生。清华源和阿里云源都保留着完整镜像我习惯用清华源。操作很简单先备份原始repo文件mkdir -p /etc/yum.repos.d/backup cp /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/CentOS 7以前是直接覆盖CentOS-Base.repo8及Stream版本现在是AppStream和BaseOS两个源。最稳妥的办法是打开清华镜像站帮助页找到和你系统对应的repo文件下载替换。如果用sed暴力替换就只改mirrorlist和baseurlsed -i s|^mirrorlist|#mirrorlist|g; s|^#baseurlhttp://mirror.centos.org|baseurlhttps://mirrors.tuna.tsinghua.edu.cn|g /etc/yum.repos.d/CentOS-*.repo替换完执行yum makecache缓存索引。如果你还要装EPEL同样把epel.repo里的baseurl指到国内镜像否则后面yum安装一些依赖包时还是会卡住。“CentOS Stream 10如何换成清华源”这类问题核心思路就是给BaseOS、AppStream、Extras三个repo各准备一份对应的清华源地址不要混用。2. 一条龙安装Docker CE内核参数与启动配置2.1 安装前要装好的基础依赖很多人以为装Docker就是yum install docker其实那个是系统自带的旧版容器引擎Podman时代的遗留我们要装的是Docker官方源里的docker-ce。首先装几个基础包yum install -y yum-utils device-mapper-persistent-data lvm2yum-utils后面要用它执行yum-config-managerdevice-mapper-persistent-data和lvm2是存储驱动需要的。Docker在CentOS上默认用overlay2存储驱动但底层还是依赖device mapper相关的工具包不装的话可能在某些内核组合下初始化失败。接着添加Docker的yum源。官方源在国内访问不稳定建议直接用清华源镜像的docker-ce仓库yum-config-manager --add-repo https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo yum makecache如果你的网络环境连清华源都慢阿里云也提供了同样的docker-ce源替换域名即可。这里有个细节docker-ce.repo文件里写了多个版本的baseurlyum会按照系统版本自动选择对应的7/8/9目录所以同一套命令在CentOS 7和Stream上都能用。2.2 内核与系统参数准备Docker跑起来其实很依赖内核模块和网络参数绝大多数“docker网络不通”的问题都跟这里没配好有关。先加载两个模块modprobe overlay modprobe br_netfilter然后写入sysctl配置让iptables能正确处理bridge网络的数据包cat /etc/sysctl.d/docker.conf EOF net.bridge.bridge-nf-call-ip6tables 1 net.bridge.bridge-nf-call-iptables 1 net.ipv4.ip_forward 1 EOF sysctl --systemnet.ipv4.ip_forward尤其重要容器访问外网、端口映射都依赖它。你要是发现容器能启动但出不去外网第一个看的就应该是这个值。把配置放到/etc/sysctl.d下重启后也会自动加载不用每次手动sysctl -w。2.3 安装、启动、自启动与验证源配好之后装包就很快了yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugindocker-compose-plugin是Compose v2插件现在官方推荐直接把compose当插件用别再去装python的docker-compose了。装完启动systemctl enable --now dockerenable和--now一起用既启动又设置开机自启。验证是否正常docker version docker info新手喜欢马上docker run hello-world这一步其实很容易劝退人因为要pull镜像如果还没配镜像加速大概率卡在TLS握手。所以我建议把第3章的镜像加速配好了再验证。如果确实想先试就直接用docker run --rm hello-world失败也不要慌看错误消息是网络还是其他问题。启动docker失败的情况我也见过不少最常见的是老系统里装了旧版docker或podman导致containerd冲突。先执行systemctl status docker看状态再用journalctl -xe看systemd日志基本能定位到80%的问题。如果提示是socket权限把自己的用户加到docker组里usermod -aG docker $USER然后重新登录。3. registry mirror与常用软件落盘3.1 daemon.json里到底该填什么镜像加速这个事原理是给Docker配置registry mirror相当于给Docker Hub套了一层缓存拉官方镜像时走的是国内节点。我需要提醒一句网上流传的很多加速地址已经失效或时灵时不灵别直接抄配完必须实测。修改/etc/docker/daemon.json{ registry-mirrors: [ https://你的加速地址 ] }然后systemctl restart docker再用docker info查看Registry Mirrors一栏是否生效最后跑一个docker pull nginx:alpine验证速度。如果拉取还是超时换一个加速地址再试。这里有个json格式的细节写错一个逗号docker直接启动失败。改完先执行docker info看报错或者dockerd --validate检查配置。另外提醒一句不要把“镜像加速”和别的概念混在一起它就是拉取公开镜像的分发优化和系统本身能否访问外网无关。3.2 实战MySQL 8.0、Redis主从、GitLab CE跑MySQL 8.0是最常见的需求。我一般会把数据目录挂载到宿主机方便备份和升级mkdir -p /data/mysql docker run -d --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDYourStrongPass \ -v /data/mysql:/var/lib/mysql \ mysql:8.0 \ --character-set-serverutf8mb4 \ --collation-serverutf8mb4_unicode_ci启动后连接验证docker exec -it mysql8 mysql -uroot -p这里最容易踩的坑是权限。MySQL容器内部以mysql用户运行uid通常是999如果/data/mysql的属主不对或者SELinux是Enforcing容器会反复重启。看docker logs mysql8会提示[ERROR] InnoDB Operating system error number 13这类权限错误。解决方式是调整目录属主chown -R 999:999 /data/mysql或者临时setenforce 0测试确认是SELinux再针对性配置。Redis主从部署要注意现在的redis官方镜像默认是Redis 7.x主从配置参数已经从slaveof改成了replicaof网上很多老教程还在用slaveof会直接报错。先建一个自定义网络docker network create redis-cluster-net docker run -d --name redis-master \ --network redis-cluster-net \ -p 6379:6379 \ redis:7 \ redis-server --appendonly yes docker run -d --name redis-slave \ --network redis-cluster-net \ -p 6380:6379 \ redis:7 \ redis-server --replicaof redis-master 6379为什么用自定义网络而不是默认bridge因为在同一个自定义网络里容器之间可以直接用容器名解析IP这是Docker内置DNS的功劳。主从验证docker exec -it redis-slave redis-cli info replication看到role:slave、master_link_status:up就算成功了。GitLab社区版用docker部署是标准操作但要注意它比较吃内存建议4G以上。启动命令网上到处都是我用的是export GITLAB_HOME/srv/gitlab docker run -d --name gitlab \ --hostname gitlab.example.com \ -p 80:80 -p 443:443 -p 22:22 \ -v $GITLAB_HOME/config:/etc/gitlab \ -v $GITLAB_HOME/logs:/var/log/gitlab \ -v $GITLAB_HOME/data:/var/opt/gitlab \ --restart always \ gitlab/gitlab-ce:latest首次启动要跑很久可能五六分钟都没有反应这是正常的别急着重启容器。看进度用docker logs -f gitlab。还有8080端口问题早期版本的GitLab镜像会用8080新版本默认已经不占用但如果你本机有Java应用监听8080还是要注意。3.3 复杂工具链的一个思路Node.js、Chromium、MediaMTX与青龙除了常规数据库很多人问CentOS 7上装Node.js、Chromium这类东西怎么老失败。核心思路就是别在裸机上一股脑装用容器隔离依赖冲突。CentOS 7自带的glibc版本旧直接装新版Chromium基本不可能而官方Chromium镜像或Playwright镜像自带运行环境一条命令拉起docker run -d --name playwright -v /tmp/browser:/tmp/browser mcr.microsoft.com/playwright:v1.50.0Node.js同理挂载代码目录进去跑docker run -it --rm -v $(pwd):/app -w /app node:20 sh免去自己在CentOS 7上源码编译node的折磨。而且容器里的依赖和宿主机完全隔离删容器就是清环境重装成本极低。流媒体服务比如MediaMTX官方也提供了镜像跑RTSP转发非常省事docker run --rm -it -p 8554:8554 bluenviron/mediamtx:latest这类“工具型容器”的使用要点是配置文件和持久化数据一定挂载到宿主机否则容器删掉什么都丢了。还有一些管理面板镜像比如青龙这类带依赖管理功能的在容器里装Python或Node依赖时要养成把依赖列表写进requirements.txt/package.json的习惯而不是启动后手动install。因为容器重建后手动装的全没了但清单文件还在启动脚本里跑一遍install就能恢复。Hadoop这类重型分布式框架也一样网上找的hadoop镜像很多但真要搭三四个节点的环境用手工docker run会疯掉建议直接写docker-compose.yml编排。4. Docker网络不通与常见失败现场排查4.1 网络不通的5个可能每次有个哥们儿跟我说“我容器启动了但访问不了”我的排查顺序基本固定照着走就行。先看容器状态和IPdocker ps -a docker inspect 容器名 | grep -A 5 NetworkSettings docker network ls如果是容器之间不通确认是不是在同一个自定义网络里同一个bridge网络内默认互通跨网络隔离是正常的。如果是容器访问外网不通本机执行sysctl net.ipv4.ip_forward如果输出是0网络肯定不通。另外检查防火墙firewall-cmd --list-all iptables -t nat -L -n | grep -i docker宿主机firewalld如果阻断FORWARD链容器出外网也会失败。这里有个常见坑有人为了“清干净”执行iptables -F把Docker加的规则全删了结果所有容器网络立刻瘫痪重启docker也不一定恢复最干净的办法是把iptables清空后直接重启docker服务让它重建规则。如果你用的CentOS 7默认防火墙玩不明白建议在看网络问题时先systemctl stop firewalld测试确认是防火墙问题再决定放行规则而不是一刀切关闭。还有一种情况是容器里DNS解析失败尤其自建DNS或公司内网环境。可以启动时手动指定DNSdocker run -d --dns 223.5.5.5 --dns 8.8.8.8 nginx:alpine窗口排查表格我放在第7章。4.2 MySQL/GitLab安装失败的常见原因说几个反复出现的问题。MySQL容器反复重启查看日志docker logs mysql8 --tail 100最常见的错误要么是权限errno 13要么是端口被宿主机占用。用ss -tlnp | grep 3306确认端口状态。还有一种情况是之前跑过同名容器旧容器没删干净docker run直接报Conflict先docker rm再跑。GitLab起不来十有八九是内存不够SSH到机器执行free -h如果可用内存低于2GGitLab大概率OOM被杀。查看dmesg | tail能看到oom-killer的记录。小内存机器跑GitLab建议增加swap或者干脆换Gitea这种轻量实现。容器启动成功但服务连不上先确认端口映射是否正确。docker port 容器名会显示映射关系再用curl -v从宿主机测端口。如果只有容器内能连、宿主机连不上检查防火墙规则别急着找Docker的问题。4.3 Windows Docker Desktop的报错与汉化包问题虽然这篇讲的是CentOS但提问区总有一堆Windows玩家。virtualization support not detected、failed to connect to the docker api at npipe这两个报错一个意思Docker Desktop的后端没起来。先检查BIOS里虚拟化有没有开再确认Windows功能里的Hyper-V和适用于Linux的Windows子系统WSL2已启用。启用了还报错就把Docker Desktop彻底退出重启Windows服务里的com.docker.service再不行卸载重装Docker Desktop。还有一个很值得提醒的事现在网上流行Docker Desktop汉化包比如asxez/dockerdesktop-cn这类第三方修改包。我明确不建议在生产或开发主力机上用这种东西。Docker Desktop涉及系统级权限第三方汉化包本质上是被二次打包的二进制你无法确认它有没有塞私货。界面英文就那几个按钮为了省这点功夫冒供应链风险不值当。如果需要中文资料直接看官方文档和社区教程就好。5. 存储扩容、系统备份与容器数据安全5.1 CentOS根分区扩容实操Docker跑久了镜像、容器日志、数据卷会把磁盘撑爆尤其默认装系统时只分了50G根分区的虚拟机一个月就满了。扩容流程分两步先扩LVM再扩容文件系统。df -h lsblk如果根分区是/dev/mapper/cl-root且所在卷组还有空闲空间直接扩lvextend -l 100%FREE /dev/mapper/cl-root文件系统扩容命令要看类型。xfs_growfs /dev/mapper/cl-root对应XFSCentOS 7默认resize2fs /dev/mapper/cl-root对应ext4。用错命令会直接报错。执行完df -h验证。我的建议是既然你已经准备部署Docker最好把/var/lib/docker单独放一个分区或独立数据盘避免和系统根分区抢空间。也可以在daemon.json里改data-root{ data-root: /data/docker }改完重启docker但注意这相当于挪容器根目录已存在的容器不会自动迁移我一般是在部署之初就规划好。5.2 用Clonezilla备份CentOS系统整机备份这件事很多人忽略等到系统搞坏了才追悔。Clonezilla是一个开源克隆工具用法不算复杂准备一个Clonezilla Live镜像启动盘开机从U盘引导选择“保存分区镜像”把包含CentOS的整个分区保存成镜像文件放到另一块磁盘或网络共享里。恢复的时候再引导进Clonezilla选“恢复分区镜像”即可。这套方案特别适合“先装好干净系统、确认没问题、再装Docker”的工作流。我的习惯是新装的CentOS升级完系统、改好源、装好基础工具先做一次干净镜像然后装完Docker和常用容器再做一次带Docker的镜像。出了问题不用从头装系统整个回滚只需要十几分钟。给虚拟机装CentOS系统也一样虚拟机快照不保险快照文件损坏就连坐Clonezilla镜像更稳。5.3 容器的两种备份习惯Docker里面的数据我始终坚持一个原则一切持久化数据都要落到宿主机挂载目录。MySQL数据目录、GitLab的/srv/gitlab全都挂载出来。然后备份就分两层。第一层是逻辑备份MySQL用mysqldump定时导出SQLGitLab官方自带backup任务这些能恢复到任意时间点。第二层是文件级备份把挂载目录整体打tar例如tar czvf /backup/mysql_data_$(date %F).tar.gz /data/mysql镜像本身不用备份反正都能pull真正有价值的是数据和你写的compose配置文件。如果是离线环境或私有大版本镜像就搭一个私有仓库。跑一个registry容器就能做基础镜像仓库docker run -d --name registry -p 5000:5000 -v /data/registry:/var/lib/registry registry:2然后给镜像打tag推送上去。镜像多了、团队用起来之后再考虑Harbor这类带Web UI和权限控制的方案。私有仓库还有一个好处生产环境拉镜像不会受外部网络波动影响配合registry mirror双保险。6. 系统维护SSH升级、开机自启与自动化6.1 OpenSSH升级的两个路线CentOS 7自带OpenSSH版本偏老安全扫描总提示漏洞所以“CentOS 7升级OpenSSH”是高频需求。路线无非两条。一条是yum直接升级如果你的源里有新版本OpenSSH直接yum update openssh-server openssh-clients这是最安全的路径。但CentOS 7官方源里的OpenSSH版本一般停留在7.4很多人不满意。另一条是源码编译升级流程长且风险高有一个非常大的坑编译安装或配置错误后sshd起不来你又通过SSH远程操作会话一旦断开就直接失联。我的建议是升级前必须先把当前sshd_config完整备份确认你还保留着带外管理手段比如物理终端、IPMI、云控制台VNC至少要有两条通道否则别碰。还有个小技巧升级后先别重启sshd先执行sshd -t检查配置没问题再重启。顺带说一句无论升不升级SSH安全配置都要做关闭密码登录、使用密钥认证、禁止root直接登录。除非你清楚自己在做什么否则别为了省事全开。6.2 让服务开机自动拉起我在生产环境用三种方式保证服务自动恢复。第一种Docker服务本身开机自启前面systemctl enable --now docker已经做了。第二种单个容器开机自启用restart策略创建容器时加--restart always。这个策略不仅能开机启动还能在容器崩溃后自动拉起我所有生产容器都带这个参数。第三种系统层面的杂项服务用systemd unit或crontab。比如经常有人问“CentOS里Oracle怎么自动启动”Oracle如果装在宿主机里我习惯写一个启动脚本然后放到crontabreboot /usr/local/bin/oracle_startup.sh /var/log/oracle_boot.log 21如果Oracle跑在Docker容器里那restart策略就够了。systemd unit其实更优雅但对新手来说crontab reboot更直观缺点是没有依赖管理系统网络没起来就可能启动失败所以脚本里要加sleep和状态判断。6.3 常用小命令与人性化配置最后分享几个日常维护用得最多的命令。看资源占用docker stats实时看容器CPU内存。看磁盘占用docker system df会列出镜像、容器、数据卷分别占多少。清理垃圾docker system prune会删掉停止的容器、悬空的镜像、无用的网络但要注意它会问你确认加-a会连没有标签的镜像一起删磁盘紧张时很有用但别在生产环境乱删删完没法恢复。容器日志清理也是一个坑默认json-file日志文件会无限增长一定要在daemon.json里加上{ log-driver: json-file, log-opts: { max-size: 20m, max-file: 3 } }不然日志文件占用可能比镜像还大。还有一个很常见的虚拟机问题“CentOS主机内容不能复制到虚拟机里面”。VMware就装open-vm-toolsVirtualBox就装virtualbox-guest-additions。CentOS 7里执行yum install -y open-vm-tools装完重启或重新登录就能共享剪贴板了。别去手动挂载什么VMware Tools ISO那是老黄历。7. 常见问题速查表与个人总结7.1 问题速查表现象常见原因快速处理Ubuntu换成CentOS后命令不会用apt与yum/dnf语法不同记住updateinstall的差异服务管理都用systemctlcentos主机内容不能复制到虚拟机缺少VM Tools装open-vm-tools或VirtualBox增强包CentOS 7装EDA工具Innovus失败缺X11运行库和基础组件yum groupinstall X Window System用ldd定位缺哪个soCentOS 7装Oracle 21c失败内核参数不满足、swap不足建议用Oracle Linux或调kernel.sem等参数容器里跑要单独评估docker启动失败旧版docker/podman冲突或配置错误systemctl status dockerjournalctl -xe看日志docker拉取镜像超时未配镜像加速或加速地址失效配置可用的registry mirror后重启dockerdocker安装MySQL失败端口占用、数据目录权限、SELinux查docker logsss看端口chown数据目录docker网络不通ip_forward未开、防火墙阻断、跨网络sysctl检查、iptables -L检查、确保同自定义网络Windows下Docker Desktop报Virtualization support not detectedBIOS虚拟化未开或WSL2未启用开BIOS VT-x启用Hyper-V/WSL2Docker Desktop报failed to connect to npipe后端服务未启动完全退出重开必要时重启com.docker.serviceDocker Desktop需要中文想用汉化包不建议用第三方汉化安全风险不值当这里面有个共性遇到任何“容器跑不了”的问题第一反应不应该是删了重来而是docker logs 容器名 --tail 50。日志会告诉你90%的真相。7.2 我的几条实战心得第一个心得系统的初始状态必须记录。我会在装完系统、装完Docker后立刻执行uname -a、docker version把内核版本、Docker版本、repo源信息写进/root/deploy-notes.md。半年后系统出问题这份笔记能帮你快速判断是升级引入的还是历史遗留的。这个方法我看没几个人用但真的救命。第二个心得不要在运行中的容器里修东西。容器出了问题第一反应是看日志第二反应是重新创建容器而不是进容器里面改文件。容器设计就是不可变的你在容器内做的任何修改都会在重建后消失。所以要我总结的话Docker用得好的标准就一条你能不能做到几分钟内从配置文件重建整个环境。第三个心得网络排查要用“最简验证”法。容器内curl不通先用docker run --rm --network host curlimages/curl http://www.example.com验证宿主机网络再逐步缩小范围。不要一上来就翻防火墙配置那里面很容易看花眼。第四个心得旧系统上跑新容器镜像版本一定要固定。mysql:8.0这种大版本标签看起来稳但实际会跟随小版本更新生产环境差异往往就在这种“看不见的更新”里。我的习惯是写死具体tag比如mysql:8.0.36这样每次部署结果才可复现。最后再说个操作习惯我每次部署完容器都会顺手执行一遍docker ps --format table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}把当前所有容器状态导出来看一眼确认没有容器处于Exited状态。如果你打算把这批CentOS机器用上三五年花十分钟把初始状态记下来、把备份策略定下来真的比什么都值。部署完Docker只是开始后面维护的路长着呢先把底子打好后面才能少熬夜。