InstaTunnel
Navigation menu o kirikae
Development
16 min read
455 views

Kubernetes-Native Tunneling: Declarative Ingress with Operators and CRDs

IT
InstaTunnel Team
Published by the InstaTunnel team | Editorial policy
Kubernetes-Native Tunneling: Declarative Ingress with Operators and CRDs

Quick answer

Kubernetes Native Tunneling: Webhook Relay & CRD Operators: webhook testing answer

For local webhook testing, run your app locally, expose it with a public HTTPS tunnel, and paste the stable callback URL into the provider dashboard.

How do I test webhooks on localhost?

Start your local server, open a public HTTPS tunnel to that port, configure the provider webhook URL, and inspect events in your local logs.

Why does a stable webhook URL matter?

Stable URLs prevent provider dashboards from needing manual callback updates every time you restart a tunnel.

Cloud-nativeチームはインフラをYAMLで記述し、コントローラーに実現させます。しかし、多くの開発者がプライベートクラスターをインターネットに公開する方法は依然として命令型です:ターミナルを開き、トンネルバイナリを実行し続ける。

このギャップを埋めるツールが増えています。クラスター内のコントローラーはKubernetesオブジェクト(カスタムリソース、Ingress、Gateway APIルート、または注釈付きService)を監視し、プロバイダーのエッジネットワークにアウトバウンド接続を確立し、マニフェストに従ってトンネルを調整します。オブジェクトを削除すれば、トンネルも消えます。

このガイドでは、現状存在するもの、動作するマニフェスト、正直な注意点、そしてGitOpsの詳細を解説します。また、かつて「Kubernetesトンネルオペレーター」のリストにあったが今は存在しないプロジェクトも紹介します。


なぜ命令型のトンネルはKubernetesに合わないのか

ngrok CLIやlocaltunnel、手作りのSSHリバースプロキシは、10分間のデバッグセッションには適していますが、クラスターでは以下の3つの問題があります:

  • ライフサイクルがない。 ノードのドレインやポッドの退避時に、デタッチされたプロセスや管理されていないサイドカーで動作しているトンネルは死にます。Kubernetesはトンネルの存在を認識しないため、再作成されません。
  • 信頼の源がない。 トンネルは誰かのシェル履歴にあり、Gitにはありません。クラスターとリポジトリが乖離します。
  • 可視性がない。 kubectl getでトンネルの状態を確認できません。

従来のサービス公開(クラウドのLoadBalancer、静的IP、ファイアウォールルール)はコストが高く、自宅ラボやオンプレミスクラスター、エッジサイト、NAT背後のノートPCでは不可能なこともあります。これらのギャップを埋めるのがオペレーター管理のトンネルです。

オペレーター管理トンネルの仕組み

共通パターンはシンプルです:

  1. エージェントまたはオペレーターがクラスター内で動作します。
  2. プロバイダーのエッジにアウトバウンド接続を開きます(インバウンドのファイアウォールルールやパブリックIPは不要)。
  3. コントローラーがKubernetesオブジェクトを監視し、APIを通じてプロバイダーを設定します。
  4. 接続が切れたりオブジェクトが変更された場合、コントローラーが調整し、オブジェクトが削除されればクリーンアップします。

このパターンの下で、ツールは書く内容が異なります:

ツール 書く内容 最適な用途 注意点
Webhook Relay Operator WebhookRelayForward カスタムリソース プライベートクラスターでのWebhookとAPIコールバック受信 Webhookのみ; 最終リリースは 0.6.0 (2022年11月)
Webhook Relay Ingress Controller Ingressスタイルリソース(別製品) GrafanaやPrometheusなどサービスへの双方向トンネル オペレーターとは別製品
ngrok Kubernetes Operator AgentEndpoint / CloudEndpoint CRD、Ingress、Gateway API IP制限やレート制限付きの公開Ingress ngrokアカウントと予約ドメインが必要
Tailscale Kubernetes Operator ingressClassName: tailscale の標準Ingress、注釈付きService プライベートTailnetアクセス、Funnelによる公開も可能 Funnelは固定ポートと帯域制限あり
Cloudflare Tunnel cloudflared Deployment(公式)、コミュニティオペレーターも Cloudflareネットワーク上のHTTP(S)公開 公式はDeployment、CRDではない
Pangolin (Newt) Helmチャート 自ホスト型のトンネルIngress NewtはHelm展開のエージェント、CRDオペレーターではない
KubeSail 該当なし 該当なし 廃止済み

Webhook Relay:Webhook型オペレーター

Webhook Relay Operatorは、公開IPやロードバランサーのないクラスター内でWebhookやAPIリクエスト(GitHub、Stripe、Slackなど)を受信するために作られました。READMEにはオンプレ、エッジ、K3s展開をターゲットと記載。Helmでインストールし、WebhookRelayForwardリソースで公開エンドポイントと転送先を記述します。

インストール例:

helm repo add webhookrelay https://charts.webhookrelay.com
helm repo update

helm upgrade --install webhookrelay-operator --namespace=default webhookrelay/webhookrelay-operator \
  --set credentials.key=$RELAY_KEY --set credentials.secret=$RELAY_SECRET

次にフォワードを宣言します。inputsは公開エンドポイントを作り、outputsはリクエストの行き先を指定します。出力先がなければ、フォワード先のないエンドポイントになります。

apiVersion: forward.webhookrelay.com/v1
kind: WebhookRelayForward
metadata:
  name: stripe-webhook-forwarder
  namespace: payment-services
spec:
  buckets:
    - name: k8s-operator
      inputs:
        - name: public-endpoint
          description: "Stripe webhook receiver"
          responseBody: "OK"
          responseStatusCode: 200
      outputs:
        - name: stripe-receiver
          lockPath: true
          destination: http://stripe-receiver.payment-services:8080/webhooks/stripe

複数チームでオペレーターを共有する場合、Helmの資格情報を省略し、各リソースでsecretRefName(必要に応じてsecretRefNamespace)を参照できます。SecretはWebhook Relayのアクセストークンのkeyとsecretを保持します。

オペレーターはバケット、入力、出力の存在を保証し、アクションに対してKubernetesのイベントを発行し、ステータスをリソースに書き戻します。公開URLはWebhook送信者に渡してください:

kubectl get webhookrelayforwards.forward.webhookrelay.com stripe-webhook-forwarder \
  -n payment-services -o 'jsonpath={.status.publicEndpoints[0]}'

注意点:

  • これはWebhook製品であり、一般的なものではありません。 Webhook Relayのドキュメントでは、GrafanaやPrometheusなどサービスへの双方向トンネルを開く推奨方法として別のIngressコントローラーを紹介しています。オペレーターが任意のサービスを公開することは期待しないでください。
  • 安定していますが静かです。 最新タグは2022年11月の0.6.0です。Webhook Relayのドキュメントでは、クラスターへのWebhookフォワーディングに推奨していますが、重要な用途にはチャートバージョンを固定し、リポジトリを確認してください。

どのようなトランスポートでも、署名(Stripeなら署名ヘッダー)をアプリケーション内で検証してください。トンネルはリクエストをあなたに届けますが、送信者を証明しません。

ngrok Kubernetes Operator:CRD、Ingress、Gateway API

ngrokのオペレーターは最も柔軟な選択肢です。AgentEndpointとCloudEndpointの2つのネイティブCRDを提供し、標準のIngressやGateway APIリソースもこれらに変換します。ngrokは、すべてのユーザーに無料で提供されており、リソースのプロビジョニングに対して料金が発生します。

helm repo add ngrok https://charts.ngrok.com
helm repo update

helm install ngrok-operator ngrok/ngrok-operator \
  --namespace ngrok-operator \
  --create-namespace \
  --set credentials.apiKey=$NGROK_API_KEY \
  --set credentials.authtoken=$NGROK_AUTHTOKEN

