Implementa una aplicación

En este documento, se describe cómo implementar una aplicación en Google Distributed Cloud.

Antes de comenzar

Para implementar una carga de trabajo, debes tener un clúster de usuario, híbrido o independiente que pueda ejecutar cargas de trabajo.

Crear una implementación

En los siguientes pasos, se crea un Deployment en tu clúster:

  1. Luego, copia el siguiente manifiesto a un archivo llamado my-deployment.yaml.

    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"
    
  2. Usa kubectl apply para crear la implementación.

    kubectl apply -f my-deployment.yaml --kubeconfig CLUSTER_KUBECONFIG
    

    Reemplaza CLUSTER_KUBECONFIG por la ruta de acceso del archivo kubeconfig del clúster de usuario.

  3. Obtén información básica sobre tu Deployment para confirmar que se creó correctamente:

    kubectl get deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
    

    El resultado muestra que el Deployment tiene tres Pods y que todos están disponibles:

    NAME            READY   UP-TO-DATE   AVAILABLE   AGE
    my-deployment   3/3     3            3           27s
    
  4. Obtén una lista de los Pods del Deployment:

    kubectl get pods --kubeconfig CLUSTER_KUBECONFIG
    

    El resultado muestra que tu Deployment tiene tres Pods en ejecución:

    NAME                             READY   STATUS    RESTARTS   AGE
    my-deployment-869f65669b-5259x   1/1     Running   0          34s
    my-deployment-869f65669b-9xfrs   1/1     Running   0          34s
    my-deployment-869f65669b-wn4ft   1/1     Running   0          34s
    
  5. Obtén información detallada sobre el Deployment:

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

    El resultado muestra detalles sobre la especificación y el estado del Deployment:

    apiVersion: apps/v1
    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: "2023-06-29T16:17:17Z"
        lastUpdateTime: "2023-06-29T16:17:17Z"
        message: Deployment has minimum availability.
        reason: MinimumReplicasAvailable
        status: "True"
        type: Available
      - lastTransitionTime: "2023-06-29T16:17:12Z"
        lastUpdateTime: "2023-06-29T16:17:17Z"
        message: ReplicaSet "my-deployment-869f65669b" has successfully progressed.
        reason: NewReplicaSetAvailable
        status: "True"
        type: Progressing
      observedGeneration: 1
      readyReplicas: 3
      replicas: 3
      updatedReplicas: 3
    
  6. Describe tu Deployment:

    kubectl describe deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
    

    En el resultado, se muestran detalles con un buen formato sobre el Deployment, incluido el ReplicaSet asociado:

    Name:                   my-deployment
    Namespace:              default
    CreationTimestamp:      Thu, 29 Jun 2023 16:17:12 +0000
    Labels:                 <none>
    Annotations:            deployment.kubernetes.io/revision: 1
    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:         <none>
        Host Port:    <none>
        Environment:  <none>
        Mounts:       <none>
      Volumes:        <none>
    Conditions:
      Type           Status  Reason
      ----           ------  ------
      Available      True    MinimumReplicasAvailable
      Progressing    True    NewReplicaSetAvailable
    OldReplicaSets:  <none>
    NewReplicaSet:   my-deployment-869f65669b (3/3 replicas created)
    Events:
      Type    Reason             Age    From                   Message
      ----    ------             ----   ----                   -------
      Normal  ScalingReplicaSet  6m50s  deployment-controller  Scaled up replica set my-deployment-869f65669b to 3
    

Crea un Service de tipo LoadBalancer

Una forma de exponer el Deployment a clientes fuera de tu clúster es crear un Service de Kubernetes de tipo LoadBalancer.

