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: