Permitir conexiones directas a pods de Autopilot mediante hostPort


En esta página se muestra cómo exponer un puerto aleatorio en un pod que se ejecuta en un clúster de Autopilot de Google Kubernetes Engine (GKE).

Al exponer un puerto en un pod, este puede aceptar conexiones entrantes directamente, sin un balanceador de carga. GKE elige un puerto aleatorio para abrirlo de un intervalo que especifiques en la especificación del pod. Este tipo de exposición de puertos aleatoria es útil cuando tu carga de trabajo requiere conexiones entrantes directas, pero no depende de un número de puerto persistente. Un ejemplo de este tipo de carga de trabajo es un recurso GameServer de Agones con la política de puertos Dynamic predeterminada.

Cuando solicitas un puerto aleatorio, GKE anula el valor del campo hostPort de la especificación del contenedor y lo sustituye por el puerto que GKE ha seleccionado.

Antes de empezar

Antes de empezar, asegúrate de que has realizado las siguientes tareas:

  • Habilita la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Si quieres usar Google Cloud CLI para esta tarea, instálala y, a continuación, inicialízala. Si ya has instalado la gcloud CLI, obtén la versión más reciente ejecutando gcloud components update.
  • Asegúrate de tener un clúster de Autopilot de GKE con la versión 1.24.7-gke.1200 o una posterior, o la versión 1.25.3-gke.1100 o una posterior.

Limitaciones

Solo puedes asignar hostPorts aleatorios a pods estáticos o a pods gestionados por un controlador personalizado, como Agones. Esta función no se admite en controladores gestionados de Kubernetes, como las implementaciones.

Solicitar un puerto aleatorio

  1. Guarda el siguiente archivo de manifiesto como host-port-pod.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: game-pod
      annotations:
        autopilot.gke.io/host-port-assignment: '{"min":MIN_PORT,"max":MAX_PORT}'
    spec:
      containers:
      - name: local-chat
        image: ubuntu
        ports:
        - containerPort: 80
          hostPort: HOST_PORT1
          protocol: tcp
      - name: game-server
        image: ubuntu
        ports:
        - containerPort: 80
          hostPort: HOST_PORT2
          protocol: udp
    

    Haz los cambios siguientes:

    • MIN_PORT: número de puerto mínimo del intervalo del que GKE elige un puerto aleatorio.
    • MAX_PORT: número de puerto máximo del intervalo del que GKE elige un puerto aleatorio.
    • HOST_PORT1, HOST_PORT2: cualquier número de puerto válido. Cuando se programa el pod, GKE actualiza este campo con el puerto asignado aleatoriamente. Si tienes varios contenedores, usa números de puerto diferentes para cada uno.

    El intervalo de puertos (la diferencia entre MAX_PORT y MIN_PORT) debe ser de al menos 1000 puertos.

  2. Aplica el archivo de manifiesto:

    kubectl apply -f host-port-pod.yaml
    

Cuando aplicas el manifiesto, GKE selecciona un puerto aleatorio de tu intervalo y lo asigna a tu contenedor. Si GKE asigna el mismo valor de puerto a dos pods, GKE coloca automáticamente los pods en nodos independientes para evitar conflictos de puertos.

Comprobar el puerto asignado

Para encontrar el número de puerto que GKE ha asignado a tus contenedores, inspecciona el pod:

kubectl get pod game-pod --output=yaml

El resultado debería ser similar al siguiente:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    autopilot.gke.io/host-port-assignment: '{"min":MIN_PORT,"max":MAX_PORT,"portsAssigned":{"HOST_PORT1":7300,"HOST_PORT2":7450}}'
  name: game-pod
  namespace: default
spec:
  containers:
  - name: local-chat
    image: ubuntu
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
      hostPort: 7300
      protocol: TCP
  - name: game-server
    image: ubuntu
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
      hostPort: 7450
      protocol: UDP

En este resultado:

  • metadata.annotations.autopilot.gke.io/host-port-assignment: las asignaciones de puertos, que muestran el valor original de hostPort que has definido para cada contenedor y el valor actualizado de hostPort que ha asignado GKE. Este campo es útil si has solicitado varios puertos en tu especificación de Pod.
  • spec.containers.ports.hostPort: el puerto abierto que GKE ha asignado a cada contenedor.

Siguientes pasos

Consulta el seguimiento de la compatibilidad con Agones en Autopilot en GitHub.