Post

Criando uma rede de aplicativos multicloud com Skupper

Referências e tecnologias utilizadas:

  1. https://skupper.io
  2. https://minikube.sigs.k8s.io
  3. Repositório com os Códigos
  4. Qpid-dispatch
  5. ActiveMQ
  6. Kubectl
  7. Kubernetes
  8. MTLS
  9. Open-source
  10. Skupper-router
  11. Skupper

Ferramentas

  • Um computador com o minikube [2] instalado;
  • Um terminal para executar os comandos;
  • kubectl > 1.15 [6] ou mais nova.

Descrição da solução

O Skupper [1] é uma ferramenta que permite conectar dois ou mais ambientes de cloud de uma maneira não intrusiva e segura. Tais ambientes podem ser de diferentes provedores de serviço em nuvem como: AWS, GCP, AZURE entre outras, e, inclusive, clusters kubernetes nativos.

tl;dr

Para quem está começando com cloud:

O Skupper é uma ferramenta que permite conectar diferentes ambientes de computação em nuvem de maneira segura e sem complicações. Imagine que você tem duas salas diferentes, cada uma com seu próprio conjunto de ferramentas. Skupper é como uma porta segura que permite que essas salas “conversem” entre si, compartilhando ferramentas conforme necessário. Isso é útil quando você tem diferentes partes de um aplicativo rodando em diferentes lugares, mas elas precisam trabalhar juntas como se estivessem no mesmo lugar.

Para quem tem algum conheciemento de cloud:

O Skupper é uma solução de rede de serviço para Kubernetes que permite a comunicação segura e fácil entre clusters. Ele cria uma camada de rede virtual que conecta pods em diferentes clusters como se estivessem na mesma rede local. Isso é feito sem a necessidade de privilégios de administrador do cluster e sem a necessidade de expor serviços à Internet pública. Além disso, o Skupper não é intrusivo com sua aplicação, pois não cria side-cars ou outros containers dentro dos Pods. Ele é open-source e oferece criptografia de ponta a ponta usando certificados digitais.

Para quem gosta de escovar bits:

O Skupper pode ser dividido em duas partes: o skupper-router e o control-plane chamado skupper-service-controller. O skupper-router é um roteador de rede de serviço baseado no Qpid-dispatch [4] e no ActiveMQ [5]. O skupper-service-controller é um controlador Kubernetes que gerencia o skupper-router e fornece uma API para configurar e gerenciar a rede de serviço. Existem outros containers que são usados para configurar e gerenciar o skupper-router, mas eles são apenas auxiliares e não são necessários para o funcionamento do Skupper. Mas isso vai ficar para outro post.


Solução

Hello World

Esse exemplo consiste em dois serviços:

1. Frontend

  • Um serviço de backend que expõe um endpoint /api/hello. Que tem como resposta Oi, <seu-nome>. Eu sou <meu-nome> (<nome-pod>). O deploy será feito no namespace confi_oeste;

2. Backend

  • Um serviço de frontend que expõe um endpoint /api/hello que faz uma chamada para o serviço de backend e retorna a resposta, mas nesse caso o serviço esta rodando em outro namespace chama config_leste, este por sua vez pode estar em outro cluster ou namespace.

Por que usar o Skupper?

Com o Skupper, você pode colocar o back-end em um cluster e o front-end em outro e manter a conectividade entre os dois serviços sem expor o back-end à Internet pública.

Detalhes:

  1. Não é necessário ter privilégios de administrador do cluster, já que a solução é no nível do namespace;
  2. Não é intrusivo com a sua aplicação, pois não cria side-cars ou outros containers dentro dos Pods;
  3. É open-source;
  4. Você pode conectar, em seu cluster, serviços externos como: Bancos de dados, aplicações legadas e ainda de alta criticidade;
  5. Criptografado de ponta a ponta usando certificados digitais;
  6. Baixa curva de aprenddizagem.
  7. MTLS [9] por padrão. MTLS é um protocolo de segurança que garante que a comunicação entre dois pontos seja feita de maneira segura e criptografada.
  8. Utilização de certificados próprios caso necessário, ou seja, você pode usar os certificados da sua empresa ou gerar novos certificados para o Skupper ( que é o padrão e são criados automaticamente).

Agora vamos preparar nosso ambiente de teste, que consiste no seguinte:

  • Um serviço de backend que está rodando em um namespace que vai prover a lógica para outro serviço de frontend que obviamente está e outro namespace*.
  • Nesse caso, cada serviço está rodando em namespaces diferentes, mas o mesmo exemplo pode (e deve) ser testado com provedores diferentes.

1. Nesse exemplo vamos utilizar dois namespaces chamados:

1.1. config_oeste onde ficará o frontend. Lembre-se de abrir uma aba do seu terminal para cada namespace

1
export KUBECONFIG=~/.kube/config-oeste

1.2. config_leste onde ficará o backend agora, no outro terminal:

1
export KUBECONFIG=~/.kube/config-leste

Obs: Você pode usar o nome que quiser para os namespaces, mas lembre-se de usar o mesmo nome no arquivo de configuração do skupper.

2. Configurando cada namespace:

2.1.config_oeste:

1
2
kubectl create namespace oeste
kubectl config set-context --current --namespace oeste