ngrokアカウントと予約ドメインが必要です。最もシンプルな公開例は単一のAgentEndpointです:

apiVersion: ngrok.k8s.ngrok.com/v1alpha1
kind: AgentEndpoint
metadata:
  name: auth-service-endpoint
  namespace: dev
spec:
  url: https://YOUR_RESERVED_DOMAIN
  upstream:
    url: http://auth-service.dev:8080

エンドポイントポリシーはリソースの一部なので、セキュリティ設定もGitに保存可能です。IP許可リストの例:

spec:
  url: https://YOUR_RESERVED_DOMAIN
  upstream:
    url: http://auth-service.dev:8080
  trafficPolicy:
    inline:
      on_http_request:
        - actions:
            - type: restrict-ips
              config:
                enforce: true
                allow:
                  - 203.0.113.10

複数サービスを一つのホスト名で公開する場合、ngrokは公開CloudEndpointと内部AgentEndpointをペアにし、forward-internalトラフィックポリシーでルートします。Gateway APIを使えば、各Gatewayリスナーホスト名はCloudEndpointになり、HTTPRouteで参照されるアップストリームサービスは内部のAgentEndpointになります。リクエストミラーのフィルターは未対応です。

Tailscale Kubernetes Operator:標準Ingress、デフォルトはプライベート

Tailscaleのオペレーターは異なるアプローチを取ります:基本的な公開にはCRDは不要です。ingressClassName: tailscaleの標準Ingressを使い、オペレーターがトラフィックをServiceに転送するプロキシポッドを作成します。デフォルトのインストールでは、tailscaleのIngressClassとProxyClass、Connector、ProxyGroup、DNSConfig、Recorderも作成されます。

OAuthクライアントとタグを管理コンソールで作成した後、Helmでインストールします:

helm repo add tailscale https://pkgs.tailscale.com/helmcharts
helm repo update

helm upgrade --install tailscale-operator tailscale/tailscale-operator \
  --namespace=tailscale --create-namespace \
  --set-string oauth.clientId="<OAuthクライアントID>" \
  --set-string oauth.clientSecret="<OAuthクライアントシークレット>" \
  --wait

IngressだけではサービスはあなたのTailnet内にしか公開されません。パブリックインターネットに公開するには、tailscale.com/funnel注釈を付けます:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: auth-service-funnel
  namespace: dev
  annotations:
    tailscale.com/funnel: "true"
spec:
  ingressClassName: tailscale
  defaultBackend:
    service:
      name: auth-service
      port:
        number: 8080
  tls:
    - hosts:
        - auth-dev

tls.hostsの値はMagicDNS名になり、例としてauth-dev.<your-tailnet>.ts.netです。kubectl get ingressでADDRESS列を確認してください。

Funnelには設計上の制約があります:

  • ts.netドメインのDNS名のみ使用可能
  • ポート443、8443、10000のみTLSでリッスン可能
  • 帯域制限があり、設定できません
  • Tailnetポリシーでfunnelノード属性と、MagicDNS、HTTPSを有効にしている必要

本番運用では、Tailscaleは高可用性モードを推奨します:複数のレプリカを持つProxyGroupを単一のプロキシに代えて使用します。証明書の制限も考慮し、多数の短期ホスト名を作成する場合は注意してください。証明書はLet’s Encryptから発行され、Tailscaleのドキュメントには週50証明書の制限が記載されています。テスト時はProxyClassを使い、Let’s Encryptのステージング環境を利用することも推奨されています。

セキュリティの観点で重要な点:TailscaleはFunnelリレーサーバーが暗号化ストリームを復号せずに転送し、TLSはあなたのノードで終了します。

Cloudflare TunnelとPangolin

