Configurar uma malha de vários clusters no Cloud Service Mesh gerenciado
Neste guia, explicamos como mesclar dois clusters em um único Cloud Service Mesh usando a CA da Mesh ou o serviço de autoridade certificadora e ativar o balanceamento de carga entre clusters. É possível ampliar facilmente esse processo para incorporar qualquer quantidade de clusters na malha.
Uma configuração do Cloud Service Mesh de vários clusters pode resolver vários cenários corporativos cruciais, como escala, local e isolamento. Para mais informações, consulte Casos de uso de vários clusters.
Pré-requisitos
Para este guia, presumimos que você tenha dois ou mais Google Cloud clusters do GKE que atendam aos seguintes requisitos:
- O Cloud Service Mesh instalado nos clusters. Você precisa de
asmcli, a ferramentaistioctle amostras queasmclifaz o download para o diretório especificado em--output_dir. - Os clusters na malha precisam ter conectividade entre todos os pods antes de configurar o Cloud Service Mesh. Além disso, você mesclar clusters que não estejam no mesmo projeto, eles vão precisar ser registrados no mesmo projeto host da frota, e será preciso que os clusters estejam em uma configuração do projeto de VPC compartilhada na mesma rede. Também recomendamos que você tenha um projeto para hospedar a VPC compartilhada e dois projetos de serviço para criar clusters. Para mais informações, consulte Como configurar clusters com a VPC compartilhada.
 - Se você usar o serviço de autoridade certificadora, todos os clusters precisam ter a respectiva cadeia de pools de CAs subordinados para o mesmo pool de CA raiz. Caso contrário, todos precisarão usar o mesmo pool de ACs.
 
Como definir variáveis de projeto e de cluster
Crie as seguintes variáveis de ambiente para o ID do projeto, a zona ou região do cluster, o nome do cluster e o contexto.
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}"Se esses forem clusters recém-criados, busque credenciais para cada cluster com os seguintes comandos
gcloud. Caso contrário, ocontextassociado não estará disponível para uso nas próximas etapas deste guia.Os comandos dependem do tipo de cluster, por região ou por zona:
Regional
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}
Criar regra de firewall
Em alguns casos, você precisa criar uma regra de firewall para permitir o tráfego entre clusters. Por exemplo, você precisa criar uma regra de firewall se:
- Você usa sub-redes diferentes para os clusters na malha.
 - Os pods abrem portas diferentes de 443 e 15002.
 
O GKE adiciona automaticamente regras de firewall a cada nó para permitir o tráfego dentro da mesma sub-rede. Se a malha contiver várias sub-redes, será necessário configurar explicitamente as regras de firewall para permitir o tráfego entre as sub-redes. Você precisa adicionar uma nova regra de firewall para cada sub-rede para permitir os bloqueios de CIDR de IP de origem e segmentar as portas de todo o tráfego de entrada.
As instruções a seguir permitem a comunicação entre todos os clusters no projeto ou apenas entre $CLUSTER_1 e $CLUSTER_2.
Reúna informações sobre a rede dos clusters.
Todos os clusters de projeto
Se os clusters estiverem no mesmo projeto, use o seguinte comando para permitir a comunicação entre todos os clusters no projeto. Se você não quiser expor alguns clusters no seu projeto, use o comando na guia Clusters específicos.
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 específicos
O comando a seguir permite a comunicação entre
$CLUSTER_1e$CLUSTER_2e não expõe outros clusters no projeto.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}"))Crie a regra de firewall.
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_NETWORKPiloto automático
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
Configurar a descoberta de endpoints
Ativar a descoberta de endpoints entre clusters públicos ou particulares com a API declarativa
Ativar o Cloud Service Mesh gerenciado com a API Fleet vai ativar a descoberta de endpoints
para este cluster. Se você provisionou o Cloud Service Mesh gerenciado com uma ferramenta diferente, é possível ativar manualmente a descoberta de endpoints em clusters públicos ou
particulares em uma frota, aplicando a configuração "multicluster_mode":"connected" no
configmap asm-options. Os clusters com essa configuração ativada na mesma frota terão a descoberta de serviços entre clusters ativada automaticamente entre si.
Essa é a única maneira de configurar a descoberta de endpoints em vários clusters se você tiver a implementação do plano de controle gerenciada (TD, na sigla em inglês) e a maneira recomendada de configurá-la se você tiver a implementação gerenciada (Istiod).
Antes de continuar, crie uma regra de firewall.
Ativar
Se o configmap asm-options já existe no seu cluster, ative a descoberta de endpoints para o cluster:
      kubectl patch configmap/asm-options -n istio-system --type merge -p '{"data":{"multicluster_mode":"connected"}}'
Se o configmap asm-options ainda não existir no cluster, crie-o com os dados associados e ative a descoberta de endpoints para o cluster:
      kubectl --context ${CTX_1} create configmap asm-options -n istio-system --from-file <(echo '{"data":{"multicluster_mode":"connected"}}')
Desativar
Desativar a descoberta de endpoints para um cluster:
      kubectl patch configmap/asm-options -n istio-system --type merge -p '{"data":{"multicluster_mode":"manual"}}'
