Avançar para o conteúdo principal
BlogContentores (Kubernetes, Docker)Escalada de Kubernetes através de Regiões

Escalada de Kubernetes através de Regiões

Gráfico da escala de Kubernetes através das regiões

Este posto faz parte da nossa série de escalas Kubernetes. Registe-se para assistir ao vivo ou aceder à gravação, e ver os nossos outros posts nesta série:

Um desafio interessante com Kubernetes é a distribuição de cargas de trabalho por várias regiões. Embora tecnicamente se possa ter um agrupamento com vários nós localizados em diferentes regiões, isto é geralmente considerado como algo que se deve evitar devido à latência extra.

Uma alternativa popular é implantar um agrupamento para cada região e encontrar uma forma de os orquestrar.

Diagrama representando um aglomerado de Kubernetes com nós em múltiplas regiões (nem sempre uma boa ideia) versus ter um aglomerado em cada região em que precisa de ser implantado (a abordagem mais avançada)
Poderá ter um aglomerado com nós que abranjam várias regiões, ou poderá ter um aglomerado para cada região.

Neste posto, irá:

  1. Criar três clusters: um na América do Norte, um na Europa, e um no Sudeste Asiático.
  2. Criar um quarto agrupamento que actuará como orquestrador para os outros.
  3. Estabelecer uma rede única a partir das três redes de agrupamento para uma comunicação sem descontinuidades.

Este posto foi programado para trabalhar com Terraform exigindo uma interacção mínima. Pode encontrar o código para isso no GitHub do LearnK8s.

Criação do Cluster Manager

Comecemos pela criação do agrupamento que irá gerir o resto. Os seguintes comandos podem ser utilizados para criar o cluster e guardar o ficheiro kubeconfig.

bash
$ linode-cli lke cluster-create \
 --label cluster-manager \
 --region eu-west \
 --k8s_version 1.23
 
$ linode-cli lke kubeconfig-view "insert cluster id here" --text | tail +2 | base64 -d > kubeconfig-cluster-manager

É possível verificar se a instalação é bem sucedida:

bash
$ kubectl get pods -A --kubeconfig=kubeconfig-cluster-manager

Excelente!

No gestor de clusters, irá instalar Karmada, um sistema de gestão que lhe permite executar as suas aplicações nativas de nuvens em múltiplos clusters e nuvens Kubernetes. Karmada tem um plano de controlo instalado no gestor de clusters e o agente instalado em todos os outros clusters.

O plano de controlo tem três componentes:

  1. E API Servidor;
  2. Um Gestor de Controlador; e
  3. Um Agendador
Diagrama do plano de controlo do Karmada, constituído por um servidor Karmada API gestor do controlador, etcd e programador.
O plano de controlo da Karmada.

Se estes parecem familiares, é porque o plano de controlo Kubernetes apresenta os mesmos componentes! Karmada teve de copiá-los e aumentá-los para trabalhar com vários aglomerados.

Já chega de teoria. Vamos ao código.
Você usará o Helm para instalar o servidor Karmada API do Karmada. Vamos adicionar o repositório Helm com:

bash
$ helm repo add karmada-charts https://raw.githubusercontent.com/karmada-io/karmada/master/charts
$ helm repo list
NAME            URL
karmada-charts   https://raw.githubusercontent.com/karmada-io/karmada/master/charts

Como o servidor Karmada API tem de ser acessível a todos os outros clusters, terá de

  • expô-lo a partir do nó; e
  • certificar-se de que a ligação é de confiança.

Portanto, vamos recuperar o endereço IP do nó que acolhe o avião de controlo:

bash
kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type==\"ExternalIP\")].address}' \
 --kubeconfig=kubeconfig-cluster-manager

Agora pode instalar o avião de controlo Karmada com:

