Docker in Docker
CI/CD 流水线常需在容器内执行 Docker 命令,下面介绍两种方案。
DinD (Docker in Docker)
使用官方 DinD 镜像
YAML
# docker-compose.yml
services:
docker:
image: docker:24-dind
privileged: true
ports:
- "2375:2375"
ci:
image: docker:24
command: docker run hello-world
environment:
DOCKER_HOST: tcp://docker:2375
depends_on:
- docker
DinD 在容器内运行完整 Docker Daemon,需要
--privileged特权。
Socket 绑定(推荐)
挂载 Docker Socket
YAML
# docker-compose.yml
services:
ci:
image: docker:24
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: docker ps
Bash
# 运行
docker run -v /var/run/docker.sock:/var/run/docker.sock \
docker:24 docker ps
Socket 绑定复用宿主 Docker Daemon,无需特权,更安全。
对比
| 对比项 | DinD | Socket 绑定 |
|---|---|---|
| 特权 | 需要 --privileged | 不需要 |
| 隔离 | 完全隔离 | 共享宿主 Daemon |
| 性能 | 额外开销 | 无开销 |
| 安全 | 较低(特权容器) | 较高 |
| 推荐度 | ⚠️ 特殊场景 | ✅ 推荐 |
GitLab Runner 配置
toml
# config.toml
[[runners]]
executor = "docker"
[runners.docker]
image = "docker:24"
privileged = true
volumes = ["/var/run/docker.sock:/var/run/docker.sock"]
Jenkins Agent
YAML
# docker-compose.yml
services:
jenkins-agent:
image: jenkins/inbound-agent
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker
environment:
- JENKINS_URL=http://jenkins:8080
安全注意
Bash
# Socket 绑定可完全控制宿主 Docker
# 相当于 root 访问宿主
# 限制措施:
# 1. 使用 DinD 隔离(需要特权)
# 2. 使用 rootless Docker
# 3. 使用特权白名单
要点总结
- DinD 在容器内运行完整 Docker Daemon,需要特权
- Socket 绑定挂载
/var/run/docker.sock,复用宿主 Daemon - Socket 绑定更安全、性能更好,推荐使用
- DinD 适合完全隔离场景,但特权容器有风险
- CI/CD 流水线优先使用 Socket 绑定方案
📝 发现内容有误?点击此处直接编辑