Docker 是如何实现隔离的呢?

149 阅读4分钟

引言

容器的技术核心在于提供轻量级、可移植的隔离环境,而docker作为容器生态的领军者,其底层机制依靠Linux内核的三大核心能力:Namespace(命名空间)Cgroups(控制组)UnionFS()联合文件系统

一、容器隔离的本质

1.什么是隔离?

容器的隔离目标是让每个进程(或进程组)认为自己独占系统资源,包括

  • 独立的进程树(PID隔离)
  • 独立的文件系统(Mount隔离)
  • 独立的网络栈(Net隔离)
  • 资源使用限制(CPU、内存、磁盘等)

2.容器 VS 虚拟机

特性Docker 容器虚拟机
虚拟化层级操作系统级(共享内核)硬件级(独立内核)
启动速度秒级分钟级
资源占用低(MB 级内存)高(GB 级内存)
隔离性进程级隔离完全硬件隔离

二、Linux Namespace:资源视图隔离

Namespace 是 Linux 内核提供的资源隔离机制,Docker 使用他创建“独立环境”的假象。

1.核心 Namespace 类型

1.PID Namespace

  • 作用 :隔离进程ID,容器内进程无法看到宿主机或其他容器的进程
  • 示例
# 宿主机查看容器进程
docker run -d --name nginx nginx
docker inspect --format '{{.State.Pid}}' nginx  # 输出容器主进程 PID(如 1234)
ps -ef | grep 1234  # 宿主机视角的进程

# 进入容器查看进程
docker exec nginx ps aux
# 容器内 PID 1 是 nginx,而宿主机中该进程 PID 为 1234

2.Mount Namespace

  • 作用:隔离文件系统挂载点,容器可以拥有独立的/根目录
  • 底层原理:通过unshare(CLONE_NEWNS)创建独立的挂载视图

3.Net Namespace

  • 作用:隔离网络设备,IP地址、端口等
  • 实现方式:每个容器拥有独立的虚拟网卡(如 veth0)和路由表

4.其他 Namespace

  • UTS Namespace:隔离主机名(hostname
  • IPC Namespace:隔离进程间通信(共享内存、信号量)
  • User Namespace:隔离用户 UID/GID (允许非 root 用户运行容器)

三、Cgroups:资源配额限制

Cgroups(Control Groups)是Linux内核提供的资源限制和统计机制,Docker 用它限制容器资源的使用。

1. Cgroups 的核心功能

子系统功能
cpu限制 CPU 使用率(如分配 50% 时间片)
memory限制内存使用量(如最大 500MB)
blkio限制磁盘 I/O 带宽
devices控制设备访问权限
pids限制最大进程数

2. Docker 资源限制示例

# 启动一个容器,限制 CPU 和内存
docker run -it --rm \
  --cpus=0.5 \          # 使用 0.5 核 CPU
  --memory=500m \       # 内存限制为 500MB
  --blkio-weight=500 \  # 磁盘 I/O 权重
  alpine sh

3. 手动操作 Cgroups

# 创建 Cgroup
mkdir /sys/fs/cgroup/memory/mydocker
echo 500000000 > /sys/fs/cgroup/memory/mydocker/memory.limit_in_bytes

# 将进程加入 Cgroup
echo <PID> > /sys/fs/cgroup/memory/mydocker/tasks

# 查看内存使用
cat /sys/fs/cgroup/memory/mydocker/memory.usage_in_bytes

四、UnionFS:文件系统隔离

UnionFS(联合文件系统)是 Docker 镜像分层存储和容器文件系统隔离的基础。

1. 镜像分层结构

  • 只读层(镜像层)​:Dockerfile 每条指令生成一个层。

  • 可写层(容器层)​:容器运行时的修改存储在此层。

  • 示例

    # 查看镜像分层
    docker inspect --format='{{.RootFS}}' nginx
    # 输出类似:[sha256:... sha256:...](各层 ID)
    

2. 写时复制(Copy-on-Write)​

  • 读取文件:从底层镜像层直接读取。
  • 修改文件:复制文件到可写层后再修改。
  • 删除文件:在可写层标记文件为删除(实际仍在镜像层)。

3. OverlayFS 工作原理

  • LowerDir:只读镜像层(多个层叠加)。
  • UpperDir:可写层(容器修改存储在此)。
  • MergedDir:合并后的视图(容器看到的文件系统)。
  • WorkDir:OverlayFS 内部工作目录。

五、安全加固机制

1. Capabilities(权能)​

  • 默认禁用高危权限:容器内进程无法执行 mountreboot 等操作。

  • 授权示例

    docker run --cap-add NET_ADMIN nginx  # 允许网络管理权限
    

2. Seccomp(系统调用过滤)​

  • 默认配置文件:禁止容器执行 44 个高危系统调用(如 sysctl)。

  • 自定义规则

    {
      "defaultAction": "SCMP_ACT_ALLOW",
      "syscalls": [
        {
          "names": ["mount"],
          "action": "SCMP_ACT_ERRNO"
        }
      ]
    }
    

3. AppArmor/SELinux

  • 强制访问控制:限制容器进程访问宿主机敏感路径。
  • 示例:禁止容器写入 /etc 目录。

六、总结

  • 隔离是容器的核心:依赖 Namespace(视图隔离)、Cgroups(资源限制)、UnionFS(文件隔离)。
  • 安全是关键:默认启用 Seccomp、Capabilities 限制,避免使用 --privileged
  • 性能优化:选择合适的基础镜像,限制资源配额,避免过度隔离。