¿Necesita depurar una aplicación que se ejecuta dentro de su clúster de Kubernetes? El reenvío de puertos es una forma de conectarse a pods que no son de acceso público. Puede usar esta técnica para inspeccionar bases de datos, herramientas de monitoreo y otras aplicaciones que desees implementar internamente sin una ruta pública.
El reenvío de puertos es integrado en Kubectl. La CLI puede iniciar sesiones de tunelización que redirigen el tráfico en los puertos locales a los pods en su clúster de Kubernetes. Aquí se explica cómo configurarlo.
Cómo funciona el reenvío de puertos
El reenvío de puertos es un tipo de regla de traducción de direcciones de red (NAT) que enruta el tráfico de una red a otra. En el contexto de Kubernetes, las solicitudes que parecen ser canceladas por localhost
se redirigen a la red interna de su clúster.
El reenvío de puertos solo funciona a nivel de puerto. Diriges un puerto específico como 33060
a un puerto de destino como 3306
en la red de destino. Cuando envía tráfico a su puerto local 33060
se reenviará automáticamente al puerto 3306
en el extremo remoto.
Esta técnica le permite acceder a cargas de trabajo privadas de Kubernetes que no están expuestas por NodePort, Ingress o LoadBalancer. Puede dirigir el tráfico local directamente a su clúster, lo que elimina la necesidad de crear servicios de Kubernetes para sus cargas de trabajo internas. Esto ayuda a reducir su superficie de ataque.
Implementación de una aplicación de muestra
Veamos ahora el reenvío de puertos de Kubernetes en acción. Comience por crear una implementación básica a la que se conectará mediante el reenvío de puertos en la siguiente sección.
Estamos usando un pod de base de datos MySQL como un ejemplo realista de cuándo podría necesitar usar esta técnica. Las bases de datos normalmente no se exponen públicamente, por lo que los administradores de Kubernetes a menudo usan el reenvío de puertos para abrir una conexión directa.
Cree un archivo YAML para su implementación:
apiVersion: apps/v1 kind: Deployment metadata: name: mysql spec: selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - image: mysql:8.0 name: mysql env: - name: MYSQL_ROOT_PASSWORD value: mysql
Asegúrese de cambiar el valor de la MYSQL_ROOT_PASSWORD
variable de entorno antes de usar este manifiesto en producción. Correr kubectl apply
para crear su implementación de MySQL:
$ kubectl apply -f mysql.yaml deployment.apps/mysql created
A continuación, utilice el get pods
Comando para comprobar que la carga de trabajo se inició correctamente:
$ kubectl get pods NAME READY STATUS RESTARTS AGE mysql-5f54dd5789-t5fzc 1/1 Running 0 2s
Uso de Kubectl para reenviar puertos a Kubernetes
Aunque MySQL ahora se está ejecutando en su clúster, no tiene forma de acceder a él desde el exterior. A continuación, configure una sesión de reenvío de puertos para que pueda usar sus instalaciones locales de herramientas como el mysql
CLI para conectarse a su base de datos.
Aquí hay un ejemplo simple:
$ kubectl port-forward deployment/mysql 33060:3306 Forwarding from 127.0.0.1:33060 -> 3306 Forwarding from [::1]:33060 -> 3306
Las conexiones al puerto 33060 se dirigirán al puerto 3306 contra el Pod que ejecuta su implementación de MySQL. Ahora puede iniciar una sesión de shell de MySQL dirigida a su base de datos en Kubernetes:
$ mysql --host 127.0.0.1 --port 33060 -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 10 Server version: 8.0.29 MySQL Community Server - GPL
Mantenga la ventana de shell que está ejecutando el kubectl port-forward
comando abierto durante la sesión de depuración. El reenvío de puertos finalizará cuando presione Ctrl+C o cierre la ventana.
Cambio de los números de puerto local y remoto
La sintaxis para los enlaces de número de puerto es local:remote
. los 33060:3306
ejemplo que se muestra arriba mapas puerto 33060 en localhost
a 3306
en el pod de destino.
Especificar solo un número, sin dos puntos, lo interpretará como el puerto local y remoto:
$ kubectl port-forward deployment/mysql 3306
Puede dejar el puerto local en blanco para asignar automáticamente un puerto aleatorio:
$ kubectl port-forward deployment/mysql :3306 Forwarding from 127.0.0.1:34923 -> 3306 Forwarding from [::1]:34923 -> 3306
Aquí usaría el número de puerto generado aleatoriamente 34923
con su cliente MySQL local.
Cambiar la dirección de escucha
Kubectl une el puerto local en el 127.0.0.1
(IPv4) y ::1
(IPv6) direcciones por defecto. En su lugar, puede especificar su propio conjunto de direcciones IP proporcionando un --address
marca cuando ejecuta el port-forward
dominio:
# Listen on two IPv4 addresses $ kubectl port-forward deployment/mysql :3306 --address 127.0.0.1,192.168.0.1
La bandera solo acepta direcciones IP y la localhost
palabra clave. Este último se interpreta para incluir 127.0.0.1
y ::1
haciendo coincidir los valores predeterminados del comando cuando --address
se omite.
Resumen
El reenvío de puertos es una técnica útil para acceder a aplicaciones privadas dentro de su clúster de Kubernetes. Kubectl canaliza el tráfico desde su red local a un puerto específico en un Pod en particular. Es un mecanismo de nivel relativamente bajo que puede manejar cualquier conexión TCP. Reenvío de puertos UDP aún no es compatible.
El uso de una sesión de reenvío de puertos ad-hoc es una forma segura de depurar cargas de trabajo que no necesitan exponerse externamente. La creación de un servicio para cada nueva implementación podría permitir que intrusos y atacantes descubran puntos finales que deben protegerse. El reenvío de puertos en Kubectl le permite conectarse de forma segura directamente a sus aplicaciones, sin tener que averiguar en qué nodos se están ejecutando.