Despliega una aplicación

En este documento se muestra un ejemplo de cómo desplegar una aplicación en un clúster de usuario creado con Google Distributed Cloud (solo software) para VMware.

Antes de empezar

En el ejemplo que se muestra aquí, necesitas un clúster de usuario que utilice el balanceo de carga de MetalLB agrupado. Para obtener instrucciones sobre cómo crear un clúster de usuarios mínimo que use MetalLB, consulta Crear clústeres básicos.

Puedes usar la Google Cloud consolakubectl o la herramienta de línea de comandos kubectl en tu estación de trabajo de administrador para implementar la aplicación.

Consola

  1. En la consola, ve a la página Descripción general de los clústeres de Google Kubernetes Engine.

    Ir a clústeres de GKE

  2. En la lista de clústeres, haz clic en tu clúster de usuario y comprueba que has iniciado sesión en él.

    Si aún no has iniciado sesión en tu clúster de usuario, hazlo siguiendo las instrucciones que se indican en Gestionar clústeres desde la consola Google Cloud .

Contenedores

  1. En Nuevo contenedor, selecciona Imagen de contenedor disponible.

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

  3. Haz clic en Continuar.

Configuración

  1. En Nombre de la implementación, escribe my-deployment.

  2. En Espacio de nombres, introduce default.

  3. Introduce estas dos etiquetas:

    • Clave 1: app, Valor 1: metrics
    • Clave 2: department, Valor 2: sales
  4. En el menú desplegable Clúster de Kubernetes, selecciona tu clúster.

  5. Haz clic en Continuar.

Expose

  1. Marca la opción Exponer el despliegue como un nuevo servicio.

  2. En Puerto 1, escribe 80.

  3. En Puerto de destino 1, introduce 8080. Este es el valor adecuado porque el contenedor hello-app escucha en el puerto TCP 8080 de forma predeterminada. Para comprobarlo, consulta el Dockerfile y el código fuente de la aplicación.

  4. En Protocolo 1, selecciona TCP.

  5. En Tipo de servicio, selecciona LoadBalancer.

En la parte inferior de la página, haz clic en el botón Implementar.

Ver los detalles de la implementación y del servicio

  1. Cuando tu implementación esté lista, se abrirá la página Detalles de la implementación en la sección Cargas de trabajo de Kubernetes de la consola Google Cloud . En esta página, puedes ver los detalles de la implementación y sus tres pods.

  2. En Exposing services (Servicios de exposición), haz clic en el nombre del servicio que expone tu implementación. En este ejercicio, el nombre es my-deployment-service.

  3. Se abrirá la página Detalles del servicio. En esta página, puedes ver detalles sobre el servicio. Por ejemplo, puedes ver que cualquier pod que tenga las etiquetas app: metrics y department: sales es miembro del servicio. Recuerda que los pods de my-deployment tienen estas etiquetas.

También puedes ver un valor en IP del balanceador de carga. La IP del balanceador de carga se ha configurado automáticamente en el balanceador de carga del clúster.

Reenvío del Servicio

Supongamos que un cliente fuera del clúster envía una solicitud a la IP del balanceador de carga en el puerto TCP 80. La solicitud se enruta al balanceador de carga del clúster. El balanceador de carga reenvía la solicitud a un pod miembro en el puerto TCP 8080. Recuerda que cada pod de my-deployment tiene un contenedor que escucha en el puerto TCP 8080.

Probar el Servicio

Ve a una máquina en la que se pueda enrutar la IP del balanceador de carga.

Para llamar a tu servicio, introduce la IP del balanceador de carga en un navegador o usa un comando como curl. Por ejemplo:

curl [LOAD_BALANCER_IP]:80

El resultado muestra un mensaje Hello, world!. Por ejemplo:

curl 203.0.113.1:80
Hello, world!
Version: 2.0.0
Hostname: my-deployment-dbd86c8c4-9wpbv

Eliminar la implementación

Ve a la página Cargas de trabajo de la sección Kubernetes Engine de la consola.

Ve a la página Cargas de trabajo.

En la lista de implementaciones, selecciona my-deployment.

En la parte superior de la página, haz clic en Eliminar. De esta forma, se eliminan tanto el Deployment como el Service de exposición.

Línea de comandos

Conectarse a la estación de trabajo de administrador

Obtén una conexión SSH a tu estación de trabajo de administrador. Sigue estos pasos en tu estación de trabajo de administrador.

Crear un despliegue

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 --kubeconfig USER_CLUSTER_KUBECONFIG -f my-deployment.yaml

donde USER_CLUSTER_KUBECONFIG es la ruta del archivo kubeconfig de tu clúster de usuario.

Obtén información básica sobre tu implementación:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployment my-deployment

El resultado muestra que la implementación tiene tres pods que están disponibles:

NAME            READY   UP-TO-DATE   AVAILABLE   AGE
my-deployment   3/3     3            3           27s

Lista los pods de tu Deployment:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get pods

La salida muestra que tu Deployment tiene tres pods en ejecución:

NAME                             READY   STATUS    RESTARTS   AGE
my-deployment-54944c8d55-4srm2   1/1     Running   0          6s
my-deployment-54944c8d55-7z5nn   1/1     Running   0          6s
my-deployment-54944c8d55-j62n9   1/1     Running   0          6s

Obtén información detallada sobre tu implementación:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployment my-deployment --output yaml

En el resultado se muestran detalles sobre la especificación y el estado del despliegue:

kind: Deployment
metadata:
  ...
  generation: 1
  name: my-deployment
  namespace: default
  ...
spec:
  ...
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: metrics
      department: sales
  ...
    spec:
      containers:
      - image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
        imagePullPolicy: IfNotPresent
        name: hello
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 3
  conditions:
  ‑ lastTransitionTime: "2019-11-11T18:44:02Z"
    lastUpdateTime: "2019-11-11T18:44:02Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  ‑ lastTransitionTime: "2019-11-11T18:43:58Z"
    lastUpdateTime: "2019-11-11T18:44:02Z"
    message: ReplicaSet "my-deployment-54944c8d55" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  observedGeneration: 1
  readyReplicas: 3
  replicas: 3
  updatedReplicas: 3

Describe tu implementación:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG describe deployment my-deployment

En la salida se muestran detalles con un formato adecuado sobre la implementación, incluido el ReplicaSet asociado:

Name:                   my-deployment
Namespace:              default
CreationTimestamp:      Mon, 11 Nov 2019 10:43:58 -0800
Labels:                 
...
Selector:               app=metrics,department=sales
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=metrics
           department=sales
  Containers:
    hello:
    Image:        us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
    Port:         
    Host Port:    
    Environment:  
    Mounts:       
  Volumes:        
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  
NewReplicaSet:   my-deployment-54944c8d55 (3/3 replicas created)

Crear un servicio de tipo LoadBalancer

Una forma de exponer tu Deployment a clientes que no estén en tu clúster es crear un Service de Kubernetes de tipo LoadBalancer.

Aquí tienes un manifiesto de un servicio de tipo LoadBalancer:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: metrics
    department: sales
  type: LoadBalancer
  ports:
  ‑ port: 80
    targetPort: 8080

Para este ejercicio, es importante que conozcas los siguientes aspectos del Servicio:

  • Todos los pods que tengan la etiqueta app: metrics y la etiqueta department: sales son miembros del servicio. Ten en cuenta que los pods de my-deployment tienen estas etiquetas.

  • Cuando un cliente envía una solicitud al servicio en el puerto TCP 80, la solicitud se reenvía a un pod miembro en el puerto TCP 8080.

  • Cada miembro del pod debe tener un contenedor que esté escuchando en el puerto TCP 8080.

De forma predeterminada, el contenedor hello-app escucha en el puerto TCP 8080. Para comprobarlo, consulta el Dockerfile y el código fuente de la aplicación.

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

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG apply -f my-service.yaml

donde USER_CLUSTER_KUBECONFIG es la ruta del archivo kubeconfig de tu clúster de usuario.

Cuando creas el servicio, Google Distributed Cloud configura automáticamente la dirección loadBalancerIP en el balanceador de carga del clúster.

Ver tu servicio:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get service my-service --output yaml

El resultado es similar al siguiente:

kind: Service
metadata:
  ...
  name: my-service
  namespace: default
  ...
spec:
  allocateLoadBalancerNodePorts: true
  clusterIP: 10.96.1.39
  clusterIPs:
  - 10.96.1.39
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - nodePort: 31184
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: metrics
    department: sales
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.1

En el resultado anterior, puedes ver que tu servicio tiene un clusterIP y un loadBalancerIP. También tiene un port y un targetPort.

El clusterIP no es relevante para este ejercicio. loadBalancerIP es la dirección IP que pueden usar los clientes que no están en el clúster para llamar al servicio.

Por ejemplo, toma los valores que se muestran en el resultado anterior. Es decir, supongamos que tu servicio tiene loadBalancerIP = 203.0.113.1, port = 80 y targetPort = 8080.

Un cliente envía una solicitud a 203.0.113.1 en el puerto TCP 80. La solicitud se enruta al balanceador de carga del clúster. El balanceador de carga reenvía la solicitud a un pod miembro en el puerto TCP 8080.

Llamar a tu servicio:

curl LOAD_BALANCER_IP

El resultado muestra un mensaje Hello, world!:

curl 203.0.113.1
Hello, world!
Version: 2.0.0
Hostname: my-deployment-dbd86c8c4-9wpbv

Eliminar tu Servicio

Eliminar tu Servicio:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete service my-service

Comprueba que tu servicio se haya eliminado:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get services

La salida ya no muestra my-service.

Eliminar tu implementación

Eliminar tu implementación:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete deployment my-deployment

Verifica que se ha eliminado tu implementación:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployments

La salida ya no muestra my-deployment.

Siguientes pasos

Crear objetos Ingress y Service