Development
14 min read
112 views

Túnel nativo en Kubernetes: el enfoque CRD y Operator para ingreso automatizado

IT
InstaTunnel Team
Published by the InstaTunnel team | Editorial policy
Túnel nativo en Kubernetes: el enfoque CRD y Operator para ingreso automatizado

Quick answer

Túnel nativo en Kubernetes: Webhook Relay y 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.

Los desarrolladores nativos en la nube no ejecutan binarios CLI imperativos; escriben YAML declarativos. Gestionar el acceso externo a clusters privados, edge o locales con proxies inversos ejecutados manualmente es un anti-patrón en un flujo de trabajo de ingeniería de plataformas. Herramientas como el Webhook Relay Kubernetes Operator y el Kubernetes Operator de Tailscale permiten a los desarrolladores gestionar el acceso a la red externa completamente a través de Definiciones de Recursos Personalizados (CRDs) estándar de Kubernetes y la API de Ingress nativa. Al tratar los túneles como recursos gestionados por GitOps, los equipos de plataforma pueden exponer servicios internos de forma segura, automatizar el enrutamiento de webhooks entrantes y gestionar el ingreso en clusters edge sin tocar un proceso CLI separado.

El problema con los túneles imperativos en un ecosistema declarativo

Los desarrolladores que dependen de infraestructura local o privada han usado históricamente herramientas como ngrok, localtunnel o proxies reversos SSH para exponer servicios a internet. Son efectivos para sesiones rápidas de depuración, pero inherentemente imperativos: abres una terminal, ejecutas un comando y lo dejas corriendo.

En Kubernetes, esto se rompe rápidamente. Kubernetes es una máquina de estados declarativa — si un nodo falla, se expulsa un pod o el clúster escala, un túnel imperativo en un proceso separado no tiene relación con ese ciclo de reconciliación. El orquestador no tiene conocimiento del túnel, no puede monitorear su salud y no tiene mecanismo para recrearlo.

Provisiones de IPs estáticas, reglas de firewall y balanceadores de carga en la nube para cada microservicio o receptor de webhooks también son costosos y operativamente pesados — especialmente en despliegues on-premise, redes edge/IoT y clusters locales donde las IPs públicas simplemente no están disponibles. El enfoque para tratar los túneles como objetos de Kubernetes versionados y en reconciliación continua, gestionados igual que un Deployment o ConfigMap, es la solución.

El cambio hacia redes gestionadas por operator

El patrón de Kubernetes Operator es un controlador personalizado que observa Recursos Personalizados y reconcilia el estado del clúster para que coincida con lo declarado en ellos. Aplicado a redes, un operator corre dentro de tu clúster, observa un CRD específico y — cuando un desarrollador hace commit de un nuevo CR en Git — se autentica con un servicio externo de túneles y abre una conexión persistente y segura saliente. Como la conexión es iniciada desde dentro hacia afuera, no requiere abrir puertos en el firewall entrantes, configurar NAT traversal ni correr un controlador de ingreso público.

Esto ofrece a los equipos de plataforma tres ventajas reales:

  • Reconciliación de estado — si el túnel se desconecta, el operator detecta que el estado actual ya no coincide con el deseado en el CR y reconstruye la conexión.
  • Sin exposición entrante — el clúster no abre puertos entrantes; el operator actúa como una puerta de enlace autenticada y solo saliente.
  • Compatibilidad con GitOps — la configuración del túnel vive en Git junto a los manifiestos de la aplicación, permitiendo que herramientas como ArgoCD o Flux desplieguen una app y su ruta pública en la misma sincronización.

Webhook Relay Kubernetes Operator: enrutamiento de tráfico webhook y API

Recibir webhooks (de GitHub, Stripe o Slack) dentro de un clúster privado generalmente requiere montar un gateway API público y abrir un puerto en el firewall corporativo. El Webhook Relay Kubernetes Operator resuelve esto sin IP pública ni balanceador de carga, y está enfocado específicamente en recibir y enrutar webhooks y solicitudes API — en despliegues on-premise, en edge con K3s y en IoT son los casos de uso documentados.

La instalación se realiza vía Helm, y el operador se configura a nivel de clúster con una clave de acceso y secreto en el momento de la instalación — no por CR:

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

export RELAY_KEY=*****-****-****-****-*********
export RELAY_SECRET=**********

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

Una vez en funcionamiento, un recurso WebhookRelayForward describe el endpoint público y a dónde reenviarlo. Es importante que tanto un input (el endpoint público) como un output (el destino interno) sean especificados — un CR solo con un input no tiene a dónde enviar tráfico:

