ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

VirtualBox+CentOS-10搭建Docker全攻略:从选型到故障排查

VirtualBox+CentOS-10搭建Docker全攻略:从选型到故障排查 如果你最近也在折腾VirtualBox下的CentOS-10并且想在这台虚拟机里把Docker环境完整搭建起来那这篇文章就是写给你看的。我前前后后帮同事、也帮自己重装过十几次这套组合踩过的坑包括 Docker 服务起不来、虚拟机重启后网卡消失、磁盘被 /var/lib/docker 吃满、端口映射两层转发死活不通等基本都有完整的排查思路和解决办法。这套环境特别适合刚学容器、又不想在宿主机上直接装 Docker Desktop 的人一台虚拟机用完即走快照一恢复就能回到初始状态比在物理机上反复折腾要稳妥得多。我不会只给你几条命令而是会把每个选择背后的理由、报错信息的含义、以及我在实际使用中验证过的最省心配置都讲清楚。1. 选型动机为什么要用 VirtualBox 装 CentOS-10 跑 Docker1.1 Docker 实验环境的三条路我为什么选了这条如果你只是想快速体验容器Docker Desktop 确实是最短的路径安装完就能跑。但今天的 Docker Desktop 在 Windows 上依赖 WSL2 或者 Hyper-V很多老一些的机器 BIOS 里没有开启虚拟化一启动就报virtualization support not detected之类的错误折腾半天发现是硬件层面的问题。而 VirtualBox 这条路虽然多了一步创建虚拟机但对硬件的兼容性反而更宽容也不挑系统版本。更重要的是虚拟机能做快照。我学 Docker 的时候经常把配置改得乱七八糟或者在容器里跑 rm -rf快照一恢复就是干净环境这种安全感是 Docker Desktop 给不了的。如果你打算学习 Dockerfile 编写、Compose 编排、Swarm 集群这些内容这种反反复复试错的能力几乎决定了学习效率。1.2 为什么是 CentOS-10而不是 CentOS 7 或 Ubuntu很多人还在翻 CentOS 7 时代的教程但那一套真的过时了。CentOS 7 的内核是 3.10新版 Docker 对老内核的兼容性越来越差cgroup 和 iptables 的行为跟现代内核有明显差异。CentOS Stream 10 的内核版本足够新默认开启 cgroup v2Docker Engine 25 以上的版本在它上面跑得非常顺滑。选 CentOS-10 而不是 Ubuntu也有我的考虑。如果你之后要往公司服务器上部署Elastic 系RHEL/CentOS Stream的 systemd、firewalld、SELinux 机制是绕不开的。自己在 VirtualBox 里先熟悉这套东西比直接在生成服务器上踩坑要安全得多。镜像下载方面去 CentOS 官方或者镜像站拿 DVD ISO 或者 Minimal ISO 都行。我更推荐Minimal ISO安装出来是纯命令行环境跑 Docker 完全不需要桌面。如果下载时拿不准选哪个体积的文件记住带dvd字样的完整安装包更大带boot字样的只是引导镜像真正安装用的那个最小体积的minimalISO 最适合虚拟机场景。2. 虚拟机创建阶段的细节直接决定后面的坑多少2.1 内存、CPU、硬盘的推荐值这一步看似简单但参数给得不对后面会非常痛苦。先说内存。CentOS-10 Minimal 本身只占用几百 MBDocker 的容器再吃几百 MB所以4GB 起步8GB 比较舒适。如果你计划跑 MySQL、Redis、Nginx 这些常用镜像4GB 也够但想跑 GitLab 这类重量级镜像建议直接给 8GB 以上。CPU 给 2 到 4 核都可以不需要太多。显存设 128MB 就够了命令行环境下显存基本用不上。硬盘是我最想强调的一项。很多人装完系统发现根分区只剩几个 GB拉几个镜像就爆了。Docker 的镜像层、容器层、日志全部堆在 /var/lib/docker 下所以至少给 20GB打算跑重量级镜像直接给 40GB。VirtualBox 的虚拟磁盘默认是动态分配你设置 40GB 并不会立即占满宿主机磁盘只是上限变高所以不用担心浪费。2.2 网络模式开局选 NAT稳定后再考虑桥接VirtualBox 提供 NAT、NAT Network、桥接、Host-Only 几种模式。我的经验是第一阶段用 NAT稳不冲突等到 Docker 跑起来、需要从局域网别的机器访问容器时再关机改成桥接。NAT 模式下虚拟机可以访问外网外面访问虚拟机则需要端口转发。默认 NAT 的虚拟地址一般是 10.0.2.15DNS 自动分配安装 CentOS 和 Docker 都够用。桥接模式则让虚拟机直接混入局域网和宿主机拿到同一网段的地址。右键虚拟机 → 设置 → 网络 → 连接方式改成“桥接网卡”再选具体的物理网卡即可。这里提醒一句如果在 WiFi 环境下用桥接虚拟机 IP 有时会不稳定甚至拿不到地址这是无线网络的限制不是 VirtualBox 的 bug。另外补充一个常见的坑有些人在 Windows 上安装 VirtualBox 7.2.x 时安装目录如果带中文或特殊字符会报invalid installation directory。解决方式是老老实实把安装路径改成纯英文的比如C:\Program Files\Oracle\VirtualBox。这个问题虽然发生在宿主机但一旦遇到虚拟机根本起不来。2.3 安装 CentOS 10 时的几个关键选择安装过程有几个默认选项我强烈建议改掉。第一个是分区。默认的自动分区虽然能用但为了 Docker 的长期运行我建议切成手动分区专门给/或者/var留出足够空间。Docker 的数据都写在 /var/lib/docker 下面如果根分区就 10GB几周后就会遇到磁盘满导致的容器崩溃。第二个是软件包。选择 Minimal Install不要装带 GNOME 的版本。我在虚拟机上装过桌面除了拖慢启动速度、占用显存之外没有收益特别是你还要用 Docker 的时候。第三个是网络。安装到“网络和主机名”界面时记得把网卡开关打开不然装完系统连不上网还得自己调。第四个是账号。你可以在安装时创建一个普通用户并加入wheel组后续用这个用户日常操作而不是一直用 root。Docker 的权限管理也和这个直接相关。安装完成后可以用ip addr确认地址用curl -I https://mirror.example.com确认外网连通性。如果 ping 不通先检查 /etc/sysconfig/network-scripts/ 下的网卡配置文件是否正常启用了 DHCP这一步排查好了再往下走。3. 安装 Docker Engine 的完整流程3.1 换源还是直接用官方源CentOS Stream 10 自带的 dnf 源里不包含 docker-ce必须添加 Docker 官方仓库。官方地址是 download.docker.com/linux/centos但国内服务器的下载速度常常让人绝望。我推荐的办法是先用dnf config-manager把官方 repo 文件拉下来然后替换 baseurl 到镜像站地址。以阿里云镜像为例repo 文件里的baseurlhttps://download.docker.com/linux/centos可以替换为镜像站对应路径。实际上只用一条命令就能添加官方源sudo dnf config-manager addrepo --from-repofilehttps://download.docker.com/linux/centos/docker-ce.repo然后编辑/etc/yum.repos.d/docker-ce.repo把 baseurl 替换成你可达性更好的镜像地址。这一步做完再用dnf list docker-ce检查一下有没有拉取到包列表没有列表说明源没配好后续安装必然报 404。3.2 安装和启动直接安装全套sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin这几个包的职责我先说清楚docker-ce是守护进程和 CLIdocker-ce-cli是命令行工具containerd.io是容器运行时实际由 containerd 管理容器生命周期docker-buildx-plugin让新版 build 命令可用docker-compose-plugin提供docker compose子命令。安装完成后不需要重启直接设置开机自启并启动sudo systemctl enable --now docker然后查看状态sudo docker info重点看Server Version和Cgroup Version应该能看到v2说明 cgroup v2 正常启用。验证整个链路是否通sudo docker run hello-world如果能打印出 “Hello from Docker!” 那说明 daemon、containerd、网络这些环节全都没问题。如果这一步在国内网络环境下卡住拉到一半超时优先去检查镜像加速器配置后面会讲到而不是重装 Docker。3.3 让当前用户免 sudo 操作 docker默认情况下普通用户执行 docker 命令会提示权限不足每次都敲 sudo 非常烦。把用户加进docker组即可sudo usermod -aG docker $USER然后重新登录或临时用newgrp docker让组生效。注意docker 组的权限等价于 root 权限因为 docker 可以通过挂载宿主机目录等方式拿到宿主机 root。物理机和生产环境务必慎用虚拟机随便玩。我自己在这台环境里顺手验证过一个常用组合用docker run -d -p 3306:3306 --name mysql8 -e MYSQL_ROOT_PASSWORD123456 mysql:8.0跑 MySQL等几十秒再用docker exec -it mysql8 mysql -uroot -p进去测试整体很顺畅但前提是磁盘和内存足够。4. 容器网段与 VirtualBox 网络模式的协同4.1 端口映射的正确理解Docker 里最常用的网络操作是端口映射docker run -d --name nginx -p 8080:80 nginx这个命令的含义是把虚拟机的 8080 端口映射到容器的 80 端口。如果你是 NAT 网络那外部的物理机要访问它还需要再做一层虚拟机的端口转发。也就是说存在两层映射。很多人在这里绕晕了Windows 宿主机浏览器访问http://localhost:8080发现完全不通。原因就是 Nginx 跑在虚拟机里面而 VirtualBox 的 NAT 没有把宿主机的 8080 转发到虚拟机的 8080。解决办法有两个一是在 VirtualBox 菜单里设置端口转发规则宿主机 8080 转发到虚拟机 10.0.2.15 的 8080二是直接切到桥接网络用虚拟机自己的局域网 IP 访问省掉一层映射。个人建议选第二种逻辑更干净以后调试容器也更直观。4.2 桥接模式下的 IP 规划桥接模式下CentOS 10 的 IP 由上层路由器分配虚拟机相当于局域网里的一台独立电脑。Docker 容器默认走docker0网桥网段一般是 172.17.x.x容器对外提供服务仍然要靠-p映射。我比较推荐这种玩法一台 CentOS 10 虚拟机里跑多个容器每个容器映射到不同的端口比如 8080、8081、8082然后用宿主机 IP 直接访问。如果需要对外只暴露一个入口就在虚拟机里再装一个 Nginx用反向代理把请求按路径分发到不同容器。这种模式下虚拟机的 IP 要固定。我踩过坑路由器 DHCP 重新分配地址结果所有端口映射路径全要改。CentOS 10 里可以用nmcli配置静态 IPsudo nmcli con mod ens160 ipv4.addresses 192.168.1.100/24 sudo nmcli con mod ens160 ipv4.gateway 192.168.1.1 sudo nmcli con mod ens160 ipv4.dns 192.168.1.1 sudo nmcli con mod ens160 ipv4.method manual注意网卡名不一定是 ens160用ip addr看清楚再改。4.3 容器间互通与自定义 bridge单机多容器场景不要全都靠-p暴露宿主机端口那样端口规划会非常混乱。更推荐的做法是用自定义 bridge 网络docker network create app-net docker run -d --network app-net --name mysql8 mysql:8.0 docker run -d --network app-net --name myapp myapp:latest同一个自定义网络里的容器互相之间可以用容器名直接访问。比如 Java 应用连数据库JDBC 地址直接写jdbc:mysql://mysql8:3306/db就行不用管 IP 是多少容器重建之后名字不变配置也不用改。这个机制在 VirtualBox 下同样适用因为这里是容器内部的网络行为和虚拟机自身的 NAT/桥接没有冲突。我实测过 mysql8 容器和业务容器放同一个自定义网络容器重启后连接依然正常比用宿主机 IP 稳定得多。5. 存储和加速运行一段时间后省心的两个设置5.1 迁移 /var/lib/docker 的实操跑几个月后Docker 的数据可能涨到几十 GB镜像、容器层、具名卷、日志都堆在 /var/lib/docker。如果当时分区给小了最省事的办法是把数据目录挪到大分区再用软链接指回原路径sudo systemctl stop docker sudo mkdir -p /data/docker sudo mv /var/lib/docker /data/docker sudo ln -s /data/docker /var/lib/docker sudo systemctl start docker迁移完成之后docker info里的 Docker Root Dir 不会变还是 /var/lib/docker但实际数据已经落在 /data 上。这个方法比改daemon.json里的>{ data-root: /data/docker }两种方式二选一别同时用软链接又用>{ registry-mirrors: [https://你的加速器地址] }保存后重启 Dockersudo systemctl restart docker注意加速器地址请填你所在网络环境实际可达的地址不同区域效果差异很大。建议配置后马上docker pull centos:latest测试如果还是超时也许是地址不可达需要换一个试试。5.3 虚拟磁盘扩容如果 CentOS 10 用过一段时间根分区满了除了清镜像还有两条路。第一条是 VirtualBox 层面扩容虚拟磁盘。先关机然后执行VBoxManage modifymedium disk /path/to/xxx.vdi --resize 40960单位是 MB所以 40960 就是 40GB。执行完成后虚拟机内部的文件系统并不知道磁盘变大了还需要第二步。第二条是虚拟机内部扩容分区。CentOS 10 根分区一般是 xfs可以用growpart和xfs_growfssudo growpart /dev/sda 2 sudo xfs_growfs /这里的/dev/sda 2只是示例实际操作前先运行lsblk确认磁盘名和分区号搞错了会出大问题。xfs 支持在线扩容不需要重启但 growpart 这一步建议还是稳妥一点在系统负载低的时候执行。6. 一段时间后必看的故障排查清单6.1 Docker 服务起不来的几种常见原因我遇到最多的一类是systemctl start docker之后状态变成 active (exited)看日志用journalctl -u docker -n 80常见报错之一和 iptables 相关。现代内核用的是 nftables而 Docker 默认调用 iptables 命令来管理宿主机规则如果系统没装iptables-nft兼容层容器网络会初始化失败。解决办法sudo dnf install -y iptables-nft sudo systemctl restart docker另一类是磁盘满。Docker 写不了日志服务反复崩溃状态怎么拉都起不来。df -h看一下清理掉没有在用的镜像docker image prune -a还有一类和 SELinux 有关。CentOS 默认开启 SELinux容器挂载目录时经常报权限被拒。个人实验环境可以直接临时设置成 permissivesudo setenforce 0但要记住这个状态重启后失效。生产环境请务必认真处理 SELinux 策略而不是一刀切关掉。6.2 VirtualBox 增强功能与共享文件夹Minimal 系统没有桌面但增强功能仍然建议装它能解决共享文件夹和剪贴板。安装前先装编译工具和内核头文件sudo dnf install -y gcc make kernel-devel kernel-headers然后挂载 VBoxGuestAdditions.iso执行里面的VBoxLinuxAdditions.run。装完重启后用lsmod | grep vboxguest确认模块加载。共享文件夹需要先关机制造虚拟机的设置里添加路径然后在虚拟机里 mountsudo mount -t vboxsf 共享名 /mnt/shared我实测下来这个功能适合传一些小文件大文件传输会有 IO 开销更推荐直接用 scp 或者 VNC。如果你愿意折腾也可以配置好后在/etc/fstab里写一行自动挂载注意挂载名里的下划线很容易写错。6.3 快照策略别让快照链越来越长VirtualBox 的快照很好用但有一个性能陷阱每次打快照后续的写入都会落到新的差异盘上。快照链越长虚拟机整体 I/O 越差而且如果你删了前面的快照后面的快照会受影响。我的策略是在干净环境打完一套基础快照随便折腾出问题就恢复确认某个实验环境以后还要用再手动打一个明确命名的快照。不要为了追求“每一步都能回退”疯狂打快照那是给虚拟机找罪受。如果你做快照做多了发现虚拟磁盘越用越慢可以在关机状态下合并快照VirtualBox 的“媒体管理”里对每个快照做“释放”或“删除”合并完成后磁盘性能会有明显改善。结尾我的使用体会这套组合我个人用了相当长时间虽然 Docker Desktop 上手更快但 VirtualBox 加 CentOS-10 加 Docker 的方式让我把内核版本、cgroup、iptables、systemd、磁盘分区这些基础知识都摸了一遍这些底子是你将来排查生产环境问题最值钱的资产。最后再分享一个小技巧安装完系统后先打一个“刚装好纯净版”的快照然后所有 Docker 相关的配置改动都在快照之上进行。这样不管后续怎么玩坏十分钟内就能回到干净状态。如果你也正在搭这套环境遇到什么奇怪的报错欢迎按照上面的排查顺序从 journalctl 开始查大概率跑不出那几类问题。希望这篇经验能帮你少走一半弯路。
返回列表