建湖县中国转运服务网

一文带你了解linux中Docker背后的原理

2026-03-24 23:28:01 浏览次数:2
详细信息

Docker 背后的核心原理,这是理解现代容器技术的关键。

一、Docker 架构概览

Docker 的架构分为三个主要层次:

用户空间
    └── Docker Client (docker CLI)
        └── Docker Daemon (dockerd)
            └── Containerd (容器运行时管理)
                └── Containerd-shim (容器进程管理)
                    └── Runc (实际创建容器的工具)

二、核心技术原理

1. 命名空间(Namespaces) - 隔离的基石

Docker 使用 Linux 命名空间实现资源隔离:

# 查看容器的命名空间
$ ls -la /proc/<容器PID>/ns/
lrwxrwxrwx 1 root root 0 Jan 1 12:00 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Jan 1 12:00 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 root root 0 Jan 1 12:00 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 root root 0 Jan 1 12:00 net -> 'net:[4026531993]'
lrwxrwxrwx 1 root root 0 Jan 1 12:00 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Jan 1 12:00 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Jan 1 12:00 uts -> 'uts:[4026531838]'

六大命名空间的作用

2. 控制组(cgroups) - 资源限制

cgroups 限制和监控容器资源使用:

# 查看容器的 cgroup 配置
$ cat /sys/fs/cgroup/cpu/docker/<容器ID>/cpu.shares
1024

$ cat /sys/fs/cgroup/memory/docker/<容器ID>/memory.limit_in_bytes
536870912  # 512MB 限制

cgroups 子系统

3. 联合文件系统(UnionFS) - 分层的秘密

Docker 镜像使用分层存储:

# 查看镜像的分层结构
$ docker history nginx:latest
IMAGE          CREATED        CREATED BY                                      SIZE
c316d5a335a5   2 weeks ago    /bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon…"]  0B
<missing>      2 weeks ago    /bin/sh -c #(nop)  STOPSIGNAL SIGQUIT           0B
<missing>      2 weeks ago    /bin/sh -c #(nop)  EXPOSE 80                    0B
<missing>      2 weeks ago    /bin/sh -c ln -sf /dev/stdout /var/log/nginx…   0B

写时复制(Copy-on-Write)机制

基础镜像层 (只读)
    └── 添加层1 (只读)
        └── 添加层2 (只读)
            └── 容器可写层 (读写)

4. 容器网络原理

Docker 网络模型

# 查看 Docker 网络
$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
bridge         bridge    bridge    local
host           host      host      local
none           null      null      local

网络命名空间创建流程

# 创建网络命名空间
$ ip netns add mynet

# 创建 veth pair(虚拟以太网设备对)
$ ip link add veth0 type veth peer name veth1

# 将 veth1 移动到容器的网络命名空间
$ ip link set veth1 netns <容器PID>

三、Docker 启动容器完整流程

1. 命令执行流程

1. 用户执行: docker run -d nginx:latest
2. Docker Client 发送请求到 Docker Daemon
3. Daemon 检查本地是否有 nginx:latest 镜像
4. 如果没有,从 Registry 拉取镜像
5. 调用 Containerd 创建容器
6. Containerd 调用 Runc
7. Runc 创建容器:
   - 创建新的命名空间
   - 设置 cgroups 限制
   - 挂载 rootfs(使用 UnionFS)
   - 设置容器网络
   - 启动容器进程
8. Containerd-shim 接管容器进程

2. 容器创建的核心代码逻辑(简化版)

// Runc 创建容器的关键步骤
func createContainer(config ContainerConfig) {
    // 1. 创建新的命名空间
    unix.Unshare(unix.CLONE_NEWNS | 
                 unix.CLONE_NEWUTS | 
                 unix.CLONE_NEWIPC | 
                 unix.CLONE_NEWPID | 
                 unix.CLONE_NEWNET | 
                 unix.CLONE_NEWUSER)

    // 2. 设置 cgroups
    cgroupPath := filepath.Join("/sys/fs/cgroup/memory", config.ID)
    os.MkdirAll(cgroupPath, 0755)
    ioutil.WriteFile(filepath.Join(cgroupPath, "memory.limit_in_bytes"), 
                     []byte(config.MemoryLimit), 0644)

    // 3. 设置 rootfs
    mount("overlay", rootfs, "overlay", 0, 
          "lowerdir="+lowerDir+",upperdir="+upperDir+",workdir="+workDir)

    // 4. 设置网络
    setupNetwork(config.NetworkConfig)

    // 5. 执行容器进程
    syscall.Exec(config.Path, config.Args, os.Environ())
}

四、高级特性原理

1. Docker Overlay 网络

物理主机 eth0 (192.168.1.100)
    └── docker0 网桥 (172.17.0.1)
        ├── veth0 <---> veth1 (容器1: 172.17.0.2)
        └── veth2 <---> veth3 (容器2: 172.17.0.3)

# 跨主机通信通过 VXLAN
物理网络: 192.168.1.0/24
  ├── 主机A: 192.168.1.100
  │       └── 容器: 10.0.0.2
  └── 主机B: 192.168.1.101
          └── 容器: 10.0.0.3

2. 存储驱动比较

3. 容器与虚拟机对比

传统虚拟机:
  ┌─────────────────────────────────────┐
  │         App1   App2   App3          │
  │        ┌──────┬──────┬──────┐       │
  │        │Guest │Guest │Guest │       │
  │        │ OS   │ OS   │ OS   │       │
  │        └──────┴──────┴──────┘       │
  │         Hypervisor (KVM, VMware)    │
  │            Host Operating System    │
  │               Hardware              │
  └─────────────────────────────────────┘

Docker 容器:
  ┌─────────────────────────────────────┐
  │      App1   App2   App3             │
  │    ┌──────┬──────┬──────┐          │
  │    │Bins/Libs│Bins/Libs│Bins/Libs│ │
  │    └──────┴──────┴──────┘          │
  │        Docker Engine (daemon)       │
  │            Host Operating System    │
  │               Hardware              │
  └─────────────────────────────────────┘

五、安全机制

1. 安全特性

2. 安全配置示例

# 运行容器时指定安全选项
$ docker run --security-opt seccomp=profile.json \
             --cap-drop=ALL --cap-add=NET_BIND_SERVICE \
             --read-only \
             nginx:latest

六、实际调试示例

# 1. 查看容器底层信息
$ docker inspect <容器ID> | grep -A 10 "State"
$ ps aux | grep <容器PID>

# 2. 查看容器的 cgroup 限制
$ cat /sys/fs/cgroup/memory/docker/<容器ID>/memory.usage_in_bytes

# 3. 进入容器的命名空间
$ nsenter -t <容器PID> -n ip addr  # 查看容器的网络
$ nsenter -t <容器PID> -m -p chroot /proc/<容器PID>/root /bin/bash

# 4. 使用 runc 直接管理容器
$ runc list  # 查看 runc 管理的容器

七、总结要点

轻量级:共享主机内核,无需完整操作系统 快速启动:直接运行应用,无需启动完整 OS 高效资源利用:多个容器共享系统资源 一致性环境:开发、测试、生产环境一致 微服务友好:天然支持微服务架构

关键理解

理解这些底层原理,能帮助你更好地使用 Docker,排查问题,设计更合理的容器化方案。

相关推荐