在不使用kubectl cp的情况下将文件复制到kubernetes pod

时间:2019-04-29 07:13:33

标签: kubernetes

我有一个用例,其中我的pod以非root用户身份运行,并且运行python应用程序。 现在,我想将文件从主节点复制到运行的Pod。但是当我尝试运行

void interrupt myISR(void)
{
........
}

该命令挂起,但是当我以root用户身份运行pod并运行相同的命令时 它执行成功。我正在查看kubectl cp的代码,其中它内部使用tar命令。

Tar命令有多个标志,例如--overwrite --no-same-owner,--no-preserve和其他几个标志。现在,从kubectl cp中,我们无法将所有这些标志传递给tar。是否可以使用kubectl exec命令或其他任何方式复制文件。

kubectl cp app.py 103000-pras-dev/simplehttp-777fd86759-w79pn:/tmp

3 个答案:

答案 0 :(得分:0)

同时我发现了一个黑客,免责声明,这并不是确切的kubectl cp,只是一种解决方法。

我编写了一个go程序,在其中创建了一个goroutine来读取文件,并将其附加到stdin并使用适当的标志运行kubectl exec tar命令。这是我所做的

reader, writer := io.Pipe()
copy := exec.CommandContext(ctx, "kubectl", "exec", pod.Name, "--namespace", pod.Namespace, "-c", container.Name, "-i",
    "--", "tar", "xmf", "-", "-C", "/", "--no-same-owner") // pass all the flags you want to
copy.Stdin = reader
go func() {
    defer writer.Close()

    if err := util.CreateMappedTar(writer, "/", files); err != nil {
        logrus.Errorln("Error creating tar archive:", err)
    }
}()

Helper函数定义

func CreateMappedTar(w io.Writer, root string, pathMap map[string]string) error {
    tw := tar.NewWriter(w)
    defer tw.Close()

    for src, dst := range pathMap {
        if err := addFileToTar(root, src, dst, tw); err != nil {
            return err
        }

    }

    return nil
}

很明显,由于权限问题,这东西不起作用,但是*我能够传递tar标志

答案 1 :(得分:0)

如果只是文本文件,也可以通过netcat“复制”。

1)您必须在两个节点上都登录

$ kubectl exec -ti <pod_name> bash

2)如果没有安装,请确保具有netcat

$ apt-get update
$ apt-get install netcat-openbsd

3)转到具有权限的文件夹,即

/tmp

4)在您要写入python文件的容器内

$ cat app.py | nc -l <random_port>

示例

$ cat app.py | nc -l 1234

它将开始在提供的端口上侦听。

5)在您想要存储文件的容器内

$ nc <PodIP_where_you_have_py_file> > app.py 

示例

$ nc 10.36.18.9 1234 > app.py

必须为POD IP ,它将无法识别广告连播名称。要获取IP,请使用kubectl get pods -o wide

它将复制app.py文件的内容到另一个容器文件。不幸的是,您将需要手动添加权限,或者可以使用如下脚本(由于“复制”的速度,睡眠是必需的):

#!/bin/sh
nc 10.36.18.9 1234 > app.py | sleep 2 |chmod 770 app.py;

答案 2 :(得分:0)

如果源文件是一个简单的文本文件,这是我的窍门:

#!/usr/bin/env bash

function copy_text_to_pod() {
  namespace=$1
  pod_name=$2
  src_filename=$3
  dest_filename=$4

  base64_text=`cat $src_filename | base64`
  kubectl exec -n $namespace $pod_name -- bash -c "echo \"$base64_text\" | base64 -d > $dest_filename"
}

copy_text_to_pod my-namespace my-pod-name /path/of/source/file /path/of/target/file

也许没有必要使用base64。我把它放在这里,以防源文件中有一些特殊字符。