Blog

2026.02.12

Research

Kubernetes Pod に手元の ssh/scp で接続できるツール「sshpod」を OSS で公開しました

Area

Kentaro Imajo

皆さん、こんにちは。エンジニアのいもす (@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> は省略可(省略時は現在の kubectl context)

仕組み

sshpod は「OpenSSH から見ると普通に SSH 接続している」ように見せつつ、裏側では Kubernetes の機能だけで経路を作っています。

sshpodの接続フロー

さらに詳細な接続の流れは次の通りです。

  1. ~/.ssh/config の ProxyCommand により、ssh/scp/sftp が sshpod proxy ... を起動 (例: --host %h --user %r --port %p
  2. sshpod がホスト名をパースして接続先(context / namespace / Pod / container)を決定 Deployment/Job は条件に合う Pod を自動選択
  3. 認証用に、ローカルに SSH 鍵(例: ~/.cache/sshpod/...)を生成し、公開鍵をコンテナ側に渡す(初回のみ)
  4. 対象コンテナ内の /tmp/sshpod/... に、アーキテクチャに合った sshd バイナリと設定・鍵を配置 (圧縮転送できる場合は圧縮、無ければフォールバック)
  5. kubectl exec 経由で sshd をランダムポートで起動
  6. kubectl port-forward でローカルポートをその sshd に転送し、ProxyCommand の標準入出力を TCP に中継
  7. 同じ 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 をお待ちしています。

https://github.com/pfnet-research/sshpod

Area

  • Twitter
  • Facebook