Uma Breve Visão sobre a Kubernetes Gateway API
September 7, 2022
Em um dos meus posts recentes no blog, descrevi várias maneiras de acessar pods do Kubernetes. É possível acessar um pod por meio de seu IP, mas os pods são naturalmente transitórios. A maneira nominal é configurar um Service
: seu IP é estável, e o trabalho do Kubernetes é manter o mapeamento entre um Service
e seus pods subjacentes atualizado. Diferentes tipos de serviços estão disponíveis: apenas internos, NodePort
para finalmente permitir o acesso de fora do cluster, e LoadBalancer
que depende de um componente de terceiros - geralmente, um provedor de nuvem. Por fim, mencionei o objeto Ingress
, que também permite roteamento.
Deliberadamente, deixei de fora o novo recurso, a API Gateway. Este é o tema deste post.
De Ingress para a API Gateway
O acesso externo aos pods do Kubernetes passou por várias etapas evolutivas, e.g., o Ingress
é a resposta para o problema da falta de roteamento no LoadBalancer
. O maior problema do Ingress
é sua dependência de objetos "proprietários". Como lembrete, aqui está o trecho para criar roteamento usando o Apache APISIX:
apiVersion: apisix.apache.org/v2beta3 #1 kind: ApisixRoute #1 metadata: name: apisix-route spec: http: - name: left match: paths: - "/left" backends: - serviceName: left servicePort: 80 - name: right match: paths: - "/right" backends: - serviceName: right servicePort: 80
- Objetos proprietários
Objetos proprietários são um problema durante a migração. Embora a migração de um provedor para outro seja provavelmente incomum, ela deve ser o mais tranquila possível. Ao usar objetos proprietários, você primeiro precisa mapear do objeto antigo para os novos. As chances são de que não seja um mapeamento um-para-um. Em seguida, você precisa traduzir a especificação para o novo modelo: é provável que seja um projeto completo.
A ideia por trás da API Gateway é ter uma separação clara entre objetos padrão e a implementação proprietária.
A API Gateway
A API Gateway é um projeto de código aberto gerenciado pela comunidade SIG-NETWORK. É uma coleção de recursos que modelam a rede de serviços no Kubernetes. Esses recursos -
GatewayClass
,Gateway
,HTTPRoute
,TCPRoute
,Service
, etc - visam evoluir a rede de serviços do Kubernetes por meio de interfaces expressivas, extensíveis e orientadas a funções que são implementadas por muitos fornecedores e têm amplo suporte da indústria.
A definição acima também menciona uma preocupação organizacional: diferentes funções devem gerenciar um conjunto diferente de objetos.
Imagem de gateway-api.sigs.k8s.io
De fato, as preocupações de um operador de cluster e de um desenvolvedor são bastante diferentes. É bastante semelhante aos antigos servidores de aplicativos Java EE, que ofereciam uma especificação organizada em torno de funções: desenvolvedores, implantadores e operadores. Na minha opinião, a maior diferença é que a especificação estava focada principalmente na experiência do desenvolvedor; o resto era responsabilidade dos implementadores. A API Gateway parece se preocupar com todas as personas.
Configurando o acesso ao pod via API Gateway
Vamos substituir o Ingress
que configuramos anteriormente pela API Gateway. Várias etapas são necessárias.
Instalar as novas CRDs do Gateway
k apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v0.5.0/standard-install.yaml
Instalar uma implementação
Vou usar o Apache APISIX. Alternativamente, o site do SIG mantém uma lista de implementações.
helm install apisix apisix/apisix \ --namespace ingress-apisix \ --create-namespace \ --devel \ #1 --set gateway.type=NodePort \ #2 --set gateway.http.nodePort=30800 \ #2 --set ingress-controller.enabled=true \ #2 --set ingress-controller.config.kubernetes.enableApiGateway=true \ #3 --set ingressPublishService="ingress-apisix/apisix-gateway" #4
- Sem a opção
--devel
, o Helm instala a versão mais recente, que não funciona com a API Gateway - O Gateway precisa ser acessível fora do cluster de qualquer maneira
- A mágica acontece aqui!
- Voltarei a isso mais tarde
Vamos verificar se tudo está funcionando:
k get all -n ingress-apisix
NAME READY STATUS RESTARTS AGE pod/apisix-5fc9b45c69-cf42m 1/1 Running 0 14m #1 pod/apisix-etcd-0 1/1 Running 0 14m #2 pod/apisix-etcd-1 1/1 Running 0 14m #2 pod/apisix-etcd-2 1/1 Running 0 14m #2 pod/apisix-ingress-controller-6f8bd94d9d-wkzfn 1/1 Running 0 14m #3 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) service/apisix-admin ClusterIP 10.96.69.19 <none> 9180/TCP service/apisix-etcd ClusterIP 10.96.226.79 <none> 2379/TCP,2380/TCP service/apisix-etcd-headless ClusterIP None <none> 2379/TCP,2380/TCP service/apisix-gateway NodePort 10.96.101.224 <none> 80:30800/TCP #4 service/apisix-ingress-controller ClusterIP 10.96.141.230 <none> 80/TCP
- O próprio Apache APISIX
- O Apache APISIX armazena sua configuração no
etcd
. O chart agenda três pods por padrão, uma boa prática para lidar com falhas em sistemas distribuídos - Controlador do Apache APISIX: um controlador do Kubernetes é um loop de controle que move o estado existente em direção ao estado desejado
- Serviço do Gateway do Apache APISIX: é o
Service
NodePort
que instalamos via o Helm Chart. É também o nome que referenciamos durante a instalação do Helm Chart -ingressPublishService
Neste ponto, a infraestrutura está pronta.
Declarar a implementação do Gateway
Como mencionei acima, a API faz uma separação clara entre a especificação e a implementação. No entanto, precisamos vinculá-la de alguma forma. Essa é a responsabilidade do objeto GatewayClass
:
apiVersion: gateway.networking.k8s.io/v1alpha2 #1 kind: GatewayClass #2 metadata: name: apisix-gateway-class #3 spec: controllerName: apisix.apache.org/gateway-controller #4
- Não usamos a versão mais recente de propósito, pois o Apache APISIX usa esta versão. Esteja ciente de que ela evoluirá no (próximo) futuro
- Objeto
GatewayClass
- Nomeie como quiser; no entanto, usaremos isso mais tarde para referenciar a classe do gateway
- O nome do controlador depende da implementação. Aqui, estamos usando o do Apache APISIX.
Observe que o GatewayClass
tem um escopo em todo o cluster. Esse modelo nos permite declarar diferentes implementações da API Gateway e usá-las em paralelo dentro do mesmo cluster.
Criar o Gateway
Com o Apache APISIX, é bastante direto:
apiVersion: gateway.networking.k8s.io/v1alpha2 #1 kind: Gateway #2 metadata: name: apisix-gateway spec: gatewayClassName: apisix-gateway-class #3 listeners: #4 - name: http protocol: HTTP port: 80
- Mesmo namespace que acima
- Objeto
Gateway
- Referencie a classe do gateway declarada anteriormente
- Permite algumas restrições neste nível para que o operador do cluster possa evitar usos indesejados
Aviso: A API Gateway especifica a opção de alterar dinamicamente a porta no lado do operador. No momento da escrita, a alocação de portas do Apache APISIX é estática. O plano é torná-la dinâmica no futuro. Por favor, inscreva-se neste problema do GitHub para acompanhar o progresso.
Rotas, rotas, rotas por toda parte
Até agora, tudo era infraestrutura; finalmente podemos configurar o roteamento.
Quero o mesmo roteamento do post anterior; um ramo /left
e um right
. Vou pular o último por questão de brevidade.
apiVersion: gateway.networking.k8s.io/v1alpha2 #1 kind: HTTPRoute #2 metadata: name: left spec: parentRefs: - name: apisix-gateway #3 rules: - matches: #4 - path: #4 type: PathPrefix #4 value: /left backendRefs: #5 - name: left #5 port: 80 #5
- Mesmo namespace que acima
- Objeto
HTTPRoute
- Referencie o
Gateway
criado acima - Regras de correspondência. No nosso caso, correspondemos a um prefixo de caminho, mas muitas regras estão disponíveis. Você pode corresponder com base em um parâmetro de consulta, em um cabeçalho, etc.
- O "upstream" para encaminhar. Definimos o
Service
left
no post anterior do blog.
Verificando se funciona
Agora que configuramos nossas rotas, podemos verificar se está funcionando.
curl localhost:30800/left
Quando instalamos o chart do Helm, dissemos ao Apache APISIX para criar um serviço NodePort
na porta 30800
. Portanto, podemos usar a porta para acessar o serviço fora do cluster.
left
Conclusão
Muitas alternativas estão disponíveis para acessar um pod de fora do cluster. A CNCF adicionou a maioria delas para melhorar a anterior.
A API Gateway é a proposta mais recente nesse sentido. A especificação está em andamento e os produtos estão em diferentes estágios de implementação. Por esse motivo, é muito cedo para basear sua produção na API. No entanto, você provavelmente deve acompanhar o progresso, pois ela está destinada a ser uma melhoria considerável em relação às abordagens anteriores.
O código-fonte completo para este post pode ser encontrado no GitHub.
Para ir mais longe: