O Service Mesh (ASM) adiciona gerenciamento de tráfego baseado em Istio a aplicações Spring Cloud sem exigir alterações no código. Após conectar seus serviços Spring Cloud ao ASM, utilize CRDs do Istio, como VirtualService e DestinationRule, para controlar roteamento, balanceamento de carga e divisão de tráfego por versão. Durante todo o processo, suas aplicações continuam usando o registro de serviços existente para descoberta.
Implementações e registros suportados
O ASM oferece suporte às seguintes implementações do Spring Cloud. Todas as migrações dispensam modificações no código.
|
Implementação do Spring Cloud |
Registro de serviços |
Migração suportada sem modificação de código |
|
Spring Cloud Alibaba |
Microservices Engine (MSE) Nacos |
Sim |
|
Spring Cloud Alibaba |
Nacos autogerenciado |
Sim |
|
Spring Cloud Netflix |
Eureka |
Sim. Requer ASM versão 1.13.4.53 ou posterior. |
|
Spring Cloud Consul |
Consul |
Sim. Requer ASM versão 1.13.4.53 ou posterior. |
|
Spring Cloud Zookeeper |
Zookeeper |
Sim. Requer ASM versão 1.13.4.53 ou posterior. |
Como funciona
Aplicações Spring Cloud dependem de um registro de serviços (Nacos, Eureka, Consul ou Zookeeper) para realizar a descoberta de serviços. O ASM integra essa descoberta baseada em registro ao modelo nativo de malha do Istio ao interceptar o tráfego do registro por meio de um EnvoyFilter. Após a interceptação, os proxies sidecar resolvem os nomes dos serviços para IPs de pods, e os CRDs do Istio governam todo o tráfego entre os serviços.
Dois métodos habilitam essa integração no plano de controle do ASM:
|
Método |
Registros suportados |
Requisitos |
|
Método 1: DNS reverso |
Todos os registros |
ASM 1.13.4.32 ou posterior |
|
Método 2: Filtro Lua |
Apenas Nacos |
SDK cliente do Nacos anterior à versão 2,0 (v2.0+ usa gRPC, incompatível com Lua) |
Pré-requisitos
Antes de começar, verifique se você possui:
Uma instância do ASM da Enterprise Edition ou Ultimate Edition. Consulte Criar uma instância do ASM
Um cluster gerenciado ACK. Consulte Criar um cluster gerenciado ACK
O cluster ACK adicionado à instância do ASM. Consulte Adicionar um cluster a uma instância do ASM
Um gateway de entrada implantado. Consulte Criar um gateway de entrada
Arquitetura da demonstração
Este tutorial utiliza uma demonstração Spring Cloud Nacos com três serviços:
Serviço consumidor: Expõe a porta 8080 com um endpoint
/echo. Encaminha solicitações ao serviço provedor e retorna a resposta.Serviço provedor (V1): Responde com
Hello Nacos Discovery From v1<parameter>.Serviço provedor (V2): Responde com
Hello Nacos Discovery From v2<parameter>.
Ambas as versões do provedor se registram no registro Nacos. O consumidor as descobre por meio do Nacos e distribui as solicitações entre V1 e V2 em round-robin.
Por exemplo, uma solicitação para /echo/world retorna Hello Nacos Discovery From v1world ou Hello Nacos Discovery From v2world.

