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

时间:2020-07-21 08:04:04

标签: docker kubernetes

我正在使用Kubernetes和Jenkins开发自动化管道。我所有的命令都在jnlp-slave容器内部运行。 Kubernetes将jnlp-slave部署到工作节点上。我的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命令的情况下使容器将文件复制到主机?容器可以运行将文件复制到主机的命令吗?

P.S。我尝试在主机上安装卷。但是文件只能从主机共享到容器,而不能相反。谢谢您的任何帮助。

1 个答案:

答案 0 :(得分:0)

如评论中所建议,您可能应该完全重新设计解决方案。

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

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

将文件从一个容器复制到所有其他容器有点过大(顺便说一句。您将其中几个放入Pod中吗?)

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

注释中提到的

emptyDir可能是允许您实现的选项。但是,请记住,存储在emptyDir卷中的数据不会以任何方式持久存在,并且会随着吊舱的删除而被删除。如果您对此表示满意,那么这可能是您的解决方案。

如果您的数据最初是图像的一部分,则应首先将其传输到您的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: {}

emptyDir将数据复制到initContainer卷之后,所有主要containers都可以使用它,并且它们中的每一个都可以安装在同一路径下