Expón aplicaciones con servicios


En esta página, se muestra cómo crear servicios de Kubernetes en un clúster de Google Kubernetes Engine. Para ver una explicación del concepto de Servicio y un análisis de los distintos tipos que existen, consulta Servicio.

Introducción

El concepto de Servicio es agrupar un conjunto de extremos de pod en un solo recurso. Puedes configurar varias formas para acceder a la agrupación. De forma predeterminada, obtienes una dirección IP de clúster estable que los clientes dentro del clúster pueden usar para comunicarse con los pods en el servicio. Un cliente envía una solicitud a una dirección IP estable, y la solicitud se enruta a uno de los pods en el Servicio.

Existen 5 tipos de Servicios:

  • ClusterIP (predeterminado)
  • NodePort
  • LoadBalancer
  • ExternalName
  • Headless

Los clústeres de Autopilot son públicos de forma predeterminada. Si eliges un clúster de Autopilot privado, debes configurar Cloud NAT para hacer conexiones a Internet salientes, por ejemplo, mediante la extracción de imágenes de DockerHub.

Este tema tiene varios ejercicios. En cada ejercicio, creas una implementación y expones sus pods mediante la creación de un Servicio. Luego, envías una solicitud HTTP al Servicio.

Antes de comenzar

Antes de comenzar, asegúrate de haber realizado las siguientes tareas:

  • Habilita la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste gcloud CLI, ejecuta gcloud components update para obtener la versión más reciente.
* Crea un clúster de GKE.

Crea un servicio de tipo ClusterIP

En esta sección, debes crear un Service de tipo ClusterIP.

kubectl apply

A continuación, se muestra un manifiesto de 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 los tres pods estén en ejecución:

kubectl get pods

El resultado muestra los 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

Aquí hay un manifiesto para 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

Este servicio tiene un selector que especifica dos etiquetas:

  • app: metrics
  • department: sales

Todos los Pods del Deployment que creaste anteriormente tienen esas dos etiquetas. Por lo tanto, formarán parte 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 revísalo:

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

La salida muestra un valor para clusterIP:

spec:
  clusterIP: 10.59.241.241

Anota el valor clusterIP para usar más adelante.

Console

Crear una implementación

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

    Ir a Cargas de trabajo

  2. Haz clic en Implementar.

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

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

  5. Haz clic en Listo y, luego, en Continuar.

  6. En Configuración, en Nombre de la aplicación, ingresa 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 deseas crear el Deployment.

  9. Haz clic en Implementar.

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

Crea un servicio para exponer tu Deployment

  1. En la página Detalles de Deployment, haz clic en Acciones > Exponer.
  2. En el diálogo Exponer, en Asignación de puertos, establece los siguientes valores:

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

  4. Haz clic en Exponer.

  5. Cuando tu servicio esté listo, se abrirá la página Detalles del servicio y podrás consultar toda la información. En IP del clúster, anota la dirección IP que Kubernetes le asignó a tu Service. Esta es la dirección IP que los clientes internos pueden usar para llamar al servicio.

Accede a tu servicio

Enumera los Pods en ejecución:

kubectl get pods

En el resultado, copia uno de los nombres de Pods que comience con my-deployment.

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

Obtén una shell en uno de tus contenedores en ejecución:

kubectl exec -it POD_NAME -- sh

Reemplaza POD_NAME por el nombre de uno de los Pods en my-deployment.

En tu shell, instala curl:

apk add --no-cache curl

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

curl CLUSTER_IP:80

Reemplaza 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 pod miembro del servicio debe tener un contenedor que esté escuchando en el puerto 8080.

La respuesta muestra la salida de hello-app:

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

Para salir de la shell hacia tu contenedor, ingresa exit.

Crea un servicio de tipo NodePort

En esta sección, debes crear un Service de tipo NodePort.

kubectl apply

A continuación, se muestra un manifiesto de 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"

Observa el objeto env en el 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 que se especifica en 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 los tres pods estén en ejecución:

kubectl get pods

A continuación, se muestra 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

Observa 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 firewall para permitir el tráfico de TCP en el puerto del nodo:

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

Reemplaza NODE_PORT por el valor del campo nodePort del servicio.

Console

Crear una implementación

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

    Ir a Cargas de trabajo

  2. Haz clic en Implementar.

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

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

  5. Haz clic en Agregar variable de entorno.

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

  7. Haz clic en Listo y, luego, en Continuar.

  8. En Configuración, en Nombre de la aplicación, ingresa 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 deseas crear el Deployment.

  11. Haz clic en Implementar.

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

Crea un servicio para exponer tu Deployment

  1. En la página Detalles de Deployment, haz clic en Acciones > Exponer.
  2. En el diálogo Exponer, en Asignación de puertos, establece los siguientes valores:

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

  4. Haz clic en Exponer.

  5. Cuando tu servicio esté listo, se abrirá la página Detalles del servicio y podrás consultar toda la información. En Puertos, anota el Puerto del nodo que Kubernetes le asignó a tu Service.