Se você cancelar o registro de um cluster na frota sem desativar a descoberta de endpoints, os secrets poderão permanecer no cluster. Você precisa limpar manualmente todos os secrets restantes.
Execute o seguinte comando para encontrar secrets que precisam de limpeza:
kubectl get secrets -n istio-system -l istio.io/owned-by=mesh.googleapis.com,istio/multiCluster=trueExclua cada secret:
kubectl delete secret SECRET_NAMERepita essa etapa para cada secret restante.
Verificar a conectividade de vários clusters
Nesta seção, você verá como implantar os serviços de amostra HelloWorld e Sleep no ambiente de vários clusters para verificar se o balanceamento de carga entre eles funciona.
Definir variável para diretório de amostras
Navegue até o local onde
asmclifoi salvo e execute o seguinte comando para configurar oASM_VERSIONexport ASM_VERSION="$(./asmcli --version)"Defina uma pasta de trabalho para as amostras que você usa para verificar se o balanceamento de carga entre clusters funciona. As amostras estão localizadas em um subdiretório, no diretório
--output_dirque você especificou no comandoasmcli install. No comando a seguir, altereOUTPUT_DIRpara o diretório especificado em--output_dir.export SAMPLES_DIR=OUTPUT_DIR/istio-${ASM_VERSION%+*}
Ative a injeção de sidecar
Crie o namespace de amostra em cada cluster.
for CTX in ${CTX_1} ${CTX_2} do kubectl create --context=${CTX} namespace sample doneAtivar o namespace para injeção. As etapas dependem da implementação do plano de controle.
Gerenciado (TD)
- Aplique o rótulo de injeção padrão ao namespace:
 
for CTX in ${CTX_1} ${CTX_2} do kubectl label --context=${CTX} namespace sample \ istio.io/rev- istio-injection=enabled --overwrite doneGerenciado (Istiod)
Recomendado:execute o comando a seguir para aplicar o rótulo de injeção padrão ao namespace:
for CTX in ${CTX_1} ${CTX_2} do kubectl label --context=${CTX} namespace sample \ istio.io/rev- istio-injection=enabled --overwrite doneSe você já for usuário do plano de controle do Istiod gerenciado:recomendamos que você use a injeção padrão, mas a injeção baseada em revisão é compatível. Siga estas instruções:
Execute o seguinte comando para localizar os canais de lançamento disponíveis:
kubectl -n istio-system get controlplanerevisionO resultado será assim:
NAME AGE asm-managed-rapid 6d7hNa saída, o valor na coluna
NAMEé o rótulo de revisão que corresponde ao canal de lançamento disponível para a versão do Cloud Service Mesh.Aplique o rótulo de revisão ao namespace:
for CTX in ${CTX_1} ${CTX_2} do kubectl label --context=${CTX} namespace sample \ istio-injection- istio.io/rev=REVISION_LABEL --overwrite done
Instalar o serviço HelloWorld
Crie o serviço HelloWorld em ambos os clusters:
kubectl create --context=${CTX_1} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l service=helloworld -n samplekubectl create --context=${CTX_2} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l service=helloworld -n sample
Implantar o HelloWorld v1 e v2 em cada cluster
Implante
HelloWorld v1emCLUSTER_1ev2emCLUSTER_2. Isso ajudará a verificar o balanceamento de carga entre clusters posteriormente:kubectl create --context=${CTX_1} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l version=v1 -n samplekubectl create --context=${CTX_2} \ -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \ -l version=v2 -n sampleConfirme se
HelloWorld v1ev2estão em execução usando os seguintes comandos. Verifique se a saída é semelhante a esta:kubectl get pod --context=${CTX_1} -n sampleNAME READY STATUS RESTARTS AGE helloworld-v1-86f77cd7bd-cpxhv 2/2 Running 0 40s
kubectl get pod --context=${CTX_2} -n sampleNAME READY STATUS RESTARTS AGE helloworld-v2-758dd55874-6x4t8 2/2 Running 0 40s
Implantar o serviço Sleep
Implante o serviço
Sleepnos dois clusters. Esse pod gera tráfego de rede artificial para fins de demonstração:for CTX in ${CTX_1} ${CTX_2} do kubectl apply --context=${CTX} \ -f ${SAMPLES_DIR}/samples/sleep/sleep.yaml -n sample doneAguarde a inicialização do serviço
Sleepem cada cluster. Verifique se a saída é semelhante a esta:kubectl get pod --context=${CTX_1} -n sample -l app=sleepNAME READY STATUS RESTARTS AGE sleep-754684654f-n6bzf 2/2 Running 0 5s
kubectl get pod --context=${CTX_2} -n sample -l app=sleepNAME READY STATUS RESTARTS AGE sleep-754684654f-dzl9j 2/2 Running 0 5s
Verificar o balanceamento de carga entre clusters
Chame o serviço HelloWorld várias vezes e confira o resultado para verificar
as respostas alternadas da v1 e da v2:
Chame o serviço
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'A resposta será semelhante a esta:
Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8 Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv ...
Chame o serviço
HelloWorldnovamente: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'A resposta será semelhante a esta:
Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8 Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv ...
Parabéns, você verificou seu balanceamento de carga com vários clusters do Cloud Service Mesh!
Limpar o serviço HelloWorld
Quando terminar de verificar o balanceamento de carga, remova os serviços HelloWorld e Sleep
do seu cluster.
kubectl delete ns sample --context ${CTX_1}
kubectl delete ns sample --context ${CTX_2}