☰
Linux内核升级与Docker安装全指南:从环境适配到避坑实操
2026/10/19 10:00:49 网站建设 项目流程

2. 升级内核的必要性与实操方案

2.1 为什么老内核带不动 Docker

Linux 内核之于 Docker,相当于发动机之于汽车。Docker 的隔离能力依赖 Namespaces、Cgroups、SELinux、iptables 等内核特性,容器镜像的层叠读写依赖 OverlayFS 支持。如果内核太老,这些能力要么缺失、要么存在已知漏洞或性能问题,Docker 跑起来就会出现莫名其妙的问题。

以 CentOS 7 为例,默认内核是 3.10.x。虽然 3.10 也能勉强跑 Docker,但会遇到一连串麻烦:存储驱动只能退回去用 device-mapper,性能差不说,磁盘占用还容易虚高;容器网络偶尔出现 iptables 规则错乱,容器重启后网络失联是常事;某些新版本的 docker-ce 直接要求在 4.0 以上的内核才能使用 overlay2 驱动,甚至有些组件会在启动时报警告。升级内核不是为了追新,而是为了避开这些真实存在的坑。

2.2 升级前先看清当前环境

动内核之前,先确认自己的发行版和当前内核版本:

cat /etc/os-release uname -r

我见过不少同学把 CentOS 和 Ubuntu 的安装命令搞混,或者直接用了一套网上找的通用脚本。先看清楚系统版本,再决定走 yum 还是 apt 路线,能省掉后面一大半的问题。

另外需要确认你的服务器架构:

arch

绝大多数场景是 x86_64,但如果是 ARM 架构的服务器,内核包和 Docker 包都要选择对应的架构版本,不能盲抄命令。

2.3 CentOS 7/8 升级内核完整记录

CentOS 官方源里的内核版本非常保守,要想拿到较新的稳定内核,最省力的办法是启用 ELRepo 仓库,通过它安装长期支持版内核。我下面记录的是在 CentOS 7.9 上的实测过程,CentOS 8 同样适用。

第一步,导入 ELRepo 的 GPG 密钥并安装仓库包:

rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org yum install -y https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm

如果是 CentOS 8,把包名换成 elrepo-release-8.el8.elrepo.noarch.rpm。

第二步,查看仓库里有哪几个内核版本:

yum --disablerepo="*" --enablerepo=elrepo-kernel list available

仓库里一般会有 kernel-ml(主线最新版,版本号高,更新激进)和 kernel-lt(长期维护版,版本号略低,更稳定)。生产环境我的建议是选 kernel-lt,不要觉得最新就是最好。Docker 只要求内核功能完整稳定,不需要追着最新主线跑,lt 版本在长时间运行时踩坑的概率小得多。

第三步,安装长期支持版内核:

yum -y --enablerepo=elrepo-kernel install kernel-lt

安装完成后查看新内核是否已经写入磁盘:

grub2-editenv list awk -F\' '$1=="menuentry " {print $2}' /etc/grub2.cfg

第三步做完先别急着重启。你要确认新内核在 grub 菜单里的位置,把默认启动项指到新版内核上。习惯用 grub2-set-default 的同学可以直接指定序号,但序号容易数错,我更推荐用内核标题来设置:

grub2-set-default 'CentOS Linux (5.4.x-xxx.el7.x86_64) 7 (Core)' grub2-editenv list

设置完看到 saved_entry 指向了新内核,再执行 reboot。重启后第一时间用 uname -r 确认已经进入新内核,别急着往下走。

2.4 Ubuntu 升级内核的姿势

Ubuntu 20.04 自带的 5.4 内核、Ubuntu 22.04 自带的 5.15 内核跑 Docker 都没问题,一般不需要额外升级。如果你用的是 Ubuntu 18.04 或者更老的版本,有两个选择。

一个是用官方自带方式升级到 HWE 内核:

apt update apt install --install-recommends linux-generic-hwe-20.04

另一个是用 mainline 工具安装 Ubuntu 主线内核。我个人不推荐在没把握的情况下直接上 mainline,主线内核没有经过 Ubuntu 的充分适配,有兼容性风险。HWE 版本虽然版本号不是最新,但至少是官方为长期支持版适配过的,更稳妥。

注意:Ubuntu 用户升级内核前记得确认一下系统是否开启了 UEFI 安全启动。如果开了 Secure Boot,新内核签名不对会导致无法启动,这种情况最好先临时关掉安全启动,或者选择官方仓库里经过签名的内核包。

2.5 升级内核的避坑提醒

升级内核本身不难,难的是别把系统整出问题。我有几条实际踩坑后总结的纪律,写在这里供参考。

  • 内核升级前至少确认有两份可用内核。升级包不会删除旧内核,新内核安装后,/boot 下会保留旧内核文件。除非磁盘空间告急,否则不要手动删除旧内核,它是你重启失败后的退路。
  • 生产机器不要在业务高峰期做升级。涉及重启的操作,给自己留出充足的时间窗,万一起不来还能连夜抢救。
  • 改 grub 默认项之前,先拍一张快照或者备份 /etc/default/grub 和 grub.cfg。很多灾难都是从一条错误的 grub2-set-default 命令开始的。
  • 升级完成后不要只盯着 uname -r,还要跑一下 docker info 确认 Storage Driver 是否变成了 overlay2。内核升上去了但 Docker 还在用 device-mapper,说明配置还有历史包袱,需要继续排查。

