如何将文件从 kubernetes Pod 复制到本地系统

Posted

技术标签:

【中文标题】如何将文件从 kubernetes Pod 复制到本地系统【英文标题】:How to copy files from kubernetes Pods to local system 【发布时间】:2019-02-23 17:05:21 【问题描述】:

我正在尝试将文件从 Kubernetes Pod 复制到我的本地系统。运行以下命令时出现以下错误:

kubectl cp aks-ssh2-6cd4948f6f-fp9tl:/home/azureuser/test.cap ./test.cap

输出:

tar: home/azureuser/test: 无法统计: 没有这样的文件或目录 tar: 由于先前的错误错误而退出失败状态: home/azureuser/test 没有这样的文件或目录

我可以看到上面给定路径下的文件。我真的很困惑。

你能帮帮我吗?

【问题讨论】:

【参考方案1】:

kubectl帮助中所述:

kubectl cp --help
Copy files and directories to and from containers.
Examples:
# !!!Important Note!!!
# Requires that the 'tar' binary is present in your container
# image.  If 'tar' is not present, 'kubectl cp' will fail.

# Copy /tmp/foo_dir local directory to /tmp/bar_dir in a remote pod in the default namespace
kubectl cp /tmp/foo_dir <some-pod>:/tmp/bar_dir

# Copy /tmp/foo local file to /tmp/bar in a remote pod in a specific container
kubectl cp /tmp/foo <some-pod>:/tmp/bar -c <specific-container>

# Copy /tmp/foo local file to /tmp/bar in a remote pod in namespace <some-namespace>
kubectl cp /tmp/foo <some-namespace>/<some-pod>:/tmp/bar

# Copy /tmp/foo from a remote pod to /tmp/bar locally
kubectl cp <some-namespace>/<some-pod>:/tmp/foo /tmp/bar

Options:
-c, --container='': Container name. If omitted, the first container in the pod will be chosen

Usage:
kubectl cp <file-spec-src> <file-spec-dest> [options]

Use "kubectl options" for a list of global command-line options (applies to all commands).

您也可以登录您的Containter 并检查文件是否存在:

kubectl exec -it aks-ssh2-6cd4948f6f-fp9tl /bin/bash
ls -la /home/azureuser/test.cap

如果还是不行,试试:

您可以尝试将文件复制到 workdir,然后仅使用它们的名称重试复制它们。这很奇怪,但它现在有效。

在此处#58692 考虑kchugalinskiy 的建议。

【讨论】:

教训:别忘了把“命名空间或项目名称(如果是openshift)”也不能cp链接文件(得到tar: Removing leading / from member names错误) 另请注意,如果您在尝试从 pod 复制到本地时收到 is outside target destination,那么似乎可行的解决方案是使其本地目的地是相对的。例如kubectl -c my-service cp namesapce/pod:/tmp/remoteFile1 localFilename 【参考方案2】:

假设您正在将文件从 bin 文件夹复制到本地系统。命令是

kubectl cp default/POD_NAME:bin/FILE_NAME /Users/username/FILE_NAME

您可以连接到 POD 以验证您指定的文件名是否正确

kubectl exec -ti POD_NAME bash

【讨论】:

【参考方案3】:

根据https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands

kubectl cp &lt;file-spec-src&gt; &lt;file-spec-dest&gt; 等价于使用

kubectl exec -n &lt;some-namespace&gt; &lt;some-pod&gt; -- tar cf - &lt;src-file&gt; | tar xf - -C &lt;dest-file&gt;

所以从技术上讲,如果你没有在 pod 上安装 tar,你可以这样做 kubectl exec -n &lt;some-namespace&gt; &lt;some-pod&gt; -- cat &lt;src-file&gt; &gt; &lt;dest-file&gt;

假设文件很小或者已经压缩,效果应该是一样的,只是你不能在一个目录或一组文件上使用cat。

【讨论】:

