Docker in docker

HostPath挂载

容器启动时, 挂载/var/run/docker.sock和/usr/bin/docker,即可在容器中执行docker命令。此时docker server仍运行在host机上,docker in docker 实际操作的是宿主机docker。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
kind: Deployment
apiVersion: apps/v1
metadata:
name: docker-in-docker-mount
namespace: default
spec:
replicas: 1
template:
metadata:
labels:
app: docker-in-docker-mount
spec:
volumes:
- name: docker-socket
hostPath:
path: /var/run/docker.sock
type: ''
- name: docker-cmd
hostPath:
path: /usr/bin/docker
type: ''
containers:
- name: container-0
image: 'ubuntu-docker-in-docker:latest'
command:
- /bin/bash
args:
- '-c'
- 'echo hello;docker image ls'
volumeMounts:
- name: docker-socket
mountPath: /var/run/docker.sock
- name: docker-cmd
mountPath: /usr/bin/docker

docker dind

docker 官方提供了docker in docker镜像: docker pull docker:18.09.7-dind, 直接使用此镜像即可在容器中在运行容器. 但是此种方式运行权限需要为特权容器, 在K8s设置securityContext.privileged为true

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
kind: Deployment
apiVersion: apps/v1
metadata:
name: dind-test10
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: dind-test10
template:
metadata:
labels:
app: dind-test10
spec:
containers:
- name: container-0
image: 'docker:18.09.7-dind'
command:
- /bin/sh
args:
- '-c'
- 'echo hello;docker image ls'
securityContext:
privileged: true
procMount: Default

两者比较

比较项 HostPath Dind
安全性 中, docker命令可以注入宿主机之中 低, 特权容器所有权限开放, 不能有用户代码存在容器之中
简便性 中, 需要额外设置HostPath 高, 配置简单, 一键使用
并发性 高, 可以用于任何容器 低, 只能基于Dind基础镜像之上构做镜像

结论: 能用HostPath模式尽量使用:

  • 如果需要在容器运行UDF, 这两种权限都不能使用, 相对来说HostPath的威胁小一点点
  • 如果要自定义镜像, 使用HostPath
  • 如果只是调用docker命令, 可以使用Dind, 但还是推荐使用HostPath, 因为你也许知道权限问题, 但是他人接手你工作的时候, 可能并不清楚