Configurer Cloud CDN via Ingress

Ce guide vous explique comment utiliser une définition de ressource personnalisée (CRD) BackendConfig pour configurer Cloud CDN dans Google Kubernetes Engine (GKE).

Présentation

Dans un cluster GKE, l'équilibrage de charge HTTP(S) (un composant de Cloud Load Balancing) gère le trafic entrant. En règle générale, l'équilibreur de charge HTTP(S) est configuré par le contrôleur GKE Ingress, qui obtient les informations de configuration à partir d'un objet Ingress Kubernetes. Le contrôleur d'entrée est associé à un ou plusieurs objets Service. Chaque objet Service contient des informations de routage utilisées pour diriger une requête entrante vers un pod et un port particuliers.

À partir de la version 1.10.5-gke.3 de Kubernetes, vous pouvez fournir une configuration supplémentaire pour l'équilibreur de charge externe en associant un port de service à une ressource personnalisée nommée BackendConfig.

Le contrôleur d'entrée GKE lit les informations de configuration à partir de BackendConfig et configure l'équilibreur de charge en conséquence. BackendConfig contient les informations de configuration spécifiques à Cloud Load Balancing. Les ressources Entrée et Service Kubernetes ne permettent pas de configurer des fonctionnalités propres à un fournisseur, telles que Cloud CDN. BackendConfig permet de procéder à cette configuration.

Voici dans les grandes lignes la façon de configurer BackendConfig dans cet exercice :

  1. Créez une ressource BackendConfig.
  2. Créez un objet Service et associez l'un de ses ports à BackendConfig.
  3. Créez un objet Ingress et associez-le à la paire (Service, Port).

Avant de commencer

Avant de commencer, effectuez les tâches suivantes :

Configurez les paramètres gcloud par défaut à l'aide de l'une des méthodes suivantes :

  • Utilisez gcloud init pour suivre les instructions permettant de définir les paramètres par défaut.
  • Utilisez gcloud config pour définir individuellement l'ID, la zone et la région de votre projet.

Utiliser gcloud init

Si le message d'erreur One of [--zone, --region] must be supplied: Please specify location s'affiche, effectuez les tâches ci-dessous.

  1. Exécutez gcloud init et suivez les instructions :

    gcloud init

    Si vous utilisez SSH sur un serveur distant, utilisez l'option --console-only pour empêcher la commande d'ouvrir un navigateur :

    gcloud init --console-only
  2. Suivez les instructions pour autoriser gcloud à utiliser votre compte Google Cloud.
  3. Créez ou sélectionnez une configuration.
  4. Choisissez un projet Google Cloud.
  5. Choisissez une zone Compute Engine par défaut.

Utiliser gcloud config

  • Définissez votre ID de projet par défaut :
    gcloud config set project project-id
  • Si vous travaillez avec des clusters zonaux, définissez votre zone de calcul par défaut :
    gcloud config set compute/zone compute-zone
  • Si vous utilisez des clusters régionaux, définissez votre région de calcul par défaut :
    gcloud config set compute/region compute-region
  • Mettez à jour gcloud vers la dernière version :
    gcloud components update

Créer un espace de noms

Créez un espace de noms Kubernetes pour les objets utilisés dans ce guide :

kubectl create namespace cdn-how-to

Créer un déploiement

  1. Créez un fichier nommé my-deployment.yaml basé sur le fichier manifeste de déploiement ci-dessous. Ce fichier manifeste indique que vous souhaitez exécuter deux instances dupliquées de l'application Web ingress-gce-echo-amd64 :

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      namespace: cdn-how-to
      name: my-deployment
    spec:
      selector:
        matchLabels:
          purpose: demonstrate-cdn
      replicas: 2
      template:
        metadata:
          labels:
            purpose: demonstrate-cdn
        spec:
          containers:
          - name: echo-amd64
            image: gcr.io/google-samples/hello-app-cdn:1.0
    
  2. Créez la ressource de déploiement :

    kubectl apply -f my-deployment.yaml
    