Baixe o código-fonte da demonstração no repositório nacos-examples.
Sem a injeção de sidecar, esses serviços funcionam normalmente, mas permanecem invisíveis ao Istio. As etapas a seguir adicionam gerenciamento de tráfego baseado em malha sobre a descoberta de serviços existente do Spring Cloud.
Etapa 1: Habilitar o suporte ao Spring Cloud no plano de controle do ASM
Método 1: DNS reverso (todos os registros)
Requer ASM 1.13.4.32 ou posterior.
Deve existir um serviço Kubernetes como serviço de destino. A porta do serviço e a porta de destino devem corresponder à porta pela qual a aplicação é roteada via instância do Server Load Balancer (SLB).
Para ASM 1.23.6.32 ou posterior, desative REGISTRY_ONLY.
Conecte o kubectl ao plano de controle do ASM. Consulte Usar kubectl no plano de controle para acessar recursos do Istio.
-
Crie um arquivo chamado
any-spring-cloud-support.yaml: Substitua os valores abaixo conforme seu ambiente:Parâmetro
Descrição
Onde encontrar
portNumberPorta do seu serviço Spring Cloud. Remova este parâmetro para corresponder a todas as portas ou crie recursos EnvoyFilter separados para direcionar portas específicas.
Configuração da aplicação
pod_cidrsBloco CIDR de pod do cluster ACK ou ACK Serverless.
No Console de Gerenciamento do Container Service, acesse Clusters, clique em seu cluster e abra a aba Cluster Resources. Clique no link da VPC para visualizar o bloco CIDR do vSwitch.
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: 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" -
Aplique o EnvoyFilter:
kubectl apply -f any-spring-cloud-support.yaml
Método 2: Filtro Lua (apenas Nacos)
Conecte o kubectl ao plano de controle do ASM. Consulte Usar kubectl no plano de controle para acessar recursos do Istio.
-
Crie um arquivo chamado
external-nacos-svc.yamlpara definir uma entrada de serviço para o servidor Nacos: Substitua<your-nacos-server-host>pelo endpoint do servidor Nacos (por exemplo,mse-xxx-p.nacos-ans.mse.aliyuncs.com). A porta8848é a porta padrão do Nacos. Caso seu Nacos autogerenciado utilize uma porta diferente, atualize o valor denumber.kind: ServiceEntry metadata: name: external-nacos-svc spec: hosts: - "<your-nacos-server-host>" # Example: mse-xxx-p.nacos-ans.mse.aliyuncs.com location: MESH_EXTERNAL ports: - number: 8848 name: http resolution: DNS -
Aplique a entrada de serviço:
kubectl apply -f external-nacos-svc.yaml -
Crie um arquivo chamado
external-envoyfilter.yamlpara o EnvoyFilter baseado em Lua:apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: labels: provider: "asm" asm-system: "true" name: nacos-subscribe-lua namespace: istio-system spec: configPatches: - 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: 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() 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 -
Aplique o EnvoyFilter:
kubectl apply -f external-envoyfilter.yaml
Etapa 2: Implantar serviços Spring Cloud
Aplique o EnvoyFilter da Etapa 1 antes de implantar os serviços. O filtro deve estar ativo para interceptar o processo de registro de serviços. Se os serviços já estiverem implantados, acione uma atualização contínua nessas implantações.
Cada serviço Spring Cloud requer um recurso de serviço Kubernetes com um endereço IP de cluster.
Conecte o kubectl ao plano de dados do ACK. Consulte Obter o arquivo kubeconfig de um cluster.
-
Implante os serviços de demonstração: Substitua
<your-nacos-endpoint>pelo endpoint do seu registro MSE Nacos ou registro Nacos autogerenciado.# Set the Nacos registry endpoint (VPC endpoint recommended) export NACOS_ADDRESS=<your-nacos-endpoint> # Download and apply the demo deployment 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 - -
Verifique se todos os pods estão em execução com 2/2 containers (aplicação + sidecar): Saída esperada: O valor
2/2na coluna READY confirma que tanto o container da aplicação quanto o proxy sidecar Envoy estão em execução.kubectl get podsconsumer-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
Etapa 3: Criar um gateway Istio e um serviço virtual
-
Crie um arquivo chamado
test-gateway.yamlpara o gateway Istio:apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: test-gateway spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "*" -
Conecte o kubectl ao plano de controle do ASM e aplique o gateway:
kubectl apply -f test-gateway.yaml -
Crie um arquivo chamado
consumer.yamlpara um serviço virtual que roteia o tráfego de entrada para o consumidor: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 -
Aplique o serviço virtual:
kubectl apply -f consumer.yaml
Etapa 4: Verificar o gerenciamento de tráfego
Esta etapa confirma que o ASM controla o tráfego do Spring Cloud. Primeiro, observe o comportamento padrão de round-robin sem regras de roteamento; em seguida, aplique regras de roteamento do Istio e verifique a alteração.
Observar o comportamento padrão (antes das regras de roteamento)
-
Obtenha o endereço IP do gateway de entrada:
Faça login no console do ASM.
No painel de navegação à esquerda, escolha Service Mesh > Mesh Management.
Clique no nome da sua instância do ASM e escolha ASM Gateways > Ingress Gateway.
Anote o Service address na página Ingress Gateway.
-
Envie várias solicitações ao serviço consumidor: As respostas alternam entre V1 e V2 em round-robin: Isso confirma que o consumidor descobre ambas as versões do provedor por meio do Nacos e distribui o tráfego uniformemente. Nenhuma regra de roteamento do Istio está ativa neste momento.
curl <ingress-gateway-ip>/echo/worldHello Nacos Discovery From v1world Hello Nacos Discovery From v2world Hello Nacos Discovery From v1world Hello Nacos Discovery From v2world
Aplicar regras de roteamento (após)
-
Crie um arquivo chamado
service-provider.yamlpara definir uma regra de destino com subconjuntos baseados em versão: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 -
Aplique a regra de destino:
kubectl apply -f service-provider.yaml -
Crie um arquivo chamado
service-provider-vs.yamlpara definir um serviço virtual que roteia solicitações/echo/hellopara V1 e todas as outras solicitações para 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 -
Aplique o serviço virtual:
kubectl apply -f service-provider-vs.yaml -
Teste as regras de roteamento: Todas as respostas agora vêm apenas da V1: Compare isso com o comportamento de round-robin observado anteriormente: Solicitações
/echo/helloagora são roteadas exclusivamente para V1, enquanto todas as outras vão para V2. Os CRDs do Istio assumiram o roteamento de tráfego do Spring Cloud, confirmando que o ASM gerencia os serviços.curl <ingress-gateway-ip>/echo/helloHello Nacos Discovery From v1hello Hello Nacos Discovery From v1hello
Perguntas frequentes
O tráfego não é interceptado pela malha
Verifique se o bloqueio de tráfego está habilitado para a porta ou endereço IP do registro:
Método 1 (DNS reverso): É necessário bloquear o endereço IP do pod. Certifique-se de que o valor
pod_cidrsno seu EnvoyFilter abranja o bloco CIDR de pod correto do seu cluster ACK.Método 2 (filtro Lua): É necessário bloquear o endereço IP do servidor Nacos e o endereço IP do cluster.
Os serviços não estão se registrando corretamente
Isso geralmente ocorre quando o EnvoyFilter não estava ativo antes do início dos serviços. O filtro deve interceptar o processo de registro desde o começo. Reinicie as implantações afetadas:
kubectl rollout restart deployment <deployment-name>
Confirme também se cada serviço Spring Cloud possui um recurso de serviço Kubernetes correspondente com um endereço IP de cluster.
As regras de roteamento não estão entrando em vigor
Duas causas comuns:
Versão do SDK cliente do Nacos (apenas Método 2): O Método 2 exige SDK cliente do Nacos anterior à versão 2,0. A versão 2.0+ usa gRPC em vez de HTTP, o que é incompatível com o filtro Lua. Mude para o Método 1 se o seu SDK cliente do Nacos for 2,0 ou posterior — o Método 1 funciona com todas as versões do Nacos.
Versão desatualizada do sidecar: Se a versão da imagem do sidecar for anterior a 1.13.4.32, o plano de dados pode não ter sido atualizado após um upgrade do plano de controle. Reinicie as implantações afetadas para obter a versão mais recente do sidecar.