bash
$ helm install karmada karmada-charts/karmada \
 --kubeconfig=kubeconfig-cluster-manager \
 --create-namespace --namespace karmada-system \
 --version=1.2.0 \
 --set apiServer.hostNetwork=false \
 --set apiServer.serviceType=NodePort \
 --set apiServer.nodePort=32443 \
 --set certs.auto.hosts[0]="kubernetes.default.svc" \
 --set certs.auto.hosts[1]="*.etcd.karmada-system.svc.cluster.local" \
 --set certs.auto.hosts[2]="*.karmada-system.svc.cluster.local" \
 --set certs.auto.hosts[3]="*.karmada-system.svc" \
 --set certs.auto.hosts[4]="localhost" \
 --set certs.auto.hosts[5]="127.0.0.1" \
 --set certs.auto.hosts[6]="<insert the IP address of the node>"

Quando a instalação estiver concluída, pode obter o kubeconfig para se ligar ao Karmada API com:

bash
kubectl get secret karmada-kubeconfig \
 --kubeconfig=kubeconfig-cluster-manager \
 -n karmada-system \
 -o jsonpath={.data.kubeconfig} | base64 -d > karmada-config

Mas espere, porquê outro ficheiro kubeconfig?

O Karmada API foi projetado para substituir o Kubernetes padrão API padrão, mas ainda mantém todas as funcionalidades com as quais você está acostumado. Por outras palavras, pode criar implementações que abrangem vários clusters com o kubectl.

Antes de testar o Karmada API e o kubectl, deve corrigir o ficheiro kubeconfig. Por padrão, o kubeconfig gerado só pode ser usado de dentro da rede do cluster.

No entanto, pode substituir a seguinte linha para que funcione:

yaml
apiVersion: v1
kind: Config
clusters:
 - cluster:
     certificate-authority-data: LS0tLS1CRUdJTi…
     insecure-skip-tls-verify: false
     server: https://karmada-apiserver.karmada-system.svc.cluster.local:5443 # <- this works only in the cluster
   name: karmada-apiserver
# truncated

Substitui-la pelo endereço IP do nó que recuperou anteriormente:

yaml
apiVersion: v1
kind: Config
clusters:
 - cluster:
     certificate-authority-data: LS0tLS1CRUdJTi…
     insecure-skip-tls-verify: false
     server: https://<node's IP address>:32443 # <- this works from the public internet
   name: karmada-apiserver
# truncated

Óptimo, está na hora de testar o Karmada.

Instalar o Agente Karmada

Emitir o seguinte comando para recuperar todos os destacamentos e todos os aglomerados:

bash
$ kubectl get clusters,deployments --kubeconfig=karmada-config
No resources found

Não é de surpreender que não haja destacamentos nem agrupamentos adicionais. Vamos adicionar mais alguns aglomerados e ligá-los ao plano de controlo Karmada.

Repetir os seguintes comandos três vezes:

bash
linode-cli lke cluster-create \
 --label <insert-cluster-name> \
 --region <insert-region> \
 --k8s_version 1.23
 
linode-cli lke kubeconfig-view "insert cluster id here" --text | tail +2 | base64 -d > kubeconfig-<insert-cluster-name>

Os valores devem ser os seguintes:

  • Nome do aglomerado euregião eu-wesficheiro t e kubeconfig kubeconfig-eu
  • Nome do aglomerado apregião ap-south e ficheiro kubeconfig kubeconfig-ap
  • Nome do aglomerado usregião us-west e ficheiro kubeconfig kubeconfig-us

Pode verificar se os aglomerados são criados com sucesso:

bash
$ kubectl get pods -A --kubeconfig=kubeconfig-eu
$ kubectl get pods -A --kubeconfig=kubeconfig-ap
$ kubectl get pods -A --kubeconfig=kubeconfig-us

Agora é tempo de fazê-los aderir ao aglomerado Karmada.

A Karmada utiliza um agente em cada outro aglomerado para coordenar a implantação com o plano de controlo.

Diagrama do agente Karmada que se liga ao plano de controlo do cluster (API servidor, gestor de controladores e programador) no cluster Kubernetes 1.
O agente Karmada.

