kubernetes: kubectl cp fails with absolute path on Windows

What happened?

I tried to copy a file from a running pod to my local machine using kubectl cp on Windows. I used the $HOME env var in Powershell and it failed to copy saying essentially no local path was specified.

PS C:\> kubectl cp -n namespace -c container pod-0:/usr/lib/os-release C:\Temp\os-release.log
error: one of src or dest must be a local file specification
PS C:\> kubectl cp -n namespace -c container pod-0:/usr/lib/os-release $HOME\os-release.log
error: one of src or dest must be a local file specification

Using relative paths works. Also removing the C: allows the command to work:

PS C:\> kubectl cp -n namespace -c container pod-0:/usr/lib/os-release \Temp\os-release.log
tar: Removing leading `/' from member names

PS C:\> cat C:\Temp\os-release.log
NAME="Ubuntu"
VERSION="20.04.4 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.4 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

What did you expect to happen?

I expected kubectl cp to succeed and copy the file to my local machine using $HOME or absolute paths like C:\Users\me

How can we reproduce it (as minimally and precisely as possible)?

  1. Start a kubernetes pod (I am using a Ubuntu container)
  2. Copy any file from the container to any absolute path on Windows : kubectl cp -n namespace -c container pod:/etc/os-release C:\Temp\os-release

Anything else we need to know?

This applies to Windows environment variables as well, such as $HOME. Removing C: from the absolute path while in the C: drive in powershell does work. It seems like the C: is causing issues (my guess is that kubectl thinks C is a pod).

Kubernetes version


PS C:\> kubectl version
WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short.  Use --output=yaml|json to get the full version.
Client Version: version.Info{Major:"1", Minor:"24", GitVersion:"v1.24.0", GitCommit:"4ce5a8954017644c5420bae81d72b09b735c21f0", GitTreeState:"clean", BuildDate:"2022-05-03T13:46:05Z", GoVersion:"go1.18.1", Compiler:"gc", Platform:"windows/amd64"}
Kustomize Version: v4.5.4
Server Version: version.Info{Major:"1", Minor:"21", GitVersion:"v1.21.11", GitCommit:"38d3c1f3d5306401bcf39a71bad3b5a5106033d7", GitTreeState:"clean", BuildDate:"2022-03-16T14:02:06Z", GoVersion:"go1.16.15", Compiler:"gc", Platform:"linux/amd64"}
WARNING: version difference between client (1.24) and server (1.21) exceeds the supported minor version skew of +/-1

Cloud provider

kubeadm, no cloud involved.

OS version

# On Windows:
C:\>wmic os get Caption, Version, BuildNumber, OSArchitecture
BuildNumber  Caption                          OSArchitecture  Version
22000        Microsoft Windows 11 Enterprise  64-bit          10.0.22000

Install tools

https://kubernetes.io/docs/tasks/tools/install-kubectl-windows/#install-kubectl-binary-with-curl-on-windows

I installed kubectl by downloading the binary and running it from my Downloads folder.

Container runtime (CRI) and version (if applicable)

docker://20.10.14

Related plugins (CNI, CSI, …) and versions (if applicable)

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 23 (8 by maintainers)

Most upvoted comments

No unfortunately that does not work with the kubectl cp command. A valid pathing would be: \\.\d:\some\file, however that doesn’t work, as kubectl infers a colon as a pod specifier.

What did work for me was using a valid UNC pathing, that didn’t use a colon: \\localhost\d$\some\file.