Configurer un maillage multicluster sur Cloud Service Mesh géré
Ce guide explique comment joindre deux clusters dans un seul Cloud Service Mesh à l'aide de Mesh CA ou du Certificate Authority Service, et comment activer l'équilibrage de charge interclusters. Vous pouvez facilement étendre ce processus pour intégrer autant de clusters que vous le souhaitez dans votre maillage.
Une configuration multicluster Cloud Service Mesh peut résoudre plusieurs scénarios d'entreprise essentiels, tels que l'échelle, l'emplacement et l'isolation. Pour en savoir plus, consultez la section Cas d'utilisation multicluster.
Prérequis
Dans ce guide, nous partons du principe que vous disposez d'au moins deux clusters GKE Google Cloud répondant aux exigences suivantes :
- Cloud Service Mesh installé sur les clusters. Vous avez besoin de
asmcli
, de l'outilistioctl
et d'exemples queasmcli
télécharge dans le répertoire que vous avez spécifié dans--output_dir
. - Les clusters de votre maillage doivent être connectés entre tous les pods avant de configurer Cloud Service Mesh. En outre, si vous joignez des clusters qui ne font pas partie du même projet, ils doivent être enregistrés dans le même projet hôte du parc et doivent tous se trouver dans la configuration d'un VPC partagé sur le même réseau. Nous vous recommandons également de disposer d'un projet pour héberger le VPC partagé et de deux projets de service pour la création de clusters. Pour en savoir plus, consultez la page Configurer des clusters avec un VPC partagé.
- Si vous utilisez Certificate Authority Service, les pools d'autorité de certification subordonnés correspondants de tous les clusters doivent être associés au même pool d'autorités de certification racine. Sinon, ils devront tous utiliser le même pool d'autorités de certification.
Définir des variables de projet et de cluster
Créez les variables d'environnement suivantes pour l'ID de projet, la zone ou la région du cluster, le nom du cluster et le contexte.
export PROJECT_1=PROJECT_ID_1 export LOCATION_1=CLUSTER_LOCATION_1 export CLUSTER_1=CLUSTER_NAME_1 export CTX_1="gke_${PROJECT_1}_${LOCATION_1}_${CLUSTER_1}" export PROJECT_2=PROJECT_ID_2 export LOCATION_2=CLUSTER_LOCATION_2 export CLUSTER_2=CLUSTER_NAME_2 export CTX_2="gke_${PROJECT_2}_${LOCATION_2}_${CLUSTER_2}"
S'il s'agit de nouveaux clusters, veillez à récupérer les identifiants de chaque cluster à l'aide des commandes
gcloud
suivantes. Sinon, la variablecontext
associée ne sera pas disponible pour les étapes suivantes de ce guide.Les commandes dépendent du type de cluster, régional ou zonal :
Régional
gcloud container clusters get-credentials ${CLUSTER_1} --region ${LOCATION_1} gcloud container clusters get-credentials ${CLUSTER_2} --region ${LOCATION_2}
Zonal
gcloud container clusters get-credentials ${CLUSTER_1} --zone ${LOCATION_1} gcloud container clusters get-credentials ${CLUSTER_2} --zone ${LOCATION_2}
Créer une règle de pare-feu
Dans certains cas, vous devez créer une règle de pare-feu pour autoriser le trafic interclusters. Par exemple, vous devez créer une règle de pare-feu dans les cas suivants :
- Vous utilisez différents sous-réseaux pour les clusters de votre maillage.
- Vos pods ouvrent des ports autres que 443 et 15002.
GKE ajoute automatiquement des règles de pare-feu à chaque nœud pour autoriser le trafic au sein du même sous-réseau. Si votre maillage contient plusieurs sous-réseaux, vous devez configurer explicitement les règles de pare-feu pour autoriser le trafic entre sous-réseaux. Vous devez ajouter une règle de pare-feu pour chaque sous-réseau afin d'autoriser les blocs CIDR des adresses IP sources et les ports cible pour l'ensemble du trafic entrant.
Les instructions suivantes permettent d'établir la communication entre tous les clusters de votre projet, ou uniquement entre $CLUSTER_1
et $CLUSTER_2
.
Recueillez des informations sur le réseau de vos clusters.
Tous les clusters du projet
Si les clusters se trouvent dans le même projet, vous pouvez utiliser la commande suivante pour autoriser la communication entre tous les clusters de votre projet. Si vous ne souhaitez pas exposer des clusters de votre projet, exécutez la commande décrite dans l'onglet Clusters spécifiques.
function join_by { local IFS="$1"; shift; echo "$*"; } ALL_CLUSTER_CIDRS=$(gcloud container clusters list --project $PROJECT_1 --format='value(clusterIpv4Cidr)' | sort | uniq) ALL_CLUSTER_CIDRS=$(join_by , $(echo "${ALL_CLUSTER_CIDRS}")) ALL_CLUSTER_NETTAGS=$(gcloud compute instances list --project $PROJECT_1 --format='value(tags.items.[0])' | sort | uniq) ALL_CLUSTER_NETTAGS=$(join_by , $(echo "${ALL_CLUSTER_NETTAGS}"))
Clusters spécifiques
La commande suivante autorise la communication entre
$CLUSTER_1
et$CLUSTER_2
, et n'expose pas les autres clusters de votre projet.function join_by { local IFS="$1"; shift; echo "$*"; } ALL_CLUSTER_CIDRS=$(for P in $PROJECT_1 $PROJECT_2; do gcloud --project $P container clusters list --filter="name:($CLUSTER_1,$CLUSTER_2)" --format='value(clusterIpv4Cidr)'; done | sort | uniq) ALL_CLUSTER_CIDRS=$(join_by , $(echo "${ALL_CLUSTER_CIDRS}")) ALL_CLUSTER_NETTAGS=$(for P in $PROJECT_1 $PROJECT_2; do gcloud --project $P compute instances list --filter="name:($CLUSTER_1,$CLUSTER_2)" --format='value(tags.items.[0])' ; done | sort | uniq) ALL_CLUSTER_NETTAGS=$(join_by , $(echo "${ALL_CLUSTER_NETTAGS}"))
Créez la règle de pare-feu.
GKE
gcloud compute firewall-rules create istio-multicluster-pods \ --allow=tcp,udp,icmp,esp,ah,sctp \ --direction=INGRESS \ --priority=900 \ --source-ranges="${ALL_CLUSTER_CIDRS}" \ --target-tags="${ALL_CLUSTER_NETTAGS}" --quiet \ --network=YOUR_NETWORK
Autopilot
TAGS="" for CLUSTER in ${CLUSTER_1} ${CLUSTER_2} do TAGS+=$(gcloud compute firewall-rules list --filter="Name:$CLUSTER*" --format="value(targetTags)" | uniq) && TAGS+="," done TAGS=${TAGS::-1} echo "Network tags for pod ranges are $TAGS" gcloud compute firewall-rules create asm-multicluster-pods \ --allow=tcp,udp,icmp,esp,ah,sctp \ --network=gke-cluster-vpc \ --direction=INGRESS \ --priority=900 --network=VPC_NAME \ --source-ranges="${ALL_CLUSTER_CIDRS}" \ --target-tags=$TAGS
Configurer la découverte des points de terminaison
Activer la découverte de points de terminaison entre les clusters publics ou privés avec l'API déclarative
Activer Cloud Service Mesh géré avec l'API Fleet active la découverte de points de terminaison pour ce cluster. Si vous avez provisionné Cloud Service Mesh géré avec un autre outil, vous pouvez activer manuellement la découverte des points de terminaison sur les clusters publics ou privés d'un parc en appliquant la configuration "multicluster_mode":"connected"
dans le fichier ConfigMap asm-options
. La détection de services interclusters est automatiquement activée entre les clusters qui disposent de cette configuration dans le même parc.
Il s'agit de la seule façon de configurer la découverte des points de terminaison multiclusters si vous disposez de l'implémentation du plan de contrôle gérée (TD) et de la méthode recommandée pour la configurer si vous disposez de l'implémentation gérée (Istiod).
Avant de continuer, vous devez avoir créé une règle de pare-feu.
Activer
Si le ConfigMap asm-options
existe déjà dans votre cluster, activez la découverte de points de terminaison pour le cluster:
kubectl patch configmap/asm-options -n istio-system --type merge -p '{"data":{"multicluster_mode":"connected"}}'
Si le mappage de configuration asm-options
n'existe pas encore dans votre cluster, créez-le avec les données associées et activez la découverte de points de terminaison pour le cluster:
kubectl --context ${CTX_1} create configmap asm-options -n istio-system --from-file <(echo '{"data":{"multicluster_mode":"connected"}}')
Désactiver
Désactivez la découverte des points de terminaison pour un cluster :
kubectl patch configmap/asm-options -n istio-system --type merge -p '{"data":{"multicluster_mode":"manual"}}'
Si vous annulez l'enregistrement d'un cluster du parc sans désactiver la découverte des points de terminaison, les secrets peuvent rester dans le cluster. Vous devez nettoyer manuellement tous les secrets restants.
Exécutez la commande suivante pour rechercher les secrets nécessitant un nettoyage :
kubectl get secrets -n istio-system -l istio.io/owned-by=mesh.googleapis.com,istio/multiCluster=true
Supprimez chaque secret :
kubectl delete secret SECRET_NAME
Répétez cette opération pour chaque secret restant.
Vérifier la connectivité multicluster
Cette section explique comment déployer les exemples de services HelloWorld
et Sleep
dans votre environnement multicluster pour vérifier que l'équilibrage de charge interclusters fonctionne.
Définir une variable pour le répertoire d'exemples
Accédez à l'emplacement où
asmcli
a été téléchargé, puis exécutez la commande suivante pour définirASM_VERSION
.export ASM_VERSION="$(./asmcli --version)"
Définissez un dossier de travail sur les exemples que vous utilisez pour vérifier que l'équilibrage de charge interclusters fonctionne. Les exemples se trouvent dans un sous-répertoire du répertoire
--output_dir
que vous avez spécifié dans la commandeasmcli install
. Dans la commande suivante, remplacezOUTPUT_DIR
par le répertoire que vous avez spécifié dans--output_dir
.export SAMPLES_DIR=OUTPUT_DIR/istio-${ASM_VERSION%+*}
Activer l'injection side-car
Créez l'exemple d'espace de noms dans chaque cluster.
for CTX in ${CTX_1} ${CTX_2} do kubectl create --context=${CTX} namespace sample done
Activez l'espace de noms pour l'injection : La procédure dépend de votre implémentation du plan de contrôle.
Géré (TD)
- Appliquez le libellé d'injection par défaut à l'espace de noms:
for CTX in ${CTX_1} ${CTX_2} do kubectl label --context=${CTX} namespace sample istio.io/rev- istio-injection=enabled --overwrite done
Géré (Istiod)
Recommandation:Exécutez la commande suivante pour appliquer le libellé d'injection par défaut à l'espace de noms:
for CTX in ${CTX_1} ${CTX_2} do kubectl label --context=${CTX} namespace sample \ istio.io/rev- istio-injection=enabled --overwrite done
Si vous êtes déjà un utilisateur du plan de contrôle Istio géré:nous vous recommandons d'utiliser l'injection par défaut, mais l'injection basée sur les révisions est prise en charge. Suivez les instructions suivantes:
Exécutez la commande suivante pour localiser les versions disponibles:
kubectl -n istio-system get controlplanerevision
Le résultat ressemble à ce qui suit :
NAME AGE asm-managed-rapid 6d7h
Dans le résultat, la valeur de la colonne
NAME
est le libellé de révision qui correspond à la version disponible pour la version de Cloud Service Mesh.Appliquez le libellé de révision à l'espace de noms.
for CTX in ${CTX_1} ${CTX_2} do kubectl label --context=${CTX} namespace sample \ istio-injection- istio.io/rev=REVISION_LABEL --overwrite done
Installer le service HelloWorld
Créez le service HelloWorld dans les deux clusters :
kubectl create --context=${CTX_1} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l service=helloworld -n sample
kubectl create --context=${CTX_2} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l service=helloworld -n sample
Déployer HelloWorld v1 et v2 sur chaque cluster
Déployez
HelloWorld v1
surCLUSTER_1
etv2
surCLUSTER_2
, ce qui vous permet de vérifier ultérieurement l'équilibrage de charge interclusters :kubectl create --context=${CTX_1} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l version=v1 -n sample
kubectl create --context=${CTX_2} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l version=v2 -n sample
Vérifiez que
HelloWorld v1
etv2
sont en cours d'exécution à l'aide des commandes suivantes. Vérifiez que le résultat ressemble à celui-ci :kubectl get pod --context=${CTX_1} -n sample
NAME READY STATUS RESTARTS AGE helloworld-v1-86f77cd7bd-cpxhv 2/2 Running 0 40s
kubectl get pod --context=${CTX_2} -n sample
NAME READY STATUS RESTARTS AGE helloworld-v2-758dd55874-6x4t8 2/2 Running 0 40s
Déployer le service Sleep
Déployez le service
Sleep
sur les deux clusters. Ce pod génère un trafic réseau artificiel à des fins de démonstration :for CTX in ${CTX_1} ${CTX_2} do kubectl apply --context=${CTX} \ -f ${SAMPLES_DIR}/samples/sleep/sleep.yaml -n sample done
Attendez que le service
Sleep
démarre dans chaque cluster. Vérifiez que le résultat ressemble à celui-ci :kubectl get pod --context=${CTX_1} -n sample -l app=sleep
NAME READY STATUS RESTARTS AGE sleep-754684654f-n6bzf 2/2 Running 0 5s
kubectl get pod --context=${CTX_2} -n sample -l app=sleep
NAME READY STATUS RESTARTS AGE sleep-754684654f-dzl9j 2/2 Running 0 5s
Vérifier l'équilibrage de charge interclusters
Appelez le service HelloWorld
plusieurs fois et vérifiez le résultat pour vérifier l'alternance des réponses de v1 et v2 :
Appelez le service
HelloWorld
:kubectl exec --context="${CTX_1}" -n sample -c sleep \ "$(kubectl get pod --context="${CTX_1}" -n sample -l \ app=sleep -o jsonpath='{.items[0].metadata.name}')" \ -- /bin/sh -c 'for i in $(seq 1 20); do curl -sS helloworld.sample:5000/hello; done'
Le résultat ressemble à ceci :
Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8 Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv ...
Appelez à nouveau le service
HelloWorld
:kubectl exec --context="${CTX_2}" -n sample -c sleep \ "$(kubectl get pod --context="${CTX_2}" -n sample -l \ app=sleep -o jsonpath='{.items[0].metadata.name}')" \ -- /bin/sh -c 'for i in $(seq 1 20); do curl -sS helloworld.sample:5000/hello; done'
Le résultat ressemble à ceci :
Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8 Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv ...
Félicitations, vous avez vérifié votre Cloud Service Mesh multicluster équilibré en charge !
Nettoyer le service HelloWorld
Lorsque vous avez terminé la vérification de l'équilibrage de charge, supprimez les services HelloWorld
et Sleep
de votre cluster.
kubectl delete ns sample --context ${CTX_1} kubectl delete ns sample --context ${CTX_2}