Irá utilizar o Helm para instalar o agente Karmada e ligá-lo ao gestor do cluster:

bash
$ helm install karmada karmada-charts/karmada \
 --kubeconfig=kubeconfig-<insert-cluster-name> \
 --create-namespace --namespace karmada-system \
 --version=1.2.0 \
 --set installMode=agent \
 --set agent.clusterName=<insert-cluster-name> \
 --set agent.kubeconfig.caCrt=<karmada kubeconfig certificate authority> \
 --set agent.kubeconfig.crt=<karmada kubeconfig client certificate data> \
 --set agent.kubeconfig.key=<karmada kubeconfig client key data> \
 --set agent.kubeconfig.server=https://<insert node's IP address>:32443 \

Terá de repetir o comando acima três vezes e inserir as seguintes variáveis:

  • O nome do agrupamento. Este é eu, apou us
  • A autoridade certificadora do gestor do agrupamento. Pode encontrar este valor na página karmada-config ficheiro under clusters[0].cluster['certificate-authority-data'].
    É possível descodificar o valor de base64.
  • Os dados do certificado de cliente do utilizador. Este valor pode ser encontrado na página karmada-config arquivo em users[0].user['client-certificate-data'].
    Pode descodificar o valor a partir da base64.
  • Os dados do certificado de cliente do utilizador. Este valor pode ser encontrado na página karmada-config arquivo em users[0].user['client-key-data'].
    Pode descodificar o valor a partir da base64.
  • O endereço IP do nó que acolhe o avião de controlo Karmada.

Para verificar se a instalação está completa, pode emitir o seguinte comando:

bash
$ kubectl get clusters --kubeconfig=karmada-config
NAME   VERSION   MODE   READY
eu     v1.23.8   Pull   True
ap     v1.23.8   Pull   True
us     v1.23.8   Pull   True

Excelente!

Implementação da Orquestração Multicluster Deployment com Políticas Karmada

Com a configuração actual, submete uma carga de trabalho à Karmada, que depois a distribuirá pelos outros agrupamentos.

Vamos testar isto, criando um destacamento:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 name: hello
spec:
 replicas: 3
 selector:
   matchLabels:
     app: hello
 template:
   metadata:
     labels:
       app: hello
   spec:
     containers:
       - image: stefanprodan/podinfo
         name: hello
---
apiVersion: v1
kind: Service
metadata:
 name: hello
spec:
 ports:
   - port: 5000
     targetPort: 9898
 selector:
   app: hello

Pode enviar a implementação para o servidor Karmada API com:

bash
$ kubectl apply -f deployment.yaml --kubeconfig=karmada-config

Este desdobramento tem três réplicas - serão estas distribuídas igualmente pelos três aglomerados?

Vamos verificar:

bash
$ kubectl get deployments --kubeconfig=karmada-config
NAME    READY   UP-TO-DATE   AVAILABLE
hello   0/3     0            0

Porque é que a Karmada não está a criar as Pods?

Vamos descrever o destacamento:

bash
$ kubectl describe deployment hello --kubeconfig=karmada-config
Name:                   hello
Namespace:              default
Selector:               app=hello
Replicas:               3 desired | 0 updated | 0 total | 0 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Events:
 Type     Reason             From               Message
 ----     ------             ----               -------
 Warning  ApplyPolicyFailed  resource-detector  No policy match for resource

A Karmada não sabe o que fazer com os destacamentos porque não especificou uma política.

O programador Karmada utiliza políticas para atribuir cargas de trabalho a clusters.

Vamos definir uma política simples que atribua uma réplica a cada agrupamento:

yaml
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
 name: hello-propagation
spec:
 resourceSelectors:
   - apiVersion: apps/v1
     kind: Deployment
     name: hello
   - apiVersion: v1
     kind: Service
     name: hello
 placement:
   clusterAffinity:
     clusterNames:
       - eu
       - ap
       - us
   replicaScheduling:
     replicaDivisionPreference: Weighted
     replicaSchedulingType: Divided
     weightPreference:
       staticWeightList:
         - targetCluster:
             clusterNames:
               - us
           weight: 1
         - targetCluster:
             clusterNames:
               - ap
           weight: 1
         - targetCluster:
             clusterNames:
               - eu
           weight: 1

Pode submeter a política ao agrupamento com:

bash
$ kubectl apply -f policy.yaml --kubeconfig=karmada-config

Vamos inspeccionar os destacamentos e as cápsulas:

bash
$ kubectl get deployments --kubeconfig=karmada-config
NAME    READY   UP-TO-DATE   AVAILABLE
hello   3/3     3            3
 
$ kubectl get pods --kubeconfig=kubeconfig-eu
NAME                    READY   STATUS    RESTARTS
hello-5d857996f-hjfqq   1/1     Running   0
 
$ kubectl get pods --kubeconfig=kubeconfig-ap
NAME                    READY   STATUS    RESTARTS
hello-5d857996f-xr6hr   1/1     Running   0
 
$ kubectl get pods --kubeconfig=kubeconfig-us
NAME                    READY   STATUS    RESTARTS
hello-5d857996f-nbz48   1/1     Running   0
Mapa gráfico mostrando os aglomerados de Kubernetes localizados em cada região (Fremont, CA, Londres, e Singapura)
A Karmada atribuiu uma cápsula a cada aglomerado.

A Karmada atribuiu uma cápsula a cada agrupamento porque a sua política definiu um peso igual para cada agrupamento.

Vamos dimensionar o desdobramento para 10 réplicas com:

bash
$ kubectl scale deployment/hello --replicas=10 --kubeconfig=karmada-config

Se inspeccionar as cápsulas, poderá encontrar o seguinte:

bash
$ kubectl get deployments --kubeconfig=karmada-config
NAME    READY   UP-TO-DATE   AVAILABLE
hello   10/10   10           10
$ kubectl get pods --kubeconfig=kubeconfig-eu
NAME                    READY   STATUS    RESTARTS
hello-5d857996f-dzfzm   1/1     Running   0
hello-5d857996f-hjfqq   1/1     Running   0
hello-5d857996f-kw2rt   1/1     Running   0
hello-5d857996f-nz7qz   1/1     Running   0
 
$ kubectl get pods --kubeconfig=kubeconfig-ap
NAME                    READY   STATUS    RESTARTS
hello-5d857996f-pd9t6   1/1     Running   0
hello-5d857996f-r7bmp   1/1     Running   0
hello-5d857996f-xr6hr   1/1     Running   0
 
$ kubectl get pods --kubeconfig=kubeconfig-us
NAME                    READY   STATUS    RESTARTS
hello-5d857996f-nbz48   1/1     Running   0
hello-5d857996f-nzgpn   1/1     Running   0
hello-5d857996f-rsp7k   1/1     Running   0

Vamos alterar a política de modo a que os clusters da UE e dos EUA detenham 40% das cápsulas e apenas 20% fiquem para o cluster AP.

yaml
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
 name: hello-propagation
spec:
 resourceSelectors:
   - apiVersion: apps/v1
     kind: Deployment
     name: hello
   - apiVersion: v1
     kind: Service
     name: hello
 placement:
   clusterAffinity:
     clusterNames:
       - eu
       - ap
       - us
   replicaScheduling:
     replicaDivisionPreference: Weighted
     replicaSchedulingType: Divided
     weightPreference:
       staticWeightList:
         - targetCluster:
             clusterNames:
               - us
           weight: 2
         - targetCluster:
             clusterNames:
               - ap
           weight: 1
         - targetCluster:
             clusterNames:
               - eu
           weight: 2

Pode submeter a política com:

bash
$ kubectl apply -f policy.yaml --kubeconfig=karmada-config

Pode observar a distribuição da sua cápsula a mudar em conformidade:

