Vous pouvez intégrer vos applications Spring Cloud à Service Mesh (ASM) pour tirer parti des capacités de gouvernance des services cloud-native sans modifier votre code. Cette rubrique explique comment utiliser ASM pour gérer les services Spring Cloud.
Prérequis
Vous disposez d'une instance ASM Enterprise ou Ultimate Edition. Pour plus d'informations, consultez la section Créer une instance ASM.
Un cluster ACK managé est créé. Pour plus d'informations, consultez la section Créer un cluster ACK managé.
Une passerelle d'entrée est déployée. Pour plus d'informations, consultez la section Créer une passerelle d'entrée.
Contexte
Spring Cloud est une norme disposant de diverses implémentations, telles que Spring Cloud Netflix, Spring Cloud Alibaba et Spring Cloud Consul. Pour ASM, la principale différence entre ces implémentations réside dans le registre de services qu'elles utilisent. Le tableau suivant présente la prise en charge de la migration ASM pour différentes versions de Spring Cloud.
|
Version de Spring Cloud |
Registre de services |
Prise en charge de la migration |
|
Spring Cloud Alibaba |
Microservices Engine (MSE) Nacos (service Alibaba Cloud) |
Prise en charge |
|
Spring Cloud Alibaba |
Nacos (autogéré) |
Prise en charge |
|
Spring Cloud Netflix |
Eureka |
Prise en charge. La version de l'instance ASM doit être 1.13.4.53 ou ultérieure. |
|
Spring Cloud Consul |
Consul |
Prise en charge. La version de l'instance ASM doit être 1.13.4.53 ou ultérieure. |
|
Spring Cloud Zookeeper |
Zookeeper |
Prise en charge. La version de l'instance ASM doit être 1.13.4.53 ou ultérieure. |
Présentation de la démonstration
Cette rubrique utilise une application construite avec Spring Cloud et Nacos comme exemple. Vous pouvez télécharger l'exemple de code depuis le dépôt nacos-example.
L'application se compose d'un service consommateur et d'un service fournisseur. Le service fournisseur dispose de deux versions, v1 et v2, toutes deux enregistrées auprès d'un registre Nacos. Le service consommateur récupère les adresses du service fournisseur depuis le registre Nacos et répartit la charge des requêtes entre elles. Lorsque le service consommateur reçoit une requête, il la transmet à un fournisseur et renvoie la réponse de ce dernier. Les deux versions du fournisseur renvoient des réponses différentes :
Le fournisseur v1 répond à une requête echo par
Hello Nacos Discovery From v1xxx.Le fournisseur v2 répond à une requête echo par
Hello Nacos Discovery From v2xxx.
Dans la réponse, .xxx est un espace réservé pour le paramètre transmis à l'API echo. Par exemple, si une requête vers /echo/world est envoyée au fournisseur v1, celui-ci renvoie Hello Nacos Discovery From v1world.
Si vous n'activez pas les capacités de maillage de services pour les services consommateur et fournisseur, c'est-à-dire si aucun sidecar n'est injecté dans les pods de l'application, les requêtes seront toujours traitées mais ne bénéficieront pas des capacités de gouvernance des services fournies par Istio. Les étapes suivantes montrent comment utiliser ASM pour gérer les services Spring Cloud.
Étape 1 : Activer la prise en charge de Spring Cloud
Méthode 1 : Pour toutes les versions et tous les registres
La version de l'instance ASM doit être 1.13.4.32 ou ultérieure.
Limitations :
Vous devez créer un service Kubernetes pour le service de destination. Le port du service et le port cible doivent être définis sur le port d'écoute de l'application.
Dans les versions d'ASM antérieures à 1.23.6.32, vous devez désactiver REGISTRY_ONLY lorsque vous utilisez cette solution.
Connectez-vous au cluster du plan de contrôle à l'aide de kubectl. Pour plus d'informations, consultez la section Accéder aux ressources Istio sur le plan de contrôle à l'aide de kubectl.
-
Créez un EnvoyFilter dans le cluster ASM.
-
Créez un fichier nommé any-spring-cloud-support.yaml avec le contenu suivant.
apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: labels: provider: "asm" asm-system: "true" name: any-spring-cloud-support namespace: istio-system spec: configPatches: - applyTo: HTTP_FILTER match: proxy: proxyVersion: "^1.*" context: SIDECAR_OUTBOUND listener: portNumber: 8070 filterChain: filter: name: "envoy.filters.network.http_connection_manager" subFilter: name: "envoy.filters.http.router" patch: operation: INSERT_BEFORE value: # reverse_dns filter specification name: com.aliyun.reverse_dns typed_config: "@type": "type.googleapis.com/udpa.type.v1.TypedStruct" type_url: type.googleapis.com/envoy.config.filter.reverse_dns.v3alpha.CommonConfig value: pod_cidrs: - "10.0.128.0/18"Modifiez les paramètres du fichier YAML en fonction de vos besoins métier. Les paramètres sont décrits ci-dessous :
portNumber: le port du service Spring Cloud. Si les ports ne sont pas uniformes, vous pouvez supprimer ce paramètre. Si les ports peuvent être consolidés, vous pouvez configurer plusieurs ressources EnvoyFilter, chacune étant liée à unportNumberspécifique.pod_cidrs: le CIDR des pods du cluster ACK ou ACK Serverless. Pour trouver cette valeur, connectez-vous à la console Container Service Management et accédez à la page Cluster Information. Dans l'onglet Cluster Resources , recherchez le bloc CIDR des pods sous VPC et utilisez cette valeur pour le paramètre.
-
Exécutez la commande suivante pour appliquer le
EnvoyFilter.kubectl apply -f any-spring-cloud-support.yaml
-
Méthode 2 : Pour les registres Nacos uniquement
Connectez-vous au cluster du plan de contrôle à l'aide de kubectl. Pour plus d'informations, consultez la section Accéder aux ressources Istio sur le plan de contrôle à l'aide de kubectl.
-
Créez un ServiceEntry.
-
Créez un fichier nommé external-nacos-svc.yaml avec le contenu suivant.
kind: ServiceEntry metadata: name: external-nacos-svc spec: hosts: - "NACOS_SERVER_HOST" ## Replace this with your Nacos Server HOST, for example, "mse-xxx-p.nacos-ans.mse.aliyuncs.com". location: MESH_EXTERNAL ports: - number: 8848 name: http resolution: DNSDans le fichier YAML précédent,
8848est le port par défaut pour Nacos. Si vous utilisez un serveur Nacos autogéré et avez modifié le port, vous devez également adapter le paramètrenumberen conséquence. -
Exécutez la commande suivante pour créer le ServiceEntry.
kubectl apply -f external-nacos-svc.yaml
-
-
Créez un EnvoyFilter.
-
Créez un fichier nommé external-envoyfilter.yaml avec le contenu suivant.
apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: labels: provider: "asm" asm-system: "true" name: nacos-subscribe-lua namespace: istio-system spec: configPatches: # The first patch adds the lua filter to the listener/http connection manager. - applyTo: HTTP_FILTER match: proxy: proxyVersion: "^1.*" context: SIDECAR_OUTBOUND listener: portNumber: 8848 filterChain: filter: name: "envoy.filters.network.http_connection_manager" subFilter: name: "envoy.filters.http.router" patch: operation: INSERT_BEFORE value: # lua filter specification name: envoy.lua typed_config: "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua" inlineCode: | -- copyright: ASM (Alibaba Cloud ServiceMesh) function envoy_on_request(request_handle) local request_headers = request_handle:headers() -- /nacos/v1/ns/instance/list?healthyOnly=false&namespaceId=public&clientIP=10.122.63.81&serviceName=DEFAULT_GROUP%40%40service-provider&udpPort=53174&encoding=UTF-8 local path = request_headers:get(":path") if string.match(path,"^/nacos/v1/ns/instance/list") then local servicename = string.gsub(path,".*&serviceName.*40([%w.\\_\\-]+)&.*","%1") request_handle:streamInfo():dynamicMetadata():set("context", "request.path", path) request_handle:streamInfo():dynamicMetadata():set("context", "request.servicename", servicename) request_handle:logInfo("subscribe for serviceName: " .. servicename) else request_handle:streamInfo():dynamicMetadata():set("context", "request.path", "") end end function envoy_on_response(response_handle) local request_path = response_handle:streamInfo():dynamicMetadata():get("context")["request.path"] if request_path == "" then return end local servicename = response_handle:streamInfo():dynamicMetadata():get("context")["request.servicename"] response_handle:logInfo("modified response ip to serviceName:" .. servicename) local bodyObject = response_handle:body(true) local body= bodyObject:getBytes(0,bodyObject:length()) body = string.gsub(body,"%s+","") body = string.gsub(body,"(ip\":\")(%d+.%d+.%d+.%d+)","%1"..servicename) response_handle:body():setBytes(body) end -
Exécutez la commande suivante pour créer l'EnvoyFilter.
kubectl apply -f external-envoyfilter.yaml
-
Étape 2 : Déployer les services Spring Cloud
Pour intercepter le processus d'enregistrement, vous devez créer l'EnvoyFilter avant de déployer les charges de travail. Si une charge de travail est créée avant l'EnvoyFilter, vous devez effectuer une mise à jour progressive (rolling update) pour celle-ci.
Vous devez créer un service Kubernetes de type ClusterIP pour chaque service.
Connectez-vous au cluster du plan de données à l'aide de kubectl. Pour plus d'informations, consultez la rubrique Obtenir le fichier kubeconfig d'un cluster et utiliser kubectl pour se connecter au cluster.
-
Exécutez les commandes suivantes pour déployer les services Spring Cloud.
export NACOS_ADDRESS=xxxx # Replace xxxx with the address of your MSE or self-managed Nacos. We recommend using an internal VPC address. wget https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/springcloud/demo.yaml -O demo.yaml sed -e "s/NACOS_SERVER_CLUSTERIP/$NACOS_ADDRESS/g" demo.yaml |kubectl apply -f - -
Exécutez la commande suivante pour vérifier les services Spring Cloud.
kubectl get podsRésultat attendu :
consumer-bdd464654-jn8q7 2/2 Running 0 25h provider-v1-66bc67fb6d-46pgl 2/2 Running 0 25h provider-v2-76568c45f6-85z87 2/2 Running 0 25h
Étape 3 : Créer une passerelle et un service virtuel
-
Créez une passerelle Istio.
-
Créez un fichier nommé test-gateway.yaml avec le contenu suivant.
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: test-gateway spec: selector: istio: ingressgateway # use istio default controller servers: - port: number: 80 name: http protocol: HTTP hosts: - "*" -
Utilisez le fichier kubeconfig de l'instance ASM et exécutez la commande suivante pour créer la passerelle Istio.
kubectl apply -f test-gateway.yaml
-
-
Créez un service virtuel.
-
Créez un fichier nommé consumer.yaml avec le contenu suivant.
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: consumer spec: hosts: - "*" gateways: - test-gateway http: - match: - uri: prefix: / route: - destination: host: consumer.default.svc.cluster.local port: number: 8080 -
Exécutez la commande suivante pour créer le service virtuel.
kubectl apply -f consumer.yaml
-
Étape 4 : Vérifier la gestion des services
-
Obtenez l'adresse IP de la passerelle d'entrée.
Connectez-vous à la console ASM. Dans le volet de navigation de gauche, sélectionnez .
Sur la page Mesh Management, cliquez sur le nom de l'instance ASM. Dans le volet de navigation de gauche, sélectionnez .
Sur la page Ingress Gateway, consultez l'Adresse du service de la passerelle d'entrée.
-
Exécutez la commande suivante pour envoyer une requête au service consommateur Spring Cloud via la passerelle d'entrée.
curl <IP address of the ingress gateway>/echo/worldRésultat attendu :
Hello Nacos Discovery From v1world Hello Nacos Discovery From v2world Hello Nacos Discovery From v1world Hello Nacos Discovery From v2worldLe résultat indique que les requêtes sont acheminées vers les fournisseurs v1 et v2 selon un algorithme round-robin par défaut.
-
Créez une règle de destination et un service virtuel.
-
Créez un fichier nommé service-provider.yaml avec le contenu suivant.
--- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: service-provider spec: host: service-provider subsets: - name: v1 labels: label: v1 - name: v2 labels: label: v2 -
Exécutez la commande suivante pour créer la règle de destination.
kubectl apply -f service-provider.yaml -
Créez un fichier nommé service-provider1.yaml avec le contenu suivant.
Le service virtuel suivant achemine les requêtes destinées à /echo/hello vers le fournisseur v1, tandis que toutes les autres requêtes sont dirigées vers le fournisseur v2.
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: service-provider spec: hosts: - service-provider http: - name: "hello-v1" match: - uri: prefix: "/echo/hello" route: - destination: host: service-provider subset: v1 - name: "default" route: - destination: host: service-provider subset: v2 -
Exécutez la commande suivante pour créer le service virtuel.
kubectl apply -f service-provider1.yaml
-
-
Exécutez la commande suivante pour envoyer une requête au service consommateur Spring Cloud.
curl <IP address of the ingress gateway>/echo/helloRésultat attendu :
Hello Nacos Discovery From v1hello Hello Nacos Discovery From v1helloLe résultat montre que toutes les requêtes adressées à
/echo/hellosont routées vers le fournisseur v1, tandis que les autres requêtes sont dirigées vers le fournisseur v2. Cela confirme qu'Istio contrôle désormais le trafic Spring Cloud, vous permettant de gérer les services à l'aide des règles de routage Istio.
FAQ
Dépannage des services Spring Cloud
-
Vérifiez si l'interception du trafic est activée pour le port ou l'adresse IP de Nacos.
Si vous utilisez la méthode reverse_dns, vous devez intercepter les adresses IP des pods.
Si vous utilisez la méthode du script Lua, vous devez intercepter l'adresse IP du serveur Nacos et l'adresse IP du cluster.
Pour intercepter le processus d'enregistrement, vous devez créer l'EnvoyFilter avant les charges de travail. Si une charge de travail a été créée en premier, vous devez effectuer une mise à jour progressive (rolling update) sur celle-ci.
Vérifiez qu'un service Kubernetes de type ClusterIP existe pour chaque service.
-
Vérifiez la méthode utilisée pour activer le support Spring Cloud sur le plan de contrôle ASM.
Si vous utilisez la Méthode 2, la version du SDK client Nacos doit être antérieure à 2,0. Le SDK client Nacos 2.0 et versions ultérieures utilise gRPC pour se connecter au serveur, ce qui rend la Méthode 2 incompatible. La Méthode 1 ne dépend pas de la version de Nacos et prend en charge toutes les versions de Nacos.
Vérifiez la version du sidecar des services. Si la version de l'image du sidecar est antérieure à 1.13.4.32, seul le plan de contrôle de l'instance ASM a été mis à niveau, mais pas le plan de données. Vous devez effectuer une mise à jour progressive (rolling update) sur les déploiements de services concernés.