我可以在没有 bash 脚本的情况下使用 docker-compose 检查容器然后将文件从容器复制到主机吗?

Can I use docker-compose without a bash script to inspect a container then copy files to host from the container?

这是我尝试并行化的工作流程:

  1. docker 建造
  2. docker 运行
  3. docker 检查容器 -> returns false
  4. 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: 数量一样多的东西。