装机时选系统、配环境,很多人现在不只装Windows或Linux,还会顺手跑几个Docker容器——比如用一个容器跑博客程序,另一个跑数据库,再开一个跑监控工具。它们都跑在同一台机器上,却互不干扰,改了A容器的配置,B容器照样稳如老狗。这背后靠的就是容器的隔离机制。
不是虚拟机,但比进程更干净
有人以为容器就是轻量版虚拟机,其实不是。虚拟机靠Hypervisor模拟整套硬件,每个VM里都跑独立内核;而容器直接复用宿主机的Linux内核,靠的是内核提供的几项底层能力:命名空间(Namespaces)、控制组(Cgroups)、文件系统分层(Layered FS)和Capability权限裁剪。
命名空间:给每个容器划出自己的“小房间”
想象你在家里给三个孩子每人分一间房,各自有独立的书桌、抽屉、玩具箱——他们看不见彼此的物品,也不能随便进别人房间。Linux命名空间就干这事:
· pid namespace:让容器只看到自己启动的进程(比如只看到nginx和sh,看不到宿主机的systemd);
· net namespace:容器有自己独立的网卡、IP、端口、路由表;
· mount namespace:容器挂载的目录(比如/app)对宿主机和其他容器不可见;
· uts namespace:能单独设主机名和域名,hostname命令在容器里返回web-server,宿主机还是my-pc。
Cgroups:管住资源,不让你“抢电”
光隔离还不行——万一某个容器疯狂占CPU、吃光内存,整台机器就卡死。Cgroups像小区物业,给每个容器发“资源配额”:
docker run -m 512m --cpus 1.5 nginx这句命令表示:这个Nginx容器最多用512MB内存、1.5个CPU核心。超了就杀进程或限频,不影响其他容器和宿主机。
根文件系统:一层层叠出来的“专属桌面”
Docker镜像不是整个打包的磁盘镜像,而是由多个只读层+一个可写层叠加而成。比如你基于ubuntu:22.04装了python3和nginx,实际是新增两层,底层不变。不同容器可以共享基础层(省空间),又各自拥有独立的运行时修改(比如各自的日志文件、临时上传的图片),互不污染。
Capability裁剪:关掉不必要的“钥匙”
传统root用户在容器里能执行reboot、mount、setuid等高危操作。但默认情况下,Docker会去掉大部分Capabilities,只留必要权限。你可以手动再收紧:
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx意思是:啥特权都不要,只允许绑定网络端口(比如监听80)。就算容器被攻破,攻击者也拿不到宿主机的完整root权限。
动手看看隔离效果
在终端里试两行命令:
docker run -it --rm ubuntu:22.04 ps aux你会看到只有几个进程;再开一个窗口运行:
ps aux | head -5宿主机上输出的进程列表长得多。这不是Docker“隐藏”了,而是两个命名空间根本不在一个视图里——就像你站在自家阳台看楼下的车流,邻居在自家阳台看,看到的车不一样,因为你们站的位置(命名空间)不同。
装机时如果要部署多服务、做开发测试、或者想把旧软件封进“安全泡泡”再跑,理解这些隔离机制,比盲目拉镜像更有底气。它不玄乎,就是Linux内核十几年打磨出来的实打实功能,只是Docker把这些能力打包得足够傻瓜化而已。