bash
$ kubectl get pods --kubeconfig=kubeconfig-eu
NAME                    READY   STATUS    RESTARTS   AGE
hello-5d857996f-hjfqq   1/1     Running   0          6m5s
hello-5d857996f-kw2rt   1/1     Running   0          2m27s
 
$ kubectl get pods --kubeconfig=kubeconfig-ap
hello-5d857996f-k9hsm   1/1     Running   0          51s
hello-5d857996f-pd9t6   1/1     Running   0          2m41s
hello-5d857996f-r7bmp   1/1     Running   0          2m41s
hello-5d857996f-xr6hr   1/1     Running   0          6m19s
 
$ kubectl get pods --kubeconfig=kubeconfig-us
hello-5d857996f-nbz48   1/1     Running   0          6m29s
hello-5d857996f-nzgpn   1/1     Running   0          2m51s
hello-5d857996f-rgj9t   1/1     Running   0          61s
hello-5d857996f-rsp7k   1/1     Running   0          2m51s
Diagrama cartográfico mostrando vagens distribuídas por regiões de acordo com a política definida pelo controlador Karmada - 40% em Fremont, CA, 40% em Londres, e 20% em Singapura .
As cápsulas são distribuídas de acordo com a política.

Ótimo!

A Karmada apoia várias políticas para distribuir as suas cargas de trabalho. Pode consultar a documentação para casos de utilização mais avançada.

As cápsulas estão a correr nos três grupos, mas como se pode aceder a elas?

Vamos inspeccionar o serviço em Karmada:

bash
$ kubectl describe service hello --kubeconfig=karmada-config
Name:              hello
Namespace:         default
Labels:            propagationpolicy.karmada.io/name=hello-propagation
                  propagationpolicy.karmada.io/namespace=default
Selector:          app=hello
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.105.24.193
IPs:               10.105.24.193
Port:              <unset>  5000/TCP
TargetPort:        9898/TCP
Events:
 Type     Reason                  Message
 ----     ------                  -------
 Normal   SyncSucceed             Successfully applied resource(default/hello) to cluster ap
 Normal   SyncSucceed             Successfully applied resource(default/hello) to cluster us
 Normal   SyncSucceed             Successfully applied resource(default/hello) to cluster eu
 Normal   AggregateStatusSucceed  Update resourceBinding(default/hello-service) with AggregatedStatus successfully.
 Normal   ScheduleBindingSucceed  Binding has been scheduled
 Normal   SyncWorkSucceed         Sync work of resourceBinding(default/hello-service) successful.

O serviço está implantado nos três clusters, mas não estão ligados.

Mesmo que a Karmada possa gerir vários aglomerados, não fornece qualquer mecanismo de rede para assegurar que os três aglomerados estejam ligados. Por outras palavras, o Karmada é uma excelente ferramenta para orquestrar a implantação de agrupamentos, mas é necessário algo mais para garantir que esses agrupamentos possam comunicar uns com os outros.

Conectando Multi Clusters com Istio

O Istio é normalmente utilizado para controlar o tráfego de rede entre aplicações no mesmo cluster. Funciona interceptando todos os pedidos de saída e de entrada e procurando-os através do Envoy.

Diagrama mostrando como os procuradores do Enviado interceptam o tráfego e distribuem para outras cápsulas.
Os procuradores dos enviados interceptam todo o tráfego.

O plano de controlo Istio é responsável pela actualização e recolha de métricas desses procuradores e pode também emitir instruções para desviar o tráfego.

Diagrama mostrando como o avião de controlo Istio pode reconfigurar os procuradores na mosca, e pode ter uma regra para negar o tráfego entre as cápsulas.
Com o Istio, pode definir uma política para gerir o tráfego no seu agrupamento.

Assim, poderia usar o Istio para interceptar todo o tráfego para um determinado serviço e direccioná-lo para um dos três clusters. Esta é a ideia com a configuração do Istio multicluster.

