Este artigo é compartilhado da comunidade Huawei Cloud " Implementando gerenciamento de tráfego multicluster baseado no Istio " pelo autor: Você pode fazer um amigo.
um plano de fundo
A governança de serviços para infraestruturas heterogêneas, como multinuvem e nuvem híbrida, é um dos cenários em que o Istio se concentra em oferecer suporte. Para melhorar a disponibilidade do serviço e evitar a dependência de fornecedores, as empresas geralmente optam por implantar aplicativos em vários clusters em várias regiões, ou mesmo em vários ambientes de nuvem, como soluções multinuvem e de nuvem híbrida que gradualmente se tornaram as melhores. escolha para implantação de aplicativos corporativos. Portanto, cada vez mais usuários têm fortes demandas por governança de serviços entre clusters. Nesse contexto, o Istio, como padrão de fato no campo ServiceMesh, lançou uma variedade de soluções de gerenciamento de vários clusters.
2. Introdução
Atualmente o Istio oferece suporte a 4 modelos multicluster.
- Modelo de plano de controle único de rede plana
- Modelo de plano multicontrole de rede plana
- Modelo de plano de controle único de rede não plana
- Modelo de plano multicontrole de rede não plana
O modelo de plano de controle único de vários clusters significa que vários clusters compartilham o mesmo plano de controle do Istio. O modelo de plano de controle múltiplo de vários clusters significa que cada cluster deve usar independentemente um conjunto de planos de controle do Istio, seja um único controle. plano ou um modelo de plano de controle múltiplo, cada conjunto de plano de controle do Istio (istiod) deve ser conectado ao Kube-apiserver de todos os clusters, e List-Watch obtém todos os clusters Service、Endpoint、Pod 、Node
e controla o acesso ao serviço dentro do cluster ou entre clusters, mas. monitora apenas VirtualService、DestinationRule、Gateway
os objetos da API do Istio do cluster principal.
Dependendo se a rede entre clusters é plana ou não, o Istio subdivide dois modelos de plano de controle:
- Rede plana: redes de contêineres com vários clusters são conectadas por meio de VPN e outras tecnologias, e os pods podem acessar diretamente entre clusters.
- Rede não plana: as redes de contêineres de cada cluster são isoladas umas das outras. O acesso entre clusters não pode ser transmitido e deve passar pelo gateway leste-oeste.
Ao escolher o modelo multicluster do Istio em um ambiente de produção, é claro que você precisa tomar uma decisão com base no seu cenário real. Se a rede entre clusters for plana, você poderá escolher um modelo de rede plana; se a rede entre clusters for isolada, você poderá escolher um modelo de rede não plana. Se o tamanho do cluster for pequeno, você poderá escolher o modelo de plano de controle único. Se o tamanho do cluster for grande, você poderá escolher o modelo de plano de controle múltiplo.
Este documento seleciona um modelo de plano multicontrole de rede não plana para instruções de instalação: O modelo de instalação é o seguinte. O
modelo de plano multicontrole de rede não plana tem as seguintes características.
- Diferentes clusters não precisam estar em uma grande rede, ou seja, a rede de contêineres não precisa estar conectada em três camadas e o acesso ao serviço entre clusters é feito por meio de
Istio East-West Gateway
encaminhamento. - Não há limite no intervalo de endereços do pod e no intervalo de endereços de serviço de cada cluster Kubernetes. Ele pode se sobrepor a outros clusters e clusters diferentes não interferem entre si.
- O Sidecar de cada cluster Kubernetes está conectado apenas ao plano de controle Istio deste cluster, tornando a comunicação mais eficiente.
- O Istiod monitora apenas a configuração do Istio do cluster principal, portanto, há problemas de replicação redundante para outros recursos.
VirtualService、DestinationRule、Gateway
- Acesso ao serviço interno no mesmo cluster: conexão direta entre pods; acesso ao serviço entre clusters: contando com o proxy DNS para resolver nomes de domínio de serviço de outros clusters. Como as redes entre clusters são isoladas umas das outras, elas dependem do tráfego de trânsito de outros clusters. o cluster remoto.
East-west Gateway
Construção de três ambientes ClusterMesh
Crie dois clusters, cluster1 e cluster2, instale o plano de controle do Istio em cada cluster e defina ambos como clusters primários. O cluster cluster1 está na rede network1 e o cluster cluster2 está na rede network2.
3.1 Pré-requisitos
As informações de ambiente para esta compilação são as seguintes: Use Kind para construir um cluster Kubernetes, e a versão do Kind é v0.19.0. A versão do Kubernetes é 1.27.3; a versão do Istio é 1.20.1.
Antes de construir um cluster k8s, certifique-se de que docker kubectl e kind estejam instalados no nó Linux.
Baixe o binário istioctl
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.20.1 TARGET_ARCH=x86_64 sh -
Adicionar cliente istioctl ao caminho
3.2 Instalação do cluster Kubernetes
Os scripts de instalação do cluster cluster1 e cluster2 são os seguintes
#criar-cluster.sh # Este script lida com a criação de vários clusters usando kind e the # capacidade de criar e configurar um registro de contêiner inseguro. definir -o xtrace set -o levantado set -o substantivo set -o pipefail # shellcheck fonte=util.sh NUM_CLUSTERS="${NUM_CLUSTERS:-2}" KIND_IMAGE="${KIND_IMAGE:-}" KIND_TAG="${KIND_TAG:-v1.27.3@sha256:3966ac761ae0136263ffdb6cfd4db23ef8a83cba8a463690e98317add2c9ba72}" SO="$(nome)" função criar clusters() { num_clusters locais=${1} imagem local_arg="" se [[ "${KIND_IMAGE}" ]]; então image_arg="--image=${KIND_IMAGE}" Elif [[ "${KIND_TAG}" ]]; então image_arg="--image=mais gentil/node:${KIND_TAG}" ser for i in $(seq "${num_clusters}"); fazer tipo criar cluster --name "cluster${i}" "${image_arg}" cluster de correção "${i}" eco feito } function fixup-cluster() { local i=${1} # número do cluster se [ "$OS" != "Darwin" ];então # Defina o endereço IP do contêiner como endpoint da API kube para que os clusters alcancem os servidores da API kube em outros clusters. docker_ip local docker_ip=$(docker inspecionar --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "cluster${i}-control-plane") kubectl config set-cluster "kind-cluster${i}" --server="https://${docker_ip}:6443" ser # Simplifique o nome do contexto configuração kubectl renomear contexto "kind-cluster${i}" "cluster${i}" } echo "Criando ${NUM_CLUSTERS} clusters" criar clusters "${NUM_CLUSTERS}" kubectl configuração use-context cluster1 echo "O tipo CIDR é $(docker network inspecionar -f '{{$map := index .IPAM.Config 0}}{{index $map "Subnet"}}' kind)" eco "Concluído"
Durante o processo de instalação do cluster acima, para que o istiod acesse apiserver
o endereço do outro cluster, kube-apiserver
o endereço do cluster é definido como o endereço do nó mestre. Por ser um cluster implantado por tipo, os nós mestres dos dois clusters são essencialmente contêineres executando o docker no mesmo host.
Confirme se cluster1 e cluster2 estão prontos
3.3 Use MetalLB para alocar IP externo para o gateway
Como o tipo é usado para implantar vários clusters, a criação do gateway istio norte-sul e do gateway leste-oeste requer a criação do serviço LoadBalencer, ambos os quais exigem o uso de IP externo. Aqui, metalLB é usado para realizar a distribuição e anúncio de endereços IP de LB.
Consulte como construir um cluster usando o segmento de sub-rede do nó: implantar no modo metalLB L2. 172.18.0.0/16
lista de configuração metalLB em cluster1: metallb-config-1.yaml
### para cluster1 ##Configure IPAddressPool para alocação de endereços lbip. No modo L2, o endereço ippool e o nó de trabalho podem estar na mesma sub-rede. versão api: metallb.io/v1beta1 tipo: IPAddressPool metadados: nome: primeiro pool namespace: sistema metallb especificação: endereços: - 172.18.1.230-172.18.1.240 --- ##Configurar L2Advertisement para anúncio de endereço versão api: metallb.io/v1beta1 tipo: L2Advertisement metadados: nome: primeiro-adv namespace: sistema metallb especificação: IPAddressPools: - primeira piscina
Lista de configuração metalLB no cluster cluster2: metallb-config-2.yaml
### para cluster2 ##Configure IPAddressPool para alocação de endereços lbip. No modo L2, o endereço ippool e o nó de trabalho podem estar na mesma sub-rede. versão api: metallb.io/v1beta1 tipo: IPAddressPool metadados: nome: segundo pool namespace: sistema metallb especificação: endereços: - 172.18.1.241-172.18.1.252 --- ##Configurar L2Advertisement para anúncio de endereço versão api: metallb.io/v1beta1 tipo: L2Advertisement metadados: nome: segundo-adv namespace: sistema metallb especificação: IPAddressPools: - segunda piscina
Instalar usando script
#!/usr/bin/env bash definir -o xtrace set -o levantado set -o substantivo set -o pipefail NUM_CLUSTERS="${NUM_CLUSTERS:-2}" para i em $(seq "${NUM_CLUSTERS}"); fazer echo "Iniciando implantação do metallb no cluster${i}" kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.10/config/manifests/metallb-native.yaml --context "cluster${i}" kubectl criar segredo genérico -n lista de membros do sistema metallb --from-literal=secretkey="$(openssl rand -base64 128)" --context "cluster${i}" ## Aumente o tempo de espera. Se a carga metallb não for implantada, um erro será relatado ao criar IPAddressPool L2Advertisement. dormir 10 kubectl apply -f ./metallb-config-${i}.yaml --context "cluster${i}" eco "----" feito
Confirme o status de implantação do metalLB
Confirme as informações do IPAddressPool:
3.4 Relacionamento de confiança de configuração de CA raiz compartilhada do cluster
Para oferecer suporte à comunicação mTLS segura entre clusters, o modelo de plano de controle múltiplo exige que o plano de controle Istiod de cada cluster use um certificado de CA intermediário emitido pela mesma autoridade de CA para que a Citatel emita certificados para oferecer suporte à autenticação bidirecional TLS entre clusters .
O gateway leste-oeste do Istio (acesso entre clusters) usa roteamento baseado em SNI durante o trabalho. Ele o encaminha automaticamente para o cluster correspondente ao SNI com base no SNI solicitado pelo TLS. Portanto, o acesso entre redes em redes não planas exige que todo o tráfego seja criptografado por TLS.
Insira o certificado e a chave no cluster. O script é o seguinte (o script precisa ser movido para o diretório do pacote de instalação do istio):
#!/usr/bin/env bash definir -o xtrace #set -o levantado set -o substantivo set -o pipefail NUM_CLUSTERS="${NUM_CLUSTERS:-2}" ##Crie um diretório no diretório de nível superior do pacote de instalação do istio para armazenar certificados e chaves. mkdir -p certificados certificados pushd ##Gerar certificado raiz e chave make -f ../tools/certs/Makefile.selfsigned.mk root-ca para i em $(seq "${NUM_CLUSTERS}"); fazer ##Para cada cluster, gere um certificado intermediário e uma chave para a CA do Istio make -f ../tools/certs/Makefile.selfsigned.mk "cluster${i}-cacerts" ##Para cada cluster, crie o namespace istio-system kubectl cria namespace istio-system --context "cluster${i}" ## Para cada cluster, adicione identificação de rede marcando o namespace do sistema istio com a tag topology.istio.io/network kubectl --context="cluster${i}" rótulo namespace istio-system topology.istio.io/network="network${i}" ##Para cada cluster, rotule o nó de trabalho com uma região e uma zona de disponibilidade para facilitar ao istio a implementação de failover regional e balanceamento de carga regional. kubectl --context="cluster${i}" nó de rótulo "cluster${i}-control-plane" topology.kubernetes.io/region="region${i}" kubectl --context="cluster${i}" nó de rótulo "cluster${i}-control-plane" topology.kubernetes.io/zone="zone${i}" #Em cada cluster, crie cacerts privados, usando todos os arquivos de entrada ca-cert.pem, ca-key.pem, root-cert.pem e cert-chain.pem. kubectl excluir cacerts secretos -n istio-system --context "cluster${i}" kubectl cria cacerts genéricos secretos -n istio-system --context "cluster${i}" \ --from-file="cluster${i}/ca-cert.pem" \ --from-file="cluster${i}/ca-key.pem"\ --from-file="cluster${i}/root-cert.pem"\ --from-file="cluster${i}/cert-chain.pem" eco "----" feito
3.5 Instalação da malha de serviço do Istio
Instale a grade istio do plano de controle múltiplo para clusters cluster1 e cluster2.
Defina cluster1 como o cluster principal e execute o seguinte comando no diretório de instalação do istio
gato <<EOF> cluster1.yaml apiVersão: install.istio.io/v1alpha1 tipo: IstioOperator especificação: valores: global: ID da malha: malha1 multiCluster: ##Habilitar configuração de vários clusters clusterName: cluster1 #Especifique o nome do cluster k8s rede: rede1 #Especifique o identificador de rede exploração madeireira: nível: depuração EOF
Defina cluster2 como o cluster principal e execute o seguinte comando no diretório de instalação do istio
gato <<EOF> cluster2.yaml apiVersão: install.istio.io/v1alpha1 tipo: IstioOperator especificação: valores: global: ID da malha: malha2 multiCluster: ##Habilitar configuração de vários clusters clusterName: cluster2 #Especifique o nome do cluster k8s rede: rede2 #Especifique o identificador de rede exploração madeireira: nível: depuração EOF
#!/usr/bin/env bash definir -o xtrace set -o levantado set -o substantivo set -o pipefail SO="$(nome)" NUM_CLUSTERS="${NUM_CLUSTERS:-2}" para i em $(seq "${NUM_CLUSTERS}"); fazer echo "Iniciando implantação do istio no cluster${i}" istioctl instalar --force --context="cluster${i}" -f "cluster${i}.yaml" echo "Gerar gateway leste-oeste no cluster${i}" ## Instale gateways leste-oeste em cada cluster. amostras bash/multicluster/gen-eastwest-gateway.sh \ --mesh "mesh${i}" --cluster "cluster${i}" --network "rede${i}" | \ istioctl --context="cluster${i}" instalar -y -f - eco feito
Execute o script para instalar e implantar o istio
Aguarde um pouco até que a instalação seja concluída
Você pode descobrir que as informações de IP externo usadas pelo gateway em cada cluster são o endereço no IPPool definido pelo metalLB configurado.3.6 Abertura de serviços no portal leste-oeste
Como os clusters estão em redes diferentes, precisamos abrir todos os serviços (*.local) nos gateways leste-oeste de ambos os clusters. Embora este gateway seja público na Internet, os serviços por trás dele só podem ser acessados por serviços com certificados mTLS confiáveis, como se estivessem na mesma rede. Execute os seguintes comandos para expor serviços em ambos os clusters:
apiVersão: networking.istio.io/v1beta1 tipo: Gateway metadados: nome: gateway de rede cruzada especificação: seletor: istio: eastwestgateway # Gateway dedicado para tráfego leste-oeste servidores: - porta: número: 15443 # Já declarado nome: tls protocolo: TLS tls: mode: AUTO_PASSTHROUGH # O modo de funcionamento do gateway leste-oeste é TLS AUTO_PASSTHROUGH anfitriões: - "*.local" # Expõe todos os serviços
Aplique a configuração de gateway acima em cada cluster separadamente:
kubectl -n istio-system --context=cluster${i} apply -f samples/multicluster/expose-services.yaml
3.7 Configure o segredo para que o istiod possa acessar o cluster remoto apiserver
O istiod em cada cluster k8s precisa listar o Kube-APIServer de outros clusters e usar as credenciais do cluster K8s para criar um objeto secreto para permitir que o Istio acesse o apiserver remoto do Kubernetes.
#!/usr/bin/env bash definir -o xtrace set -o levantado set -o substantivo set -o pipefail SO="$(nome)" NUM_CLUSTERS="${NUM_CLUSTERS:-2}" para i em $(seq "${NUM_CLUSTERS}"); fazer para j em $(seq "${NUM_CLUSTERS}"); fazer se [ "$i" -ne "$j" ] então echo "Habilitar descoberta de endpoint entre cluster${i} e cluster${j}" se ["$OS" == "Darwin"] então # Defina o endereço IP do contêiner como endpoint da API kube para que os clusters alcancem os servidores da API kube em outros clusters. docker_ip=$(docker inspeciona -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "cluster${i}-control-plane") istioctl criar-segredo remoto \ --context="cluster${i}" \ --server="https://${docker_ip}:6443"\ --name="cluster${i}" | \ kubectl aplicar --validate=false --context="cluster${j}" -f - outro istioctl criar-segredo remoto \ --context="cluster${i}" \ --name="cluster${i}" | \ kubectl aplicar --validate=false --context="cluster${j}" -f - ser ser feito feito
Execute o script acima: o segredo remoto é criado.
Verifique o log do istiod e descubra que o cluster remoto já está monitorado.
Quatro práticas de gerenciamento de tráfego multicluster do Istio
Crie um namespace de amostra para cada cluster e configure a injeção automática secundáriaExemplo de namespace kubectl create --context=cluster1 Exemplo de namespace kubectl create --context=cluster2 rótulo kubectl --context=amostra de namespace cluster1 \ istio-injection = habilitado rótulo kubectl --context=amostra de namespace cluster2 \ istio-injection = habilitado kubectl aplicar --context=cluster1 \ -f amostras/helloworld/helloworld.yaml \ -l serviço=helloworld -n amostra kubectl aplicar --context=cluster2 \ -f amostras/helloworld/helloworld.yaml \ -l serviço=helloworld -n amostra
Implante diferentes versões de serviços em clusters diferentes
Implante o aplicativo helloworld-v1 no cluster1:kubectl aplicar --context=cluster1 \ -f amostras/helloworld/helloworld.yaml \ -l versão=v1 -n amostraImplante o aplicativo helloworld-v2 no cluster2:
kubectl aplicar --context=cluster2 \ -f amostras/helloworld/helloworld.yaml \ -l versão=v2 -n amostraImplantar cliente de teste
kubectl aplicar --context=cluster1 \ -f amostras/sleep/sleep.yaml -n amostra kubectl aplicar --context=cluster2 \ -f amostras/sleep/sleep.yaml -n amostra
Confirme se a instância de carregamento foi implantada com sucesso e o arquivo secundário foi injetado
4.1 Verifique o tráfego entre clusters
Use o Sleep pod para chamar repetidamente o serviço HelloWorld. Para confirmar se o balanceamento de carga está funcionando conforme esperado, o serviço HelloWorld precisa ser chamado em todos os clusters.
Envie uma solicitação ao serviço HelloWorld do pod Sleep no cluster1
Envie uma solicitação ao serviço HelloWorld do pod Sleep no cluster2
4.3 Verifique o acesso do gateway
Acesse o servidor Helloworld através do gateway
Crie recursos istio, como virtualservice e gateway. A lista de configuração é a seguinte.
# helloworld-gateway.yaml apiVersão: networking.istio.io/v1beta1 tipo: Gateway metadados: nome: helloworld-gateway especificação: seletor: istio: ingressgateway # usa o controlador padrão do istio servidores: - porta: número: 80 nome: http protocolo: HTTP anfitriões: - "*" --- apiVersão: networking.istio.io/v1beta1 tipo: VirtualService metadados: nome: Olá mundo especificação: anfitriões: - "*" entradas: - helloworld-gateway http: - corresponder: - tipo: exato: /olá rota: - destino: anfitrião: Olá mundo porta: número: 5000
Nota: Esta configuração precisa ser aplicada a ambos os clusters
O efeito de acesso é o seguinte:
4.3 Verifique o balanceamento de carga regional
Para obter um controle mais refinado sobre o tráfego, defina os pesos das duas regiões como 80% e 20%, respectivamente, e use DestinationRule para configurar a distribuição de peso . region1 -> zone1
region1 -> zone2
# localidade-lb-peso.yaml apiVersão: networking.istio.io/v1beta1 tipo: DestinationRule metadados: nome: Olá mundo namespace: amostra especificação: host: helloworld.sample.svc.cluster.local política de tráfego: pool de conexão: http: maxRequestsPerConnection: 1 balanceador de carga: simples: ROUND_ROBIN localidadeLbConfiguração: habilitado: verdadeiro distribuir: - de: região1/* para: "região1/*": 80 "região2/*": 20 - de: região2/* para: "região2/*": 80 "região1/*": 20 detecção de outlier: Erros 5xx consecutivos: 1 intervalo: 1s baseEjectionTime: 1m
Nota: Esta configuração precisa ser aplicada a ambos os clusters
Envie uma solicitação ao serviço HelloWorld do cluster1 através do gateway
Envie uma solicitação ao serviço HelloWorld do cluster2 através do gateway
4.4 Verifique o failover regional
Quando várias instâncias de serviço são implantadas em diversas regiões/regiões, se a instância de serviço em uma determinada região/região não estiver disponível, o tráfego poderá ser transferido para instâncias de serviço em outras regiões/regiões para obter failover regional, garantindo assim a alta disponibilidade do serviço.
# localidade-lb-failover.yaml apiVersão: networking.istio.io/v1beta1 tipo: DestinationRule metadados: nome: Olá mundo namespace: amostra especificação: host: helloworld.sample.svc.cluster.local política de tráfego: pool de conexão: http: maxRequestsPerConnection: 1 # Desative o HTTP Keep-Alive e force cada solicitação HTTP a usar uma nova política de conexão balanceador de carga: simples: ROUND_ROBIN localityLbSetting: # Configuração de balanceamento de carga regional, após ativar a detecção de outliers, ela é ativada por padrão. habilitado: verdadeiro failover: # Estratégia de failover regional - de: região1 para: região2 - de: região2 para: região1 detecção de outlier: consecutivo5xxErrors: 1 # 1 erro 5xx consecutivo intervalo: 1s # Intervalo de detecção 1s baseEjectionTime: 1m #Tempo de ejeção básico 1m
Nota: Esta configuração precisa ser aplicada a ambos os clusters
Envie uma solicitação ao serviço HelloWorld do cluster1 através do gateway
Simule uma falha e configure manualmente a versão Helloworld V1 no cluster cluster1 para falhar.
Acesse novamente, a detecção de falhas entra em vigor, aciona o failover e verifica se a versão na resposta é sempre v2, o que significa que estamos acessando o serviço helloworld na região 2, conseguindo assim o failover regional.
A premissa do failover é que quando todas as instâncias da região atual estiverem indisponíveis, ele será transferido para a região atual. Caso contrário, o tráfego será enviado para outras instâncias disponíveis na região atual.
Cinco observações
As referências são as seguintes:
-
comunidade de código aberto istio (instruções de instalação para arquitetura multiprimária entre redes): https://istio.io/latest/zh/docs/setup/install/multicluster/multi-primary_multi-network/
-
referência de script de cluster de instalação tipo: https://github.com/cnych/multi-cluster-istio-kind/tree/main/kind-create
-
Referência de gerenciamento de certificados multicluster: https://istio.io/latest/zh/docs/tasks/security/cert-management/plugin-ca-cert/
Clique para seguir e conhecer as novas tecnologias da Huawei Cloud o mais rápido possível~
A primeira grande atualização de versão do JetBrains 2024 (2024.1) é de código aberto. Até a Microsoft planeja pagar por isso. Por que ainda está sendo criticado por ser de código aberto? [Recuperado] O back-end do Tencent Cloud travou: um grande número de erros de serviço e nenhum dado após o login no console. A Alemanha também precisa ser "controlável de forma independente". O governo estadual migrou 30.000 PCs do Windows para o Linux deepin-IDE e finalmente conseguiu inicialização! O Visual Studio Code 1.88 foi lançado. Bom rapaz, a Tencent realmente transformou o Switch em uma "máquina de aprendizagem pensante". A área de trabalho remota RustDesk inicia e reconstrói o cliente Web. O banco de dados de terminal de código aberto do WeChat baseado em SQLite, WCDB, recebeu uma grande atualização.