Déployer une application

Ce document explique comment déployer une application sur Google Distributed Cloud.

Avant de commencer

Pour déployer une charge de travail, vous devez disposer d'un cluster utilisateur, hybride ou autonome capable d'exécuter des charges de travail.

Créer un déploiement

La procédure suivante permet de créer un objet Déploiement sur votre cluster:

  1. Copiez le fichier manifeste suivant dans un fichier nommé 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. Créez l'objet Déploiement à l'aide de kubectl apply :

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

    Remplacez CLUSTER_KUBECONFIG par le chemin d'accès au fichier kubeconfig de votre cluster.

  3. Obtenez des informations de base sur votre objet Déploiement pour vérifier qu'il a bien été créé:

    kubectl get deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
    

    Le résultat indique que l'objet Déploiement comporte trois pods tous disponibles :

    NAME            READY   UP-TO-DATE   AVAILABLE   AGE
    my-deployment   3/3     3            3           27s
    
  4. Répertoriez les pods dans votre objet Déploiement :

    kubectl get pods --kubeconfig CLUSTER_KUBECONFIG
    

    Le résultat indique que votre objet Déploiement comporte trois pods en cours d'exécution :

    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. Obtenez des informations détaillées sur votre objet Déploiement :

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

    Le résultat fournit des détails sur les spécifications et l'état de l'objet Déploiement :

    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. Décrivez votre objet Déploiement :

    kubectl describe deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
    

    Le résultat affiche des détails bien formatés sur l'objet Déploiement, y compris les ReplicaSet :

    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
    

Créer un service de type LoadBalancer

Une façon d'exposer votre objet Déploiement à des clients extérieurs à votre cluster consiste à créer un objet Service Kubernetes de type LoadBalancer.

Pour créer un service de type LoadBalancer:

  1. Copiez le fichier manifeste suivant dans un fichier nommé my-service.yaml :

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

    Voici les points importants à noter à propos du service dans cet exercice:

    • Tous les pods comportant les étiquettes app: metrics et department: sales sont membres du service. Les pods dans my-deployment portent ces libellés.

    • Lorsqu'un client envoie une requête au service sur le port TCP 80, la requête est transmise à un pod membre sur le port TCP 8080.

    • Chaque pod membre doit disposer d'un conteneur qui écoute sur le port TCP 8080.

    Par défaut, le conteneur hello-app écoute sur le port TCP 8080. Vous pouvez voir ce paramètre de port en consultant le fichier Dockerfile et le code source de l'application.

  2. Utilisez kubectl apply pour créer le service sur votre cluster :

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

    Remplacez CLUSTER_KUBECONFIG par le chemin d'accès au fichier kubeconfig de votre cluster.

  3. Affichez votre service :

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

    Le résultat ressemble à ce qui suit :

    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
    

    Dans le résultat précédent, vous pouvez voir que votre service possède un clusterIP et une adresse IP externe. Il comporte également un nodePort, un port et un targetPort.

    Le clusterIP n'est pas pertinent pour cet exercice. L'adresse IP externe (status.loadBalancer.ingress.ip) provient de la plage d'adresses que vous avez spécifiée lorsque vous avez défini des pools d'adresses de l'équilibreur de charge (spec.loadBalancer.addressPools) dans le fichier de configuration du cluster.

    À titre d'exemple, prenons les valeurs affichées dans le résultat précédent de votre service:

    • Adresse IP externe : 192.168.1.13
    • port : 80
    • nodePort : 31565
    • targetPort : 8080

    Un client envoie une requête à l'adresse 192.168.1.13 sur le port TCP 80. La requête est acheminée vers votre équilibreur de charge, puis transférée à un pod membre sur le port TCP 8080.

  4. Appelez votre service :

    curl INGRESS_IP_ADDRESS
    

    Remplacez INGRESS_IP_ADDRESS par l'adresse IP d'entrée dans la section status du service que vous avez récupérée à l'étape précédente (status.loadBalancer.ingress).

    Le résultat affiche un message Hello, world! :

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

Limites de ports de l'équilibreur de charge

Le type LoadBalancer est une extension du type NodePort. Ainsi, un service de type LoadBalancer a une adresse IP de cluster ainsi qu'une ou plusieurs valeurs nodePort. Par défaut, Kubernetes alloue des ports de nœud aux services de type LoadBalancer. Ces allocations peuvent rapidement épuiser les ports de nœud disponibles à partir des 2 768 attributions à votre cluster. Pour enregistrer les ports de nœud, désactivez l'allocation de ports de nœud de l'équilibreur de charge en définissant le champ allocateLoadBalancerNodePorts sur false dans la spécification du service LoadBalancer. Ce paramètre empêche Kubernetes d'allouer des ports de nœud aux services LoadBalancer. Pour en savoir plus, consultez la section Désactiver l'allocation NodePort de l'équilibreur de charge dans la documentation de Kubernetes.

Voici un fichier manifeste permettant de créer un service qui n'utilise aucun port de nœud:

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

Supprimez votre service

Pour supprimer votre service, procédez comme suit:

  1. Utilisez kubectl delete pour supprimer le service de votre cluster:

    kubectl delete service my-service --kubeconfig CLUSTER_KUBECONFIG
    
  2. Vérifiez que votre service a été supprimé :

    kubectl get services --kubeconfig CLUSTER_KUBECONFIG
    

    Le résultat n'affiche plus my-service.

Supprimez votre objet Déploiement

Pour supprimer votre objet Déploiement

  1. Utilisez kubectl delete pour supprimer votre votre objet Déploiement de votre cluster :

    kubectl delete deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
    

    Vérifiez que votre objet Déploiement a bien été supprimé :

    kubectl get deployments --kubeconfig CLUSTER_KUBECONFIG
    

    Le résultat n'affiche plus my-deployment.

Étape suivante

Créer un service et un objet Ingress