Já chega de teoria - vamos sujar as nossas mãos. O primeiro passo é instalar o Istio nos três clusters.

Embora existam várias formas de instalar o Istio, eu normalmente prefiro o Helm:

bash
$ helm repo add istio https://istio-release.storage.googleapis.com/charts
$ helm repo list
NAME            URL
istio                 https://istio-release.storage.googleapis.com/charts

Pode instalar o Istio nos três clusters com:

bash
$ helm install istio-base istio/base \
 --kubeconfig=kubeconfig-<insert-cluster-name> \
 --create-namespace --namespace istio-system \
 --version=1.14.1

Deve substituir o cluster-name com ap, eu e us e executar o comando para cada um.

O gráfico de base instala sobretudo recursos comuns, tais como Roles e RoleBindings.

A instalação real é embalada no istiod gráfico. Mas antes de prosseguir com isso, tem de configurar a Autoridade Certificadora do Istio (AC) para garantir que os três agrupamentos se possam ligar e confiar uns nos outros.

Num novo directório, clonar o repositório Istio com:

bash
$ git clone https://github.com/istio/istio

Criar um certs pasta e mudar para esse directório:

bash
$ mkdir certs
$ cd certs

Criar o certificado de raiz com:

bash
$ make -f ../istio/tools/certs/Makefile.selfsigned.mk root-ca

O comando gerou os seguintes ficheiros:

  • root-cert.pem: o certificado de raiz gerado
  • root-key.pema chave de raiz gerada
  • root-ca.confa configuração para OpenSSL para gerar o certificado de raiz
  • root-cert.csro CSR gerado para o certificado de raiz

Para cada agrupamento, gerar um certificado intermédio e uma chave para a Autoridade Certificadora do Istio:

bash
$ make -f ../istio/tools/certs/Makefile.selfsigned.mk cluster1-cacerts
$ make -f ../istio/tools/certs/Makefile.selfsigned.mk cluster2-cacerts
$ make -f ../istio/tools/certs/Makefile.selfsigned.mk cluster3-cacerts

Os comandos gerarão os seguintes ficheiros num directório com o nome cluster1, cluster2e cluster3:

bash
$ kubectl create secret generic cacerts -n istio-system \
 --kubeconfig=kubeconfig-<cluster-name>
 --from-file=<cluster-folder>/ca-cert.pem \
 --from-file=<cluster-folder>/ca-key.pem \
 --from-file=<cluster-folder>/root-cert.pem \
 --from-file=<cluster-folder>/cert-chain.pem

Deve executar os comandos com as seguintes variáveis:

| cluster name | folder name |
| :----------: | :---------: |
|      ap      |  cluster1   |
|      us      |  cluster2   |
|      eu      |  cluster3   |

Com os que estão feitos, está finalmente pronto para instalar o istiod:

bash
$ helm install istiod istio/istiod \
 --kubeconfig=kubeconfig-<insert-cluster-name> \
 --namespace istio-system \
 --version=1.14.1 \
 --set global.meshID=mesh1 \
 --set global.multiCluster.clusterName=<insert-cluster-name> \
 --set global.network=<insert-network-name>

Deve-se repetir o comando três vezes com as seguintes variáveis:

| cluster name | network name |
| :----------: | :----------: |
|      ap      |   network1   |
|      us      |   network2   |
|      eu      |   network3   |

Deve também etiquetar o espaço de nomes Istio com uma anotação topológica:

bash
$ kubectl label namespace istio-system topology.istio.io/network=network1 --kubeconfig=kubeconfig-ap
$ kubectl label namespace istio-system topology.istio.io/network=network2 --kubeconfig=kubeconfig-us
$ kubectl label namespace istio-system topology.istio.io/network=network3 --kubeconfig=kubeconfig-eu

É tudo?

Quase.

Trânsito em túnel com um portal Este-Oeste

Ainda precisa:

  • uma porta de entrada para canalizar o tráfego de um aglomerado para o outro; e
  • um mecanismo para descobrir endereços IP noutros clusters.
