Telepresence:10分かかる再ビルドなしでローカルのマイクロサービスをデバッグする

DevOps tutorial - IT technology blog
DevOps tutorial - IT technology blog

「インナーループ」による生産性の低下

Kubernetes向けのマイクロサービス開発は、ペンキが乾くのを待っているような気分になることがよくあります。コードを書き、Dockerイメージをビルドし、レジストリにプッシュし、マニフェストを更新して、Podが入れ替わるのを待つ……。この標準的なサイクルは非常に疲れるものです。もし1文字でも間違えていれば、さらに10分を失うことになります。この「インナーループ」のボトルネックこそが、エンジニアリングの勢いを削ぐ原因です。

私は数ヶ月間、リモートのKubernetesクラスターをあたかも自分のデスクの下で動いているかのように扱う方法を探していました。目標はシンプルでした。ローカルのIDEからクラスター内のサービスと通信し、クラスターからのトラフィックをローカルのプロセスにルーティングすることです。チームでTelepresenceを導入した結果、機能のターンアラウンドタイムが約60%短縮されました。パイプラインとの戦いをやめ、ロジックに集中できるようになったのです。

クイックスタート:5分でゼロからインターセプトまで

Telepresenceは双方向のネットワークブリッジとして機能します。これにより、ラップトップが物理的にクラスターネットワークの内部にあるかのように感じられます。使い方は以下の通りです。

1. CLIのインストール

macOSユーザーはHomebrew経由で取得できます。

brew install datawire/blackbird/telepresence

Linuxユーザーの場合は以下の通りです:

sudo curl -fL https://app.getambassador.io/download/tel2/linux/amd64/latest/telepresence -o /usr/local/bin/telepresence
sudo chmod a+x /usr/local/bin/telepresence

2. クラスターへの接続

まず、kubectlのコンテキストを開発環境またはステージング環境に向けます。次に、以下を実行します:

telepresence connect

このコマンドは、ローカルのデーモンとクラスター内のTraffic Manager Podを起動します。接続が確立されると、内部サービスに直接クエリを投げることができます。標準のターミナルから curl http://auth-service.staging.svc.cluster.local を実行してみてください。これだけで動作します。

3. トラフィックのインターセプト

クラスター内で通常ポート8080で待ち受けている order-api のバグを修正しているとしましょう。そのトラフィックを、代わりにローカルマシンのポート3000に送りたいとします。

telepresence intercept order-api --port 3000:8080 --env-file ~/dev/order-api/.env

これで、Kubernetes内の order-api サービスに届くリクエストはすべてローカルの開発サーバーに転送されます。--env-file フラグは大幅な時間の節約になります。データベースの認証情報やシークレットなどのリモート環境変数を自動的に取得し、アプリが使用できるローカルファイルに書き出してくれます。

仕組み:ネットワークレイヤーのブリッジング

Telepresenceは単なるポートフォワーダーではありません。マシン上にTUNデバイスをセットアップすることで、ネットワークレイヤーで動作します。これにより、OSは実際のクラスターDNS(CoreDNS)を使用して .cluster.local ドメインをシームレスに解決できるようになります。

サービスをインターセプトすると、TelepresenceはリモートのPodに traffic-agent サイドカーを注入します。このサイドカーはスマートスイッチとして機能し、トラフィックをクラスター内のコンテナに送るか、セキュアなトンネルを介してラップトップに再ルーティングするかを判断します。ローカルサービスはあたかもPod内にあるかのように振る舞い、追加の設定なしで内部のRedisキャッシュやプライベートデータベースにアクセスできます。

高度な使い方:パーソナルインターセプト

共有のステージング環境では、すべてのトラフィックを単に乗っ取るわけにはいきません。チームメイトがフロントエンドをテストしているときに、自分の壊れたローカルビルドで彼らのセッションをクラッシュさせるべきではないからです。ここでパーソナルインターセプト(Personal Intercepts)が不可欠になります。

Telepresenceは、特定のHTTPヘッダーに基づいてトラフィックをルーティングできます。私は自分の作業を分離するために、これを毎日使用しています:

telepresence intercept order-api --port 3000:8080 --http-header=x-debug-user=myname

この設定により、クラスターは2つのルールに従います:

  • 標準のリクエストは、クラスター内の安定したバージョンのコードに送られ続けます。
  • ヘッダー x-debug-user: myname を含むリクエストは、私のローカルIDEにルーティングされます。

「ModHeader」のようなブラウザ拡張機能を使用すれば、チームの他のメンバーに全く影響を与えることなく、自分のローカルコードを呼び出すことができます。

IDEでのデバッグ

トラフィックがローカルポートに届くようになるため、VS Code、IntelliJ、GoLandなどを、ローカルのモノリス開発と全く同じように使用できます。ブレークポイントを設定し、クラスターのパブリックIngress経由でリクエストを送信すれば、画面上で実行が一時停止します。これで、技術的にはリモートクラスターの「内部」にあるコードをステップ実行していることになります。

実践で得た教訓

Telepresenceを1年間使用して、開発体験をスムーズに保つためのいくつかの方法を見つけました:

  • サイドカーのオーバーヘッドを監視する: インターセプトごとにサイドカーが追加されます。メモリ消費は50MB程度ですが、リソース制限の厳しいクラスターでは、制限がギリギリだとOOM(メモリ不足)が発生する可能性があります。
  • VPNの競合を解決する: Telepresenceはルーティングテーブルを変更します。Cisco AnyConnectのような企業用VPNを使用している場合、競合が発生することがあります。--mapped-namespaces フラグを使用してDNSスコープを制限し、ルーティングループを防止しましょう。
  • 正常に終了する: ラップトップの蓋を閉じるだけで終わらせないでください。放置されたインターセプトは、リモートサービスを「転送中(diverted)」の状態のままにしてしまう可能性があります。必ず telepresence quit -s を実行して、デーモンとクラスターコンポーネントをクリーンアップしてください。
  • シークレット取得をスクリプト化する: 私はインターセプトコマンドをシェルスクリプトでラップしています。これにより、アプリが起動する前に、KubernetesのVaultやConfigMapから最新のシークレットが常にローカル環境に反映されるようにしています。

Telepresenceは「自分のマシンでは動くのに」という言い訳をなくしてくれます。ローカル開発の快適さとクラウドネイティブの現実とのギャップを埋め、Kubernetes開発を再び高速なものにしてくれます。

Share: