Exponer aplicaciones mediante servicios

En esta página se muestra cómo hacer que tus aplicaciones sean accesibles desde tu red interna o desde Internet creando servicios de Kubernetes en Google Kubernetes Engine (GKE) para exponer esas aplicaciones. Abarca cinco tipos de servicio: ClusterIP, NodePort, LoadBalancer, ExternalName y Headless.

El tutorial incluye ejemplos de cada tipo de servicio, en los que se muestra cómo crear implementaciones, exponerlas mediante servicios y acceder a ellas.

Esta página está dirigida a operadores y desarrolladores que aprovisionan y configuran recursos en la nube, y despliegan aplicaciones y servicios. Para obtener más información sobre los roles habituales y las tareas de ejemplo que se mencionan en el contenido, consulta Roles y tareas habituales de los usuarios de GKE. Google Cloud

Antes de leer esta página, asegúrate de que sabes cómo usar kubectl.

Introducción

La idea de un servicio es agrupar un conjunto de endpoints de pods en un único recurso. Puedes configurar varias formas de acceder a la agrupación. De forma predeterminada, obtienes una dirección IP de clúster estable que los clientes del clúster pueden usar para ponerse en contacto con los pods del servicio. Un cliente envía una solicitud a la dirección IP estable y la solicitud se dirige a uno de los pods del servicio.

Hay cinco tipos de Servicios:

  • ClusterIP (predeterminado)
  • NodePort
  • LoadBalancer
  • ExternalName
  • Sin interfaz gráfica

Los clústeres de Autopilot son públicos de forma predeterminada. Si eliges un clúster de Autopilot privado, debes configurar Cloud NAT para establecer conexiones salientes a Internet, como descargar imágenes de Docker Hub.

Este tema tiene varios ejercicios. En cada ejercicio, crearás un Deployment y expondrás sus Pods creando un Service. A continuación, envía una solicitud HTTP al servicio.

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.

Crear un servicio de tipo ClusterIP

En esta sección, crearás un servicio de tipo ClusterIP.

kubectl apply

Aquí tienes un manifiesto de un Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  selector:
    matchLabels:
      app: metrics
      department: sales
  replicas: 3
  template:
    metadata:
      labels:
        app: metrics
        department: sales
    spec:
      containers:
      - name: hello
        image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"

Copia el manifiesto en un archivo llamado my-deployment.yaml y crea la implementación:

kubectl apply -f my-deployment.yaml

Verifica que se estén ejecutando tres pods:

kubectl get pods

El resultado muestra tres pods en ejecución:

NAME                            READY   STATUS    RESTARTS   AGE
my-deployment-dbd86c8c4-h5wsf   1/1     Running   0          7s
my-deployment-dbd86c8c4-qfw22   1/1     Running   0          7s
my-deployment-dbd86c8c4-wt4s6   1/1     Running   0          7s

A continuación, se muestra un manifiesto de un servicio de tipo ClusterIP:

apiVersion: v1
kind: Service
metadata:
  name: my-cip-service
spec:
  type: ClusterIP
  # Uncomment the below line to create a Headless Service
  # clusterIP: None
  selector:
    app: metrics
    department: sales
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

El servicio tiene un selector que especifica dos etiquetas:

  • app: metrics
  • department: sales

Cada Pod de la implementación que haya creado anteriormente tiene esas dos etiquetas. Por lo tanto, los pods del despliegue se convertirán en miembros de este servicio.

Copia el manifiesto en un archivo llamado my-cip-service.yaml y crea el servicio:

kubectl apply -f my-cip-service.yaml

Espera un momento a que Kubernetes asigne una dirección interna estable al servicio y, a continuación, consulta el servicio:

kubectl get service my-cip-service --output yaml

En la salida se muestra un valor de clusterIP:

spec:
  clusterIP: 10.59.241.241

Anota el valor de clusterIP para más adelante.

Consola

