在容器内将文件从容器复制到主机

Posted

技术标签:

【中文标题】在容器内将文件从容器复制到主机【英文标题】:Copy files from container to host while inside the container 【发布时间】:2020-11-10 13:43:21 【问题描述】:

我正在使用 Kubernetes 和 Jenkins 开发自动化管道。我所有的命令都是从 jnlp-slave 容器内部运行的。 jnlp-slave 由 Kubernetes 部署到工作节点上。我的 jnlp-slave 上有 -v /var/run/docker.sock ,因此它可以从容器内部运行 docker 命令。

问题:

我正在尝试将 jnlp-slave 容器内的文件复制到主机(工作节点),但下面的命令不会将文件复制到主机,而是复制到容器本身的目标:

docker cp <container_id>:/home/jenkins/workspace /home/jenkins/workspace

澄清

由于容器正在执行命令,位于容器内的文件被复制到容器内的目标路径。

通常,docker 命令在主机上执行。因此,docker cp 可用于将文件从容器复制到主机以及从主机复制到容器。但在这种情况下,docker cp 是从容器内部执行的。


如何使容器将文件复制到主机而不在主机上运行 docker 命令?容器是否可以运行命令将文件复制到主机?

附:我已经尝试在主机上安装卷。但是文件只能从主机共享到容器,反之则不行。任何帮助表示赞赏,谢谢。

【问题讨论】:

不要删除旧问题再问同样的问题 抱歉,您错误地将我的问题标记为重复问题。我已经修改了我的问题,但它已经关闭了。 你应该在上一个问题中评论过,我会重新打开它..删除并提出相同的问题可能会导致问题被禁止 抱歉,我会牢记这一点。我不经常发帖。 您想使用 Docker 将文件从 Kubernetes pod 复制到集群中某处的随机主机文件系统上吗?您可以重新设计它以将文件推送到已知位置或将文件拉出 pod,而无需特别涉及主机文件系统之一。 【参考方案1】:

按照 cmets 的建议,您可能应该完全重新设计您的解决方案。

但是让我们总结一下您目前拥有的东西,并尝试弄清楚您可以用它做什么,同时不要让您的解决方案变得更加复杂。

我所做的是将文件从 jnlp-slave 容器复制到另一个 容器。

将文件从一个容器复制到所有其他容器有点矫枉过正(顺便说一句。您将其中多少个放在一个容器中 Pod ?)

也许您的容器不必使用相同的 Pod 进行部署?如果由于某种原因这目前是不可能的,那么至少/home/jenkins/workspace 目录的内容不应该像现在一样成为您的 docker 映像的组成部分?如果这也是不可能的,除了以某种方式将这些文件从基于该映像的原始容器复制到共享位置之外,您别无他法,该共享位置也可用于同一 Pod 中存在的其他容器。

emptyDir,在 cmets 中提到可能是一个允许您实现它的选项。但是请记住,存储在emptyDir 卷中的数据不会以任何方式持久化,并且会随着 pod 的删除而被删除。如果您对此事实感到满意,那么这可能是您的解决方案。

如果您的数据最初是图像的一部分,则应首先将其传输到您的 emptyDir 卷,因为根据其定义,它最初是空的。简单地将其安装在/home/jenkins/workspace 下不会使容器中此目录中最初可用的数据自动出现在emptyDir 卷中。从您将emptyDir 挂载到/home/jenkins/workspace 下的那一刻起,它将包含emptyDir 的内容,即什么都没有。

因此,您需要以某种方式预先填充它,并且可用的解决方案之一是使用initContainer。由于您的数据最初是 docker 映像的组成部分,因此您也必须为 initContainer 使用相同的映像。

您的部署可能与以下类似:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      initContainers:
      - name: pre-populate-empty-dir
        image: <image-1>
        command: ['sh', '-c', 'cp -a /home/jenkins/workspace/* /mnt/empty-dir-content/']
        volumeMounts:
         - name: cache-volume
           mountPath: "/mnt/empty-dir-content/"
      containers:
      - name: app-container-1
        image: <image-1>
        ports:
        - containerPort: 8081
        volumeMounts:
          - name: cache-volume
            mountPath: "/home/jenkins/workspace"
      - name: app-container-2
        image: <image-2>
        ports:
        - containerPort: 8082
        volumeMounts:
          - name: cache-volume
            mountPath: "/home/jenkins/workspace"
      - name: app-container-3
        image: <image-3>
        ports:
        - containerPort: 8083
        volumeMounts:
          - name: cache-volume
            mountPath: "/home/jenkins/workspace"
      volumes:
      - name: cache-volume
        emptyDir: 

一旦您的数据被initContainer 复制到emptyDir 卷中,它将可供所有主要containers 使用,并且每个人都可以将其安装在同一路径下。

【讨论】:

以上是关于在容器内将文件从容器复制到主机的主要内容,如果未能解决你的问题,请参考以下文章

docker cp:从容器复制文件到宿主机,从宿主机复制文件到容器

docker cp:从容器复制文件到宿主机,从宿主机复制文件到容器

Docker将文件从主机复制到容器

Docker之宿主机与容器之间的文件复制与挂载

Docker之宿主机与容器之间的文件复制与挂载

Docker核心基础之容器的文件复制与挂载