百万感谢!拯救了我的一天。但它是如何工作的?由于我们只是指定了一个 pod 不知道的文件夹,pod 如何理解将文件放在哪里? 之所以有效,是因为您在本地终端中运行命令并将一个输出传送到另一个(或在cat 的情况下传送到文件中)。在tar 示例中,您正在运行本地命令kubectl 并将其输出传送到本地命令tarkubectl 命令恰好在 pod 中运行命令,并将该命令的输出透明地带到本地终端。【参考方案4】:

发布的问题中的命令是绝对正确的。与之前的answered 一样,这个特殊问题似乎是容器中缺少tar 二进制文件。我实际上并不知道它是否需要,但确认 pod 有它:

# find / -name tar
/bin/tar
/usr/lib/mime/packages/tar
/usr/share/doc/tar

我的错误是使用. 复制到当前目录(适用于cpscp),因为它需要完整路径,如原始问题所示:

kubectl cp pod-name-shown-in-get-pods:path/to/filename /local/dir/filename

不是

kubectl cp pod-name-shown-in-get-pods:path/to/filename .

这给出了:

error: open .: is a directory
tar: Removing leading `/' from member names

现在错误消息中的tar 有意义了!

请注意,如果source路径中有前导/,如下例所示:

kubectl cp pod-name-shown-in-get-pods:/etc/resolv.conf /local/dir/resolv.conf

你还会看到:

tar: Removing leading `/' from member names

但是,可以忽略该警告,因为该文件仍会被复制。在上面的示例中使用etc/resolv.conf 而不是/etc/resolv.conf,复制时不会出现警告。

【讨论】:

奇怪的是为什么领先的/ 会发出警告。【参考方案5】:
kubectl cp <pod-id>:<path> <destination-path> -n <namespace>

为我工作。

【讨论】:

【参考方案6】:

您可以将本地目录挂载到 pod 中。

更新您的 aks-ssh yaml 文件:

spec:
  ...
  containers:
    ...
    volumeMounts:
    - name: test-dir
      mountPath: /home/azureuser
    ...
  volumes:
  - name: test-dir
    hostPath:
      path: /path/to/your/local/dir

现在您可以访问本地目录中的文件了。

【讨论】:

如果您调用的机器不是 Kubernetes 节点之一,那也无济于事;例如,如果您正在使用托管云 Kubernetes 安装并尝试将其中的内容下载到本地笔记本电脑上。【参考方案7】:

我通过将源文件夹设置为相对路径来解决此问题。 如果文件位置是 /home/azureuser/test.cap,工作目录是 /home/azureuser/,则 cmd 是

kubectl cp aks-ssh2-6cd4948f6f-fp9tl:test.cap ./test.cap

【讨论】:

【参考方案8】:

如果有人使用 windows pod,可能很难使用 kubectl cp 命令的这些 linux 路径从本地机器将文件复制到 pod:

将文件从本地机器复制到kubernetes pod的过程:(尤其是windows容器)

    我想将 node.aspx 从我的本地机器复制到 podname:\c:\inetpub\wwwroot 首先将 Node.aspx 上传到您的云盘,路径为 /home/your_username 在我的情况下 /home/pranesh 然后找出 pod 名称,在我的例子中是 aspx-deployment-84597d88f5-pk5nh,按照以下命令进行
PS /home/pranesh> kubectl cp /home/pranesh/Node.aspx aspx-deployment-84597d88f5-pk5nh:/Node.aspx
    这会将文件复制到容器的c盘, 然后使用 powershell 将文件从 c 盘移动到所需路径
PS /home/pranesh> kubectl exec aspx-deployment-84597d88f5-pk5nh powershell "Copy-Item "C:\Node.aspx" -Destination "C:\inetpub\wwwroot""
    使用相反的过程从容器复制到云驱动器并下载。

【讨论】:

【参考方案9】:

“kubectl cp”命令用于将文件从 pod 复制到本地路径,反之亦然

    将文件从 pod 复制到本地

kubectl cp :

    将文件从 pod 的特定容器复制到本地

kubectl cp : -c specific_container

    将文件从本地复制到 pod

kubectl cp :

【讨论】:

【参考方案10】:

对于在 Windows 机器上工作的人,还有一个额外的问题:从 2021 年 10 月起,您不能在本地路径中包含驱动器号。

