15.1.5 Docker运行原理与关键流程

Docker运行原理基于“客户端—守护进程—容器运行时”的协作模型:Docker CLI/REST API向dockerd发起请求,dockerd负责镜像管理、网络与存储编排,并通过containerd/OCI运行时创建与管理容器进程。容器本质是宿主机上的隔离进程,依赖Linux内核的Namespace与Cgroup实现资源隔离与限制,联合文件系统实现镜像与容器层。

原理草图:运行链路与核心组件

文章图片

关键组件协作流程
- Docker Client:发起build/pull/run/exec等操作,经REST API与dockerd通信。
- Docker Daemon(dockerd):核心调度与资源编排,调用containerd管理镜像与容器。
- containerd:负责镜像生命周期与容器生命周期管理。
- runc/OCI运行时:按OCI规范创建容器进程并完成Namespace/Cgroup设置。
- Network/Storage Driver:完成虚拟网络、桥接与卷挂载等操作。


关键流程示例与命令解释#

1)查看运行时与驱动(验证运行链路)

# 查看Docker版本与运行时
docker version

# 查看容器运行时与存储/网络驱动
docker info | egrep -i "Runtimes|Default Runtime|Storage Driver|Logging Driver|Cgroup Driver|Plugins"

# 预期:Default Runtime为runc,Storage Driver常见为overlay2

2)镜像拉取流程(pull)

# 拉取镜像:客户端请求 -> dockerd -> registry -> 分层镜像
docker pull nginx:1.25

# 查看本地镜像层与元数据
docker image inspect nginx:1.25 --format '{{.Id}} {{.Os}} {{.RootFS.Type}}'

3)构建流程(build)

# Dockerfile示例(保存为./Dockerfile)
cat > Dockerfile <<'EOF'
FROM alpine:3.19
RUN apk add --no-cache curl
CMD ["sh", "-c", "curl -s https://example.com | head -n 2"]
EOF

# 构建镜像:每条指令生成新层
docker build -t demo/curl:1.0 .

# 查看构建缓存与层信息
docker history demo/curl:1.0

4)容器启动关键流程(docker run)

# 运行容器,映射端口与限制CPU/内存
docker run -d --name web \
  -p 8080:80 \
  --cpus=0.5 --memory=256m \
  nginx:1.25

# 查看容器状态与进程
docker ps
docker top web

命令解释
- docker run:触发创建容器、分配网络命名空间、挂载文件系统、调用runc启动进程。
- --cpus/--memory:对应Cgroup限制,影响容器资源调度。
- -p 8080:80:端口映射,涉及iptables NAT规则。


网络与存储运行机制示例#

1)网络:bridge与端口映射验证

# 查看docker0桥接网络
ip addr show docker0

# 查看容器网络命名空间与IP
docker inspect -f '{{.NetworkSettings.IPAddress}}' web

# 访问验证
curl -I http://127.0.0.1:8080

2)存储:可写层与数据卷

# 创建卷并挂载
docker volume create data_vol
docker run -d --name app \
  -v data_vol:/data \
  alpine:3.19 sh -c "echo hello > /data/hello.txt && sleep 3600"

# 容器删除后数据仍在卷中
docker rm -f app
docker run --rm -v data_vol:/data alpine:3.19 cat /data/hello.txt

常见排错与诊断命令(含预期效果)#

1)容器启动失败

# 查看容器退出码与日志
docker ps -a
docker logs <容器ID>
docker inspect -f '{{.State.ExitCode}} {{.State.Error}}' <容器ID>
  • 预期:若退出码非0,结合日志定位入口命令或权限问题。

2)镜像拉取失败

# 验证DNS与Registry连通性
nslookup registry-1.docker.io
curl -I https://registry-1.docker.io/v2/

# 配置镜像加速(示例,路径:/etc/docker/daemon.json)
cat > /etc/docker/daemon.json <<'EOF'
{
  "registry-mirrors": ["https://xxxx.mirror.aliyuncs.com"]
}
EOF
systemctl restart docker

3)网络不通

# 检查端口映射与iptables
docker port web
iptables -t nat -L -n | grep 8080

# 检查容器内部网络
docker exec -it web sh -c "ip addr; ping -c 1 8.8.8.8"

4)性能问题与资源限制

# 查看容器实时资源使用
docker stats --no-stream

# 查看cgroup限制(以systemd为例)
systemd-cgls | grep -A2 docker

练习(带预期结果)#

1)验证运行链路
- 任务:查看默认运行时与存储驱动。
- 命令:docker info | egrep -i "Default Runtime|Storage Driver"
- 预期:输出包含Default Runtime: runcStorage Driver: overlay2(或其他驱动)。

2)构建并运行自定义镜像
- 任务:使用给定Dockerfile构建镜像并运行,输出网页前两行。
- 命令:docker build -t demo/curl:1.0 . && docker run --rm demo/curl:1.0
- 预期:终端显示example.com页面前两行HTML内容。

3)验证数据持久化
- 任务:创建卷写入文件,删除容器后读取文件。
- 预期:读取到hello

4)模拟启动失败并排错
- 任务:运行不存在的命令导致容器退出,查看退出码。

docker run --name bad alpine:3.19 nosuchcmd
docker inspect -f '{{.State.ExitCode}} {{.State.Error}}' bad
  • 预期:退出码非0,State.Error显示命令不存在。