2.2.config_leste:

1
2
kubectl create namespace leste
kubectl config set-context --current --namespace leste

3. Instalando o Skupper:

Você possui algumas maneiras de instalar o skupper, como por exemplo:

4. Instaçação do CLI do Skupper:

1
 curl https://skupper.io/install.sh | sh

5. Iniciando o skupper nos dois namespaces:

5.1.config_oeste:

1
skupper init

5.2.config_leste:

1
skupper init

6. Conectando os namespaces:

A criação de um link requer o uso de dois comandos skupper em conjunto: skupper token create e skupper link create.

O comando skupper token create gera um token secreto que significa permissão para criar um link. O token também carrega os detalhes do link. Em seguida, em um namespace remoto, o comando skupper link create usa o token para criar um link para o namespace que o gerou.

Nota: O token de link é realmente um segredo. Qualquer pessoa que tenha o token pode vincular ao seu namespace. Certifique-se de que apenas aqueles em quem você confia tenham acesso a ele. Porém sua utilização pode ser controlada por número de usos e tempo de vida. Veja a documentação do skupper [1] para mais detalhes.

6.1. Criando o token no namespace config_oeste:

1
2
skupper token create ~/secret.token
Token written to ~/secret.token
1
skupper link create ~/secret.token

7. Fazendo o deploy do frontend e do backend:

7.1. Applicando o YAML para fazer o deploy do frontend no namespace config_oeste:

1
2
kubectl create deployment frontend --image quay.io/skupper/hello-world-frontend
deployment.apps/frontend created

7.2. Applicando o YAML para fazer o deploy do backend no namespace config_leste:

1
2
kubectl create deployment backend --image quay.io/skupper/hello-world-backend --replicas 3
deployment.apps/backend created

8. Expondo os serviços de backend:

Agora que os serviços estão rodando, vamos expor os serviços para que possamos acessá-los. Nesse caso, vamos expor o serviço de backend para que o frontend possa acessá-lo, independente de onde ele esteja rodando.

8.1. Expondo o serviço de backend no namespace config_leste:

1
2
skupper expose deployment/backend --port 8080
deployment backend exposed as backend

9. Expondo os serviços de frontend:

Agora que os serviços estão rodando, vamos expor os serviços para que possamos acessá-los. Nesse caso, vamos expor o serviço de frontend para que possamos acessá-lo, independente de onde ele esteja rodando.

9.1. Expondo o serviço de frontend no namespace config_oeste:

1
2
kubectl expose deployment frontend --port 8080 --type LoadBalancer
service/frontend exposed

10. Testando a aplicação:

Agora que os serviços estão rodando, vamos testar a aplicação. Nesse caso, vamos acessar o serviço de frontend e verificar se ele consegue acessar o serviço de backend. Para isso, vamos fazer uma chamada para o endpoint /api/health do serviço de frontend e verificar se ele consegue acessar o serviço de backend.

10.1.config_oeste:

1
2
3
4
5
6
kubectl get service/frontend
NAME       TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
frontend   LoadBalancer   10.103.232.28   <external-ip>   8080:30407/TCP   15s

curl http://<external-ip>:8080/api/health
OK

11. Apagando tudo:

Pronto! Agora que você já testou o Skupper, vamos apagar tudo para que você possa testar novamente ou fazer outras experiências.

11.1. Apagando tudo no namespace config_oeste:

1
2
3
skupper delete
kubectl delete service/frontend
kubectl delete deployment/frontend

11.2. Apagando tudo no namespace config_leste:

1
2
skupper delete
kubectl delete deployment/backend

Resumo

Este exemplo localiza os serviços de front-end e back-end em namespaces diferentes, em clusters diferentes. Normalmente isso significa que eles não tem como se comunicar, a menos que sejam expostos à Internet pública.

A introdução do Skupper em cada namespace nos permite criar uma rede de aplicativos virtuais que pode conectar serviços em diferentes clusters. Qualquer serviço exposto na rede de aplicativos é representado como um serviço local em todos os namespaces vinculados.

O serviço de back-end está localizado no leste, mas o serviço de front-end no oeste pode “vê-lo” como se fosse local. Quando o front-end envia uma solicitação ao back-end, o Skupper encaminha a solicitação para o namespace em que o back-end está sendo executado e roteia a resposta de volta ao front-end.

Nâo foi necessário expor o serviço de back-end à Internet pública. O Skupper criou uma rede de aplicativos que conecta os serviços em diferentes clusters. O serviço de back-end está localizado no leste, mas o serviço de front-end no oeste pode “vê-lo” como se fosse local. Quando o front-end envia uma solicitação ao back-end, o Skupper encaminha a solicitação para o namespace em que o back-end está sendo executado e roteia a resposta de volta ao front-end.

Nenhuma VPN ou conexão Layer 3 foi necessária. O Skupper cria uma rede de aplicativos que conecta os serviços em diferentes clusters. O serviço de back-end está localizado no leste, mas o serviço de front-end no oeste pode “vê-lo” como se fosse local. Quando o front-end envia uma solicitação ao back-end, o Skupper encaminha a solicitação para o namespace em que o back-end está sendo executado e roteia a resposta de volta ao front-end.

Esta postagem está licenciada sob CC BY 4.0 pelo autor.