Cloudflare Tunnel. Cloudflareの公式Kubernetesガイドは、cloudflaredを通常のDeploymentとして実行し、トンルトークンをSecretに保存します。cloudflaredは独立したDeploymentとしてスケールし、複数のレプリカが負荷を共有します。各レプリカはクラスター内のすべてのサービスにアクセス可能です。Cloudflareはcloudflaredの自動スケーリングを推奨しません。トンネルとDNSレコードをCRDとして管理したい場合、adyanth/cloudflare-operatorのようなコミュニティプロジェクトもありますが、これはアルファ段階です。

Pangolin. Pangolinは自己ホスト可能なリバースプロキシです。Kubernetes用エージェントのNewtはHelmチャート(バージョン1.4.0)として提供され、Kubernetes 1.30.14以降が必要です。ドキュメントではHelm、Kustomize、GitOps(Argo CD、Flux)をサポートし、Flux用のHelmRelease例もあります。Pangolinのサーバーチャートはプレリリースのため、バージョンを固定してください。Newtの資格情報は既存のSecretに保持し、Helm値に直接書き込まないことが推奨されています。

KubeSailはどうなったのか

古い資料(この文章の前の草稿も含む)では、KubeSailをモデル例として挙げていました:標準Ingressリソースを監視し、TLS付きのサブドメインを提供するホームラボ用オペレーターです。KubeSailは終了しました。 ホームページには別れの通知が掲載されており、コミュニティの報告では2025年9月中旬にホスティングゲートウェイの最終停止とされています。創業者のメッセージはLemmyに転載されており、Tailscale FunnelやCloudflare Tunnelを推奨しています。

もしKubeSailエージェントのインストールを案内するガイドを見つけたら、それは旧式です。従来のワークフロー(通常のIngressを書き、公開URLを得る)は、上記のTailscaleオペレーターに引き継がれています。

Minikube:3つの異なる「トンネル」

OAuthコールバックやサードパーティWebhookのローカルクラスターでのテストは典型的な用途です。Minikubeのコマンドは混乱を招きやすいです:

  • minikube service はNodePortサービスを開きます。ドキュメントによると、DockerドライバーではSSHを使ったローカルポートフォワーディングで動作します。デフォルトのNodePort範囲は30000〜32767。
  • minikube tunnel は、LoadBalancerタイプのサービスに対してローカルルートを作り、外部IPを設定します。これを停止すると(Ctrl+C)、アクセスはなくなります。これはあなたのローカルマシンからのみサービスにアクセス可能です。
  • Ingressアドオンとhostsファイルの編集は、自分のマシンだけが解決するドメインに有効です。

これらは外部の協力者やWebhook送信者に公開URLを提供しません。そのため、上記のオペレーターをMinikube内で動かす必要があります。ngrokならAgentEndpointを使い、TailscaleならFunnelのIngressをそのまま使えます(クラスターがTailscaleネットワークに到達できる必要あり)。

トンネルはリソースによって定義され、そのライフサイクルはリソースに従います。kubectl deleteでAgentEndpointやIngressを削除すれば、公開エンドポイントも消え、ポートを開いたままのターミナルタブは不要です。

GitOps:Deploymentsの横にトンネルを

YAMLで定義されたトンネルは、DeploymentやServiceと同じリポジトリに置き、Argo CDやFluxが一緒に適用できます。クラスター再構築時にリポジトリを再適用すれば、オペレーターとカスタムリソースも再作成され、トンネルも復活します。

注意点は順序です。カスタムリソースは、そのCRDが存在してから適用される必要があります。Argo CDでは、CRDはしばしばオペレーターのHelmチャートとともに到着しますが、SkipDryRunOnMissingResourceオプションを使わないと、CRDがない状態で適用しようとするとエラーになります。対策は次の通り:

apiVersion: forward.webhookrelay.com/v1
kind: WebhookRelayForward
metadata:
  name: stripe-webhook-forwarder
  namespace: payment-services
  annotations:
    argocd.argoproj.io/sync-wave: "2"
    argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true

Argo CDのドキュメントによると、CRDが既に存在している場合はドライランも実行されるため、最初のインストール時だけこの設定が有効です。