Diagrama mostrando o Istio multicluster descobrindo os pontos finais e instalando o portal este-oeste entre as cápsulas.
Istio multicluster: descobrir os pontos finais e instalar o portão este-oeste.

Para o portal, pode utilizar o Helm para o instalar:

bash
$ helm install eastwest-gateway istio/gateway \
 --kubeconfig=kubeconfig-<insert-cluster-name> \
 --namespace istio-system \
 --version=1.14.1 \
 --set labels.istio=eastwestgateway \
 --set labels.app=istio-eastwestgateway \
 --set labels.topology.istio.io/network=istio-eastwestgateway \
 --set labels.topology.istio.io/network=istio-eastwestgateway \
 --set networkGateway=<insert-network-name> \
 --set service.ports[0].name=status-port \
 --set service.ports[0].port=15021 \
 --set service.ports[0].targetPort=15021 \
 --set service.ports[1].name=tls \
 --set service.ports[1].port=15443 \
 --set service.ports[1].targetPort=15443 \
 --set service.ports[2].name=tls-istiod \
 --set service.ports[2].port=15012 \
 --set service.ports[2].targetPort=15012 \
 --set service.ports[3].name=tls-webhook \
 --set service.ports[3].port=15017 \
 --set service.ports[3].targetPort=15017 \

Deve-se repetir o comando três vezes com as seguintes variáveis:

| cluster name | network name |
| :----------: | :----------: |
|      ap      |   network1   |
|      us      |   network2   |
|      eu      |   network3   |

Depois, para cada aglomerado, expor um Gateway com o seguinte recurso:

yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
 name: cross-network-gateway
spec:
 selector:
   istio: eastwestgateway
 servers:
   - port:
       number: 15443
       name: tls
       protocol: TLS
     tls:
       mode: AUTO_PASSTHROUGH
     hosts:
       - "*.local"

Pode enviar o ficheiro para os agrupamentos com:

bash
$ kubectl apply -f expose.yaml --kubeconfig=kubeconfig-eu
$ kubectl apply -f expose.yaml --kubeconfig=kubeconfig-ap
$ kubectl apply -f expose.yaml --kubeconfig=kubeconfig-us

Para os mecanismos de descoberta, é necessário partilhar as credenciais de cada agrupamento. Isto é necessário porque os aglomerados não se conhecem uns aos outros.

Para descobrirem outros endereços IP, precisam de aceder a outros clusters e registar esses como possíveis destinos para o tráfego. Para o fazer, é necessário criar um segredo Kubernetes com o ficheiro kubeconfig para os outros clusters.

O Istio utilizará aqueles para se ligar aos outros aglomerados, descobrir os pontos finais e instruir os procuradores do Enviado para encaminhar o tráfego.

Vai precisar de três segredos:

yaml
apiVersion: v1
kind: Secret
metadata:
 labels:
   istio/multiCluster: true
 annotations:
   networking.istio.io/cluster: <insert cluster name>
 name: "istio-remote-secret-<insert cluster name>"
type: Opaque
data:
 <insert cluster name>: <insert cluster kubeconfig as base64>

Deve-se criar os três segredos com as seguintes variáveis:

| cluster name | secret filename |  kubeconfig   |
| :----------: | :-------------: | :-----------: |
|      ap      |  secret1.yaml   | kubeconfig-ap |
|      us      |  secret2.yaml   | kubeconfig-us |
|      eu      |  secret3.yaml   | kubeconfig-eu |

Agora deve submeter os segredos ao agrupamento, prestando atenção para não submeter o segredo AP ao agrupamento AP.

Os comandos devem ser os seguintes:

bash
$ kubectl apply -f secret2.yaml -n istio-system --kubeconfig=kubeconfig-ap
$ kubectl apply -f secret3.yaml -n istio-system --kubeconfig=kubeconfig-ap
 
