文章目录
docker in docker
说白了,就是在docker容器内启动一个docker daemon,对外提供服务。
每个运行中的容器,都是一个进程;这个进程都托管在docker daemon中。
优点在于:
- 镜像和容器都在一个隔离的环境,保持宿主机的环境。
- 想到了再补充 :)
一、实现方式
dind一般分两种方式:
- 一种是使用宿主机的docker.sock,通过docker run -v /var/run/docker.sock:/var/run/docker.sock,将宿主机sock引入到容器内。这样当容器内使用docker命令时,实际上调用的是宿主机的docker daemon,这种方式速度快,但是安全性不够。
- 另一种是启动一个docker:dind容器a,再启动一个docker容器b,容器b指定host为a容器内的docker daemon;
二、低版本启动及访问
启动1.12.6-dind
docker run --privileged -d --name mydocker docker:1.12.6-dind
在其他容器访问
docker run --rm --link mydocker:docker docker:1.12.6 version
在宿主机访问
docker -H 172.17.0.2:2375 version
docker -H 0.0.0.0:${hostport} version
三、18.09以上dind镜像,加入了tls
19.03+默认tls模式,通过DOCKER_TLS_CERTDIR=‘’,可以关闭
#启动stable 19.03.1版本
docker run --privileged --name some-docker -d \
#--network some-network --network-alias docker \
-e DOCKER_TLS_CERTDIR=/certs \
-v some-docker-certs-ca:/certs/ca \
-v some-docker-certs-client:/certs/client \
docker:stable-dind
#其他容器内访问
docker run --rm \
#--network some-network \
-e DOCKER_TLS_CERTDIR=/certs \
-v some-docker-certs-client:/certs/client:ro \
--link some-docker:docker \
docker:stable version
四、dind实现原理
- build时,使用的docker cli版本是dind内的版本
- 传递数据到dind容器,然后再编译
- 编译压力在dind容器内
- 通过抓包,可以其实这是一个http请求
- 代码:
func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) {
query, err := cli.imageBuildOptionsToQuery(options)
if err != nil {
return types.ImageBuildResponse{
}, err
}
headers := http.Header(make