因此,如果您要尝试以下命令:

kubectl cp aks-ssh2-6cd4948f6f-fp9tl:/home/azureuser/test.cap C:/Temp/Test

您会收到此错误,因为kubectl cp 将 Windows 路径中的冒号视为 pod 名称和 pod 内路径之间的分隔符。 所以它会将C:/Temp/Test 视为一个名为“C”的 pod,路径为“/Temp/Test”

解决此问题的方法是使用相对 Windows 路径而不是绝对路径。它需要与您当前的工作目录相关。

所以如果我当前的工作目录是C:\Users\JoeBloggs 并且我想复制到C:\Temp\Test 我需要使用命令:

kubectl cp aks-ssh2-6cd4948f6f-fp9tl:/home/azureuser/test.cap ../../Temp/Test

请注意,此问题似乎很快就会得到解决。见https://github.com/kubernetes/kubernetes/pull/94165

【讨论】:

【参考方案11】:

如果您的容器在 PATH 中没有 tar 命令,kubectl cp 将不起作用。从您的错误中可以看出 tar 命令在您的容器上不可用。 https://github.com/kubernetes/kubernetes/issues/58512 请探索其他选项

【讨论】:

【参考方案12】:

当用户没有 Pod 的权限时,Kubernetes 会给出文件未找到错误。那是我的问题。

【讨论】:

【参考方案13】:

就我而言,问题在于 pod 中有多个容器:

kubectl cp -c grafana \
    metrics/grafana-5c4f76b49b-p88lc:/etc/grafana \
    ./grafana/etc

所以用 -c grafana 设置容器名称,并在我的例子中为 pod 的命名空间正确添加前缀 metrics/

【讨论】:

【参考方案14】:

我在 Azure 上尝试过这种方法,它奏效了:

kubectl cp 'POD NAME':xyz.json test

kubectl cp is the command for copying

POD NAME =  vote-app

xyz.json是需要从pod复制的文件 测试是在AZURE目录的驱动中创建的文件...

所以最后的命令是:

kubectl cp vote-app:xyz.json test

测试将在 Azure 目录中生成,稍后您可以从 Azure 的下载选项下载test 文件

【讨论】:

【参考方案15】:

我无法让 kubectl 为这个工作。出现错误:

The connection to the server localhost:8080 was refused - did you specify the right host or port?

这对我有用:

docker cp CONTAINERID:FILEWITHPATH DESTFILENAME

其中“CONTAINERID”是通过调用 docker ps 检索到的。

【讨论】:

【参考方案16】:

也许有人会遇到这个错误

tar: removing leading '/' from member names
error: open .: is a directory

由以下命令引起的

 kc cp -n monitoring <pod name>:/usr/share/grafana/conf/defaults.ini ./

 kc cp -n monitoring <pod name>:/usr/share/grafana/conf/defaults.ini ./default.ini

为了解决这个问题,我们应该为doc添加一个目标文件夹

kc cp -n monitoring &lt;pod name&gt;:/usr/share/grafana/conf/defaults.ini ./tmp/default.ini

【讨论】:

【参考方案17】:

这对我有用:

kubectl cp "namespace"/"pod_name":"path_in_pod" "local_path"

例子:

kubectl cp mynamespace/mypod:var/www/html/index.html \Users\myuser\Desktop\index.html

【讨论】:

【参考方案18】:

您需要提及您的 pod 所在的命名空间。

【讨论】:

以上是关于如何将文件从 kubernetes Pod 复制到本地系统的主要内容,如果未能解决你的问题,请参考以下文章

kubernetes:如何编写 pod yaml 文件以将卷从主机映射到容器

从 docker 容器到 kubernetes pod 的端口发布如何工作?

谷歌发布订阅。从 AppEngine 到 Kubernetes pod 以及从一个 Kubernetes pod 到另一个 Kubernetes pod 的通信

text 将文件从pod复制到本地

如何在 kubernetes 中使用 yaml 文件删除和重新创建 pod

Kubernetes 上的 Redis 主/从复制,实现超低延迟