$ kubectl apply -f secret1.yaml -n istio-system --kubeconfig=kubeconfig-us
$ kubectl apply -f secret3.yaml -n istio-system --kubeconfig=kubeconfig-us
 
$ kubectl apply -f secret1.yaml -n istio-system --kubeconfig=kubeconfig-eu
$ kubectl apply -f secret2.yaml -n istio-system --kubeconfig=kubeconfig-eu

E é tudo!

Está pronto para testar a configuração.

Teste da Rede Multicluster

Vamos criar um destacamento para uma cápsula de dormir.

Irá utilizar esta cápsula para fazer um pedido para a implantação do Olá que criou anteriormente:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 name: sleep
spec:
 selector:
   matchLabels:
     app: sleep
 template:
   metadata:
     labels:
       app: sleep
   spec:
     terminationGracePeriodSeconds: 0
     containers:
       - name: sleep
         image: curlimages/curl
         command: ["/bin/sleep", "3650d"]
         imagePullPolicy: IfNotPresent
         volumeMounts:
           - mountPath: /etc/sleep/tls
             name: secret-volume
     volumes:
       - name: secret-volume
         secret:
           secretName: sleep-secret
           optional: true

Pode criar a implantação com:

bash
$ kubectl apply -f sleep.yaml --kubeconfig=karmada-config

Uma vez que não existe uma política para esta implantação, a Karmada não a processará e deixá-la-á pendente. Pode alterar a política de modo a incluir o destacamento:

yaml
apiVersion: policy.karmada.io/v1alpha1
kind: PropagationPolicy
metadata:
 name: hello-propagation
spec:
 resourceSelectors:
   - apiVersion: apps/v1
     kind: Deployment
     name: hello
   - apiVersion: v1
     kind: Service
     name: hello
   - apiVersion: apps/v1
     kind: Deployment
     name: sleep
 placement:
   clusterAffinity:
     clusterNames:
       - eu
       - ap
       - us
   replicaScheduling:
     replicaDivisionPreference: Weighted
     replicaSchedulingType: Divided
     weightPreference:
       staticWeightList:
         - targetCluster:
             clusterNames:
               - us
           weight: 2
         - targetCluster:
             clusterNames:
               - ap
           weight: 2
         - targetCluster:
             clusterNames:
               - eu
           weight: 1

Pode aplicar a política com:

bash
$ kubectl apply -f policy.yaml --kubeconfig=karmada-config

É possível descobrir com quem a cápsula foi colocada:

bash
$ kubectl get pods --kubeconfig=kubeconfig-eu
$ kubectl get pods --kubeconfig=kubeconfig-ap
$ kubectl get pods --kubeconfig=kubeconfig-us

Agora, assumindo que a cápsula aterrou no agrupamento dos EUA, execute o seguinte comando:

Now, assuming the pod landed on the US cluster, execute the following command:
bash
for i in {1..10}
do
 kubectl exec --kubeconfig=kubeconfig-us -c sleep \
   "$(kubectl get pod --kubeconfig=kubeconfig-us -l \
   app=sleep -o jsonpath='{.items[0].metadata.name}')" \
   -- curl -sS hello:5000 | grep REGION
done

Poderá reparar que a resposta vem de diferentes cápsulas de diferentes regiões!

Trabalho feito!

Para onde ir a partir daqui?

Esta configuração é bastante básica e carece de várias outras características que provavelmente pretende incorporar:

Para recapitular o que cobrimos neste post:

  • usando Karmada para controlar vários clusters;
  • definição de políticas para agendar cargas de trabalho em vários agrupamentos;
  • utilizando o Istio para fazer a ligação em rede de múltiplos clusters; e
  • como Istio intercepta o tráfego e o encaminha para outros aglomerados.

Pode ver um passeio completo da escalada Kubernetes através de regiões, para além de outras metodologias de escalada, registando-se para a nossa série de webinars e assistindo on-demand.


Comentários

Deixe uma resposta

O seu endereço de correio electrónico não será publicado. Os campos obrigatórios estão marcados com *