Crea una regla de firewall para el puerto del nodo

  1. Ve a la página de políticas de firewall en la consola de Google Cloud.

    Ir a Políticas de firewall

  2. Haz clic en Crear regla de firewall.

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

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

  5. En Rangos de IPv4 de origen, ingresa 0.0.0.0/0.

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

  7. Selecciona la casilla de verificación tcp y, luego, ingresa el valor del puerto de nodo que anotaste.

  8. Haz clic en Crear.

Obtén la dirección IP de un nodo

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

kubectl get nodes --output wide

El resultado es similar a este:

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, los nodos de clústeres privados no tienen direcciones IP externas.

Accede a tu servicio

En la barra de direcciones del navegador, ingresa lo siguiente:

NODE_IP_ADDRESS:NODE_PORT

Reemplaza lo siguiente:

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

El resultado es similar a este:

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

Crea un Service de tipo LoadBalancer

En esta sección, debes crear un Service de tipo LoadBalancer.

kubectl apply

A continuación, se muestra un manifiesto de 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 los tres pods estén en ejecución:

kubectl get pods

Aquí hay un manifiesto para 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 Service de tipo LoadBalancer, un controlador de Google Cloud se activa y configura un balanceador de cargas de red de transferencia externo. Espera un minuto a que el controlador configure el balanceador de cargas de red de transferencia externo y genere una dirección IP estable.

Observa el Service:

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

En el resultado, se 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

Console

Crear una implementación

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

    Ir a Cargas de trabajo

  2. Haz clic en Implementar.

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

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

  5. Haz clic en Agregar variable de entorno.

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

  7. Haz clic en Listo y, luego, en Continuar.

  8. En Configuración, en Nombre de la aplicación, ingresa 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 deseas crear el Deployment.

  11. Haz clic en Implementar.

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

Crea un servicio para exponer tu Deployment

  1. En la página Detalles de Deployment, haz clic en Acciones > Exponer.
  2. En el diálogo Exponer, en Asignación de puertos, establece los siguientes valores:

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

  4. Haz clic en Exponer.

  5. Cuando tu servicio esté listo, se abrirá la página Detalles del servicio y podrás consultar toda la información. En Balanceador de cargas, toma nota de la dirección IP externa del balanceador de cargas.

Accede a tu servicio

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

En la barra de direcciones del navegador, ingresa lo siguiente:

LOAD_BALANCER_ADDRESS:60000

Reemplaza LOAD_BALANCER_ADDRESS por la dirección IP externa del balanceador de cargas.

La respuesta muestra la salida 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, esto se demuestra con el valor port en 60000.

Crea un servicio de tipo ExternalName

En esta sección, debes crear un Service de tipo ExternalName.

Un servicio de tipo ExternalName proporciona un alias interno para un nombre de DNS externo. Los clientes internos hacen solicitudes con el nombre de DNS interno, y las solicitudes se redireccionan a un nombre externo.

Aquí hay un manifiesto para 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, esta se redirecciona a example.com.

Usa kubectl expose para crear un servicio

Como alternativa a escribir un manifiesto de servicio, puedes crear un servicio con kubectl expose para exponer una implementación.

Si deseas exponer my-deployment, tal como se demostró antes en este tema, puedes ingresar este comando:

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

Si deseas exponer my-deployment-50000, tal como se demostró antes en este tema, puedes ingresar este comando:

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

Si deseas exponer my-deployment-50001, tal como se demostró antes en este tema, puedes ingresar este comando:

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

Realiza una limpieza

Después de completar los ejercicios de esta página, sigue estos pasos para quitar los recursos a fin de prevenir cobros no deseados en tu cuenta:

kubectl apply

Borra tus Servicios

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

Borrar tus Deployments

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

Borra tus reglas de firewall

gcloud compute firewall-rules delete test-node-port

Console

Borra tus Servicios

  1. Ve a la página Service de BigQuery en la consola de Google Cloud.

    Ir a Servicios

  2. Selecciona los objetos de Servicio que creaste en este ejercicio y, luego, haz clic en Borrar.

  3. Cuando se te solicite confirmar, haz clic en Borrar.

Borrar tus Deployments

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

    Ir a Cargas de trabajo

  2. Selecciona los objetos Deployment que creaste en este ejercicio y haz clic en Borrar.

  3. Cuando se te solicite confirmación, selecciona la casilla de verificación Borrar los escaladores automáticos de pod horizontales asociados con los Deployments seleccionados y, luego, haz clic en Borrar.

Borra tus reglas de firewall

  1. Ve a la página de políticas de firewall en la consola de Google Cloud.

    Ir a Políticas de firewall

  2. Selecciona la casilla de verificación test-node-port y, luego, haz clic en Borrar.

  3. Cuando se te solicite confirmar, haz clic en Borrar.

¿Qué sigue?