# cr.yaml
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: "Receptor de Webhook de Stripe"
          responseBody: "OK"
          responseStatusCode: 200
      outputs:
        - name: webhook-receiver
          destination: http://destination:5050/webhooks
kubectl apply -f cr.yaml

El operador crea el bucket, abre el endpoint público y enruta el tráfico coincidente al servicio destino; eliminar el CR (kubectl delete -f cr.yaml) detiene el reenvío. También emite eventos en Kubernetes y actualiza los campos de estado del CR, por lo que kubectl describe webhookrelayforward muestra el estado en vivo de la entrega.

Es importante ser preciso con el alcance: este operador es solo para reenvío de webhooks/API. Webhook Relay ofrece un producto separado — el Webhook Relay Ingress Controller (relay ingress init, manifiestos de despliegue en github.com/webrelay/ingress) — para túneles bidireccionales que exponen un servicio completo como Grafana o Prometheus a través de un subdominio *.webrelay.io mediante recursos Ingress estándar. Los dos se instalan de manera diferente y resuelven problemas distintos; no esperes que el CRD del operador de webhooks proxye toda una app web.

Una adición más reciente que vale la pena señalar para equipos que ya integran agentes de IA en su infraestructura: Webhook Relay ahora expone un servidor MCP (https://my.webhookrelay.com/v1/mcp) que permite a un agente listar buckets, crear o actualizar inputs/outputs, inspeccionar logs y estadísticas de entrega de webhooks, e incluso enviar webhooks de prueba sintéticos a través del pipeline real — útil si quieres que un agente depure “¿por qué falló este webhook de GitHub en llegar a mi clúster?” en lugar de hacerlo manualmente.

La brecha de KubeSail — y qué la reemplaza hoy

KubeSail fue, durante varios años, el ejemplo más citado de “observar un recurso Ingress estándar y provisionar automáticamente un subdominio público con TLS en el edge” para clusters domésticos y bare-metal. Es importante aclarar que KubeSail cerró sus servicios en septiembre de 2025. La propia página de despedida de la compañía confirma: “Tras seis años maravillosos, hemos tomado la difícil decisión de dejar de operar nuestros servicios alojados… KubeSail ya no acepta nuevos usuarios ni vende hardware.” Sus fundadores recomendaron explícitamente Tailscale Funnel y Cloudflare Tunnel como alternativas. Cualquier artículo — o borrador — que describa el operador de KubeSail como opción vigente está hablando de un producto discontinuado.

La buena noticia es que el patrón popularizado por KubeSail sigue vivo y, de hecho, más maduro hoy a través del Tailscale Kubernetes Operator.

Tailscale Kubernetes Operator

Instalado vía Helm usando credenciales OAuth, el operador puede exponer una carga de trabajo del clúster a tu tailnet privado — y opcionalmente, a internet público — de forma declarativa, observando un recurso Ingress estándar. Ni siquiera se requiere un tipo personalizado específico para el caso común.

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app
  namespace: dev
  annotations:
    tailscale.com/funnel: "true"
spec:
  defaultBackend:
    service:
      name: my-app
      port:
        number: 80
  ingressClassName: tailscale
  tls:
    - hosts:
        - my-app
kubectl apply -f ingress.yaml
kubectl get ingress my-app -n dev   # espera el hostname asignado

Configurar ingressClassName: tailscale indica que el operador tomará control del Ingress: crea un nodo Tailscale, emite un certificado TLS para su nombre MagicDNS y enruta el tráfico al Service backend — sin reglas de firewall en el clúster. La carga de trabajo solo será accesible desde otros dispositivos en tu tailnet (una red privada), lo cual ya es útil para dashboards internos o runners de CI. Agregar la anotación tailscale.com/funnel: "true" hace que sea accesible públicamente en internet, similar a lo que hacía KubeSail automáticamente.

Para entornos de producción, un recurso ProxyGroup permite correr múltiples réplicas de proxy de ingreso para que la ruta sobreviva a reinicios del pod proxy, y la documentación de Tailscale menciona explícitamente gestionar despliegues multi-clúster con ArgoCD como caso de uso soportado — esto encaja en el mismo modelo GitOps descrito abajo. Eliminar el Ingress elimina limpiamente el nodo Tailscale correspondiente, garantizando que no queden conexiones huérfanas, como lo hace el enfoque CRD.

Opción auto-hospedada: Helm chart Newt de Pangolin

Para equipos que quieren el mismo patrón solo saliente pero auto-hospedado, Pangolin — un proxy inverso tunelizado basado en WireGuard (Traefik para TLS, Gerbil para WireGuard y un conector ligero llamado Newt que llama desde la red privada) — ahora publica un Helm chart oficial para Kubernetes, diferente de la instalación con Docker Compose que muchos auto-hospedadores han usado hasta hace poco. Actualmente, el chart está en versión 1.4.0 para la app Newt 1.12.3 y requiere Kubernetes 1.30 mínimo. Soporta namespaces por instancia y leer credenciales de conexión desde un Secret de Kubernetes existente en lugar de valores en texto plano, importante si se despliega mediante el mismo pipeline GitOps.

Exponer cargas de trabajo locales de Minikube a internet

Minikube es la forma estándar de correr un clúster de un solo nodo en una laptop, pero probar funciones públicas — callbacks OAuth, webhooks de terceros, integraciones API externas — ha sido históricamente incómodo.

Las opciones tradicionales son:

  1. kubectl expose + minikube service. Esto expone un Deployment vía NodePort, y minikube service <nombre> abre una ventana en el navegador apuntando a él. En el driver Docker — que es el predeterminado en macOS y Windows, donde Docker Desktop no puede enrutar directamente a IPs de contenedores — este comando en realidad abre un túnel SSH desde el host hacia el nodo de minikube para acceder al servicio, en lugar de acceder directamente al NodePort. Es un mecanismo real (el kic.ServiceTunnel de minikube usa SSH), no solo un lookup de puerto, y permanece abierto solo mientras el comando se mantenga en ejecución.
  2. El addon Ingress (minikube addons enable ingress) más minikube tunnel. minikube tunnel expone servicios de tipo LoadBalancer y requiere privilegios elevados porque modifica rutas del host; corre en primer plano hasta que se interrumpe con Ctrl-C, y olvidar que está corriendo suele ser molesto. Ninguna de estas opciones escala bien si quieres compartir tu entorno local con un compañero remoto o un proveedor externo.

Dado que el operador Tailscale (arriba) solo usa la API estándar Ingress, funciona en Minikube igual que en cualquier otro clúster — instala el operador con Helm, y aplica el mismo ingress.yaml mostrado antes, con ingressClassName: tailscale y todo, directamente en tu contexto de Minikube:

minikube start
helm install tailscale-operator tailscale/tailscale-operator \
  --namespace=tailscale --create-namespace \
  --set-string oauth.clientId=<CLIENT_ID> \
  --set-string oauth.clientSecret=<CLIENT_SECRET>

kubectl apply -f ingress.yaml   # mismo manifiesto, con anotación funnel incluida

Esto te proporciona una URL HTTPS pública real a la que GitHub o Google OAuth pueden enviar callbacks, proveniente de una carga de trabajo en Minikube en tu laptop — sin proceso minikube tunnel separado, y sin editar /etc/hosts. Eliminar el Ingress elimina el nodo y su certificado de la misma forma que en cualquier clúster, sin dejar endpoints públicos huérfanos tras las pruebas.

Integración GitOps y entrega continua

El enfoque CRD/operator se mantiene en un flujo GitOps, donde Git es la única fuente de verdad para infraestructura y estado de la aplicación. En un setup tradicional, un pipeline CI/CD despliega código y un humano configura manualmente el proxy inverso o túnel para exponerlo — creando divergencias entre lo en control de versiones y lo accesible.

Con definiciones de túneles expresadas como CRDs u objetos Ingress estándar, la configuración de enrutamiento es solo otro YAML junto a los manifiestos de Deployment, Service y ConfigMap:

  1. Un desarrollador hace push de una rama con una nueva microservicio y un CR WebhookRelayForward (o un Ingress anotado con Tailscale) a Git.
  2. ArgoCD o Flux detectan el commit y sincronizan el estado del clúster, aplicando el microservicio y el objeto de enrutamiento juntos.
  3. El operador relevante recoge el nuevo objeto, contacta su servicio externo y establece la ruta.
  4. El servicio es accesible — públicamente o en el tailnet — sin intervención manual en la configuración del proxy.

Si el clúster se reconstruye desde cero, ArgoCD vuelve a aplicar el repositorio en el nuevo clúster, y los operadores vuelven a provisionar cada ruta desde los objetos existentes sin intervención manual. Este patrón es exactamente el patrón multi-clúster que Tailscale documenta para su propio operador.

Beneficios de seguridad arquitectónica

Pasar de port-forwarding y balanceadores de carga en la nube a túneles salientes gestionados por operador mejora significativamente la postura de seguridad del clúster. Como la conexión es iniciada desde dentro hacia afuera, no es necesario abrir puertos entrantes en el firewall o grupos de seguridad del clúster — el clúster permanece oscuro para internet público, sin ser escaneado ni vulnerable a DDoS directo.

El RBAC estándar de Kubernetes se aplica a estos CRDs y recursos Ingress igual que a cualquier otro objeto: un administrador puede limitar roles para que solo ciertos namespaces puedan crear CRDs de túneles o recursos Ingress con ingressClassName: tailscale, permitiendo que dev y staging tengan endpoints públicos auto-gestionados, mientras que production pasa por un camino más controlado. Esto no es una característica especial de ningún operador — es RBAC ordinario a nivel de namespace aplicado a un nuevo tipo de objeto.

La terminación TLS y, en los casos de Tailscale y Webhook Relay, la autenticación, ocurren en el edge, antes de que el tráfico llegue al clúster — por lo que lo que llega al servicio interno ya está cifrado en tránsito y, en algunas configuraciones, ya autenticado.

En qué queda esto

La tendencia apunta a la abstracción: los desarrolladores escriben lógica de aplicación y un manifiesto Deployment, no túneles CLI imperativos ni reglas NAT gestionadas manualmente. Para enrutamiento específico de webhooks y API, el Webhook Relay Operator sigue siendo una opción sólida y de alcance limitado. Para ingreso de propósito general — el trabajo que KubeSail solía hacer — el Tailscale Kubernetes Operator es la opción estándar y mantenida hoy, con el Helm chart de Pangolin Newt como alternativa auto-hospedada para equipos que quieren el mismo patrón sin pasar por una red de borde de terceros. Los tres siguen la misma forma: un CRD o un objeto anotado estándar, reconciliado continuamente, eliminado limpiamente al borrarlo y desplegado mediante pipeline Git como todo lo demás en el clúster.


Verificación de hechos y registro de revisiones

  • KubeSail está discontinuado (corrección mayor). La sección original sobre “KubeSail Reverse Proxy” fue escrita en presente sobre un servicio activo. La página de despedida de KubeSail confirma: “Tras seis años, hemos decidido dejar de operar nuestros servicios alojados en septiembre de 2025.” Sus fundadores recomendaron Tailscale Funnel y Cloudflare Tunnel. Cualquier artículo o borrador que describa el operador de KubeSail como opción vigente está hablando de un producto discontinuado.
  • El CR WebhookRelayForward en el ejemplo estaba incompleto y con campo fabricado. La YAML del borrador incluía un campo secretRefName: whr-credentials que no forma parte del esquema del CRD (las credenciales se suministran al operador vía Helm con --set credentials.key/secret en la instalación, creando un Secret a nivel de clúster — no referenciado por CR) y omitía el bloque outputs, lo que hacía que el ejemplo tuviera un endpoint público pero sin destino para reenviar tráfico. Se corrigió con la documentación oficial en webhookrelay.com/docs/installation/kubernetes/, agregando el campo outputs, responseStatusCode y el flujo correcto de instalación con Helm.
  • Se añadió una distinción nueva y verificada: Webhook Relay ofrece dos productos separados — el operador de reenvío de webhooks (WebhookRelayForward CRD) y un controlador de ingreso separado (relay ingress init) para túneles bidireccionales. La versión original mezclaba implícitamente estos conceptos; la revisión aclara el alcance de cada uno.
  • Se añadió un detalle nuevo y verificado no en el borrador: el servidor MCP de Webhook Relay para gestión de buckets/inputs/outputs/logs, relevante para la cobertura de túneles MCP/IA en este blog.
  • La afirmación sobre SSH en Minikube fue verificada, no asumida. Confirmado con la fuente de minikube (kic.ServiceTunnel, SSH) que minikube service en el driver Docker abre un túnel SSH en lugar de acceder directamente al NodePort — la afirmación del borrador era correcta — y se añadió que esto importa especialmente en macOS/Windows Docker Desktop, donde el driver no puede enrutar directamente a IPs de contenedores.
  • Se reemplazó el ejemplo fabricado tunneling.example.com/v1alpha1 / LocalTunnel por un manifiesto real y verificado: un Kubernetes Ingress con ingressClassName: tailscale y la anotación tailscale.com/funnel: "true", aplicado directamente en un contexto Minikube usando el Tailscale Kubernetes Operator — extraído de la documentación de inicio rápido y de ingress de Tailscale.
  • Se suavizó la afirmación sobre RBAC y entornos productivos: en realidad, es RBAC ordinario a nivel de namespace, no una característica especial del operador, y cualquier operador lo hereda.
  • Se verificaron y mantuvieron las afirmaciones: la descripción del patrón Operator, la narrativa de reconciliación GitOps, y los comandos Helm de Webhook Relay, todos revisados y con ligeras ediciones.

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