Blog
皆さん、こんにちは。エンジニアのいもす (@imos) です。
今日は、Kubernetes 上の Pod に対して 普段使っている OpenSSH クライアント(ssh / scp)からそのまま接続できるようにする CLI ツール sshpod をオープンソースとして公開したので、このツールについて紹介します。
sshpod は kubectl exec と kubectl port-forward を組み合わせて、対象コンテナ内に sshd をオンデマンドで配置・起動し、ローカルの SSH クライアントからの接続を中継します。コンテナイメージの変更、Service の作成、Pod へのポート開放は不要です。
sshpod が解決したいこと
Kubernetes 上で開発・運用していると、Pod の中に入って調査したり、一時的にファイルをやり取りしたくなる場面がよくあります。定番の手段は kubectl exec / kubectl cp ですが、普段 SSH が使えるサーバに使っているツールを修正する必要があったり、鍵の転送が大変で非公開リポジトリに対して git clone がなかなかできなかったりします。sshpod は、こうした「SSH が使えたら楽なのに」を Pod 側の恒久的な変更なしで実現するためのツールです。
使い方
インストール
Linux / macOS では、次の 1 行で最新リリースを入れられます(インストール先はデフォルトは ~/.local/bin ですが、–prefix で変更できます)。
curl -fsSL https://raw.githubusercontent.com/pfnet-research/sshpod/main/install.sh | sh -s -- --yes
Windows(PowerShell)では、以下で入れられます。
Set-ExecutionPolicy Bypass -Scope Process -Force; ` & ([scriptblock]::create((irm https://raw.githubusercontent.com/pfnet-research/sshpod/main/install.ps1))) -Yes
バイナリを手動ダウンロードし導入する方法も README にまとめていますので、好みに応じて使い分けてください。
接続してみる
以降は、いつも通り ssh / scp を使うだけです。
# Pod を直接指定して接続する例 ssh root@pod--my-pod.namespace--default.sshpod # scp で転送する例 scp ./local-file.txt root@pod--my-pod.namespace--default.sshpod:/tmp/
ホスト名で「どこに繋ぐか」を指定する
sshpod は、接続しようとしたホスト名を受け取り、そこから接続先(Pod / Deployment / Job、namespace、context、container)を解決します。 このホスト名は DNS で引ける必要はありません。末尾の .sshpod が「sshpod 経由で接続する」目印になり、sshpod に処理を引き継ぎます。
例
# Deployment / Job は Ready な Pod を自動選択します ssh app@deployment--web.namespace--app.context--dev.sshpod ssh ubuntu@job--batch.namespace--etl.context--dev.sshpod # マルチコンテナ Pod の場合は container-- を付けて明示します ssh app@container--sidecar.pod--debug.namespace--tools.context--dev.sshpod
ルール(要点)
- 末尾に
.sshpodをつける - 対象は
pod--<pod>/deployment--<deployment>/job--<job>のいずれかで指定 container--<container>はマルチコンテナ Pod では必須(単一コンテナなら省略可)namespace--<namespace>は省略可(context に namespace が設定されていればそれを、無ければクラスタ既定)context--<context>は省略可(省略時は現在のkubectlcontext)
仕組み
sshpod は「OpenSSH から見ると普通に SSH 接続している」ように見せつつ、裏側では Kubernetes の機能だけで経路を作っています。

さらに詳細な接続の流れは次の通りです。
~/.ssh/configのProxyCommandにより、ssh/scp/sftpがsshpod proxy ...を起動 (例:--host %h --user %r --port %p)- sshpod がホスト名をパースして接続先(context / namespace / Pod / container)を決定 Deployment/Job は条件に合う Pod を自動選択
- 認証用に、ローカルに SSH 鍵(例:
~/.cache/sshpod/...)を生成し、公開鍵をコンテナ側に渡す(初回のみ) - 対象コンテナ内の
/tmp/sshpod/...に、アーキテクチャに合ったsshdバイナリと設定・鍵を配置 (圧縮転送できる場合は圧縮、無ければフォールバック) kubectl exec経由でsshdをランダムポートで起動kubectl port-forwardでローカルポートをそのsshdに転送し、ProxyCommand の標準入出力を TCP に中継- 同じ Pod/コンテナに対しては
/tmp/sshpodが残っている限り、バンドルや鍵を再利用し高速化
この仕組みにより、クラスタ内外へのポート公開や Pod 定義の変更をせずに、SSH が動いている仮想マシンに接続するような感覚で Pod に入れます。
制約と注意点
sshpod は「できるだけどこでも動く」を目指していますが、現状の前提があります。
- ローカルで
kubectl(具体的にはkubectl execとkubectl port-forward)が動作すること - 対象コンテナが Linux
amd64またはarm64で、shが使え、/tmpが書き込み可能であること - コンテナ内のユーザと SSH で指定するユーザ名を一致させること
が必要です。具体的には、alpine や busybox のような軽量なイメージでも動作しますが、distroless は現在サポートしていません。
おわりに
sshpod を使うことで、Kubernetes 環境でのデバッグや作業が、SSH で常時接続できる開発環境に近い感覚で行えるようになります。Rust で実装されており、シングルバイナリで動作するため導入も容易です。ぜひ試してみてください。
不具合の報告や機能要望は、GitHub の Issue や Pull Request をお待ちしています。
Area




