[k8s]kubectl copy が「tar: Removing leading `/' from member names」で失敗

`kubectl copy`コマンドで Pod のファイルをローカルホストへコピー出来るが、これが「tar: Removing leading `/' from member names」というようなメッセージが出力され失敗した時のメモ。

# 結論

`WORKDIR` がポイントとなるので、確認をしてパスを設定したほうが良い。
以下は Pod からローカルホストへコピーする場合の例。

```bash
# WORKDIR = / の場合
$kubectl cp <pod name>:etc/hostname hostname

# WORKDIR = /etc/ の場合
$kubectl cp <pod name>:hostname hostname
```

また、`kubectl cp --help` によるとコンテナ内に tar も必要らしいのでこちらも注意したほうが良いだろう。
詳細は以下の「調査経緯」に記載。

# 確認環境

```bash
$kubectl version
Client Version: version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.5", GitCommit:"20c265fef0741dd71a66480e35bd69f18351daea", GitTreeState:"clean", BuildDate:"2019-10-15T19:16:51Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"12+", GitVersion:"v1.12.10-eks-aae39f", GitCommit:"aae39f4697508697bf16c0de4a5687d464f4da81", GitTreeState:"clean", BuildDate:"2019-12-23T08:19:12Z", GoVersion:"go1.12.9", Compiler:"gc", Platform:"linux/amd64"}
```

# 調査したこと

`kubectl copy`コマンドで Pod のファイルをローカルホストへコピー出来る。

ただし、以下のようなコマンドを実行したら失敗した。

```bash
# ファイルはある
$kubectl exec -it nginx-deployment-web-6479c87c-zjc8s cat /etc/hostname
nginx-deployment-web-6479c87c-zjc8s

# コピーが失敗
$kubectl cp nginx-deployment-web-6479c87c-zjc8s:/etc/hostname .
tar: Removing leading `/' from member names
error: open .: is a directory
```

ヘルプを見てみる。

```bash
$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 from a remote pod to /tmp/bar locally
  kubectl cp <some-namespace>/<some-pod>:/tmp/foo /tmp/bar

```

tar がいるらしいので確認。

```bash
$kubectl exec -it nginx-deployment-web-6479c87c-zjc8s /bin/sh
# tar --version
tar (GNU tar) 1.26
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by John Gilmore and Jay Fenlason.
```

これは問題なし。
次に help に書いてる書式でやってみる。

```bash
$kubectl cp default/nginx-deployment-web-6479c87c-zjc8s:/etc/hostname . /tmp/hostname
tar: Removing leading `/' from member names
error: open .: is a directory
```

これも同じようにエラー。
同じようなエラーが発生したという Github issue を見つける。

[Kubectl cp gives "tar: removing leading '/' from member names" warning #58692](https://github.com/kubernetes/kubernetes/issues/58692)

>Something I found is that if I do not put a / at the beginning of my path following : in <pod>:<path> that the kubectl cp command works fine.

これをやってみる。

```bash
$kubectl cp nginx-deployment-web-6479c87c-zjc8s:etc/hostname hostname

$cat hostname
nginx-deployment-web-6479c87c-zjc8s
```

成功。
Github issue を見るとこんなコメントが。

> The issue has nothing to do with the drives on your local Windows computer. The latter works for you because the WORKDIR in your pod is /. Try setting a different WORKDIR in your pod, and you will also experience the warning.

Pod の WORKDIR が / なので動くよと言っている。
試しに　WORKDIR を `/etc/` にした イメージを作り、 Pod でやってみる。

[toshihirock/nginx-change-workdir](https://hub.docker.com/repository/docker/toshihirock/nginx-change-workdir)

```bash
# 同じ位置にファイルが有る
$ kubectl exec -it sample-pod cat /etc/hostname
sample-pod

# 同じコマンドでも失敗
$kubectl cp sample-pod:etc/hostname hostname
tar: etc/hostname: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors

# WORKDIR = /etc/ という事を踏まえてパスを指定
$kubectl cp sample-pod:hostname hostname

# 成功している
$ cat hostname
sample-pod
```
確かに `WORKDIR` によって挙動が変わった。
つまりコメントの通り、`WORKDIR` がポイント。