Créer un BackendConfig

  1. Créez un fichier nommé my-backend-config.yaml basé sur le fichier manifeste BackendConfig suivant. Le fichier manifeste spécifie une stratégie de mise en cache de Cloud CDN et déclare que Cloud CDN doit être activé :

      apiVersion: cloud.google.com/v1
      kind: BackendConfig
      metadata:
        namespace: cdn-how-to
        name: my-backend-config
      spec:
        cdn:
          enabled: true
          cachePolicy:
            includeHost: true
            includeProtocol: true
            includeQueryString: false
    
  2. Créez la ressource BackendConfig :

    kubectl apply -f my-backend-config.yaml
    
  3. Affichez la ressource BackendConfig :

    kubectl get backendconfig my-backend-config --output yaml --namespace cdn-how-to
    

    Vous pouvez voir la stratégie de mise en cache de Cloud CDN dans la sortie :

      apiVersion: cloud.google.com/v1
      kind: BackendConfig
      metadata:
        name: my-backend-config
        namespace: cdn-how-to
        ...
      spec:
        cdn:
          cachePolicy:
            includeHost: true
            includeProtocol: true
            includeQueryString: false
          enabled: true
    

Créer une ressource Service

  1. Créez un fichier nommé my-service.yaml basé sur le fichier manifeste Service suivant :

    apiVersion: v1
    kind: Service
    metadata:
      namespace: cdn-how-to
      name: my-service
      labels:
        purpose: demonstrate-cdn
      annotations:
        cloud.google.com/backend-config: '{"ports": {"80":"my-backend-config"}}'
    spec:
      type: NodePort
      selector:
        purpose: demonstrate-cdn
      ports:
      - port: 80
        protocol: TCP
        targetPort: 8080
    
  2. Créez la ressource Service :

    kubectl apply -f my-service.yaml
    
  3. Consultez le service :

    kubectl get service my-service --namespace cdn-how-to --output yaml
    

    Le résultat est semblable à ceci :

    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        cloud.google.com/backend-config: '{"ports": {"80":"my-backend-config"}}'
        ...
      labels:
        purpose: demonstrate-cdn
      name: my-service
      namespace: cdn-how-to
      ...
    spec:
      clusterIP: 10.51.255.39
      externalTrafficPolicy: Cluster
      ports:
      - nodePort: 31484
        port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        purpose: demonstrate-cdn
      sessionAffinity: None
      type: NodePort
    status:
      loadBalancer: {}
    

    Pour les besoins de cet exercice, voici les points importants à noter à propos de votre service :

    • Le port 80 du service est associé à un BackendConfig nommé my-backend-config. Cela est spécifié dans l'annotation cloud.google.com/backend-config.

    • Le service est de type NodePort. Il s'agit du type typique pour les services qui vont être associés à un objet Ingress.

    • Tout Pod portant le libellé purpose: demonstrate-cdn est membre du service. Cela est spécifié dans le champ selector.

    • Le trafic dirigé vers le service sur le port TCP 80 est acheminé vers le port TCP 8080 de l'un des pods membres. Cela est spécifié dans les champs port et targetPort.

Réserver une adresse IP externe statique

  1. Réservez une adresse IP externe statique :

    gcloud compute addresses create cdn-how-to-address --global
    
  2. Affichez votre adresse IP externe statique :

    gcloud compute addresses list --filter "name=cdn-how-to-address"
    

    La sortie affiche le nom et la valeur de l'adresse :

    NAME                ...     ADDRESS        STATUS
    cdn-how-to-address          203.0.113.1    RESERVED
    

