ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Docker CE 安装完全指南:从环境检查到常见故障排查

Docker CE 安装完全指南:从环境检查到常见故障排查 如果你常年和服务器、部署、测试环境打交道大概早就被一件事折磨过同一个应用在开发环境好好的一挪到测试机或者生产服务器上就开始缺依赖、版本对不上、系统库不一致折腾一晚上问题还在原地打转。Docker CE社区版就是奔着这个痛点来的——把应用连同它的运行环境一起打包成镜像装好 Docker 之后一条命令就能在任何 Linux 机器上跑起来。Docker CE 是 Docker 的免费开源版本功能完整覆盖个人开发、中小团队协作、生产服务器部署等绝大多数场景。这篇内容不是把官方文档复述一遍而是从实践者视角把“安装 Docker CE”这件事从环境检查、源配置、装包、验证到踩坑完整走一遍。刚接触容器的新手可以照着一步步装好服务器经验比较多的老手也能在这里核对几个容易忽略的细节比如用户组权限、日志策略、存储驱动这类装完才想起来的东西。1. 安装之前先想明白几件事1.1 为什么选 Docker CE 而不是其他容器方案市面上容器方案不少裸用 containerd、Podman、LXC 都有但大多数情况下 Docker CE 依然是最稳的起点。先说 Docker CE 和 Docker EE 的差异。EEEnterprise Edition是商业版本带企业级支持、认证镜像、安全扫描这类付费能力普通团队和个人根本用不上。CE 是社区版由 Docker 官方和社区共同维护该有的核心功能一个不少cl i、镜像构建、Compose、网络、存储全都覆盖。咱们平时说的“装 Docker”默认指的就是 CE。再说容器运行时层面的选择。Docker CE 底层使用 containerd 来做容器生命周期管理而 containerd 又可以独立作为轻量级运行时使用Kubernetes 也能直接对接。那为什么还要装 Docker CE 而不是只装 containerd因为 Docker CE 提供的是完整用户侧工具链docker build 构建镜像、docker compose 编排多容器、docker network 管理网络、docker volume 管理数据卷这些高频操作 containerd 一个都不直接提供。如果你不是 Kubernetes 深度用户从 Docker CE 开始最省力。选 Docker CE 还有一个现实理由社区资料多。搜一个报错GitHub issue、Stack Overflow、技术博客里十有八九都是围绕 Docker 生态的解决方案。对于入门者和运维团队这种“可搜性”本身就是生产力。1.2 你的机器满足安装条件吗很多安装失败其实在动手之前就注定了——系统不满足要求还在闷头装自然各种报错。Docker CE 对宿主机的硬件和内核有明确要求我建议先做一轮检查再继续。系统方面必须是 64 位架构x86_64 或者 arm64 都行。常见的 Ubuntu、Debian、CentOS、Rocky Linux、openSUSE 都在官方支持列表里。比较老的 32 位系统比如 i386 的老机器基本可以告别 Docker CE。内核方面官方文档要求 Linux 内核版本至少 3.10。但请注意这只是“能跑”的下限实际用起来非常吃力。我实测过 CentOS 7 默认的 3.10 内核overlay2 存储驱动、cgroup 相关特性都容易出问题运行高并发容器时稳定性明显不如 4.x/5.x 内核。建议内核版本不低于 4.18生产环境能上 5.x 就上 5.x尤其是在 Ubuntu 22.04、Rocky Linux 9 这类新系统上内核基本都是 5.10 以上不用额外操心。检查内核版本用这条命令uname -r检查系统发行版信息cat /etc/os-release内存和磁盘方面官方没说硬性最低值但我的经验是内存低于 512MB 的机器装完 Docker 后跑几个小容器就捉襟见肘1GB 以上才算舒服。磁盘方面Docker 默认数据目录在 /var/lib/docker镜像、容器、数据卷都往这里塞如果准备跑常规开发测试环境建议预留 20GB 以上的可用空间。安装之前用 df -h 看一下根分区和 /var 所在分区的剩余容量别等磁盘写满了才反应过来。1.3 四种安装方式怎么选Docker CE 的安装方式主要有四种我按推荐程度排个序。第一种是官方软件源安装也就是通过 apt 或 yum/dnf 从配置好的软件源拉取 docker-ce 等软件包。这是最推荐的方式原因很简单依赖关系由包管理器自动处理后续升级也是走系统标准流程一句 apt upgrade 或者 yum update 就能把 Docker 一起升了。第二种是下载 Docker 官方提供的静态二进制包解压后手动部署。这种方式适合无法访问外网、必须离线安装的内网服务器。它的麻烦之处在于containerd、runc、docker-init 这些组件都要自己配套处理好升级也没法通过包管理器完成运维负担重一些。第三种是使用官方安装脚本curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh这个脚本本质上是帮你配好源然后调包管理器安装适合最快速的临时环境。但我一般不推荐直接curl | sh因为脚本会从这个地球上各个角落拉取 REPO网络稍有波动就失败而且你没法完整看到脚本每一步做了什么。真要临时用先下载到本地看一遍脚本内容再执行也不迟。第四种是 Docker Desktop 和以 rootless 模式运行。Docker Desktop 适合 macOS 和 Windows不在本文讨论范围。rootless 模式允许普通用户无 root 权限运行 Docker 守护进程安全性更好但对系统配置要求更繁琐普通场景还是以传统模式为主。综合来看绝大多数 Linux 服务器场景直接选软件源安装。下面就以 Ubuntu 为主、CentOS 为辅完整走一遍。2. Ubuntu 系统安装 Docker CE 完整流程2.1 卸载旧版本和清理环境如果这台机器之前装过老版本 Docker比如系统自带的 docker.io、docker-engine或者不完整的残留先清理掉否则新版本装上去可能出现二进制冲突、配置互相覆盖的问题。Debian/Ubuntu 系列执行sudo apt remove docker docker-engine docker.io containerd runc需要注意的是这个命令只会卸载软件包不会删除镜像、容器、数据卷等数据。这些数据默认存放在 /var/lib/docker。如果你希望彻底“回到干净状态”需要手动清理sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd但这里有一个重要提醒如果这是一台曾经实际运行过业务容器的服务器千万别急着删 /var/lib/docker。先确认里面的容器和数据卷是否需要保留。我处理过好几次客户现场因为图省事直接删了数据目录业务数据全没了。在清理之前至少先看一下目录占用sudo du -sh /var/lib/docker如果发现里面有几个 GB 的数据十有八九是有实际业务数据先做备份再动手。2.2 配置 apt 软件源清理干净之后第一步是更新索引并安装 apt 使用 HTTPS 所需的依赖包。Docker 软件源需要这些工具来安全地拉取仓库信息sudo apt update sudo apt install ca-certificates curl gnupg lsb-release接着添加 Docker 官方的 GPG 密钥这一步是为了让 apt 校验软件包的签名防止软件源被篡改sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod ar /etc/apt/keyrings/docker.gpg然后写入软件源列表。这里有个细节很多人会踩坑仓库地址里的 codename 部分比如 jammy、focal应该和系统版本匹配不要手动写死。用下面的命令自动获取echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null如果你用的是国内云服务器从官方源下载可能速度不佳可以替换源地址。把上面命令中的https://download.docker.com换成国内各云厂商提供的基础软件镜像地址即可。我在生产环境里通常直接用国内镜像源速度差距非常明显尤其是执行 apt update 拉取索引的时候。配置完成后重新加载源sudo apt update此时如果源配置有问题比如架构不对、密钥验证失败会直接报错。正常的输出里应该能看到 Name: Docker CE 这类条目出现说明仓库已经正常工作。2.3 安装 Docker 核心软件包现在进入真正的安装步骤。在 Ubuntu 上安装 Docker CE 及相关组件的命令是sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin这几个包分别干什么我解释一下docker-ceDocker 守护进程本体dockerd和服务管理脚本是核心。docker-ce-clidocker 命令行工具客户端。守护进程和客户端虽然是分开的包但平时都得装。containerd.io容器运行时负责容器的实际创建和运行。docker-buildx-pluginBuildx 插件用于扩展镜像构建能力新版构建缓存、多平台构建都靠它。docker-compose-pluginCompose 插件支持使用 docker compose 命令编排多容器应用。如果你希望安装特定版本的 Docker CE可以先用下面的命令列出可选版本apt-cache madison docker-ce输出里会显示版本号比如 5:26.1.1-1~ubuntu.22.04~jammy安装在版本号前面加等号即可sudo apt install docker-ce5:26.1.1-1~ubuntu.22.04~jammy docker-ce-cli5:26.1.1-1~ubuntu.22.04~jammy containerd.io生产环境我建议锁定版本安装因为 Docker 的升级有时候会带来行为变化比如 iptables 处理逻辑、默认网段调整这些在业务运行中可能引起惊扰。开发测试环境则无所谓直接装最新版就好。2.4 启动服务与验证安装安装完成后先启动 Docker 守护进程并设置开机自启sudo systemctl start docker sudo systemctl enable dockerenable 这条很多人会忘装完当时能跑服务器一旦重启就发现 docker 命令报 Cannot connect to the Docker daemon原因就是服务没设开机自启。养成习惯装完立刻 enable。验证安装是否成功最简单的两步docker --version sudo docker run hello-worlddocker --version 能看到客户端与守护进程的版本号。docker run hello-world 则会从镜像仓库拉取一个测试镜像然后运行一个输出示例信息的容器。如果看到 Hello from Docker! 的输出说明整个链路——客户端、守护进程、镜像拉取、容器运行——全部正常。这一步如果卡在拉取镜像阶段多半是网络问题先不急着解决后面专门讲。先通过 docker info 确认基本状态docker info重点关注 Server 段的 Docker Root Dir默认 /var/lib/docker、Storage Driver理想情况是 overlay2、Kernel Version、Operating System 这几项。看到这些信息说明守护进程确实健康运行中。3. CentOS / Rocky Linux 系列安装 Docker CE 的关键差异3.1 安装依赖与配置源CentOS 7、Rocky Linux 8/9 等 RHEL 系发行版安装思路和 Ubuntu 一致但命令体系不同。先说前置依赖sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo在 Rocky Linux 9 或 CentOS Stream 上yum 和 dnf 已经统一直接使用 yum 命令也能生效。添加完仓库后同样可以把仓库地址替换成国内镜像源方式是把 docker-ce.repo 文件里的 baseurl 地址替换为云厂商提供的镜像地址。然后安装sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin如果不指定版本默认会安装仓库里最新的稳定版。查看所有可选版本yum list docker-ce --showduplicates | sort -r锁定版本安装时用完整的包名与版本号例如sudo yum install -y docker-ce-3:26.1.1-1.el8 docker-ce-cli-3:26.1.1-1.el8 containerd.ioRHEL 系安装完成后同样要启动并设置自启sudo systemctl start docker sudo systemctl enable docker3.2 防火墙与 SELinux 处理RHEL 系系统默认开着 firewalld 和 SELinux这两个东西经常让 Docker 安装后表现异常。最常见的诡异现象是docker run 一个容器端口映射死活不生效外部访问不到但容器内部是好的。排查半天发现是 firewalld 拦了。处理端口相关需求我建议不要粗暴地停掉 firewalld而是放行 Docker 需要的端口范围。比如容器映射了 8080就执行sudo firewall-cmd --permanent --add-port8080/tcp sudo firewall-cmd --reload如果你用的是默认的 docker0 桥接网络Docker 会通过 iptables 的 NAT 规则做端口转发但 firewalld 可能会在启动时刷新 iptables 规则把 Docker 的规则清掉。这种冲突在 CentOS 7 上尤其常见。最省心的方案是确认 firewalld 和 Docker 的 iptables 策略兼容。SELinux 的情况更微妙。CentOS 7 默认 enforcing 模式下Docker 挂载宿主目录、持久化数据卷时容易出现 Permission denied而且日志里看不到明显原因。官方对这种情况的处理策略是建议关闭 SELinux 或者在 Docker 服务参数中调整。我个人的做法是在需要 Docker 挂载目录的服务器上把 SELinux 设为 permissive 模式而不是彻底 disabled。这样既保留审计能力又不阻塞业务sudo setenforce 0持久化修改需要编辑 /etc/selinux/config将 SELINUX 设置为 permissive 或 disabled。设置完必须重启才完全生效。生产环境如果对 SELinux 有严格要求更规范的方案是让容器使用启用 SELinux 的存储驱动选项或者为挂载目录设置正确的安全上下文。这话题比较大非安全强相关的环境先走 permissive 路线最现实。3.3 RHEL 系特有的坑位提示RHEL 系安装还有一个容易忽略的点有些系统镜像自带老版本 podman、buildah 或容器工具集比如 CentOS 8 自带 container-tools 模块。这些工具和 Docker 共享部分容器运行时的命名空间偶尔会产生冲突。如果安装后 docker 命令显示异常检查一下是否有 podman 同名别名干扰which docker如果输出的是 /usr/bin/podman说明系统把 docker 软链接到了 podman。需要把 podman 移除或调整 PATH 优先级确保使用的是 /usr/bin/docker 下的 Docker CE 本体。我在 Rocky Linux 9 上就遇到过这种情况折腾了一下午才发现是替代包占了坑。4. 装完立刻要做的三件小事4.1 配置镜像加速避免拉取超时Docker Hub 的拉取速度对海外服务器很友好但国内普通服务器直连 Docker Hub 经常超时。装完第一件事配置镜像加速地址。修改 Docker 守护进程配置文件 /etc/docker/daemon.json加入 registry-mirrors 字段{ registry-mirrors: [https://your-mirror-address.example.com] }这里的加速地址建议使用你所用云服务商提供的容器镜像加速服务注册后即可获取专属地址。不建议随便在网上找公开的第三方地址稳定性、安全性都没有保障。修改完成后重启 Dockersudo systemctl daemon-reload sudo systemctl restart docker验证加速是否生效docker info | grep -A 2 Registry Mirrors看到 Registry Mirrors 下列出了你配置的地址说明已经生效。配置之后拉镜像的速度会明显提升尤其是 mysql、nginx、redis 这类热门镜像体感很直观。4.2 让普通用户免 sudo 使用 docker默认情况下Docker 守护进程监听在 /var/run/docker.sock 上这个 socket 文件归属于 root 用户和 docker 组。只有 root 用户和 docker 组成员才能直接操作 Docker普通用户执行 docker 命令会报权限不足。把当前用户加入 docker 组sudo usermod -aG docker $USER newgrp dockernewgrp docker 是让当前会话立即生效不用退出重新登录。如果不想敲 newgrp重新登录 Shell 也可以。这里必须讲一个安全权衡加入 docker 组等同于获得 root 权限因为你可以通过挂载宿主目录到容器来读取宿主机文件可以执行特权容器。所以不要为了图方便把所有用户都塞进 docker 组。正确的做法是只把确实需要操作 Docker 的运维人员、开发人员加进去。如果你一个人管服务器那无妨。4.3 配置日志轮转和数据目录容器日志是磁盘杀手。默认情况下 Docker 的 json-file 日志驱动会把每个容器的标准输出日志无限累积。我遇到过一个跑了一两个月的 nginx 容器日志文件膨胀到几十 GB直接把根分区写满。解决方法是限制日志大小和数量。在 daemon.json 中增加日志相关的 log-opts 配置{ registry-mirrors: [https://your-mirror-address.example.com], data-root: /data/docker, log-driver: json-file, log-opts: { max-size: 50m, max-file: 5 } }这里同时配置了>sudo du -sh /var/lib/docker/containers如果已经出现超大日志文件最快速的处理方式是清空容器日志文件而不是删除它。因为容器还在运行时直接删除日志文件可能导致 fd 句柄仍指向旧文件磁盘空间并不会释放。正确做法sudo truncate -s 0 /var/lib/docker/containers/container-id/container-id-json.log这个命令在日志已经爆掉、磁盘快满的情况下非常救命。5. 安装与启动常见问题排查实录5.1 apt/yum 源不可用或找不到软件包症状执行 apt update 或 yum install 时报 404或者提示找不到 docker-ce 包。排查思路先确认源地址可访问curl 一下源 URL看能否返回正常响应。检查架构和系统代号。Ubuntu 源里 arch 写错、codename 写错都会导致 404。比如在 Ubuntu 23.04 上套用 22.04 的源会直接找不到对应目录。如果用的是历史版本系统比如 CentOS 7官方仓库对 EOL 系统的支持可能已调整需要仔细核对仓库是否还维护对应 releasever。我遇到过最离奇的情况是 apt 源文件里 signed-by 参数指向的密钥路径不对apt update 直接忽略整个仓库。检查密钥路径确保 /etc/apt/keyrings/docker.gpg 文件存在并且权限至少是 ar。5.2 docker 命令报 Cannot connect to the Docker daemon这是一个高频率报错很多人第一时间以为是 Docker 没装好其实排除起来很简单按顺序查三件事。先看服务是否在运行sudo systemctl status docker如果输出里有 Active: failed直接看服务日志sudo journalctl -u docker --no-pager -n 50日志里最常出现的几类原因containerd 启动失败和 containerd.io 版本不匹配有关需要重新安装匹配版本。iptables 相关错误常见于 RHEL 系firewalld 抢占 iptables 规则导致 dockerd 初始化网络失败。存储驱动不兼容老内核搭配 overlay2 出问题可以尝试改用 vfs但不推荐这条只是临时测试手段。另一个容易被忽略的原因是 socket 文件权限异常。检查 /var/run/docker.sock 是否存在以及当前用户是否在 docker 组内。执行ls -l /var/run/docker.sock sudo usermod -aG docker $USER如果文件不存在说明 dockerd 进程没起来回到上一步查服务日志。5.3 拉取镜像慢或超时症状docker pull 卡在等待状态或者报 net/http: TLS handshake timeout。原因一般是网络链路问题。先测试网络连通性docker pull hello-world如果超时执行 curl 测试源站的连通性。再确认 daemon.json 里的 registry-mirrors 配置是否正确被加载docker info | grep -i mirror注意配置文件改动后必须重启 Docker很多人改了 daemon.json 只执行了 daemon-reload但 registry 镜像参数只在 dockerd 启动时读取光 reload 不重启是不生效的。还有一个容易被忽略的点DNS 解析问题。服务器配置的 DNS 如果解析不了 Docker Hub 的域名也会卡住。检查 /etc/resolv.conf必要时切换为公共 DNS 或者可信的内部 DNS。5.4 端口映射不生效症状docker run -p 8080:80 之后本机 curl 8080 端口无响应。RHEL 系先查防火墙sudo firewall-cmd --list-all如果 8080 不在列表里要么放行端口要么评估能否临时停 firewalld 测试。注意即使你修改了 docker 服务的 iptables 规则服务重启后 firewalld 也可能重新加载规则覆盖掉。再查 Docker 的网络确认端口映射状态docker ps docker port container-name如果 docker port 显示 0.0.0.0:8080说明映射本身建立成功问题几乎可以锁定在宿主机防火墙或云安全组。5.5 常见问题速查表症状可能原因快速排查命令常用解决动作apt/yum 找不到 docker-ce 包源未配置或 codename 不匹配apt-cache policy docker-ce检查 source list核对 codenameCannot connect to daemondockerd 未启动systemctl status docker查看 journalctl -u docker 日志docker ps 报权限不足用户不在 docker 组groups $USERusermod -aG docker $USER端口映射不通firewalld / 安全组拦截firewall-cmd --list-all放行端口或调整安全组规则日志撑爆磁盘未限制 log 大小du -sh /var/lib/docker/containers配置 max-size 并 truncate 旧日志拉镜像超时registry 网络问题curl -I https://registry-1.docker.io/配置镜像加速地址并重启 docker5.5.1 另外两个“高级”问题除了上面这些我再补充两个我实际遇到过的、不那么常见但很有代表性的事故。第一个是内核 cgroup 版本问题。Ubuntu 22.04 使用 cgroup v2而非常老的容器镜像或自定义 runc 可能对 cgroup v2 支持不完整容器启动后会报 Failed to start cgroup。如果遇到这种情况优先升级 Docker 版本和 containerd 版本而不是切换回 cgroup v1。切换 cgroup v1 在内核启动参数里加 systemd.unified_cgroup_hierarchy0 确实能行但会影响系统上其他依赖 cgroup v2 的组件属于牵一发动全身的操作。第二个是 docker 默认网段和公司内网网段冲突。Docker 默认的 docker0 网桥网段是 172.17.0.0/16如果公司内网正好用了这个网段容器一启动宿主机上到内网的路由就乱了表现是某些内网服务突然连不上。解决方式是在 daemon.json 里调整默认网段{ default-address-pools: [ {base: 192.168.100.0/24, size: 28} ] }这个配置的含义是Docker 创建桥接网络时从 192.168.100.0/24 这个地址池里分配子网每个子网掩码为 28 位。这样就不会和常见的内网段撞车避免了很多莫名其妙的“装好了但连不上”问题。6. 个人习惯与后续建议装完 Docker CE 并不是终点而是容器化管理的起点。我个人在实操中形成一个习惯每台服务器装完 Docker第一件事不是急着跑业务容器而是先把 daemon.json 里镜像加速、日志限制、存储目录这三项配置好然后跑一遍容器生命周期测试包括 run、stop、restart、rm确认基本流程无异常再开始部署业务。这个检查流程大概只需要十分钟但能避免后续业务上线后才发现基础配置不对的尴尬。版本升级路径上建议跟随官方 LTS 节奏。Docker CE 大约每六个月发布一个大版本没必要追新但也不要长期停留在太老的版本。旧版本在漏洞修复、新内核兼容性上都会逐渐掉队。升级前注意docker-ce 和 containerd.io 往往需要一起升版本不匹配会出现无法启动容器的情况。如果你后面开始接触 Kubernetes你会发现这台装好的 Docker CE 节点可以直接作为运行时基础。或者你想在公司内部搭建一个简单的镜像私有仓库配合这台服务器的 Docker CE用 docker tag 和 docker push 就能搭出最基础的 CI/CD 流程。装了 Docker CE 之后的可扩展方向很多建议先从最日常的镜像构建、容器编排开始熟悉再根据业务需求逐步深入。我在实际运维中积累的一个小建议把 Docker 相关的所有自定义配置都注释清楚放在一个文档里尤其是 daemon.json 的每一行改了什么、为什么改否则半年之后再来看你大概率会忘记当初为什么把默认网段改成了 192.168.100.0。工具本身是简单的围绕工具的决策和记录才是让这套环境长期稳定运行的关键。
返回列表