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

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

Sigue estos pasos a fin de prepararte para esta tarea:

  • Asegúrate de haber habilitado la API de Google Kubernetes Engine.
  • Habilitar la API de Google Kubernetes Engine
  • Asegúrate de que instalaste el SDK de Cloud.
  • Establece tu ID del proyecto predeterminado:
    gcloud config set project [PROJECT_ID]
  • Si trabajas con clústeres zonales, establece tu zona de procesamiento predeterminada:
    gcloud config set compute/zone [COMPUTE_ZONE]
  • Si trabajas con clústeres regionales, establece tu región de procesamiento predeterminada:
    gcloud config set compute/region [COMPUTE_REGION]
  • Actualiza gcloud a la versión más reciente:
    gcloud components update

Crea un servicio de tipo ClusterIP

kubectl apply

A continuación, se muestra un manifiesto de implementación:

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: "gcr.io/google-samples/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
service-how-to-76699757f9-h4xk4   1/1       Running   0          4s
service-how-to-76699757f9-tjcfq   1/1       Running   0          4s
service-how-to-76699757f9-wt9d8   1/1       Running   0          4s

Aquí hay un manifiesto para un servicio de tipo ClusterIP:

apiVersion: v1
kind: Service
metadata:
  name: my-cip-service
spec:
  type: ClusterIP
  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 de la implementación 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

El resultado muestra un valor para clusterIP.

spec:
  clusterIP: 10.59.241.241

Anota tu valor clusterIP para usar más adelante.

Console

Crea una implementación

  1. Visita el menú Cargas de trabajo de Google Kubernetes Engine en Cloud Console.

    Visitar el menú Cargas de trabajo

  2. Haz clic en Implementar.

  3. En la casilla Contenedor, para Imagen del contenedor, ingresa gcr.io/google-samples/hello-app:2.0 y haz clic en Listo.

  4. Para Nombre de la aplicación, ingresa my-deployment.

  5. En Etiquetas, crea dos etiquetas. Para una etiqueta, configura Clave como app y Valor como metrics. En la otra, configura Clave como department y Valor como sales.

  6. En el menú desplegable Clúster, selecciona el clúster que desees.

  7. Haz clic en Implementar.

  8. Cuando tu implementación esté lista, se abrirá la página Detalles de la implementación y verás que esta tiene uno o más pods en ejecución.

Crear un servicio para exponer tu implementación

  1. En la página de detalles de la implementación, haz clic en Exponer.

  2. En la casilla Nueva asignación de puertos, configura Puerto como 80 y Puerto de destino como 8080. Deja Protocolo configurado como TCP. Haz clic en Listo.

  3. En el menú desplegable Tipo de servicio, selecciona IP de clúster.

  4. Para Nombre del servicio, ingresa my-cip-service.

  5. Haz clic en Exponer.

  6. Cuando tu servicio esté listo, se abrirá la página Detalles del servicio y podrás consultar toda la información. En concreto, puedes ver el valor de IP de clúster que Kubernetes le asignó a tu servicio. Esta es la dirección IP que los clientes internos pueden usar para llamar al servicio. Toma nota del valor IP de clúster para usar más adelante.

Acceder 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-6897d9577c-7z4fv     1/1       Running   0          5m

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

kubectl exec -it [YOUR_POD_NAME] -- sh

en el que [YOUR_POD_NAME] es 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

en el que [CLUSTER_IP] es 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 el resultado de hello-app:

Hello, world!
Version: 2.0.0
Hostname: service-how-to-76699757f9-hsb5x

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

Crea un servicio de tipo NodePort

kubectl apply

A continuación, se muestra un manifiesto de implementación:

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: "gcr.io/google-samples/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

El resultado muestra un valor nodePort.

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

Si los nodos de tu clúster tienen direcciones IP externas, busca la dirección IP externa de uno de tus nodos:

kubectl get nodes --output wide

En el resultado aparecerán las direcciones IP externas de tus nodos:

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.

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

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

En el ejemplo anterior, [NODE_PORT] es el valor del campo nodePort del servicio.

Console

Crea una implementación

  1. Visita el menú Cargas de trabajo de Google Kubernetes Engine en Cloud Console.

    Visitar el menú Cargas de trabajo

  2. Haz clic en Implementar.

  3. En el cuadro Contenedor, ingresa gcr.io/google-samples/hello-app:2.0 en Imagen del contenedor. Haz clic en Agregar variables de entorno. En Clave, ingresa PORT y en Valor, ingresa 50000. Haz clic en Listo.

  4. En la sección Configuración, para Nombre de la aplicación, ingresa my-deployment-50000.

  5. En Etiquetas, crea dos etiquetas. Para una etiqueta, configura Clave como app y Valor como metrics. En la otra, configura Clave como department y Valor como engineering.

  6. En el menú desplegable Clúster, selecciona el clúster que desees.

  7. Haz clic en Implementar.

  8. Cuando tu implementación esté lista, se abrirá la página Detalles de la implementación y verás que esta tiene uno o más pods en ejecución.

Crear un servicio para exponer tu implementación

  1. En la página de detalles de la implementación, en Servicios, haz clic en Exponer.

  2. En la casilla Nueva asignación de puertos, configura Puerto como 80 y Puerto de destino como 50000. Deja Protocolo configurado como TCP. Haz clic en Listo.

  3. En el menú desplegable Tipo de servicio, selecciona Puerto del nodo.

  4. Para Nombre del servicio, ingresa my-np-service.

  5. Haz clic en Exponer.

  6. Cuando tu servicio esté listo, se abrirá la página Detalles del servicio y podrás consultar toda la información. En específico, en Puertos, puedes ver el valor Puerto del nodo que Kubernetes le asignó a tu servicio. Toma nota del valor Puerto del nodo para usar más adelante.

Crea una regla de firewall para el puerto del nodo

  1. Visita el menú Reglas de firewall en Cloud Console.

    Visitar el menú Reglas de firewall.

  2. Haz clic en Crear regla de firewall.

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

  4. En el menú desplegable Destinos, selecciona Todas las instancias de la red.

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

  6. En Puerto y protocolos especificados, selecciona TCP y, luego, ingresa el valor del puerto de tu nodo.

  7. Haz clic en Crear.

Busca la dirección IP externa de uno de los nodos de tu clúster.

  1. Visita el menú de Google Kubernetes Engine en Cloud Console.

    Ir al menú de Google Kubernetes Engine

  2. Haz clic en el nombre del clúster que usas para el ejercicio.

  3. En Grupos de nodos, haz clic en el nombre de un grupo de instancias. Aparecerá una lista de nodos. Toma nota de la dirección IP externa de uno de los nodos.

Accede a tu servicio

En la barra de direcciones de tu navegador, ingresa [NODE_IP_ADDRESS]:[NODE_PORT].

En el ejemplo anterior, se ilustra lo siguiente:

  • [NODE_IP_ADDRESS] es la dirección IP externa de uno de tus nodos.
  • [NODE_PORT] es el valor del puerto de tu nodo.

La respuesta muestra el resultado de hello-app:

Hello, world!
Version: 2.0.0
Hostname: service-how-to-50000-695955857d-q76pb

Crea un servicio de tipo LoadBalancer

kubectl apply

A continuación, se muestra un manifiesto de implementación:

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: "gcr.io/google-samples/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 a 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 servicio de tipo LoadBalancer, un controlador de Google Cloud se activa y configura un balanceador de cargas de red. Espera un minuto a que el controlador configure el balanceador de cargas de la red y genere una dirección IP estable.

Observa el servicio:

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

Crea una implementación

  1. Visita el menú Cargas de trabajo de Google Kubernetes Engine en Cloud Console.

    Visitar el menú Cargas de trabajo

  2. Haz clic en Implementar.

  3. En la casilla Contenedor, ingresa gcr.io/google-samples/hello-app:2.0 para Imagen del contenedor. Haz clic en Agregar variables de entorno. En Clave, ingresa PORT y en Valor, ingresa 50001. Haz clic en Listo.

  4. Para Nombre de la aplicación, ingresa my-deployment-50001.

  5. En Etiquetas, crea dos etiquetas. Para una etiqueta, configura Clave como app y Valor como products. En la otra, configura Clave como department y Valor como sales.

  6. En el menú desplegable Clúster, selecciona el clúster que desees.

  7. Haz clic en Implementar.

  8. Cuando tu implementación esté lista, se abrirá la página Detalles de la implementación y verás que esta tiene uno o más pods en ejecución.

Crear un servicio para exponer tu implementación

  1. En la página de detalles de la implementación, haz clic en Exponer.

  2. En la casilla Nueva asignación de puertos, configura Puerto como 60000 y Puerto de destino como 50001. Deja Protocolo configurado como TCP. Haz clic en Listo.

  3. En el menú desplegable Tipo de servicio, selecciona Balanceador de cargas.

  4. Para Nombre del servicio, ingresa my-lb-service.

  5. Haz clic en Exponer.

  6. Cuando tu servicio esté listo, se abrirá la página Detalles del servicio y podrás consultar toda la información. En concreto, puedes ver la dirección IP externa del balanceador de cargas. Toma nota de la dirección IP del balanceador de cargas para más adelante.

Acceder a tu servicio

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

En la barra de direcciones de tu navegador, ingresa [LOAD_BALANCER_ADDRESS]:60000.

en el que [LOAD_BALANCER_ADDRESS] es la dirección IP externa del balanceador de cargas.

La respuesta muestra el resultado de hello-app:

Hello, world!
Version: 2.0.0
Hostname: service-how-to-50001-644f8857c7-xxdwg

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

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

Borrar tus servicios

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

Borrar tus implementaciones

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

Borrar tus reglas de firewall

gcloud compute firewall-rules delete test-node-port

Console

Borra tus servicios

  1. Visita el menú de Servicios de Google Kubernetes Engine en Cloud Console.

    Visitar el menú Servicios.

  2. Haz clic en my-cip-service y, luego, en Borrar.

  3. Haz clic en my-np-service y, luego, en Borrar.

  4. Haz clic en my-lb-service y, luego, en Borrar.

Borra tus implementaciones

  1. Visita el menú Cargas de trabajo de Google Kubernetes Engine en Cloud Console.

    Visitar el menú Cargas de trabajo

  2. Haz clic en my-deployment y, luego, en Borrar. Deja seleccionada la casilla Borrar el escalador automático horizontal del pod my-deployment-hpa y haz clic en Borrar.

  3. Haz clic en my-deployment-50000 y, luego, en Borrar. Deja seleccionada la casilla Borrar el escalador automático horizontal del pod my-deployment-50000-hpa y haz clic en Borrar.

  4. Haz clic en my-deployment-50001 y, luego, en Borrar. Deja seleccionada la casilla Borrar el escalador automático horizontal del pod my-deployment-50001-hpa y haz clic en Borrar.

Borra tus reglas de firewall

  1. Visita el menú Reglas de firewall en Cloud Console.

    Visitar el menú Reglas de firewall.

  2. Haz clic en test-node-porty, luego, en Borrar.

Próximos pasos