如何将文件从 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 <file-spec-src> <file-spec-dest>
等价于使用
kubectl exec -n <some-namespace> <some-pod> -- tar cf - <src-file> | tar xf - -C <dest-file>
所以从技术上讲,如果你没有在 pod 上安装 tar,你可以这样做 kubectl exec -n <some-namespace> <some-pod> -- cat <src-file> > <dest-file>
假设文件很小或者已经压缩,效果应该是一样的,只是你不能在一个目录或一组文件上使用cat。
【讨论】:
百万感谢!拯救了我的一天。但它是如何工作的?由于我们只是指定了一个 pod 不知道的文件夹,pod 如何理解将文件放在哪里? 之所以有效,是因为您在本地终端中运行命令并将一个输出传送到另一个(或在cat
的情况下传送到文件中)。在tar
示例中,您正在运行本地命令kubectl
并将其输出传送到本地命令tar
。 kubectl
命令恰好在 pod 中运行命令,并将该命令的输出透明地带到本地终端。【参考方案4】:
发布的问题中的命令是绝对正确的。与之前的answered 一样,这个特殊问题似乎是容器中缺少tar
二进制文件。我实际上并不知道它是否需要,但确认 pod 有它:
# find / -name tar
/bin/tar
/usr/lib/mime/packages/tar
/usr/share/doc/tar
我的错误是使用.
复制到当前目录(适用于cp
和scp
),因为它需要完整路径,如原始问题所示:
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
-
将文件从本地复制到 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 <pod name>:/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 的通信