Crear un despliegue

  1. Ve a la página Cargas de trabajo de la Google Cloud consola.

    Ve a Cargas de trabajo.

  2. Haz clic en Desplegar.

  3. En Especificar contenedor, selecciona Imagen de contenedor disponible.

  4. En Ruta de la imagen, introduce us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0.

  5. Haz clic en Hecho y, a continuación, en Continuar.

  6. En Configuración, en Nombre de la aplicación, introduce my-deployment.

  7. En Etiquetas, crea las siguientes etiquetas:

    • Clave: app y Valor: metrics
    • Clave: department y Valor: sales
  8. En Clúster, elige el clúster en el que quieras crear la implementación.

  9. Haz clic en Desplegar.

  10. Cuando la implementación esté lista, se abrirá la página Detalles de la implementación. En Pods gestionados, puedes ver que tu Deployment tiene uno o varios pods en ejecución.

Crear un servicio para exponer tu despliegue

  1. En la página Deployment details (Detalles de la implementación), haga clic en Actions > Expose (Acciones > Exponer).
  2. En el cuadro de diálogo Exponer, en Asignación de puertos, define los siguientes valores:

    • Puerto: 80
    • Puerto de destino: 8080
    • Protocolo: TCP
  3. En la lista desplegable Service type (Tipo de servicio), selecciona Cluster IP (IP de clúster).

  4. Haz clic en Exponer.

  5. Cuando tu servicio esté listo, se abrirá la página Detalles del servicio, donde podrás ver información sobre él. En IP de clúster, anota la dirección IP que Kubernetes ha asignado a tu servicio. Esta es la dirección IP que pueden usar los clientes internos para llamar al servicio.

Acceder a tu Servicio

Lista tus pods en ejecución:

kubectl get pods

En la salida, copia uno de los nombres de Pod que empiece por my-deployment.

NAME                            READY   STATUS    RESTARTS   AGE
my-deployment-dbd86c8c4-h5wsf   1/1     Running   0          2m51s

Obtener un shell en uno de los contenedores en ejecución:

kubectl exec -it POD_NAME -- sh

Sustituye POD_NAME por el nombre de uno de los pods de my-deployment.

En tu shell, instala curl:

apk add --no-cache curl

En el contenedor, haz una solicitud a tu servicio mediante la dirección IP de tu clúster y el puerto 80. Ten en cuenta que 80 es el valor del campo port de tu servicio. Este es el puerto que usas como cliente del servicio.

curl CLUSTER_IP:80

Sustituye CLUSTER_IP por el valor de clusterIP en tu servicio.

Tu solicitud se reenvía a uno de los pods miembros en el puerto TCP 8080, que es el valor del campo targetPort. Ten en cuenta que cada uno de los pods miembros del servicio debe tener un contenedor que escuche en el puerto 8080.

La respuesta muestra el resultado de hello-app:

Hello, world!
Version: 2.0.0
Hostname: my-deployment-dbd86c8c4-h5wsf

Para salir de la shell y volver al contenedor, introduce exit.

Crear un servicio de tipo NodePort

En esta sección, crearás un servicio de tipo NodePort.

kubectl apply

Aquí tienes un manifiesto de un Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment-50000
spec:
  selector:
    matchLabels:
      app: metrics
      department: engineering
  replicas: 3
  template:
    metadata:
      labels:
        app: metrics
        department: engineering
    spec:
      containers:
      - name: hello
        image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50000"

Fíjate en el objeto env del manifiesto. El objeto env especifica que la variable de entorno PORT del contenedor en ejecución tendrá el valor 50000. La aplicación hello-app escucha en el puerto especificado por la variable de entorno PORT. Por lo tanto, en este ejercicio, le indicas al contenedor que escuche en el puerto 50000.

Copia el manifiesto en un archivo llamado my-deployment-50000.yaml y crea la implementación:

kubectl apply -f my-deployment-50000.yaml

Verifica que se estén ejecutando tres pods:

kubectl get pods

Este es un manifiesto de un servicio de tipo NodePort:

apiVersion: v1
kind: Service
metadata:
  name: my-np-service
spec:
  type: NodePort
  selector:
    app: metrics
    department: engineering
  ports:
  - protocol: TCP
    port: 80
    targetPort: 50000

Copia el manifiesto en un archivo llamado my-np-service.yaml y crea el servicio:

kubectl apply -f my-np-service.yaml

Ver el servicio:

kubectl get service my-np-service --output yaml

La salida muestra un valor nodePort:

...
  spec:
    ...
    ports:
    - nodePort: 30876
      port: 80
      protocol: TCP
      targetPort: 50000
    selector:
      app: metrics
      department: engineering
    sessionAffinity: None
    type: NodePort
...

Crea una regla de cortafuegos para permitir el tráfico TCP en el puerto de tu nodo:

gcloud compute firewall-rules create test-node-port \
    --allow tcp:NODE_PORT

Sustituye NODE_PORT por el valor del campo nodePort de tu servicio.

Consola

Crear un despliegue

  1. Ve a la página Cargas de trabajo de la Google Cloud consola.

    Ve a Cargas de trabajo.

  2. Haz clic en Desplegar.

  3. En Especificar contenedor, selecciona Imagen de contenedor disponible.

  4. En Ruta de la imagen, escribe us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0.

  5. Haz clic en Añadir variable de entorno.

  6. En Clave, introduce PORT y, en Valor, introduce 50000.

  7. Haz clic en Hecho y, a continuación, en Continuar.

  8. En Configuración, en Nombre de la aplicación, introduce my-deployment-50000.

  9. En Etiquetas, crea las siguientes etiquetas:

    • Clave: app y Valor: metrics
    • Clave: department y Valor: engineering
  10. En Clúster, elige el clúster en el que quieras crear la implementación.

  11. Haz clic en Desplegar.

  12. Cuando la implementación esté lista, se abrirá la página Detalles de la implementación. En Pods gestionados, puedes ver que tu Deployment tiene uno o varios pods en ejecución.

Crear un servicio para exponer tu despliegue

  1. En la página Deployment details (Detalles de la implementación), haga clic en Actions > Expose (Acciones > Exponer).
  2. En el cuadro de diálogo Exponer, en Asignación de puertos, define los siguientes valores:

    • Puerto: 80
    • Puerto de destino: 50000
    • Protocolo: TCP
  3. En la lista desplegable Tipo de servicio, selecciona Puerto de nodo.

  4. Haz clic en Exponer.

  5. Cuando tu servicio esté listo, se abrirá la página Detalles del servicio, donde podrás ver información sobre él. En Puertos, anota el Puerto de nodo que Kubernetes ha asignado a tu servicio.

Crear una regla de cortafuegos para el puerto de tu nodo

  1. Ve a la página Políticas de cortafuegos de la consola de Google Cloud .

    Ir a Políticas de cortafuegos

  2. Haz clic en Crear regla de cortafuegos.

  3. En Nombre, escribe test-node-port.

  4. En la lista desplegable Destinos, selecciona Todas las instancias de la red.

  5. En Intervalos IPv4 de origen, introduce 0.0.0.0/0.

  6. En Protocolos y puertos, selecciona Protocolos y puertos especificados.

  7. Seleccione la casilla tcp e introduzca el valor del puerto del nodo que ha anotado.

  8. Haz clic en Crear.

Obtener una dirección IP de nodo

Busca la dirección IP externa de uno de tus nodos:

kubectl get nodes --output wide

El resultado debería ser similar al siguiente:

NAME          STATUS    ROLES     AGE    VERSION        EXTERNAL-IP
gke-svc-...   Ready     none      1h     v1.9.7-gke.6   203.0.113.1

No todos los clústeres tienen direcciones IP externas para los nodos. Por ejemplo, si tienes habilitados los nodos privados, los nodos no tendrán direcciones IP externas.

Acceder a tu Servicio

En la barra de direcciones de tu navegador, escribe lo siguiente:

NODE_IP_ADDRESS:NODE_PORT

Haz los cambios siguientes:

  • NODE_IP_ADDRESS: la dirección IP externa de uno de tus nodos, que se encuentra al crear el servicio en la tarea anterior.
  • NODE_PORT: el valor del puerto de tu nodo.

El resultado debería ser similar al siguiente:

Hello, world!
Version: 2.0.0
Hostname: my-deployment-50000-6fb75d85c9-g8c4f

Crear un servicio de tipo LoadBalancer

En esta sección, crearás un servicio de tipo LoadBalancer.

kubectl apply

Aquí tienes un manifiesto de un Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment-50001
spec:
  selector:
    matchLabels:
      app: products
      department: sales
  replicas: 3
  template:
    metadata:
      labels:
        app: products
        department: sales
    spec:
      containers:
      - name: hello
        image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50001"

Ten en cuenta que los contenedores de esta implementación escucharán en el puerto 50001.

Copia el manifiesto en un archivo llamado my-deployment-50001.yaml y crea la implementación:

kubectl apply -f my-deployment-50001.yaml

Verifica que se estén ejecutando tres pods:

kubectl get pods

A continuación, se muestra un manifiesto de un servicio de tipo LoadBalancer:

apiVersion: v1
kind: Service
metadata:
  name: my-lb-service
spec:
  type: LoadBalancer
  selector:
    app: products
    department: sales
  ports:
  - protocol: TCP
    port: 60000
    targetPort: 50001

Copia el manifiesto en un archivo llamado my-lb-service.yaml, y crea el servicio:

kubectl apply -f my-lb-service.yaml

Cuando creas un servicio de tipo LoadBalancer, un controlador de Google Cloudse activa y configura un balanceador de carga de red de transferencia externo. Espera un minuto a que el controlador configure el balanceador de carga de red de paso a través externo y genere una dirección IP estable.

Ver el servicio:

kubectl get service my-lb-service --output yaml

El resultado muestra una dirección IP externa estable en loadBalancer:ingress:

...
spec:
  ...
  ports:
  - ...
    port: 60000
    protocol: TCP
    targetPort: 50001
  selector:
    app: products
    department: sales
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.10

Consola

Crear un despliegue

  1. Ve a la página Cargas de trabajo de la Google Cloud consola.

    Ve a Cargas de trabajo.

  2. Haz clic en Desplegar.

  3. En Especificar contenedor, selecciona Imagen de contenedor disponible.

  4. En Ruta de la imagen, escribe us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0.

  5. Haz clic en Añadir variable de entorno.

  6. En Clave, introduce PORT y, en Valor, introduce 50001.

  7. Haz clic en Hecho y, a continuación, en Continuar.

  8. En Configuración, en Nombre de la aplicación, introduce my-deployment-50001.

  9. En Etiquetas, crea las siguientes etiquetas:

    • Clave: app y Valor: products
    • Clave: department y Valor: sales
  10. En Clúster, elige el clúster en el que quieras crear la implementación.

  11. Haz clic en Desplegar.

  12. Cuando la implementación esté lista, se abrirá la página Detalles de la implementación. En Pods gestionados, puedes ver que tu Deployment tiene uno o varios pods en ejecución.

Crear un servicio para exponer tu despliegue

  1. En la página Deployment details (Detalles de la implementación), haga clic en Actions > Expose (Acciones > Exponer).
  2. En el cuadro de diálogo Exponer, en Asignación de puertos, define los siguientes valores:

    • Puerto: 60000
    • Puerto de destino: 50001
    • Protocolo: TCP
  3. En la lista desplegable Tipo de servicio, selecciona Balanceador de carga.

  4. Haz clic en Exponer.

  5. Cuando tu servicio esté listo, se abrirá la página Detalles del servicio, donde podrás ver información sobre él. En Balanceador de carga, anota la dirección IP externa del balanceador de carga.

Acceder a tu Servicio

Espera unos minutos a que GKE configure el balanceador de carga.

En la barra de direcciones de tu navegador, escribe lo siguiente:

LOAD_BALANCER_ADDRESS:60000

Sustituye LOAD_BALANCER_ADDRESS por la dirección IP externa de tu balanceador de carga.

La respuesta muestra el resultado de hello-app:

Hello, world!
Version: 2.0.0
Hostname: my-deployment-50001-68bb7dfb4b-prvct

Ten en cuenta que el valor de port en un servicio es arbitrario. En el ejemplo anterior se muestra cómo se hace esto con un valor port de 60.000.