Créer une ressource Ingress

  1. Créez un fichier nommé my-ingress.yaml basé sur le fichier manifeste Ingress suivant :

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      namespace: cdn-how-to
      name: my-ingress
      annotations:
        kubernetes.io/ingress.global-static-ip-name: "cdn-how-to-address"
    spec:
      rules:
      - http:
          paths:
          - path: /*
            backend:
              serviceName: my-service
              servicePort: 80
    
  2. Créez la ressource Ingress :

    kubectl apply -f my-ingress.yaml
    
  3. Patientez environ 10 minutes pour permettre au contrôleur d'entrée Kubernetes de configurer un équilibreur de charge Cloud, puis affichez l'entrée :

    kubectl get ingress my-ingress --output yaml --namespace cdn-how-to
    

    Le résultat est semblable à ceci :

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      ...
      name: my-ingress
      namespace: cdn-how-to
      ...
    spec:
      rules:
      - http:
          paths:
          - backend:
              serviceName: my-service
              servicePort: 80
            path: /*
    status:
      loadBalancer:
        ingress:
        - ip: 201.0.113.1
    

    Pour les besoins de cet exercice, voici les points importants à noter à propos de votre ressource Ingress :

    • L'adresse IP du trafic entrant est indiquée sous loadBalancer:ingress:.

    • L'Entrée a une règle qui s'applique aux requêtes HTTP entrantes de n'importe quel hôte. En effet, il n'y a pas de champ host dans la règle. Donc, par défaut, la règle s'applique à tous les hôtes.

    • Toutes les requêtes entrantes sont traitées de la même manière, quel que soit le chemin de l'URL. Cela est spécifié par la valeur /* pour path.

    • Les requêtes entrantes sont acheminées vers un pod membre de my-service. Dans cet exercice, les pods membres ont le libellé purpose: demonstrate-cdn.

    • Les requêtes sont acheminées vers le pod sur le port cible spécifié dans my-service. Dans cet exercice, le port cible du pod est 8080.

Afficher l'appli Web

Saisissez deux fois cette commande curl :

curl -v static-address/?cache=true

static-address est votre adresse IP externe statique.

Le résultat comporte les en-têtes et le corps de la réponse. Dans les en-têtes de réponse, vous pouvez constater que le contenu a été mis en cache. L'en-tête Age indique le nombre de secondes pendant lesquelles le contenu a été mis en cache :

...
< HTTP/1.1 200 OK
< Date: Fri, 25 Jan 2019 02:34:08 GMT
< Content-Length: 70
< Content-Type: text/plain; charset=utf-8
< Via: 1.1 google
< Cache-Control: max-age=86400,public
< Age: 2716
<
Hello, world!
Version: 1.0.0
Hostname: my-deployment-7f589cc5bc-l8kr8

Afficher les journaux d'équilibrage de charge

Vous pouvez vérifier que le contenu a bien été mis en cache en consultant les journaux Stackdriver relatifs à l'équilibrage de charge HTTP. Avant de consulter les journaux, assurez-vous d'avoir demandé une réponse de l'application au moins deux fois.

Console

  1. Dans Cloud Console, accédez à la page Journaux du menu Journalisation.

    Accéder à la page "Journaux"

  2. Dans le premier menu déroulant, sélectionnez Équilibreur de charge HTTP Cloud.

  3. Développez l'entrée de journal la plus récente, puis le champ httpRequest de l'entrée.

  4. Dans le champ httpRequest, vous pouvez voir que cacheHit est défini sur true :

    httpRequest: {
    cacheHit:  true
    cacheLookup:  true
    ...
    

gcloud

Exécutez la commande suivante, où project-id est l'ID de votre projet :

gcloud logging read \
    'logName="projects/project-id/logs/requests"' \
    --limit 2

Le résultat indique un "succès de cache" :

httpRequest:
cacheHit: true
cacheLookup: true

Nettoyer

Après avoir suivi les exercices de ce guide, procédez comme suit pour supprimer les ressources afin d'éviter que des frais inutiles ne vous soient facturés :

  1. Supprimez les objets Kubernetes que vous avez créés pour cet exercice :

    kubectl delete ingress my-ingress --namespace cdn-how-to
    kubectl delete service my-service --namespace cdn-how-to
    kubectl delete backendconfig my-backend-config --namespace cdn-how-to
    kubectl delete deployment my-deployment --namespace cdn-how-to
    kubectl delete namespace cdn-how-to
    
  2. Supprimez votre adresse IP externe statique :

    gcloud compute addresses delete cdn-how-to-address --global
    

Limites

Cloud CDN et Identity-Aware Proxy ne peuvent pas être activés pour le même service de backend d'équilibrage de charge HTTP(S).

Dépannage

BackendConfig introuvable

Cette erreur se produit lorsque BackendConfig est spécifié pour un port dans l'annotation Service, mais que la ressource BackendConfig réelle est introuvable. Cela peut se produire si vous n'avez pas du tout créé la ressource BackendConfig, si vous l'avez créée dans un espace de noms incorrect ou si vous avez mal orthographié la référence dans l'annotation Service.

kubectl get event
KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: error getting BackendConfig for port 80 on service “default/my-service”:
no BackendConfig for service port exists

Cloud CDN et IAP tous deux activés

Cette erreur se produit lorsque vous avez activé IAP et Cloud CDN dans une ressource BackendConfig.

kubectl get event
KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: BackendConfig default/config-default is not valid:
iap and cdn cannot be enabled at the same time.

Contenu non mis en cache

Si vous constatez que votre contenu n'est pas mis en cache, assurez-vous que votre application est correctement configurée pour permettre la mise en cache du contenu. Pour plus d'informations, reportez-vous à la section Exigences de mise en cache.

Étapes suivantes