不使用kubectl cp将文件复制到kubernetes Pod

siotufzp  于 2022-11-02  发布在  Kubernetes
关注(0)|答案(4)|浏览(183)

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

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

这个命令挂起了,但是当我以root用户身份运行pod,然后运行同一个命令时,它会成功执行。我正在浏览kubectl cp的代码,它在内部使用tar命令。
Tar命令有多个标志,如--overwrite --no-same-owner,--no-preserve和其他一些标志。现在我们不能从kubectl cp将所有这些标志传递给tar。有没有什么方法可以使用kubectl exec命令或其他方法复制文件?

kubectl exec simplehttp-777fd86759-w79pn -- cp app.py /tmp/**flags**
8iwquhpp

8iwquhpp1#

如果源文件是一个简单的文本文件,下面是我的技巧:


# !/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是不必要的。我把它放在这里的情况下,有一些特殊的字符在源文件。

sirbozc5

sirbozc52#

同时,我发现了一个黑客,免责声明这不是确切的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标志

c0vxltue

c0vxltue3#

如果它只是一个文本文件,也可以通过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,它将无法识别pod名称。要获取IP,请使用kubectl get pods -o wide

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


# !/bin/sh

nc 10.36.18.9 1234 > app.py | sleep 2 |chmod 770 app.py;
oknwwptz

oknwwptz4#

不使用kubectl cp将文件复制到kubernetes pod
使用kubectl cp有点麻烦。例如:

  • 安装kubectl并配置它(可能在多台机器上需要它)。在我们公司,大多数人只有一个限制性的kubectl访问从牧场web图形用户界面。没有CLI访问提供给大多数人。
  • 企业中的网络限制
  • 大文件下载/上传有时可能会停止或冻结,可能是因为流量通过k8s API服务器。
  • 奇怪的tar相关错误不断弹出等。

不支持从pod(或其他方式)复制文件的原因之一是,k8s pod从未像VM一样使用。它们是短暂的。因此,预期不会在pod/容器磁盘上存储/创建任何文件。
但有时我们不得不这样做,尤其是在调试问题或使用外部卷时。

以下是我们认为有效的解决方案。这可能不适合您/您的团队。

我们现在使用azureblob storage作为中介,在Kubernetes pod和任何其他位置之间交换文件。修改容器映像以包含azcopy实用程序(下面的Dockerfile RUN指令将在您的容器中安装azcopy)。

RUN /bin/bash -c 'wget https://azcopyvnext.azureedge.net/release20220511/azcopy_linux_amd64_10.15.0.tar.gz && \
  tar -xvzf azcopy_linux_amd64_10.15.0.tar.gz && \
  cp ./azcopy_linux_amd64_*/azcopy /usr/bin/ && \
  chmod 775 /usr/bin/azcopy && \
  rm azcopy_linux_amd64_10.15.0.tar.gz && \
  rm -rf azcopy_linux_amd64_*'

请查看此SO question以了解更多关于azcopy安装的信息。
当我们需要下载文件时,
1.我们只需要使用azcopy将文件从pod中复制到Azure blob存储中。2这可以通过编程或手动完成。
1.然后,我们从Azure Blob存储资源管理器将文件下载到本地计算机。或者,一些作业/脚本可以从Blob容器中获取此文件。
上传时也会执行类似的操作。首先将文件放置在blob存储容器中。这可以使用blob存储资源管理器手动完成,也可以通过编程完成。接下来,在pod中,azcopy可以从blob存储中提取文件,并将其放置在pod中。

AWS(S3)或GCP或使用任何其他云提供商也可以实现同样的功能。甚至可能使用SCP、SFTP、RSYNC。

相关问题