Crear un servicio de tipo ExternalName

En esta sección, crearás un servicio de tipo ExternalName.

Un servicio de tipo ExternalName proporciona un alias interno para un nombre de DNS externo. Los clientes internos hacen solicitudes mediante el nombre de DNS interno y las solicitudes se redirigen al nombre externo.

A continuación, se muestra un manifiesto de un servicio de tipo ExternalName:

apiVersion: v1
kind: Service
metadata:
  name: my-xn-service
spec:
  type: ExternalName
  externalName: example.com

En el ejemplo anterior, el nombre de DNS es my-xn-service.default.svc.cluster.local. Cuando un cliente interno hace una solicitud a my-xn-service.default.svc.cluster.local, la solicitud se redirige a example.com.

Usar kubectl expose para crear un servicio

Como alternativa a escribir un manifiesto de servicio, puedes crear un servicio usando kubectl expose para exponer un despliegue.

Para exponer my-deployment, que se ha mostrado anteriormente en este tema, puedes introducir este comando:

kubectl expose deployment my-deployment --name my-cip-service \
    --type ClusterIP --protocol TCP --port 80 --target-port 8080

Para exponer my-deployment-50000, como se muestra en este tema, puedes introducir este comando:

kubectl expose deployment my-deployment-50000 --name my-np-service \
    --type NodePort --protocol TCP --port 80 --target-port 50000

Para exponer my-deployment-50001, que se ha mostrado anteriormente en este tema, puedes introducir este comando:

kubectl expose deployment my-deployment-50001 --name my-lb-service \
    --type LoadBalancer --port 60000 --target-port 50001

Ver tus servicios

Puedes ver los servicios que has creado en la página Servicios de la Google Cloud consola.

Ir a Servicios

También puedes ver tus servicios en App Hub en el contexto de las funciones empresariales que admiten. App Hub ofrece una vista general centralizada de todas tus aplicaciones y sus servicios asociados.

Para ver tus servicios en App Hub, ve a la página App Hub de la consola de Google Cloud .

Ir a App Hub

Como servicio de Kubernetes gestionado, GKE envía automáticamente metadatos de servicio, concretamente URIs de recursos, a App Hub cada vez que se crean o se destruyen recursos. Esta ingestión de metadatos continua mejora la experiencia de creación y gestión de aplicaciones en App Hub.

Para obtener más información sobre los recursos que admite App Hub, consulta los recursos admitidos.

Para saber cómo configurar App Hub en tu proyecto, consulta Configurar App Hub.

Eliminar los recursos utilizados

Después de completar los ejercicios de esta página, sigue estos pasos para quitar recursos y evitar que se apliquen cargos no deseados a tu cuenta:

kubectl apply

Eliminar tus servicios

kubectl delete services my-cip-service my-np-service my-lb-service

Eliminar tus implementaciones

kubectl delete deployments my-deployment my-deployment-50000 my-deployment-50001

Eliminando tu regla de cortafuegos

gcloud compute firewall-rules delete test-node-port

Consola

Eliminar tus servicios

  1. Ve a la página Servicios de la Google Cloud consola.

    Ir a Servicios

  2. Selecciona los servicios que has creado en este ejercicio y haz clic en Eliminar.

  3. Cuando se te pida que confirmes la acción, haz clic en Eliminar.

Eliminar tus implementaciones

  1. Ve a la página Cargas de trabajo de la Google Cloud consola.

    Ve a Cargas de trabajo.

  2. Selecciona las implementaciones que has creado en este ejercicio y, a continuación, haz clic en Eliminar.

  3. Cuando se te pida que confirmes la acción, marca la casilla Eliminar Horizontal Pod Autoscalers asociados a las implementaciones seleccionadas y haz clic en Eliminar.

Eliminando tu regla de cortafuegos

  1. Ve a la página Políticas de cortafuegos de la consola de Google Cloud .

    Ir a Políticas de cortafuegos

  2. Selecciona la casilla test-node-port y, a continuación, haz clic en Eliminar.

  3. Cuando se te pida que confirmes la acción, haz clic en Eliminar.

Siguientes pasos