Deployment di un'applicazione

Questo documento descrive come eseguire il deployment di un'applicazione su GKE su Bare Metal.

Prima di iniziare

Per eseguire il deployment di un carico di lavoro, devi avere un cluster utente, ibrido o autonomo in grado di eseguire carichi di lavoro.

Creazione di un deployment

I passaggi seguenti creano un deployment sul tuo cluster:

  1. Copia il seguente manifest in un file denominato 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 per creare il deployment:

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

    Sostituisci CLUSTER_KUBECONFIG con il percorso del file kubeconfig per il tuo cluster.

  3. Ottieni le informazioni di base sul deployment per verificare che sia stato creato correttamente:

    kubectl get deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
    

    L'output mostra che il deployment ha tre pod disponibili:

    NAME            READY   UP-TO-DATE   AVAILABLE   AGE
    my-deployment   3/3     3            3           27s
    
  4. Elenca i pod nel tuo deployment:

    kubectl get pods --kubeconfig CLUSTER_KUBECONFIG
    

    L'output mostra che il deployment ha tre pod in esecuzione:

    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. Ottieni informazioni dettagliate sul tuo deployment:

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

    L'output mostra i dettagli relativi alla specifica e allo stato 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. Descrivi il tuo deployment:

    kubectl describe deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
    

    L'output mostra dettagli formattati correttamente sul deployment, inclusi il ReplicaSet associato:

    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 servizio di tipo LoadBalancer

Un modo per esporre il deployment ai client esterni al cluster è creare un servizio Kubernetes di tipo LoadBalancer.

Per creare un servizio di tipo LoadBalancer:

  1. Copia il seguente manifest in un file denominato my-service.yaml:

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

    Di seguito sono riportati gli aspetti importanti da comprendere sul Servizio durante questo esercizio:

    • Qualsiasi pod con l'etichetta app: metrics e l'etichetta department: sales è membro del servizio. I pod in my-deployment hanno queste etichette.

    • Quando un client invia una richiesta al servizio sulla porta TCP80, la richiesta viene inoltrata al pod di un membro sulla porta TCP 8080.

    • Ogni pod membro deve avere un container in ascolto sulla porta TCP 8080.

    Per impostazione predefinita, il container hello-app rimane in ascolto sulla porta TCP 8080. Puoi visualizzare questa impostazione della porta esaminando il Dockerfile e il codice sorgente dell'app.

  2. Usa kubectl apply per creare il servizio sul tuo cluster:

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

    Sostituisci CLUSTER_KUBECONFIG con il percorso del file kubeconfig per il tuo cluster.

  3. Visualizza il servizio:

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

    L'output è simile al seguente:

    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
    

    Nell'output precedente, puoi vedere che il servizio ha un clusterIP e un indirizzo IP esterno. Ha anche un nodePort, un port e un targetPort.

    La clusterIP non è pertinente a questo esercizio. L'indirizzo IP esterno (status.loadBalancer.ingress.ip) proviene dall'intervallo di indirizzi specificato quando hai definito i pool di indirizzi del bilanciatore del carico (spec.loadBalancer.addressPools) nel file di configurazione del cluster.

    Ad esempio, prendi in considerazione i valori mostrati nell'output precedente per il tuo servizio:

    • Indirizzo IP esterno: 192.168.1.13
    • port: 80
    • nodePort: 31565
    • targetPort: 8080

    Un client invia una richiesta a 192.168.1.13 sulla porta TCP 80. La richiesta viene instradata al bilanciatore del carico, e da lì viene inoltrata al pod di un membro sulla porta TCP 8080.

  4. Chiama il servizio:

    curl INGRESS_IP_ADDRESS
    

    Sostituisci INGRESS_IP_ADDRESS con l'indirizzo IP in entrata nella sezione status del servizio che hai recuperato nel passaggio precedente (status.loadBalancer.ingress).

    L'output mostra un messaggio Hello, world!:

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

Limiti di porte LoadBalancer

Il tipo LoadBalancer è un'estensione del tipo NodePort. Un servizio di tipo LoadBalancer ha quindi un indirizzo IP cluster e uno o più valori nodePort. Per impostazione predefinita, Kubernetes alloca le porte dei nodi ai servizi di tipo LoadBalancer. Queste allocazioni possono esaurire rapidamente le porte disponibili dei nodi dalle 2768 assegnate al tuo cluster. Per salvare le porte dei nodi, disabilita l'allocazione delle porte dei nodi del bilanciatore del carico impostando il campo allocateLoadBalancerNodePorts su false nella specifica del servizio LoadBalancer. Questa impostazione impedisce a Kubernetes di allocare le porte dei nodi ai servizi LoadBalancer. Per ulteriori informazioni, consulta Disabilitazione dell'allocazione di NodePort del bilanciatore del carico nella documentazione di Kubernetes.

Di seguito è riportato un manifest per creare un servizio che non utilizza porte dei nodi:

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

Elimina il servizio

Per eliminare il servizio:

  1. Usa kubectl delete per eliminare il servizio dal cluster:

    kubectl delete service my-service --kubeconfig CLUSTER_KUBECONFIG
    
  2. Verifica che il servizio sia stato eliminato:

    kubectl get services --kubeconfig CLUSTER_KUBECONFIG
    

    L'output non mostra più my-service.

Elimina il tuo deployment

Per eliminare il tuo deployment:

  1. Usa kubectl delete per eliminare il deployment dal cluster:

    kubectl delete deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
    

    Verifica che il tuo deployment sia stato eliminato:

    kubectl get deployments --kubeconfig CLUSTER_KUBECONFIG
    

    L'output non mostra più my-deployment.

Passaggi successivi

Crea un servizio e un Ingress