Kubernetesポッドとあなたのマシン間でファイルをコピーする方法
Kubernetesポッド内で実行されているコンテナは、手動で操作する必要がない自己完結型の計算ユニットを目的としています。しかし、デバッグの問題が発生した場合には、ポッドのファイルシステムにファイルをコピーする必要があるかもしれません。たとえば、ログ、設定ファイル、またはコンテナに保存されたキャッシュをアーカイブするためです。
Pod内のコンテナとあなたのマシン間でファイルを移動する方法は、Kubectlの組み込み転送機能や手動の代替手段を使用します。
あなたのマシンからまたはあなたのマシンへのコピー
「kubectl cp」コマンドは、コンテナファイルシステムにコピーする最も簡単な方法です。それは、次のように機能します。
docker cpあなたは地元のコンテナ開発からすでに親しんでいるかもしれません。
kubectl cpにはソースと宛先の引数が必要です。ソースまたは宛先のいずれかはPodの参照でなければなりません。これはPodの名前の後にコロンとコンテナ内のファイルシステムパスが続く形式です。
kubectl cp example-pod:/tmp/example-dir ./example-dirこの例は、/tmp/example-dir の内容を example-pod からあなたのローカルファイルシステムの example-dir にコピーします。引数を逆にすると、あなたのマシンの example-dir をPodに戻すことができます。
コマンド引数
単一のポッドは複数のコンテナを保持できるため、cpを使用する際にはこれを念頭に置くことが重要です。Kubernetesはデフォルトでポッド内の最初のコンテナインスタンスにコピーを行います。特定のコンテナをターゲットにするには、-cフラグを追加できます。
kubectl cp example-pod:/tmp/example-dir ./example-dir -c second-container他のすべてのkubectlコマンドと同様に、cpはあなたのKUBECONFIG環境変数で定義されたクラスター接続に対して実行されます。デフォルトでは~/.kube/confになります。
名前空間付きポッドを参照する際には2つのオプションがあります。標準の--namespace example-namespaceフラグを追加するか、ファイルシステムの参照で完全なポッドパスを使用することができます:
kubectl cp example-namespace/example-pod:/tmp/example-dir ./example-dirファイルの属性はデフォルトで保持されます。cpコマンドに--no-preserveフラグを追加すると、宛先に残されたコピーされたファイルから所有権と権限データが削除されます。通常のUnixのcpとは異なり、Kubectlの実装は常に再帰的であるため、ディレクトリを参照するとその内容も含まれます。
Kubectl Cpが動作しない場合
kubectl cp には大きな注意点があります。それは、内部的には tar の単純なラッパーであることです。このコマンドは、ソースパスを圧縮し、アーカイブを宛先にコピーし、その後に内容を抽出します。この機能が動作するためには、コンテナイメージに tar バイナリがパスに含まれている必要があります。
これは、kubectl cpが、イメージを小さく保つためのDockerのベストプラクティスに従っているときには常にオプションではない可能性があることを意味します。alpineのような人気のあるミニマルベースにはtarが含まれていますが、すべてのイメージに含まれているわけではなく、ゼロからイメージを組み立てる場合には存在しません。
tarの使用は、kubectl cpがコピーできるものにも制限を与えます。シンボリックリンクを解決したり、/tmp/*.logのようなワイルドカードを使用することはできません。この機能が必要な場合は、別のアプローチを使用する必要があります。
1つのオプションは、kubectl exec、catコマンド、およびシェルリダイレクションを組み合わせて、クラスタからファイルの内容をストリームし、ローカルファイルに出力することです:
kubectl exec
--namespace example-namespace
example-pod -c second-container
-- cat /tmp/example-file > local-file
このkubectl execコマンドは、Pod内でシェルセッションを開始します。--の後のすべては、コンテナ内で実行されます。ファイルに対してcatを呼び出すと、その出力はターミナルに表示され、ローカルファイルにリダイレクトすることができます。
この技術は、比較的小さなファイルを何点かコピーする場合に適しています。大きなディレクトリを取り出す必要があると、すぐに面倒になります。残念ながら、コンテナに追加のソフトウェアを加えずにもっと良い代替手段はありません。
もしあなたが大胆な気持ちであれば、コンテナにSSHをインストールし、scpを使ってホストからそのファイルシステムにアクセスすることができます。これにより、余分なデーモンを実行し、潜在的なセキュリティ問題を引き起こす代償として、完全なコピー体験が得られます。これは適切に保護されたクラスターでのみ検討されるべきです。
tarをコンテナイメージに追加することは、はるかに安全なオプションです。これにより、kubectl cpを使用でき、必要に応じてkubectl execを介してより高度な手動コピーが可能になります。cp構文に制限に直面した場合、コマンドに追加のフラグを加えるために直接tarをkubectl execを介して呼び出してください:
kubectl exec
--namespace example-namespace
example-pod -c second-container
-- tar -cf /tmp/example-dir | tar xf - -C ./extracted-dir
これは、コンテナ内でtar -cFを実行し、その結果をローカルマシンのtar xf抽出コマンドにパイプします。-は、tarに標準入力ストリームを介して供給されたデータを抽出するよう指示します。-Cは、宛先ディレクトリを指定するために使用されます。
要約
kubectl cp コマンドは、Kubernetes Pod とあなたのマシンの間でファイルをコピーすることを可能にします。これはどちらの方向にも機能しますが、Pod から Pod へファイルを移動するためには使用できません。それを行う必要がある場合は、まず Pod A からあなたのマシンにコピーし、次に Pod B に進むという二段階の手順を使用するのが最良です。
cp は内部で tar を利用しているため、コンテナイメージにそれが含まれていることを確認する必要があります。コンテナに tar がない状態で cp を実行しようとすると、No such file or directory tar というエラーが表示されます。この場合、コンテナに tar を追加するか、必要なファイルが少しだけであれば kubectl exec と cat の組み合わせを使用してください。