Para crear un Service de tipo LoadBalancer, haz lo siguiente:

  1. Luego, copia el siguiente manifiesto a un archivo llamado my-service.yaml.

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

    Estos son los aspectos importantes que debes comprender sobre el servicio en este ejercicio:

    • Cualquier pod que tenga las etiquetas app: metrics y department: sales es miembro del servicio. Los Pods en my-deployment tienen estas etiquetas.

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

    • Cada Pod miembro debe tener un contenedor que escuche en el puerto TCP 8080.

    De forma predeterminada, el contenedor hello-app escucha en el puerto TCP 8080. Puedes ver este parámetro de configuración de puerto si observas el Dockerfile y el código fuente de la app.

  2. Usa kubectl apply para crear el servicio en tu clúster:

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

    Reemplaza CLUSTER_KUBECONFIG por la ruta de acceso del archivo kubeconfig del clúster de usuario.

  3. Observa tu servicio:

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

    El resultado es similar a este:

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

    En el resultado anterior, puedes ver que tu servicio tiene una clusterIP y una dirección IP externa. También tiene un nodePort, un port y un targetPort.

    El clusterIP no es relevante para este ejercicio. La dirección IP externa (status.loadBalancer.ingress.ip) proviene del rango de direcciones que especificaste cuando definiste los grupos de direcciones del balanceador de cargas (spec.loadBalancer.addressPools) en el archivo de configuración del clúster.

    Por ejemplo, toma los valores que se muestran en el resultado anterior para tu servicio:

    • Dirección IP externa: 192.168.1.13
    • port: 80
    • nodePort: 31565
    • targetPort: 8080

    Un cliente envía una solicitud a 192.168.1.13 en el puerto TCP 80. La solicitud se enruta a tu balanceador de cargas y, desde allí, se reenvía a un Pod miembro en el puerto TCP 8080.

  4. Llama a tu Service:

    curl INGRESS_IP_ADDRESS
    

    Reemplaza INGRESS_IP_ADDRESS por la dirección IP de entrada en la sección status del servicio que recuperaste en el paso anterior (status.loadBalancer.ingress).

    El resultado muestra un mensaje Hello, world!:

    Hello, world!
    Version: 2.0.0
    Hostname: my-deployment-869f65669b-wn4ft
    

Límites de puertos de LoadBalancer

El tipo LoadBalancer es una extensión del tipo NodePort. Entonces, un servicio de tipo LoadBalancer tiene una dirección IP de clúster y uno o más valores nodePort. De forma predeterminada, Kubernetes asigna puertos de nodo a servicios de tipo LoadBalancer. Estas asignaciones pueden agotar rápidamente los puertos de nodo disponibles de los 2,768 asignados a tu clúster. Para guardar los puertos de nodo, inhabilita la asignación de puertos de nodo del balanceador de cargas configurando el campo allocateLoadBalancerNodePorts en false en la especificación del servicio LoadBalancer. Este parámetro de configuración evita que Kubernetes asigne puertos de nodo a los servicios. Para obtener más información, consulta Cómo inhabilitar la asignación de NodePort del balanceador de cargas en la documentación de Kubernetes.

Este es un manifiesto para crear un servicio que no use ningún puerto de nodo:

apiVersion: v1
kind: Service
metadata:
  name: service-does-not-use-nodeports
spec:
  selector:
    app: my-app
  type: LoadBalancer
  ports:
  - port: 8000
  # Set allocateLoadBalancerNodePorts to false
  allocateLoadBalancerNodePorts: false

Borra el Service

Para borrar tu servicio, haz lo siguiente:

  1. Usa kubectl delete para borrar tu servicio del clúster:

    kubectl delete service my-service --kubeconfig CLUSTER_KUBECONFIG
    
  2. Verifica que se haya borrado tu Service:

    kubectl get services --kubeconfig CLUSTER_KUBECONFIG
    

    El resultado ya no muestra my-service.

Borra el Deployment

Para borrar tu Deployment, sigue estos pasos:

  1. Usa kubectl delete para borrar tu Deployment de tu clúster:

    kubectl delete deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
    

    Verifica que se haya borrado el Deployment:

    kubectl get deployments --kubeconfig CLUSTER_KUBECONFIG
    

    El resultado ya no muestra my-deployment.

¿Qué sigue?

Crea un Service y un Ingress