資格情報はGitに含めないこと。上記のオペレーターはトークンやAPIキー、OAuthシークレットを必要とします。Secretに格納し、マニフェストから参照してください。

セキュリティ:アウトバウンド専用のメリットと制約

アウトバウンドだけの接続は大きな改善です。企業のファイアウォールにインバウンドポートを開く必要もなく、サービスごとのクラウドLoadBalancerも不要です。ただし、このアーキテクチャに関する一般的な主張には注意が必要です:

  • 公開ホスト名は依然として公開されている。 クラスターのネットワークは閉じていますが、公開したURLは誰でもアクセス可能です。ngrokのTraffic Policy(例:restrict-ips)やアプリケーションレベルの認証で制御可能です。
  • TLSはエッジで終端される。 リクエストレベルのポリシーを適用するプロバイダーはHTTPを復号し、平文を見ます。これは信頼の問題です。Tailscale Funnelは例外で、TLSはあなたのノードで終了します。
  • エッジのフィルタリングはサニタイズではない。 トンネルを通じて到達したトラフィックは認証済み・クリーンとは限りません。入力と署名の検証はアプリケーション側で行います。
  • RBACは付与のみ。拒否はしない。 devやstagingに権限を限定し、productionでは権限を与えない設定も可能です。より細かいルールにはValidatingAdmissionPolicy(Kubernetes 1.30以降)が有効です。
  • トークンはベアラ資格情報。 トークンを持つ者は自己のエージェントを動かせるため、スコープとローテーションが重要です。

アプローチの選択

  • プライベートクラスターでWebhookだけ必要? Webhook RelayのOperatorが最適です。
  • 完全な公開IngressとエッジポリシーをGitで管理したい? ngrokのオペレーターとAgentEndpoint、Ingress、Gateway API。
  • プライベートアクセス中心で、たまに公開URLが欲しい? Tailscaleのオペレーターと、例外的にFunnelを利用。
  • Cloudflareを既に使っている? cloudflaredをDeploymentとして動かし、コミュニティのオペレーターはアルファ版です。
  • エッジを自己ホストしたい? PangolinとNewt Helmチャート。
  • KubeSailを使いたい? もう使えません。

今後の方向性は明確です:サービスを宣言し、コントローラーに接続を管理させ、すべてをバージョン管理に置く。ツールごとに詳細は異なるため、導入前に各プロジェクトの最新ドキュメントを確認してください。この分野は急速に動いています(KubeSailの終了もその一例です)。


参考資料


更新履歴(編集者用メモ:公開前に削除)

大きな修正点

  1. KubeSailは廃止済み。 以前の草稿では、KubeSailのオペレーター、my-app.kubesail.ioサブドメイン、エッジTLSを現行のオプションとして記載していましたが、現在は公式サイトに終了通知が掲載され、コミュニティの報告では2025年9月中旬に最終停止とされています。このセクションは短い「何が起きたか」の説明に置き換え、標準Ingress経由のアクセスはTailscaleのオペレーターに置き換えられています。
  2. LocalTunnel CRD (tunneling.example.com/v1alpha1)はプレースホルダーであり、実在しません。 Minikubeの例は、実際のマニフェスト(ngrokのAgentEndpointとTailscaleのFunnelIngress)に置き換えました。
  3. Webhook Relayのマニフェストは不完全でした。 入力(公開エンドポイント)はあったものの、outputsがなく、フォワード先が設定されていませんでした。destination、lockPath、responseStatusCodeを追加し、secretRefNameも有効です(READMEに記載)。この誤りにより、唯一のモードと誤解されていました。Helm資格情報はデフォルトです。ステータスコマンドも正しいリソース名に修正しました。
  4. minikube tunnelは公開露出と混同されていた。 minikube tunnelはLoadBalancerサービスをローカルにルーティングするだけで、minikube serviceはNodePortを開きます。どちらも公開URLは作りません。これに合わせて修正しました。