3. Docker Engine 安装全流程实录

3.1 安装源的选择:为什么不用一键脚本

网上有大量“curl 一下就能装好 Docker”的一键脚本,确实方便,但我建议你正经安装时不要用。一键脚本默认装的是 Docker 官方最新版,可能和你的操作系统版本、内核版本不完全匹配,而且它会把源固定成官方源,后续你换镜像加速源时要多绕一步。更重要的是,一键脚本不会问你要装哪个版本,出问题时想降级会很麻烦。

正路是走系统官方源或者 Docker 官方源。这样装出来的包能被系统的包管理器统一管理,依赖关系清晰,后续升级、卸载都干净。至于选择 yum 还是 apt,取决于你的发行版,下面分开记录。

3.2 CentOS 7/8 通过 yum 安装 Docker

先装依赖工具:

yum install -y yum-utils device-mapper-persistent-data lvm2

yum-utils 主要提供 yum-config-manager 命令,用来管理仓库配置;device-mapper-persistent-data 和 lvm2 是存储驱动的依赖,虽然用 overlay2 时不是必须,但装全了可以避免异常场景下的麻烦。

接着配置 Docker 官方 yum 源:

yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

国内服务器访问 download.docker.com 可能比较慢,甚至超时。如果你的 yum 源一直拉不下来,可以考虑把上面的 url 换成国内可用的镜像源地址,方法一样,只是域名变了。我不在这里写具体域名,避免版本变迁导致内容失真,你只要理解:reponame.repo 文件里存放的就是仓库地址,手动修改 repo 文件里的 baseurl 也可以。

仓库配好后,通常的做法是直接安装最新版:

yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

注意我这次把 docker-ce-cli 和 containerd.io 单独列出来了,这两个包在 cache 版本中很容易被漏掉。docker-ce-cli 提供 docker 命令本身,containerd.io 是容器运行时,少了任何一个都会出现“装完了 docker 命令找不到”或者“daemon 启动失败”的情况。

当然,也可以先查看可用版本,再安装指定版本:

yum list docker-ce --showduplicates | sort -r yum install -y docker-ce-24.0.7 docker-ce-cli-24.0.7 containerd.io

提示:指定版本安装时,三个主要包的版本号要尽量保持一致,避免 docker 客户端和 daemon 版本差异过大导致命令行为不一致。

3.3 Ubuntu/Debian 通过 apt 安装 Docker

Ubuntu 侧先更新索引并装依赖:

apt update apt install -y apt-transport-https ca-certificates curl software-properties-common

接着把 Docker 官方 GPG key 导入到系统可信列表:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

这个步骤的目的是让 apt 验证 docker-ce 源里包的签名,如果不导入,后面 apt update 会报 NO_PUBKEY 之类的错误。

然后添加仓库:

echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null

注意 lsb_release -cs 取到的是系统代号,比如 focal、jammy。如果你的系统没有安装 lsb-release 包,这个变量会取不到值,可以手动填代号,或者先 apt install lsb-release。

之后更新索引并安装:

apt update apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

3.4 镜像加速配置

不配置加速源,装完 Docker 去拉一个 hello-world 都有可能卡半天,这不是玩笑。因为默认的 Docker Hub 拉取链路在国内普遍不稳定,小镜像还能忍,大镜像基本没法用。

配置方法很简单,创建或修改 /etc/docker/daemon.json:

mkdir -p /etc/docker cat > /etc/docker/daemon.json <<EOF { "registry-mirrors": ["https://你的加速源地址"] } EOF

加速源地址需要根据你自己的网络环境选择,我这边不强行推荐某个具体服务,因为这类服务的可用性和注册策略经常调整。你只要知道:这一步的目的是把镜像拉取的请求转发到国内节点,大幅提升 docker pull 的速度。配置完记得重启 Docker 再拉镜像验证:

systemctl daemon-reload systemctl restart docker docker info | grep -A 2 "Registry Mirrors"

看到 Registry Mirrors 下面列出了你的加速地址,说明配置生效。

4. 安装后的启动、验证与基础调优

4.1 启动 Docker 服务并设置开机自启

安装阶段结束后,Docker daemon 不会自动启动,需要手动执行:

systemctl enable --now docker

enable 的作用是注册开机自启,--now 表示立即启动。执行完用下面三兄弟确认状态:

systemctl is-enabled docker systemctl status docker docker version

docker version 会同时打印 Client 和 Server 部分。很多人装完发现只有 Client 信息,Server 报 cannot connect,原因通常是 daemon 根本没起来,或者起来后又崩了。真遇到这种情况,先用 journalctl -u docker --no-pager -n 50 看日志,比瞎猜效率高得多。

4.2 用 hello-world 验证容器生命周期

