我可以在没有 bash 脚本的情况下使用 docker-compose 检查容器然后将文件从容器复制到主机吗?
Can I use docker-compose without a bash script to inspect a container then copy files to host from the container?
这是我尝试并行化的工作流程:
- docker 建造
- docker 运行
- docker 检查容器 -> returns false
- docker cp container:file /host/
我想使用 docker-compose 在单个主机上执行此操作,然后稍后过渡到 Kubernetes,以便我可以在多个主机上进行编排。
我应该创建一个 bash 脚本并将其 运行 放入 Dockerfile 中吗?
我正在寻找社区接受为最佳实践的解决方案。
在单主机-Docker 土地上,您可以尝试安排事情,以便docker run
做您需要的一切。避免 docker inspect
(它会转储出通常不感兴趣的低级诊断)和 docker cp
。根据您构建事物的方式,您可以在 Docker 文件中构建工件,然后将其复制出来
docker build -t the-image .
# use "cat" to get it out?
docker run --rm the-image \
cat /app/file \ # from the container
> file # via the container's stdout, to the host
# use volumes to get it out?
docker run --rm -v $PWD:/host the-image \
cp /app/file /host
根据您正在构建的内容,您可以进一步扩展它以批量传递输入和输出,因此图像只是一个工具链。对于最小的 Go 应用程序,使用 Docker Hub golang
image,例如:
# don't docker build anything, but run a container with the toolchain
docker run --rm \
-v $PWD:/app \
-w /app \
golang:1.15 \
go build -o the_app ./cmd/the_app
在最后的设置中,-w
工作目录是绑定安装的 /app
目录,因此 go build -o ./the_app
写入主机。
由于此设置更倾向于一次性容器(请注意 docker run --rm
选项),因此它不太适合 Compose,后者通常需要 long-运行ning 服务器类型集装箱。
此设置也不能很好地转换为 Kubernetes。 Kubernetes 并不擅长在容器之间或与集群外的系统共享文件。如果您碰巧有一个 NFS 服务器,您可以使用它,但没有本地选项;大多数 volume types 可以直接获得的是 ReadWriteOnce
不能在多个 Kubernetes Pods(容器)之间重复使用的卷。
原则上,您可以编写一个执行单个编译的 Kubernetes 作业。它不能 运行 docker build
,因此“运行”步骤必须进行实际构建。您不能 kubectl cp
离开已完成的 pod(参见 例如 kubernetes/kubectl#454),因此它需要在完成后将其内容发送到特定的地方。
这里更好的高级方法是查找或安装某种网络可访问存储,尤其是保存结果(Artifactory 服务器;对象存储,如 AWS S3)。将您的构建序列重写为一个“任务”,它获取输入和输出的位置并 运行s 构建,忽略本地文件系统。像 RabbitMQ 一样设置一个作业队列,并将任务注入队列。最后,运行 builder-worker 作为 Kubernetes Deployment;它将并行构建与部署中 replicas:
数量一样多的东西。
这是我尝试并行化的工作流程:
- docker 建造
- docker 运行
- docker 检查容器 -> returns false
- docker cp container:file /host/
我想使用 docker-compose 在单个主机上执行此操作,然后稍后过渡到 Kubernetes,以便我可以在多个主机上进行编排。
我应该创建一个 bash 脚本并将其 运行 放入 Dockerfile 中吗?
我正在寻找社区接受为最佳实践的解决方案。
在单主机-Docker 土地上,您可以尝试安排事情,以便docker run
做您需要的一切。避免 docker inspect
(它会转储出通常不感兴趣的低级诊断)和 docker cp
。根据您构建事物的方式,您可以在 Docker 文件中构建工件,然后将其复制出来
docker build -t the-image .
# use "cat" to get it out?
docker run --rm the-image \
cat /app/file \ # from the container
> file # via the container's stdout, to the host
# use volumes to get it out?
docker run --rm -v $PWD:/host the-image \
cp /app/file /host
根据您正在构建的内容,您可以进一步扩展它以批量传递输入和输出,因此图像只是一个工具链。对于最小的 Go 应用程序,使用 Docker Hub golang
image,例如:
# don't docker build anything, but run a container with the toolchain
docker run --rm \
-v $PWD:/app \
-w /app \
golang:1.15 \
go build -o the_app ./cmd/the_app
在最后的设置中,-w
工作目录是绑定安装的 /app
目录,因此 go build -o ./the_app
写入主机。
由于此设置更倾向于一次性容器(请注意 docker run --rm
选项),因此它不太适合 Compose,后者通常需要 long-运行ning 服务器类型集装箱。
此设置也不能很好地转换为 Kubernetes。 Kubernetes 并不擅长在容器之间或与集群外的系统共享文件。如果您碰巧有一个 NFS 服务器,您可以使用它,但没有本地选项;大多数 volume types 可以直接获得的是 ReadWriteOnce
不能在多个 Kubernetes Pods(容器)之间重复使用的卷。
原则上,您可以编写一个执行单个编译的 Kubernetes 作业。它不能 运行 docker build
,因此“运行”步骤必须进行实际构建。您不能 kubectl cp
离开已完成的 pod(参见 例如 kubernetes/kubectl#454),因此它需要在完成后将其内容发送到特定的地方。
这里更好的高级方法是查找或安装某种网络可访问存储,尤其是保存结果(Artifactory 服务器;对象存储,如 AWS S3)。将您的构建序列重写为一个“任务”,它获取输入和输出的位置并 运行s 构建,忽略本地文件系统。像 RabbitMQ 一样设置一个作业队列,并将任务注入队列。最后,运行 builder-worker 作为 Kubernetes Deployment;它将并行构建与部署中 replicas:
数量一样多的东西。