看到不少朋友在CentOS7上装Docker时,经常卡在“命令报错”这一步——要么yum源没配好,要么内核版本不对,要么装完发现启动不了。CentOS7算是很经典的服务器系统了,Docker的安装命令其实不复杂,但很多教程只给几行命令,不解释为什么要这么做,导致环境一变就翻车。这篇就把CentOS7安装docker命令的完整流程、背后的原理、实际踩过的坑一次性讲清楚,从环境检查到镜像加速,再到MySQL、Redis这类常用部署,尽量让新手也能照着敲完不出错。
这套流程适合谁呢?刚接触Linux服务器的小白、需要在CentOS7上快速搭Docker环境的运维同学,以及后端开发要本地或测试环境跑容器化应用的朋友。我会把每一步命令的作用、常见报错和排查思路都写上,建议收藏后按顺序操作。
1. 环境准备与安装前的关键检查
1.1 确认系统版本和内核
CentOS7安装Docker不是无脑执行的,第一步一定先确认系统版本和内核。Docker对内核版本有要求,CentOS7默认内核是3.10.x,这个版本跑老版本Docker没问题,但如果装太新的Docker引擎,部分版本会提示内核特性不支持。
查看系统版本的命令:
cat /etc/redhat-release查看内核版本:
uname -r我碰到过不少例子:系统是CentOS 7.6,内核3.10.0-957,直接装了最新版Docker,结果运行容器时报“iptables failed”或者“overlay2”相关的权限问题。所以官方其实有一个兼容矩阵,CentOS7对应的是Docker CE 20.10系列以及之前的版本,Docker 23.0之后对CentOS7的支持就逐渐减弱了,不要盲目追新。
如果内核版本过低,可以先执行系统升级:
yum update -y升级完重启,再继续。这一步虽然耗时,但能省掉后面很多麻烦。另外,还要确认系统架构,绝大多数服务器是x86_64,用uname -m查看,如果是ARM架构,后面所有yum源和镜像地址都要对应调整。
1.2 提前规划网络与软件源
CentOS7自带的yum源在服务器上往往会遇到两个问题:速度慢、部分包找不到。装Docker之前,我强烈建议先把yum源切换到国内镜像站,这样后面安装依赖包会快很多,也少一些“Could not resolve host”之类莫名其妙的错误。
备份并替换CentOS-Base.repo:
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo然后清理缓存并重新生成:
yum clean all yum makecache注意,这里换的是系统基础yum源。Docker本身有自己的yum源,等会安装Docker时还要单独配置,别搞混。还有一个小细节:如果服务器的DNS没配好,直接访问外部yum源会报域名解析失败,curl的时候会卡很久。我一般会顺手检查一下/etc/resolv.conf,确保里面至少有一行nameserver 223.5.5.5这样的配置。
1.3 清理可能存在的旧版本Docker
很多服务器不是全新的,之前可能装过docker或者docker-compose,甚至装了一半失败留下的残留。如果直接覆盖安装,会出现命令不存在、服务启动异常、二进制版本冲突等情况。
看看系统里有没有残留的Docker相关包:
yum list installed | grep docker如果有旧版本,先卸载:
yum remove -y docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine另外还要检查/var/lib/docker目录,这是Docker默认的数据目录,里面存着镜像、容器、卷。卸载旧版本后这个目录不会自动删除,如果你想保留之前的数据,就先不动;如果是重新部署,建议直接清空,不然新环境会带着一堆旧数据:
rm -rf /var/lib/docker清理完再检查一下docker命令是否还残留:
which docker如果提示“no docker in ...”,说明清理干净了,可以进入下一步。
2. 安装Docker的核心命令全流程
2.1 安装依赖包与配置Docker yum仓库
CentOS7上不能用系统自带的yum源直接安装Docker,因为那个源里的docker版本太老,而且稳定源里其实并没有Docker官方仓库的包。正确做法是先把依赖包装上,再把Docker的yum源加进来。
安装基础依赖:
yum install -y yum-utils device-mapper-persistent-data lvm2这三个包的作用要理清楚:
yum-utils提供yum-config-manager命令,后面配置Docker仓库要用;device-mapper-persistent-data是Docker存储驱动device-mapper需要的工具;lvm2是逻辑卷管理工具,同样服务于存储。
接下来添加Docker官方仓库:
yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo这里有个国内环境下经常遇到的问题:download.docker.com被墙或者访问超时,导致整个命令卡住。我通常直接把这个仓库地址换成阿里云的镜像仓库,效果一样,速度却快很多:
yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo装完仓库文件后,还可以顺便看一下仓库里的Docker版本列表,确认有哪些版本可选:
yum list docker-ce --showduplicates | sort -r这一步非常有用,能让你知道当前yum源里有哪些版本的Docker,后面精确控制版本号就靠它。
2.2 安装Docker引擎并启动
仓库配置好之后,安装就简单了。默认安装最新版本:
yum install -y docker-ce docker-ce-cli containerd.io值得注意的是,CentOS7的Docker 20.10之后,默认是使用containerd作为容器运行时,所以containerd.io是必装的。不少新手只装了docker-ce,结果启动docker服务时报错,提示找不到containerd,就是因为少装了这个包。
如果不想装最新版,想装一个兼容性更稳的版本,比如20.10.9,可以这样指定:
yum install -y docker-ce-20.10.9 docker-ce-cli-20.10.9 containerd.io注意版本号后面不用带-3.el7这样的完整包名,yum会自动匹配。
装完以后,启动Docker并设置开机自启,这两条命令几乎是固定组合:
systemctl start docker systemctl enable docker启动之后,很多人喜欢立刻验证一下,最简单的方式就是跑官方测试镜像:
docker run hello-world看到“Hello from Docker!”就说明整个链路通了。如果这一步报错,基本能定位到网络拉镜像或内核兼容性问题,后面在常见问题里详细说。
2.3 验证安装状态的细节
除了docker run hello-world,还可以用几条命令确认服务的健康状态:
systemctl status docker docker version docker infodocker version会输出Client和Server两部分信息。如果Server部分显示不出来或报“Cannot connect to the Docker daemon”,说明docker服务没起来或者权限有问题。docker info会显示存储驱动、镜像数量、系统信息等,我习惯先看Storage Driver是不是overlay2,如果显示devicemapper,说明配置被改动过,后面容器性能会受影响。
docker version具体输出类似这样:
Client: Docker Engine - Community Version: 23.0.1 API version: 1.42 Server: Docker Engine - Community Engine: Version: 23.0.1只要Server部分信息完整,基本可以放心用了。另外记得确认一下当前用户有没有权限执行docker命令。如果是以root身份操作,自然没问题;如果用普通用户,不加 sudo 直接敲 docker 命令,会提示权限不足。解决办法是把用户加入docker组:
usermod -aG docker 用户名 newgrp docker重启终端后才能生效。
2.4 顺手装好Docker Compose
很多场景下,单个容器还好,一旦涉及多容器编排,比如MySQL + Redis + 应用服务一起跑,有Docker Compose会方便得多。CentOS7上装Docker Compose有几种方式,我最常用的是直接下载二进制文件。
先到GitHub或国内镜像站找对应版本,然后执行:
curl -L "https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose docker-compose version如果GitHub访问慢,也可以用国内加速地址下载,或者用Python的pip方式安装旧版本,但我不太推荐,因为依赖容易冲突。文件大小大概几十MB,下载后一定记得执行chmod +x,否则会报“Permission denied”。
Docker Compose v2之后已经作为Docker插件集成在Docker CLI中,如果你系统装的是新版Docker,可以直接用docker compose命令(注意有个空格),不一定非要单独下载docker-compose命令。两种方式选一种就行,别重复装,容易混淆。
3. 安装后的基础配置与常见部署场景
3.1 配置镜像加速器,否则拉镜像能急死人
Docker装完,第一件事就是配置镜像加速器,不然docker pull一个几百MB的镜像能卡到怀疑人生。这一步在国内环境基本是必做的。
修改/etc/docker/daemon.json,如果文件不存在就新建:
mkdir -p /etc/docker cat > /etc/docker/daemon.json <<EOF { "registry-mirrors": [ "https://docker.m.daocloud.io", "https://dockerproxy.com", "https://docker.nju.edu.cn" ] } EOF改完后重启Docker:
systemctl daemon-reload systemctl restart docker可以用docker info查看是否生效,输出的Registry Mirrors部分会列出刚才填的地址。如果镜像加速地址失效了,可以换新的公共镜像源,或者直接用你所在云厂商的镜像加速地址,比如阿里云控制台里申请到的专属加速地址,这个通常最稳定。
配置镜像加速器的时候要注意:daemon.json是Docker守护进程的配置文件,里面不只可以配镜像加速,还可以配存储驱动、日志大小限制等。我习惯把日志限制也顺手配上,防止容器日志把磁盘打满:
{ "registry-mirrors": ["https://docker.m.daocloud.io"], "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" } }这个配置在生产环境非常实用。不限制日志时,一个不写日志策略的容器,跑一个月可能吃掉几十GB磁盘。
3.2 用Docker安装MySQL 8.0,避坑挂载和数据持久化
Docker安装MySQL是大家用得最多的场景之一,也是踩坑最多的场景。很多人照着网上的命令直接跑docker run mysql:8.0,结果启动失败,或者数据一删容器就全没了。这里的关键点有三个:数据目录挂载、密码配置、字符集配置。
先创建一个数据目录:
mkdir -p /data/mysql/conf /data/mysql/data然后准备一个配置文件,或者直接用命令行参数跑。我建议用命令行参数方式,简单直接:
docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=YourPassword123 \ -v /data/mysql/data:/var/lib/mysql \ -v /data/mysql/conf:/etc/mysql/conf.d \ --restart=always \ mysql:8.0这里解释几个容易忽略的点:
-e MYSQL_ROOT_PASSWORD是设置root密码,如果不设置,MySQL容器会随机生成一个root密码,打印在日志里,很容易错过;-v /data/mysql/data:/var/lib/mysql把容器内的数据目录挂载到宿主机,这样容器删了数据还在;--restart=always让容器在Docker重启或服务重启后自动拉起,非常实用。
等MySQL启动起来后,进入容器检查:
docker exec -it mysql8 mysql -uroot -p输入密码后能看到进入MySQL命令行的提示,说明部署成功。如果启动失败,先看日志:
docker logs mysql8MySQL启动失败的常见原因我后面会再总结,这里提一个最常见的:挂载了宿主机的空目录到/var/lib/mysql,但MySQL初始化时需要写文件到该目录,而SELinux限制了权限。CentOS7默认是开启SELinux的,如果报权限错,可以直接临时关闭SELinux:
setenforce 0也可以只给目录放行,但这个操作复杂一些,测试环境直接关SELinux是最省事的。
3.3 用Docker部署Redis主从,练手容器网络
Redis也是容器化部署的常客。单机Redis很简单:
docker run -d \ --name redis \ -p 6379:6379 \ -v /data/redis/data:/data \ redis:7.0 \ redis-server --appendonly yes但很多人练手的时候喜欢搭Redis主从,这里其实会接触到Docker的容器网络知识点。Docker默认的bridge网络里,同主机上的容器之间可以用容器名互相访问。
启动主节点:
docker run -d --name redis-master -p 6380:6379 redis:7.0 redis-server --appendonly yes启动从节点时,不能直接写slaveof redis-master 6379,因为从节点启动时主节点可能还没准备好。更稳的做法是先启动一个普通Redis从容器,再进去用命令动态配置:
docker run -d --name redis-slave -p 6381:6379 redis:7.0 redis-server --appendonly yes docker exec redis-slave redis-cli replicaof redis-master 6379注意这里用的是容器名redis-master代替IP地址,前提是两个容器在同一个自定义网络里。默认bridge网络支持容器互联,但自定义网络更清晰,建议先创建一个网络:
docker network create redis-net然后在docker run时加上--network redis-net,这样容器之间解析名字就没问题了。这个操作能帮助你理解Docker网络的基本概念,后续搞微服务编排也会用到。
4. 常见问题排查与踩坑实录
4.1 启动失败:内核不支持或virtualization support not detected
这个报错在两类场景最常见:一类是真实服务器装了CentOS7,但内核太老,启动Docker时报类似“kernel not supported”或“failed to start docker”的错误;另一类是Windows上装了Docker Desktop,启动时报“virtualization support not detected”。这里主要说前者,但很多CentOS7虚拟机用户也会遇到类似问题。
如果是VMware虚拟机里装的CentOS7,先检查虚拟机的“虚拟化Intel VT-x”是否开启。这个选项默认可能是关闭的,会导致Docker使用硬件加速时失败。如果用的是VirtualBox,也要在系统设置里勾选“启用硬件虚拟化”。
确认虚拟化支持后,如果启动还失败,看Docker daemon的状态:
journalctl -u docker -n 50我看到过很典型的错误日志,里面提到:
Error starting daemon: error initializing graphdriver: driver not supported这种情况大多是存储驱动问题。解决办法是手动指定存储驱动为overlay2,在daemon.json中写入:
{ "storage-driver": "overlay2" }然后重启:
systemctl restart docker如果内核真的比较老,3.10以下,建议先升级内核到3.10以上的新版本,或者直接用Docker 18.09这类老版本。新内核跑新Docker永远是最省心的组合。
4.2 拉镜像失败、ping不通外网该怎么查
拉镜像失败是使用Docker时最折磨人的问题。报错一般长这样:
Get https://registry-1.docker.io/v2/: net/http: request canceled或者一直卡在Pulling fs layer不动。原因分两类:
第一类是 Docker 拉镜像的默认地址registry-1.docker.io访问慢,这个可以通过配置镜像加速器解决,就像前面讲的daemon.json配置。如果加速器也失效,就换成其他公共镜像源。
第二类是服务器本身网络不通,特别是新装的CentOS7,很多网卡默认没开。一个经典问题就是CentOS7刚装完,发现ping www.baidu.com都不通,但ping 网关IP却通。这通常是因为DNS没配置好。检查一下:
cat /etc/resolv.conf如果没有nameserver或只有内网DNS,直接加进去:
echo "nameserver 223.5.5.5" >> /etc/resolv.conf另外,CentOS7的NetworkManager有时会接管网络配置,直接改/etc/sysconfig/network-scripts/ifcfg-eth0里的DNS项更持久。检查里面有没有DNS1=8.8.8.8这种配置,然后重启网络:
systemctl restart network这个地方还要注意,有些云服务器安全组默认禁止出方向访问外网,或者只开了22端口,也会导致拉镜像超时。先在宿主机上用curl测试一下目标地址能不能通,能通说明是Docker配置问题,不能通就是网络策略问题。
4.3 Docker安装MySQL失败的定位思路
MySQL容器启动失败,很多人第一反应是删了重建,反复试还是一样的错。实际排查流程很简单,先看日志:
docker logs mysql8日志里如果出现:
[ERROR] [MY-010457] [Server] --initialize specified but the data directory has existing files这说明数据目录不是空的,容器误以为要启动一个已有数据的MySQL实例,但目录里又没有完整的系统表。原因多半是你把宿主机一个非空目录挂载到/var/lib/mysql,或者之前启动失败残留了文件。解决办法是清空数据目录再启动:
rm -rf /data/mysql/data/*另一种常见报错是权限问题:
chown: changing ownership of '/var/lib/mysql': Operation not permitted这个和前面提到的SELinux有关。用docker run的时候挂载宿主机目录,容器内MySQL进程需要对挂载目录有写权限。如果是测试环境,可以直接关闭SELinux解决;如果要保持SELinux开启,可以给SELinux打标签,但这条命令在新旧版本上有差异,我一般优先选择关闭SELinux。
还有一点,MySQL 8.0 默认是区分大小写的,很多旧项目的表名是小写,迁移过来会报错。可以在docker run时加参数--lower-case-table-names=1,或者通过配置文件挂载进去。
4.4 Docker升级与降级,别把数据搞丢了
CentOS7上Docker升级也是热点需求。很多人直接从旧版本升到最新版,升完发现容器全没了,或者docker-compose.yml里的配置格式不兼容。其实Docker升级命令和安装差不多:
yum install -y docker-ce docker-ce-cli containerd.io但升级前有几件事必须要做:
- 备份所有容器列表和配置。容器本身很难“导出”成文件,但可以用
docker commit把容器保存成镜像再导出:
docker commit 容器名 镜像备份名 docker save -o /data/backup.tar 镜像备份名- 记录当前镜像列表:
docker images > /data/images_before_upgrade.txt检查
daemon.json里的配置是否和新版本兼容。比如旧Docker可能用的是devicemapper存储驱动,升到新版本后必须改成overlay2,不改的话直接无法启动。升级完成后重启Docker,并检查所有容器状态:
systemctl restart docker docker ps -a如果容器状态是Exited,先看日志再启动,千万别直接docker rm把容器删了。数据卷挂载的目录还在,容器没了可以重建,但如果你误删了数据卷目录,那就真没了。
5. 一些实操习惯和必须收藏的命令
5.1 系统镜像下载与最小化安装建议
很多新手在实际服务器上装CentOS7时,总是下载完整版镜像,几百MB的包还带一堆图形界面组件,完全没有必要。CentOS7有最小化安装选项,装完系统占用才700MB左右,跑Docker这类服务绰绰有余。官方镜像下载地址在国内可以直接访问,选择“Minimal ISO”版本就行。
安装过程中记得选对安装位置和分区方案。我见过不少人在默认分区下用Docker,跑一段时间根目录满了,因为Docker默认/var/lib/docker在根分区下。所以装系统时,我习惯单独分一个/var/lib/docker分区,或者干脆给根分区预留80GB以上空间。如果已经装完系统才发现根目录不够,网上有扩容命令教程,但在装系统时直接规划好是最省事的。
5.2 平时最常用的Docker命令速查
安装完Docker之后,下面这组命令是日常使用频率最高的,建议直接存下来:
# 查看当前运行的容器 docker ps # 查看所有容器(包括已停止的) docker ps -a # 查看本地镜像 docker images # 启动/停止/重启容器 docker start 容器名 docker stop 容器名 docker restart 容器名 # 进入容器内部 docker exec -it 容器名 bash # 查看容器日志 docker logs -f 容器名 # 查看容器资源占用 docker stats # 删除容器和镜像 docker rm 容器名 docker rmi 镜像名 # 清理所有没有被使用的资源 docker system prune -adocker system prune -a这条命令要慎用,它会清理所有未被容器使用的镜像,可能导致你下次启动某容器时需要重新拉镜像。我一般在磁盘快满时才执行。
5.3 清理C盘或系统盘时的Docker数据搬迁
Windows用户装了Docker Desktop之后,系统盘经常被占满,然后在网上搜“c盘清理命令”。这个问题在CentOS7上也类似,只是换成了根分区被/var/lib/docker占满。解决办法是把Docker数据目录迁移到其他分区。
迁移步骤不复杂:
systemctl stop docker mkdir -p /data/docker rsync -avz /var/lib/docker/ /data/docker/然后修改daemon.json:
{ "data-root": "/data/docker" }重启Docker:
systemctl daemon-reload systemctl restart docker确认所有容器正常后,再删除旧目录:
rm -rf /var/lib/docker这个操作我在生产环境做过好几次,没什么风险,关键点是:迁移前一定停Docker服务,迁移完先启服务再删旧目录,顺序不能反。
我个人在实际操作中的体会是,CentOS7安装Docker这件事,八成的失败都出在安装前没做环境检查,而不是命令本身敲错。多花五分钟看一下内核、yum源和网络,后面省下的是几小时的排查时间。还有一个备用技巧:如果你实在不想手动配仓库,可以用阿里云等云厂商提供的一键安装脚本,但脚本也建立在网络和依赖正常的前提下,出了问题反而更难定位。掌握命令背后的逻辑,永远比死记命令重要。