Ce document vous explique comment effectuer les tâches suivantes :
- Déployer des applications distribuées à l'échelle mondiale et exposées via GKE Gateway et Cloud Service Mesh.
- Exposez une application à plusieurs clients en combinant Cloud Load Balancing à Cloud Service Mesh.
- Intégrez des équilibreurs de charge à un maillage de services déployé dans plusieurs régions Google Cloud.
Ce guide de déploiement s'adresse aux administrateurs de plate-forme. Il s'adresse également aux professionnels avancés qui exécutent Cloud Service Mesh. Les instructions fonctionnent également pour Istio sur GKE.
Architecture
Le schéma suivant illustre la topologie d'entrée par défaut d'un maillage de services, à savoir un équilibreur de charge TCP/UDP externe qui expose les proxys de passerelle d'entrée sur un seul cluster :
Ce guide de déploiement utilise des ressources Gateway Google Kubernetes Engine (GKE). Plus précisément, il utilise une passerelle multicluster pour configurer l'équilibrage de charge multirégional devant plusieurs clusters Autopilot répartis sur deux régions.
Le schéma précédent montre comment les données circulent dans les scénarios d'entrée cloud et d'entrée dans le maillage. Pour en savoir plus, consultez l'explication du schéma d'architecture dans le document d'architecture de référence associé.
Objectifs
- Déployez une paire de clusters GKE Autopilot sur Google Cloud dans le même parc.
- Déployez un Cloud Service Mesh basé sur Istio sur le même parc.
- Configurez un équilibreur de charge à l'aide de GKE Gateway pour mettre fin au trafic HTTPS public.
- Trafic HTTPS public direct vers les applications hébergées par Cloud Service Mesh, déployées dans plusieurs clusters et régions.
- Déployer l'exemple d'application whereami sur les deux clusters Autopilot.
Optimisation des coûts
Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :
- Google Kubernetes Engine
- Cloud Load Balancing
- Cloud Service Mesh
- Multi Cluster Ingress
- Google Cloud Armor
- Certificate Manager
- Cloud Endpoints
Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût.
Une fois que vous avez terminé les tâches décrites dans ce document, vous pouvez éviter de continuer à payer des frais en supprimant les ressources que vous avez créées. Pour en savoir plus, consultez la section Effectuer un nettoyage.
Avant de commencer
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, activate Cloud Shell.
Vous exécutez toutes les commandes de terminal de ce déploiement depuis Cloud Shell.
Définissez votre projet Google Cloud par défaut :
export PROJECT=YOUR_PROJECT export PROJECT_NUMBER=$(gcloud projects describe PROJECT_ID --format="value(projectNumber)") gcloud config set project PROJECT_ID
Remplacez
PROJECT_ID
par l'ID du projet que vous souhaitez utiliser pour ce déploiement.Créez un répertoire de travail :
mkdir -p ${HOME}/edge-to-mesh-multi-region cd ${HOME}/edge-to-mesh-multi-region export WORKDIR=`pwd`
Créer des clusters GKE
Dans cette section, vous allez créer des clusters GKE pour héberger les applications et l'infrastructure de soutien, que vous créerez plus tard dans ce guide de déploiement.
Dans Cloud Shell, créez un fichier
kubeconfig
. Cette étape vous permet de ne pas créer de conflit avec votre fichierkubeconfig
(par défaut) existant.touch edge2mesh_mr_kubeconfig export KUBECONFIG=${WORKDIR}/edge2mesh_mr_kubeconfig
Définissez les variables d'environnement utilisées lors de la création des clusters GKE et des ressources qu'ils contiennent. Modifiez les choix de région par défaut en fonction de vos besoins.
export CLUSTER_1_NAME=edge-to-mesh-01 export CLUSTER_2_NAME=edge-to-mesh-02 export CLUSTER_1_REGION=us-central1 export CLUSTER_2_REGION=us-east4 export PUBLIC_ENDPOINT=frontend.endpoints.PROJECT_ID.cloud.goog
Activez les API Google Cloud utilisées tout au long de ce guide :
gcloud services enable \ container.googleapis.com \ mesh.googleapis.com \ gkehub.googleapis.com \ multiclusterservicediscovery.googleapis.com \ multiclusteringress.googleapis.com \ trafficdirector.googleapis.com \ certificatemanager.googleapis.com
Créez un cluster GKE Autopilot avec des nœuds privés dans
CLUSTER_1_REGION
. Utilisez l'option--async
pour éviter d'attendre que le premier cluster soit provisionné et enregistré dans le parc :gcloud container clusters create-auto --async \ ${CLUSTER_1_NAME} --region ${CLUSTER_1_REGION} \ --release-channel rapid --labels mesh_id=proj-${PROJECT_NUMBER} \ --enable-private-nodes --enable-fleet
Créez et enregistrez un deuxième cluster Autopilot dans
CLUSTER_2_REGION
:gcloud container clusters create-auto \ ${CLUSTER_2_NAME} --region ${CLUSTER_2_REGION} \ --release-channel rapid --labels mesh_id=proj-${PROJECT_NUMBER} \ --enable-private-nodes --enable-fleet
Assurez-vous que les clusters sont en cours d'exécution. Un délai de 20 minutes peut être nécessaire avant que tous les clusters ne soient en cours d'exécution :
gcloud container clusters list
Le résultat ressemble à ce qui suit :
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS edge-to-mesh-01 us-central1 1.27.5-gke.200 34.27.171.241 e2-small 1.27.5-gke.200 RUNNING edge-to-mesh-02 us-east4 1.27.5-gke.200 35.236.204.156 e2-small 1.27.5-gke.200 RUNNING
Rassemblez les identifiants de
CLUSTER_1_NAME
. Vous avez crééCLUSTER_1_NAME
de manière asynchrone afin de pouvoir exécuter des commandes supplémentaires pendant le provisionnement du cluster.gcloud container clusters get-credentials ${CLUSTER_1_NAME} \ --region ${CLUSTER_1_REGION}
Pour clarifier les noms des contextes Kubernetes, renommez-les avec les noms des clusters :
kubectl config rename-context gke_PROJECT_ID_${CLUSTER_1_REGION}_${CLUSTER_1_NAME} ${CLUSTER_1_NAME} kubectl config rename-context gke_PROJECT_ID_${CLUSTER_2_REGION}_${CLUSTER_2_NAME} ${CLUSTER_2_NAME}
Installer un maillage de services
Dans cette section, vous configurez le service Cloud Service Mesh géré avec l'API Fleet. L'utilisation de l'API Fleet pour activer Cloud Service Mesh fournit une approche déclarative pour provisionner un service mesh.
Dans Cloud Shell, activez Cloud Service Mesh sur le parc :
gcloud container fleet mesh enable
Activez la gestion automatique du plan de contrôle et du plan de données :
gcloud container fleet mesh update \ --management automatic \ --memberships ${CLUSTER_1_NAME},${CLUSTER_2_NAME}
Patientez 20 minutes environ. Vérifiez ensuite que l'état du plan de contrôle est
ACTIVE
:gcloud container fleet mesh describe
Le résultat ressemble à ce qui suit :
createTime: '2023-11-30T19:23:21.713028916Z' membershipSpecs: projects/603904278888/locations/us-central1/memberships/edge-to-mesh-01: mesh: management: MANAGEMENT_AUTOMATIC projects/603904278888/locations/us-east4/memberships/edge-to-mesh-02: mesh: management: MANAGEMENT_AUTOMATIC membershipStates: projects/603904278888/locations/us-central1/memberships/edge-to-mesh-01: servicemesh: controlPlaneManagement: details: - code: REVISION_READY details: 'Ready: asm-managed-rapid' implementation: ISTIOD state: ACTIVE dataPlaneManagement: details: - code: OK details: Service is running. state: ACTIVE state: code: OK description: |- Revision ready for use: asm-managed-rapid. All Canonical Services have been reconciled successfully. updateTime: '2024-06-27T09:00:21.333579005Z' projects/603904278888/locations/us-east4/memberships/edge-to-mesh-02: servicemesh: controlPlaneManagement: details: - code: REVISION_READY details: 'Ready: asm-managed-rapid' implementation: ISTIOD state: ACTIVE dataPlaneManagement: details: - code: OK details: Service is running. state: ACTIVE state: code: OK description: |- Revision ready for use: asm-managed-rapid. All Canonical Services have been reconciled successfully. updateTime: '2024-06-27T09:00:24.674852751Z' name: projects/e2m-private-test-01/locations/global/features/servicemesh resourceState: state: ACTIVE spec: {} updateTime: '2024-06-04T17:16:28.730429993Z'
Déployer un équilibreur de charge d'application externe et créer des passerelles d'entrée
Dans cette section, vous allez déployer un équilibreur de charge d'application externe via le contrôleur GKE Gateway et créer des passerelles Ingress pour les deux clusters. Les ressources gateway
et gatewayClass
automatisent le provisionnement de l'équilibreur de charge et la vérification de l'état du backend. Pour fournir une terminaison TLS sur l'équilibreur de charge, vous devez créer des ressources Gestionnaire de certificats et les associer à l'équilibreur de charge. De plus, vous utilisez Cloud Endpoints pour provisionner automatiquement un nom DNS public pour l'application.
Installer une passerelle d'entrée sur les deux clusters
Pour des raisons de sécurité, nous vous recommandons de déployer la passerelle d'entrée dans un espace de noms différent du plan de contrôle maillé.
Dans Cloud Shell, créez un espace de noms
asm-ingress
dédié sur chaque cluster :kubectl --context=${CLUSTER_1_NAME} create namespace asm-ingress kubectl --context=${CLUSTER_2_NAME} create namespace asm-ingress
Ajoutez un libellé d'espace de noms à l'espace de noms
asm-ingress
:kubectl --context=${CLUSTER_1_NAME} label namespace asm-ingress istio-injection=enabled kubectl --context=${CLUSTER_2_NAME} label namespace asm-ingress istio-injection=enabled
Le résultat ressemble à ce qui suit :
namespace/asm-ingress labeled
L'ajout d'un libellé
istio-injection=enabled
aux espaces de nomsasm-ingress
indique à Cloud Service Mesh d'injecter automatiquement des proxys side-car Envoy lors du déploiement d'un pod.Générez un certificat autosigné pour une utilisation ultérieure :
openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \ -subj "/CN=frontend.endpoints.PROJECT_ID.cloud.goog/O=Edge2Mesh Inc" \ -keyout ${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.key \ -out ${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.crt
Le certificat fournit une couche de chiffrement supplémentaire entre l'équilibreur de charge et les passerelles d'entrée du service mesh. Il permet également d'utiliser les protocoles basés sur HTTP/2, tels que gRPC. Des instructions sur l'association du certificat autosigné aux passerelles d'entrée sont fournies plus loin dans la section Créer des ressources d'adresse IP externe, d'enregistrement DNS et de certificat TLS.
Pour en savoir plus sur les exigences liées au certificat de passerelle d'entrée, consultez la section Chiffrement entre l'équilibreur de charge et les backends.
Créez un secret Kubernetes sur chaque cluster pour stocker le certificat autosigné :
kubectl --context ${CLUSTER_1_NAME} -n asm-ingress create secret tls \ edge2mesh-credential \ --key=${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.key \ --cert=${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.crt kubectl --context ${CLUSTER_2_NAME} -n asm-ingress create secret tls \ edge2mesh-credential \ --key=${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.key \ --cert=${WORKDIR}/frontend.endpoints.PROJECT_ID.cloud.goog.crt
Pour procéder à l'intégration à l'équilibreur de charge d'application externe, créez une variante kustomize pour configurer les ressources de passerelle d'entrée :
mkdir -p ${WORKDIR}/asm-ig/base cat <<EOF > ${WORKDIR}/asm-ig/base/kustomization.yaml resources: - github.com/GoogleCloudPlatform/anthos-service-mesh-samples/docs/ingress-gateway-asm-manifests/base EOF mkdir ${WORKDIR}/asm-ig/variant cat <<EOF > ${WORKDIR}/asm-ig/variant/role.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: asm-ingressgateway namespace: asm-ingress rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "watch", "list"] EOF cat <<EOF > ${WORKDIR}/asm-ig/variant/rolebinding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: asm-ingressgateway namespace: asm-ingress roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: asm-ingressgateway subjects: - kind: ServiceAccount name: asm-ingressgateway EOF cat <<EOF > ${WORKDIR}/asm-ig/variant/service-proto-type.yaml apiVersion: v1 kind: Service metadata: name: asm-ingressgateway namespace: asm-ingress spec: ports: - name: status-port port: 15021 protocol: TCP targetPort: 15021 - name: http port: 80 targetPort: 8080 appProtocol: HTTP - name: https port: 443 targetPort: 8443 appProtocol: HTTP2 type: ClusterIP EOF cat <<EOF > ${WORKDIR}/asm-ig/variant/gateway.yaml apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: asm-ingressgateway namespace: asm-ingress spec: servers: - port: number: 443 name: https protocol: HTTPS hosts: - "*" # IMPORTANT: Must use wildcard here when using SSL, as SNI isn't passed from GFE tls: mode: SIMPLE credentialName: edge2mesh-credential EOF cat <<EOF > ${WORKDIR}/asm-ig/variant/kustomization.yaml namespace: asm-ingress resources: - ../base - role.yaml - rolebinding.yaml patches: - path: service-proto-type.yaml target: kind: Service - path: gateway.yaml target: kind: Gateway EOF
Appliquez la configuration de la passerelle d'entrée aux deux clusters :
kubectl --context ${CLUSTER_1_NAME} apply -k ${WORKDIR}/asm-ig/variant kubectl --context ${CLUSTER_2_NAME} apply -k ${WORKDIR}/asm-ig/variant
Exposer les pods de passerelle d'entrée à l'équilibreur de charge à l'aide d'un service multicluster
Dans cette section, vous allez exporter les pods de la passerelle d'entrée via une ressource personnalisée ServiceExport
. Vous devez exporter les pods de la passerelle d'entrée via une ressource personnalisée ServiceExport
pour les raisons suivantes :
- Permet à l'équilibreur de charge d'adresser les pods de passerelle d'entrée sur plusieurs clusters.
- Permet aux pods de la passerelle d'entrée de proxyer les requêtes vers les services exécutés dans le maillage de services.
Dans Cloud Shell, activez les services multiclusters (MCS) pour le parc :
gcloud container fleet multi-cluster-services enable
Accordez à MCS les autorisations IAM requises pour le projet ou le parc :
gcloud projects add-iam-policy-binding PROJECT_ID \ --member "serviceAccount:PROJECT_ID.svc.id.goog[gke-mcs/gke-mcs-importer]" \ --role "roles/compute.networkViewer"
Créez le fichier YAML
ServiceExport
:cat <<EOF > ${WORKDIR}/svc_export.yaml kind: ServiceExport apiVersion: net.gke.io/v1 metadata: name: asm-ingressgateway namespace: asm-ingress EOF
Appliquez le fichier YAML
ServiceExport
aux deux clusters :kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/svc_export.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/svc_export.yaml
Si le message d'erreur suivant s'affiche, attendez quelques instants que les définitions de ressources personnalisées (CRD) MCS soient installées. Exécutez ensuite à nouveau les commandes pour appliquer le fichier YAML
ServiceExport
aux deux clusters.error: resource mapping not found for name: "asm-ingressgateway" namespace: "asm-ingress" from "svc_export.yaml": no matches for kind "ServiceExport" in version "net.gke.io/v1" ensure CRDs are installed first
Créer des ressources d'adresse IP externe, d'enregistrement DNS et de certificat TLS
Dans cette section, vous allez créer des ressources réseau compatibles avec les ressources d'équilibrage de charge que vous créerez ultérieurement dans ce déploiement.
Dans Cloud Shell, réservez une adresse IP externe statique :
gcloud compute addresses create mcg-ip --global
La ressource de passerelle GKE utilise une adresse IP statique. Il permet de conserver l'adresse IP, même si l'équilibreur de charge externe est recréé.
Obtenez l'adresse IP statique et stockez-la en tant que variable d'environnement :
export MCG_IP=$(gcloud compute addresses describe mcg-ip --global --format "value(address)") echo ${MCG_IP}
Pour créer un mappage stable et lisible avec votre adresse IP Gateway, vous devez disposer d'un enregistrement DNS public.
Vous pouvez utiliser le fournisseur DNS de votre choix et l'automatisation de votre choix. Ce déploiement utilise Endpoints au lieu de créer une zone DNS gérée. Endpoints offre un enregistrement DNS géré par Google gratuit pour une adresse IP externe.
Exécutez la commande suivante pour créer un fichier YAML nommé
dns-spec.yaml
:cat <<EOF > ${WORKDIR}/dns-spec.yaml swagger: "2.0" info: description: "Cloud Endpoints DNS" title: "Cloud Endpoints DNS" version: "1.0.0" paths: {} host: "frontend.endpoints.PROJECT_ID.cloud.goog" x-google-endpoints: - name: "frontend.endpoints.PROJECT_ID.cloud.goog" target: "${MCG_IP}" EOF
Le fichier
dns-spec.yaml
définit l'enregistrement DNS public sous la formefrontend.endpoints.PROJECT_ID.cloud.goog
, oùPROJECT_ID
est votre identifiant de projet unique.Déployez le fichier
dns-spec.yaml
pour créer l'entrée DNS. Ce processus prend quelques minutes.gcloud endpoints services deploy ${WORKDIR}/dns-spec.yaml
Créez un certificat à l'aide du gestionnaire de certificats pour le nom d'entrée DNS que vous avez créé à l'étape précédente :
gcloud certificate-manager certificates create mcg-cert \ --domains="frontend.endpoints.PROJECT_ID.cloud.goog"
Un certificat TLS géré par Google permet de mettre fin aux requêtes client entrantes à l'équilibreur de charge.
Créer un mappage de certificat
gcloud certificate-manager maps create mcg-cert-map
L'équilibreur de charge fait référence au certificat via l'entrée de mappage de certificat que vous créez à l'étape suivante.
Créez une entrée de mappage de certificat pour le certificat que vous avez créé précédemment dans cette section :
gcloud certificate-manager maps entries create mcg-cert-map-entry \ --map="mcg-cert-map" \ --certificates="mcg-cert" \ --hostname="frontend.endpoints.PROJECT_ID.cloud.goog"
Créer des règles de service de backend et des ressources d'équilibreur de charge
Dans cette section, vous allez effectuer les tâches suivantes :
- Créer une stratégie de sécurité Google Cloud Armor avec des règles.
- Créer une règle qui permet à l'équilibreur de charge de vérifier la réactivité des pods de la passerelle d'entrée via le fichier YAML
ServiceExport
que vous avez créé précédemment. - Utiliser l'API GKE Gateway pour créer une ressource d'équilibreur de charge.
- Utiliser la ressource personnalisée
GatewayClass
pour définir le type d'équilibreur de charge spécifique. - Activer l'équilibrage de charge multicluster pour le parc et désigner l'un des clusters comme cluster de configuration pour le parc.
Dans Cloud Shell, créer une stratégie de sécurité Google Cloud Armor :
gcloud compute security-policies create edge-fw-policy \ --description "Block XSS attacks"
Créer une règle pour votre stratégie de sécurité :
gcloud compute security-policies rules create 1000 \ --security-policy edge-fw-policy \ --expression "evaluatePreconfiguredExpr('xss-stable')" \ --action "deny-403" \ --description "XSS attack filtering"
Créez un fichier YAML pour la stratégie de sécurité et référencer le fichier YAML
ServiceExport
via un fichier YAMLServiceImport
correspondant :cat <<EOF > ${WORKDIR}/cloud-armor-backendpolicy.yaml apiVersion: networking.gke.io/v1 kind: GCPBackendPolicy metadata: name: cloud-armor-backendpolicy namespace: asm-ingress spec: default: securityPolicy: edge-fw-policy targetRef: group: net.gke.io kind: ServiceImport name: asm-ingressgateway EOF
Appliquez la stratégie Google Cloud Armor aux deux clusters :
kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/cloud-armor-backendpolicy.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/cloud-armor-backendpolicy.yaml
Créez un fichier YAML personnalisé qui permet à l'équilibreur de charge d'effectuer des vérifications d'état par rapport au point de terminaison d'état Envoy (port
15021
sur le chemin/healthz/ready
) des pods de passerelle d'entrée dans les deux clusters :cat <<EOF > ${WORKDIR}/ingress-gateway-healthcheck.yaml apiVersion: networking.gke.io/v1 kind: HealthCheckPolicy metadata: name: ingress-gateway-healthcheck namespace: asm-ingress spec: default: config: httpHealthCheck: port: 15021 portSpecification: USE_FIXED_PORT requestPath: /healthz/ready type: HTTP targetRef: group: net.gke.io kind: ServiceImport name: asm-ingressgateway EOF
Appliquez le fichier YAML personnalisé que vous avez créé à l'étape précédente aux deux clusters :
kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/ingress-gateway-healthcheck.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/ingress-gateway-healthcheck.yaml
Activez l'équilibrage de charge multicluster pour le parc et désignez
CLUSTER_1_NAME
comme cluster de configuration :gcloud container fleet ingress enable \ --config-membership=${CLUSTER_1_NAME} \ --location=${CLUSTER_1_REGION}
Accordez des autorisations IAM pour le contrôleur Gateway dans le parc :
gcloud projects add-iam-policy-binding PROJECT_ID \ --member "serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-multiclusteringress.iam.gserviceaccount.com" \ --role "roles/container.admin"
Créez le fichier YAML de l'équilibreur de charge via une ressource personnalisée Gateway qui fait référence à
gke-l7-global-external-managed-mc
gatewayClass
et à l'adresse IP statique que vous avez créée précédemment :cat <<EOF > ${WORKDIR}/frontend-gateway.yaml kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: external-http namespace: asm-ingress annotations: networking.gke.io/certmap: mcg-cert-map spec: gatewayClassName: gke-l7-global-external-managed-mc listeners: - name: http # list the port only so we can redirect any incoming http requests to https protocol: HTTP port: 80 - name: https protocol: HTTPS port: 443 allowedRoutes: kinds: - kind: HTTPRoute addresses: - type: NamedAddress value: mcg-ip EOF
Appliquez le fichier YAML
frontend-gateway
aux deux clusters. SeulCLUSTER_1_NAME
fait autorité, sauf si vous désignez un autre cluster de configuration comme faisant autorité :kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/frontend-gateway.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/frontend-gateway.yaml
Créez un fichier YAML
HTTPRoute
appelédefault-httproute.yaml
qui indique à la ressource Gateway d'envoyer des requêtes aux passerelles d'entrée :cat << EOF > ${WORKDIR}/default-httproute.yaml apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: default-httproute namespace: asm-ingress spec: parentRefs: - name: external-http namespace: asm-ingress sectionName: https rules: - backendRefs: - group: net.gke.io kind: ServiceImport name: asm-ingressgateway port: 443 EOF
Appliquez le fichier YAML
HTTPRoute
que vous avez créé à l'étape précédente aux deux clusters :kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/default-httproute.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/default-httproute.yaml
Pour effectuer des redirections HTTP vers HTTP(S), créez un fichier YAML
HTTPRoute
supplémentaire appelédefault-httproute-redirect.yaml
:cat << EOF > ${WORKDIR}/default-httproute-redirect.yaml kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: http-to-https-redirect-httproute namespace: asm-ingress spec: parentRefs: - name: external-http namespace: asm-ingress sectionName: http rules: - filters: - type: RequestRedirect requestRedirect: scheme: https statusCode: 301 EOF
Appliquez le fichier YAML de redirection
HTTPRoute
aux deux clusters :kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/default-httproute-redirect.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/default-httproute-redirect.yaml
Inspectez la ressource Gateway pour vérifier la progression du déploiement de l'équilibreur de charge :
kubectl --context=${CLUSTER_1_NAME} describe gateway external-http -n asm-ingress
Le résultat affiche les informations que vous avez saisies dans cette section.
Déployer l'exemple d'application "whereami"
Ce guide utilise whereami comme exemple d'application pour fournir des commentaires directs sur les clusters qui répondent aux requêtes. La section suivante configure deux déploiements distincts sur les deux clusters : un déploiement frontend
et un déploiement backend
.
Le déploiement frontend
est la première charge de travail à recevoir la requête. Il appelle ensuite le déploiement backend
.
Ce modèle permet de présenter une architecture d'application multiservice.
Les services frontend
et backend
sont déployés sur les deux clusters.
Dans Cloud Shell, créez les espaces de noms pour un
frontend
et unbackend
whereami sur les deux clusters, puis activez l'injection d'espaces de noms :kubectl --context=${CLUSTER_1_NAME} create ns frontend kubectl --context=${CLUSTER_1_NAME} label namespace frontend istio-injection=enabled kubectl --context=${CLUSTER_1_NAME} create ns backend kubectl --context=${CLUSTER_1_NAME} label namespace backend istio-injection=enabled kubectl --context=${CLUSTER_2_NAME} create ns frontend kubectl --context=${CLUSTER_2_NAME} label namespace frontend istio-injection=enabled kubectl --context=${CLUSTER_2_NAME} create ns backend kubectl --context=${CLUSTER_2_NAME} label namespace backend istio-injection=enabled
Créez une variante kustomize pour le
backend
whereami :mkdir -p ${WORKDIR}/whereami-backend/base cat <<EOF > ${WORKDIR}/whereami-backend/base/kustomization.yaml resources: - github.com/GoogleCloudPlatform/kubernetes-engine-samples/quickstarts/whereami/k8s EOF mkdir ${WORKDIR}/whereami-backend/variant cat <<EOF > ${WORKDIR}/whereami-backend/variant/cm-flag.yaml apiVersion: v1 kind: ConfigMap metadata: name: whereami data: BACKEND_ENABLED: "False" # assuming you don't want a chain of backend calls METADATA: "backend" EOF cat <<EOF > ${WORKDIR}/whereami-backend/variant/service-type.yaml apiVersion: "v1" kind: "Service" metadata: name: "whereami" spec: type: ClusterIP EOF cat <<EOF > ${WORKDIR}/whereami-backend/variant/kustomization.yaml nameSuffix: "-backend" namespace: backend commonLabels: app: whereami-backend resources: - ../base patches: - path: cm-flag.yaml target: kind: ConfigMap - path: service-type.yaml target: kind: Service EOF
Appliquez la variante
backend
whereami aux deux clusters :kubectl --context=${CLUSTER_1_NAME} apply -k ${WORKDIR}/whereami-backend/variant kubectl --context=${CLUSTER_2_NAME} apply -k ${WORKDIR}/whereami-backend/variant
Créez une variante kustomize pour le
frontend
whereami :mkdir -p ${WORKDIR}/whereami-frontend/base cat <<EOF > ${WORKDIR}/whereami-frontend/base/kustomization.yaml resources: - github.com/GoogleCloudPlatform/kubernetes-engine-samples/quickstarts/whereami/k8s EOF mkdir whereami-frontend/variant cat <<EOF > ${WORKDIR}/whereami-frontend/variant/cm-flag.yaml apiVersion: v1 kind: ConfigMap metadata: name: whereami data: BACKEND_ENABLED: "True" BACKEND_SERVICE: "http://whereami-backend.backend.svc.cluster.local" EOF cat <<EOF > ${WORKDIR}/whereami-frontend/variant/service-type.yaml apiVersion: "v1" kind: "Service" metadata: name: "whereami" spec: type: ClusterIP EOF cat <<EOF > ${WORKDIR}/whereami-frontend/variant/kustomization.yaml nameSuffix: "-frontend" namespace: frontend commonLabels: app: whereami-frontend resources: - ../base patches: - path: cm-flag.yaml target: kind: ConfigMap - path: service-type.yaml target: kind: Service EOF
Appliquez la variante
frontend
whereami aux deux clusters :kubectl --context=${CLUSTER_1_NAME} apply -k ${WORKDIR}/whereami-frontend/variant kubectl --context=${CLUSTER_2_NAME} apply -k ${WORKDIR}/whereami-frontend/variant
Créez un fichier YAML
VirtualService
pour acheminer les requêtes vers lefrontend
whereami :cat << EOF > ${WORKDIR}/frontend-vs.yaml apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: whereami-vs namespace: frontend spec: gateways: - asm-ingress/asm-ingressgateway hosts: - 'frontend.endpoints.PROJECT_ID.cloud.goog' http: - route: - destination: host: whereami-frontend port: number: 80 EOF
Appliquez le fichier YAML
frontend-vs
aux deux clusters :kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/frontend-vs.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/frontend-vs.yaml
Maintenant que vous avez déployé
frontend-vs.yaml
sur les deux clusters, essayez d'appeler le point de terminaison public de vos clusters :curl -s https://frontend.endpoints.PROJECT_ID.cloud.goog | jq
Le résultat ressemble à ce qui suit :
{ "backend_result": { "cluster_name": "edge-to-mesh-02", "gce_instance_id": "8396338201253702608", "gce_service_account": "e2m-mcg-01.svc.id.goog", "host_header": "whereami-backend.backend.svc.cluster.local", "metadata": "backend", "node_name": "gk3-edge-to-mesh-02-pool-2-675f6abf-645h", "pod_ip": "10.124.0.199", "pod_name": "whereami-backend-7cbdfd788-8mmnq", "pod_name_emoji": "📸", "pod_namespace": "backend", "pod_service_account": "whereami-backend", "project_id": "e2m-mcg-01", "timestamp": "2023-12-01T03:46:24", "zone": "us-east4-b" }, "cluster_name": "edge-to-mesh-01", "gce_instance_id": "1047264075324910451", "gce_service_account": "e2m-mcg-01.svc.id.goog", "host_header": "frontend.endpoints.e2m-mcg-01.cloud.goog", "metadata": "frontend", "node_name": "gk3-edge-to-mesh-01-pool-2-d687e3c0-5kf2", "pod_ip": "10.54.1.71", "pod_name": "whereami-frontend-69c4c867cb-dgg8t", "pod_name_emoji": "🪴", "pod_namespace": "frontend", "pod_service_account": "whereami-frontend", "project_id": "e2m-mcg-01", "timestamp": "2023-12-01T03:46:24", "zone": "us-central1-c" }
Si vous exécutez la commande curl
plusieurs fois, vous constaterez que les réponses (à la fois de frontend
et de backend
) proviennent de différentes régions. Dans sa réponse, l'équilibreur de charge fournit un routage géographique. Cela signifie que l'équilibreur de charge achemine les requêtes du client vers le cluster actif le plus proche, mais que les requêtes continuent d'atterrir de manière aléatoire. Lorsque les requêtes passent occasionnellement d'une région à une autre, la latence et les coûts augmentent.
Dans la section suivante, vous allez implémenter l'équilibrage de charge de la zone dans le service mesh pour conserver les requêtes locales.
Activer et tester l'équilibrage de charge de la localité pour whereami
Dans cette section, vous allez implémenter l'équilibrage de charge de localité dans le maillage de services pour que les requêtes restent locales. Vous effectuez également des tests pour voir comment whereami gère différents scénarios d'échec.
Lorsque vous envoyez une requête au service frontend
whereami, l'équilibreur de charge envoie la requête au cluster ayant la latence la plus faible par rapport au client. Cela signifie que les pods de passerelle d'entrée du réseau maillé équilibrent la charge des requêtes vers les pods frontend
whereami sur les deux clusters. Cette section aborde ce problème en activant l'équilibrage de charge de localité dans le réseau maillé.
Dans Cloud Shell, créez un fichier YAML
DestinationRule
qui active le basculement régional d'équilibrage de charge de la zone vers le servicefrontend
:cat << EOF > ${WORKDIR}/frontend-dr.yaml apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: name: frontend namespace: frontend spec: host: whereami-frontend.frontend.svc.cluster.local trafficPolicy: connectionPool: http: maxRequestsPerConnection: 0 loadBalancer: simple: LEAST_REQUEST localityLbSetting: enabled: true outlierDetection: consecutive5xxErrors: 1 interval: 1s baseEjectionTime: 1m EOF
L'exemple de code précédent n'active que le routage local pour le service
frontend
. Vous avez également besoin d'une configuration supplémentaire qui gère le backend.Appliquez le fichier YAML
frontend-dr
aux deux clusters :kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/frontend-dr.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/frontend-dr.yaml
Créez un fichier YAML
DestinationRule
qui active le basculement régional d'équilibrage de charge de la zone vers le servicebackend
:cat << EOF > ${WORKDIR}/backend-dr.yaml apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: n ame: backend namespace: backend spec: host: whereami-backend.backend.svc.cluster.local trafficPolicy: connectionPool: http: maxRequestsPerConnection: 0 loadBalancer: simple: LEAST_REQUEST localityLbSetting: enabled: true outlierDetection: consecutive5xxErrors: 1 interval: 1s baseEjectionTime: 1m EOF
Appliquez le fichier YAML
backend-dr
aux deux clusters :kubectl --context=${CLUSTER_1_NAME} apply -f ${WORKDIR}/backend-dr.yaml kubectl --context=${CLUSTER_2_NAME} apply -f ${WORKDIR}/backend-dr.yaml
Lorsque les deux ensembles de fichiers YAML
DestinationRule
sont appliqués aux deux clusters, les requêtes restent locales au cluster vers lequel elles sont acheminées.Pour tester le basculement du service
frontend
, réduisez le nombre d'instances répliquées de la passerelle d'entrée dans votre cluster principal.Du point de vue de l'équilibreur de charge multirégional, cette action simule une défaillance de cluster. Cela entraîne l'échec des vérifications de l'état de l'équilibreur de charge de ce cluster. Cet exemple utilise le cluster dans
CLUSTER_1_REGION
. Seules les réponses du cluster devraient s'afficher dansCLUSTER_2_REGION
.Réduisez à zéro le nombre d'instances répliquées de la passerelle d'entrée de votre cluster principal, puis appelez le point de terminaison public pour vérifier que les requêtes ont basculé vers l'autre cluster :
kubectl --context=${CLUSTER_1_NAME} -n asm-ingress scale --replicas=0 deployment/asm-ingressgateway
La sortie doit ressembler à ceci :
$ curl -s https://frontend.endpoints.PROJECT_ID.cloud.goog | jq { "backend_result": { "cluster_name": "edge-to-mesh-02", "gce_instance_id": "2717459599837162415", "gce_service_account": "e2m-mcg-01.svc.id.goog", "host_header": "whereami-backend.backend.svc.cluster.local", "metadata": "backend", "node_name": "gk3-edge-to-mesh-02-pool-2-675f6abf-dxs2", "pod_ip": "10.124.1.7", "pod_name": "whereami-backend-7cbdfd788-mp8zv", "pod_name_emoji": "🏌🏽♀", "pod_namespace": "backend", "pod_service_account": "whereami-backend", "project_id": "e2m-mcg-01", "timestamp": "2023-12-01T05:41:18", "zone": "us-east4-b" }, "cluster_name": "edge-to-mesh-02", "gce_instance_id": "6983018919754001204", "gce_service_account": "e2m-mcg-01.svc.id.goog", "host_header": "frontend.endpoints.e2m-mcg-01.cloud.goog", "metadata": "frontend", "node_name": "gk3-edge-to-mesh-02-pool-3-d42ddfbf-qmkn", "pod_ip": "10.124.1.142", "pod_name": "whereami-frontend-69c4c867cb-xf8db", "pod_name_emoji": "🏴", "pod_namespace": "frontend", "pod_service_account": "whereami-frontend", "project_id": "e2m-mcg-01", "timestamp": "2023-12-01T05:41:18", "zone": "us-east4-b" }
Pour reprendre le routage du trafic standard, restaurez les instances répliquées de la passerelle d'entrée à la valeur d'origine dans le cluster :
kubectl --context=${CLUSTER_1_NAME} -n asm-ingress scale --replicas=3 deployment/asm-ingressgateway
Simulez une défaillance du service
backend
en réduisant le nombre d'instances répliquées dans la région principale à 0 :kubectl --context=${CLUSTER_1_NAME} -n backend scale --replicas=0 deployment/whereami-backend
Vérifiez que les réponses du service
frontend
proviennent de la région principaleus-central1
via l'équilibreur de charge et que les réponses du servicebackend
proviennent de la région secondaireus-east4
.Le résultat doit également inclure une réponse pour le service
frontend
de la région principale (us-central1
) et une réponse pour le servicebackend
de la région secondaire (us-east4
), comme prévu.Restaurez les instances répliquées du service de backend à leur valeur d'origine pour reprendre le routage du trafic classique :
kubectl --context=${CLUSTER_1_NAME} -n backend scale --replicas=3 deployment/whereami-backend
Vous disposez maintenant d'un équilibreur de charge HTTP(S) global servant d'interface à votre application multirégionale hébergée par le maillage de services.
Effectuer un nettoyage
Pour éviter que les ressources utilisées dans le cadre de ce déploiement soient facturées sur votre compte Google Cloud, supprimez le projet contenant les ressources, ou conservez le projet et supprimez les ressources individuelles.
Supprimer le projet
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Supprimer les ressources individuelles
Si vous souhaitez conserver le projet Google Cloud que vous avez utilisé dans ce déploiement, supprimez les différentes ressources.
Dans Cloud Shell, supprimez les ressources
HTTPRoute
:kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/default-httproute-redirect.yaml kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/default-httproute-redirect.yaml kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/default-httproute.yaml kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/default-httproute.yaml
Supprimez les ressources GKE Gateway :
kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/frontend-gateway.yaml kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/frontend-gateway.yaml
Supprimez les règles :
kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/ingress-gateway-healthcheck.yaml kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/ingress-gateway-healthcheck.yaml kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/cloud-armor-backendpolicy.yaml kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/cloud-armor-backendpolicy.yaml
Supprimez les exportations de service :
kubectl --context=${CLUSTER_1_NAME} delete -f ${WORKDIR}/svc_export.yaml kubectl --context=${CLUSTER_2_NAME} delete -f ${WORKDIR}/svc_export.yaml
Supprimez les ressources Google Cloud Armor :
gcloud --project=PROJECT_ID compute security-policies rules delete 1000 --security-policy edge-fw-policy --quiet gcloud --project=PROJECT_ID compute security-policies delete edge-fw-policy --quiet
Supprimez les ressources du gestionnaire de certificats :
gcloud --project=PROJECT_ID certificate-manager maps entries delete mcg-cert-map-entry --map="mcg-cert-map" --quiet gcloud --project=PROJECT_ID certificate-manager maps delete mcg-cert-map --quiet gcloud --project=PROJECT_ID certificate-manager certificates delete mcg-cert --quiet
Supprimez l'entrée Endpoints DNS :
gcloud --project=PROJECT_ID endpoints services delete "frontend.endpoints.PROJECT_ID.cloud.goog" --quiet
Supprimez l'adresse IP statique :
gcloud --project=PROJECT_ID compute addresses delete mcg-ip --global --quiet
Supprimez les clusters GKE Autopilot. Cette étape prend plusieurs minutes.
gcloud --project=PROJECT_ID container clusters delete ${CLUSTER_1_NAME} --region ${CLUSTER_1_REGION} --quiet gcloud --project=PROJECT_ID container clusters delete ${CLUSTER_2_NAME} --region ${CLUSTER_2_REGION} --quiet
Étape suivante
- Découvrez les autres fonctionnalités offertes par GKE Gateway que vous pouvez utiliser avec votre maillage de services.
- Découvrez les différents types d'équilibrage de charge cloud disponibles pour GKE.
- Découvrez les fonctionnalités proposées par Cloud Service Mesh.
- Pour découvrir d'autres architectures de référence, schémas et bonnes pratiques, consultez le Cloud Architecture Center.
Contributeurs
Auteurs :
- Alex Mattson | Ingénieur spécialiste des applications
- Mark Chilvers | Ingénieur spécialiste des applications
Autres contributeurs :
- Abdelfettah Sghiouar | Advocate pour les développeurs dans le cloud
- Greg Bray | Ingénieur client
- Paul Revello | Architecte de solutions cloud
- Valavan Rajakumar | Architecte d'entreprise principal