本文介绍在 Docker 中使用 Docker(Docker in Docker)的一种实现方法。
Docker 本身是 C/S 架构的。docker 命令本质上是一个命令行客户端,它将用户请求发送给 dockerd 服务,真正做事情的是 dockerd。因为 dockerd 监听本机的 Unix Socket,docker 请求本机的 dockerd,所以给人带来的感觉是 docker 命令做了全部事情。
在单独的服务器启动 dockerd,并使其绑定一个 TCP Socket。比如:
xxxxxxxxxx
/usr/bin/dockerd -H tcp://0.0.0.0:5678 -H fd:// --containerd=/run/containerd/containerd.sock
下面是一个 Python(3.10)示例。
项目结构:
xxxxxxxxxx
.
├── Dockerfile
├── main.py
Dockerfile:
xxxxxxxxxx
FROM python:3.10-alpine3.16
# 安装 Docker Client
RUN pip3 install docker==6.0.0
WORKDIR /dind-demo
# 拷贝文件
COPY main.py /dind-demo/main.py
COPY Dockerfile /dind-demo/Dockerfile
main.py:
x
import datetime
import docker
# 创建客户端
client = docker.DockerClient(
base_url="tcp://X.X.X.X:Port",
timeout=30,
max_pool_size=10
)
# 测试拉镜像
pulled_image = client.images.pull("alpine", tag="3.15")
print(f"pulled image {pulled_image} just now")
# 测试打镜像
built_image, building_logs = client.images.build(
path=".",
tag=f"docker-in-docker-demo:{datetime.datetime.now().strftime('%Y%m%d%H%M%S')}")
print(f"Image {built_image} was built just now")
print("building logs shown below:")
for line in building_logs:
print(line)
# 测试删除镜像
client.images.remove(image="alpine:3.15", force=True)
print("alpine:3.15 was deleted just now")
其中 X.X.X.X:Port 需要被替换成运行 dockerd 的服务器的 IP 地址和 dockerd 监听的端口。
打测试镜像:
docker build -t dind-demo:dind-demo-test .
启动容器:
xxxxxxxxxx
docker container run --rm -it dind-demo:dind-demo-test /bin/sh
在容器中执行:
xxxxxxxxxx
python main.py
输出类似:
xpulled image <Image: 'alpine:3.15'> just now
Image <Image: 'docker-in-docker-demo:20221017073232'> was built just now
building logs shown below:
{'stream': 'Step 1/5 : FROM python:3.10-alpine3.16'}
{'stream': '\n'}
{'stream': ' ---> 880fc229346e\n'}
{'stream': 'Step 2/5 : RUN pip3 install docker==6.0.0'}
{'stream': '\n'}
{'stream': ' ---> Using cache\n'}
{'stream': ' ---> e5b05ed4c9e9\n'}
{'stream': 'Step 3/5 : WORKDIR /dind-demo'}
{'stream': '\n'}
{'stream': ' ---> Using cache\n'}
{'stream': ' ---> 68802a86d706\n'}
{'stream': 'Step 4/5 : COPY main.py /dind-demo/main.py'}
{'stream': '\n'}
{'stream': ' ---> 206cff9020a6\n'}
{'stream': 'Step 5/5 : COPY Dockerfile /dind-demo/Dockerfile'}
{'stream': '\n'}
{'stream': ' ---> c2a433550566\n'}
{'aux': {'ID': 'sha256:c2a4335505668083445a1fe5e360f5673d13c7b4c90dfaf1376757511a227d3c'}}
{'stream': 'Successfully built c2a433550566\n'}
{'stream': 'Successfully tagged docker-in-docker-demo:20221017073232\n'}
alpine:3.15 was deleted just now
查看在容器中创建的镜像(在运行 dockerd 的服务器上执行):
xxxxxxxxxx
docker image ls docker-in-docker-demo