在容器内将文件从容器复制到主机 [英] Copy files from container to host while inside the container

查看:56
本文介绍了在容器内将文件从容器复制到主机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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.我已经尝试在主机上安装卷.但是文件只能从主机共享到容器,而不能相反.感谢您的任何帮助.

解决方案

如注释中所建议,您可能应该完全重新设计解决方案.

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

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

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

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

emptyDir 可能是允许您执行以下操作的选项实现这一目标.但是,请记住,存储在 emptyDir 卷中的数据不会以任何方式持久保存,并且会随着删除Pod而被删除.如果您对此表示满意,那么这可能是您的解决方案.

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

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

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

  apiVersion:apps/v1种类:部署元数据:名称:样本部署规格:复制品:1选择器:matchLabels:应用:示例应用模板:元数据:标签:应用:示例应用规格:initContainers:-名称:pre-populate-empty-dir图片:< image-1>命令:['sh','-c','cp -a/home/jenkins/workspace/*/mnt/empty-dir-content/']volumeMounts:-名称:缓存量mountPath:"/mnt/empty-dir-content/";容器:-名称:app-container-1图片:< image-1>端口:-containerPort:8081volumeMounts:-名称:缓存量mountPath:"/home/jenkins/workspace";-名称:app-container-2图片:< image-2>端口:-containerPort:8082volumeMounts:-名称:缓存量mountPath:"/home/jenkins/workspace";-名称:app-container-3图片:< image-3>端口:-containerPort:8083volumeMounts:-名称:缓存量mountPath:"/home/jenkins/workspace";数量:-名称:缓存量emptyDir:{} 

一旦您的数据已由 initContainer 复制到 emptyDir 卷,则所有主要的 containers 都可以使用该数据,并且可以它们每个都安装在同一条路径下.

I'm working on automation pipeline using Kubernetes and Jenkins. All my commands are running from inside the jnlp-slave container. The jnlp-slave is deployed onto a worker node by Kubernetes. I have -v /var/run/docker.sock on my jnlp-slave so it can run docker commands from inside the container.

Issue:

I'm trying to copy files inside the jnlp-slave container to the host machine (worker node), but the command below does not copy files to host machine, but to destination of the container itself:

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


Clarification:

Since the container is executing the command, files located inside the container is copied to the destination path which is also inside the container.

Normally, docker commands are executed on the host machine. Therefore, the docker cp can be used to copy files from container to host and from host to container. But in this case, the docker cp is executed from inside the container.


How can I make the container to copy files to the host machine without running docker commands on the host? Is there a command which the container can run to copy files to the host?

P.S. I've tried mounting volume on the host. But the files only can be shared from the host to the container and not the other way around. Any help is appreciated, thanks.

解决方案

As suggested in comments, you should probably redesign entirely your solution.

But let's summarize what you currently have and try to figure out what you can do with it and not make your solution even more complicated at the same time.

What I did was copy the files from jnlp-slave container to the other containers.

Copying files from one container to all others is a bit an overkill (btw. How many of them do you place in one Pod ?)

Maybe your containers don't have to be deployed withing the same Pod ? If for some reason this is currently impossible, maybe at least the content of the /home/jenkins/workspace directory shouldn't be integral part of your docker image as it is now ? If this is also impossible, you have no other remedy than to copy somehow those files from the original container based on that image to the shared location which is also available for other containers existing within the same Pod.

emptyDir, mentioned in comments might be an option allowing you to achieve it. However keep in mind that the data stored in an emptyDir volume is not persistent in any way and is deleted along with the deletion of the pod. If you're ok with this fact, it may be a solution for you.

If your data is originally part of your image, it should be first transferred to your emptyDir volume as by its very definition it is initially empty. Simply mounting it under /home/jenkins/workspace won't make the data originally available in this directory in your container automagically appear in the emptyDir volume. From the moment you mount your emptyDir under /home/jenkins/workspace it will contain the content of emptyDir i.e. nothing.

Therefore you need to pre-populate it somehow and one of the available solutions to do that is using an initContainer. As your data is originally the integral part of your docker image, you must use the same image also for the initContainer.

Your deployment may look similar to the one below:

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: {}

Once your data has been copied to an emptyDir volume by the initContainer, it will be available for all the main containers and can be mounted under the same path by each of them.

这篇关于在容器内将文件从容器复制到主机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