第一次运行容器建议先跑 hello-world,这个镜像极小,专门用来验证 Docker 能否正常工作:

docker run hello-world

如果看到 “Hello from Docker!” 的输出,说明 Docker 的基本链路已经通了。此时再用 docker ps -a 能看到 hello-world 退出后的容器记录,用 docker images 能看到本地已经缓存的 hello-world 镜像。

4.3 当前用户免 sudo 执行 docker

dockerd 默认监听在 /var/run/docker.sock,这个 socket 文件属于 root 组。普通用户执行 docker 命令会报 permission denied,解决办法是把用户加入 docker 组:

usermod -aG docker 你的用户名

改完以后需要重新登录一次终端,组权限才会生效。这里提醒一下:把用户加入 docker 组,相当于给了这个用户 root 级别的系统权限,因为 docker 容器可以挂载宿主机目录。如果你只是临时在服务器上测试,可以考虑继续用 sudo;但如果是自己的开发机,加进去确实方便很多,取舍看你的场景。

4.4 存储驱动检查

Docker 默认会优先使用 overlay2,但老内核环境下可能被迫回退到 vfs 或者 device-mapper。验证方法:

docker info | grep "Storage Driver"

输出应该是 overlay2。如果看到的是 devicemapper,说明内核版本或配置有问题,需要回到第 2 章确认内核是否真的刷成功,或者检查 daemon.json 里有没有历史遗留的 storage-driver 配置项。这个坑藏得深,有人重新安装 Docker 之后依然出现,一查发现 daemon.json 里老配置还在,指向了 devicemapper。

5. 安装过程中最常见的 6 个问题和排查记录

5.1 问题速查表

现象可能原因排查方向
yum install 报 No package docker-ce available仓库未正确添加或 baseurl 失效检查 docker-ce.repo 文件;尝试 yum clean all && yum makecache
docker: command not founddocker-ce-cli 没装确认安装包列表是否包含 docker-ce-cli
Cannot connect to the Docker daemondaemon 没启动或启动崩溃执行 systemctl status docker 和 journalctl -u docker 查看日志
Storage Driver 显示 devicemapper内核太老或配置残留先升级内核,再检查 daemon.json 是否强制指定了驱动
docker pull 长时间卡住网络问题,没配加速源配置 registry-mirrors 后重启 docker
容器启动后网络异常,容器间 ping 不通iptables 规则被清或内核模块未加载检查 iptables -L;确认 br_netfilter 模块已加载

5.2 内核模块没加载这个隐形坑

Docker 网络依赖 br_netfilter 内核模块,装完 Docker 后如果发现容器网络异常,先手动加载并设置开机加载:

modprobe br_netfilter echo "br_netfilter" > /etc/modules-load.d/br_netfilter.conf

同时确保内核参数里桥接流量也走 iptables:

cat <<EOF >> /etc/sysctl.conf net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 EOF sysctl -p

这个小坑平时不显山露水,等你搭跨主机容器网络或者装 Kubernetes 的时候就会踩得明明白白。我当年排查了一个下午,最后发现是 br_netfilter 没加载,iptables 规则看着都对,就是不通,气得不行。

5.3 不要忽略 containerd 的存在

从 Docker 20.10 开始,containerd 是独立的运行时组件,docker-ce 的安装包里不会替你自动装好。很多人只装了 docker-ce,结果 daemon 能起,但容器创建时一直报错,查日志才发现 containerd 的 socket 找不到。解决方法是把 containerd.io 这个包和 docker-ce 一起装,装完以后 containerd 会由 systemd 自动管理,不需要额外操作。

5.4 升级内核后 Docker 反而变慢的怪现象

有个别情况下,内核升级后 Docker 启动、容器创建反而变慢。这通常不是内核本身的锅,而是升级后 Docker 还没有重新初始化存储池,旧数据还挂在老驱动的逻辑上。处理方法是先确认镜像和容器数量不多的情况下,把旧数据清掉重建存储目录,或者保留镜像数据、升级驱动后重建容器。如果数据重要,千万别直接 rm -rf /var/lib/docker,那是祖宗级事故操作。正确姿势是先 docker ps 和 docker images 确认,再做镜像导出备份。

6. 收尾时的几句体己话

整套流程走完,你会发现安装 Docker 本身不是一个高难度操作,真正花时间的其实是环境适配。内核版本、存储驱动、网络模块、镜像加速,每一环都得对得上,容器跑起来才流畅。我自己的习惯是:新服务器到手先看内核和发行版,再决定装什么版本的 Docker,最后才动手,顺序反了很容易陷入反复卸载重装死循环。

多说一句,内核升级后千万别把旧内核删得太干净,留一两个旧版本当保险,能让你在系统异常时多一条退路。另外,所有步骤里涉及重启的操作,尽量避开业务时间,给自己留出排查问题的余地。

这篇内容到这里就算完整了,如果你按步骤走完,现在应该已经有一个能正常拉镜像、跑容器、开机自启 Docker 的环境了。下一步可以去折腾镜像管理、容器数据卷或者 Compose 编排,那才是真正有意思的部分。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询