過剰な表現の緩和

  1. 「ポートスキャン、DDoS、ブルートフォース攻撃に免疫」→削除。公開ホスト名は依然として公開されており、露出はプロバイダーのエッジに移動します。
  2. 「サービスに到達したトラフィックはすでに復号済み、認証済み、サニタイズ済み」→削除。エッジTLS終端は平文を見られる状態であり、エッジのフィルタリングはアプリケーション側の検証に置き換わりません。
  3. 「本番環境でのトンネルCRの作成を厳格に拒否」→修正。KubernetesのRBACは付与のみであり、拒否はできません。ValidatingAdmissionPolicy(1.30以降)を使った細かいルール設定を推奨します。
  4. Webhook Relayの最新情報(2022年11月の0.6.0)とドキュメントの推奨について追記。

新規追加内容

  1. ngrokのCRD(AgentEndpoint、CloudEndpoint)、Ingress、Gateway APIの解説と、無料で使えること、予約ドメイン必須について。
  2. Tailscaleの標準Ingressクラス、Funnel注釈、HA構成のProxyGroup、ポート・帯域制限、証明書制限について。
  3. Cloudflare Tunnelの公式Deployment、非自動スケール推奨、コミュニティのアルファオペレーターについて。
  4. PangolinのNewt Helmチャート(バージョン1.4.0)、Kubernetes 1.30.14+対応について。
  5. Webhook RelayのオペレーターとIngressコントローラーの別物化について。
  6. Argo CDのCRD適用順序問題とシークレット管理について。
  7. 比較表と導入ガイドの追加。

未検証・意図的に省略した内容

  • 各プロバイダーの料金や無料枠の最新情報(頻繁に変わるためリンク推奨)
  • Tailscale Funnelのベータラベルの有無(記載なし)
  • Webhook Relayの新機能(オペレーターとIngressコントローラー以降)

これらの内容は、最新のドキュメントを確認しながら導入してください。動きが早いため、KubeSailの終了もその一例です。

Continue from this article into the most relevant product guides and workflows.

Related Topics

#Webhook Relay Kubernetes Operator, KubeSail reverse proxy, expose local Minikube custom resource, Kubernetes tunnel automation, Kubernetes CRD operator tunneling, GitOps reverse proxy automation, Kubernetes custom resource definitions, local Kubernetes webhook tunneling, cloud native tunnel automation, Minikube external ingress operator, Webhook Relay CRD guide, KubeSail tunnel operator, DevOps GitOps tunneling, platform engineering reverse proxy, Kubernetes ingress alternative, expose localhost to internet Kubernetes, Minikube webhook forwarding, k8s operator tunnel management, Declarative Kubernetes tunneling, YAML driven reverse proxy, Kubernetes local environment tunneling, Kubernetes developer tooling, Webhook Relay installation guide, KubeSail deployment tutorial, Minikube external access setup, Kubernetes webhook listener, Kubernetes custom controller development, cloud native developer workflow, GitOps webhook proxy setup, k8s CRD architecture breakdown, Kubernetes local cluster exposure, secure Kubernetes tunneling, Kubernetes API server extensions, Webhook Relay vs KubeSail, Kubernetes developer productivity, microservices local tunneling, local development cluster ingress, Kubernetes operator pattern tutorial, Minikube tunnel operator, automated local endpoint exposure, Kubernetes external traffic routing, k8s operator lifecycle manager, Kubernetes continuous deployment proxy, infrastructure as code tunneling, cloud native proxy automation, Kubernetes cluster webhook relay, local testing Kubernetes operator, Kubernetes YAML tunnel configuration, edge proxy Kubernetes operator, devops Kubernetes tunnel workflows, Kubernetes local host reverse proxy, KubeSail custom resources, Webhook Relay k8s configuration, Kubernetes native edge ingress, cloud native reverse proxy operator

Keep building with InstaTunnel

Read the docs for implementation details or compare plans before you ship.

Share this article

More InstaTunnel Insights

Discover more tutorials, tips, and updates to help you build better with localhost tunneling.

Browse All Articles