Kong: uma introdução não tão breve

Kong: uma introdução não tão breve

Photo by Ian Taylor on Unsplash

Introdução da introdução

Kong é um API Gateway e Microservices Management Layer escalável, flexível e de alto desempenho. Ele funciona como uma porta de entrada para suas APIs, unindo diversas interfaces de microsserviços em uma única API. Kong oferece recursos essenciais, como roteamento, autenticação, rate-limiting, analytics e muito mais, através de plugins que são extremamente fáceis de serem instalados e operados.

Neste post, aprenderemos a usar o Kong usando Docker, uma forma fácil de empacotar, distribuir e gerenciar aplicações. Para nossa demonstração, criei um repositório contendo uma estrutura de arquivos e diretórios específicos, bem como um Dockerfile e um arquivo docker-compose.yaml que tornará a configuração do Kong uma brisa.

Instalação

Clone o repositório: https://github.com/fabiano-amaral/kong-api-gateway-quickstart

git clone https://github.com/fabiano-amaral/kong-api-gateway-quickstart.git

Navegue até a pasta do projeto:

cd kong-api-gateway-quickstart

Construa e levante os serviços com Docker Compose:

docker-compose up --build -d

Estrutura do Projeto

A estrutura do nosso projeto Kong em uma pasta de sua preferência é a seguinte:

.
├── certs
├── config
│   ├── plugins
│   │   ├── rate-limit.yaml
│   │   └── README.md
│   └── services
│       ├── example.yaml
│       └── README.md
├── docker-compose.yaml
├── Dockerfile
├── LICENSE.md
├── plugins.yaml
├── README.md
└── scripts
    ├── init-kong.sh
    └── README.md

Dockerfile

Nosso Dockerfile começa com a imagem oficial do Kong 3 e prossegue copiando o arquivo plugins.yaml (esse arquivo criei para facilitar a adição de novos plugins a nossa imagem) para o contêiner e instala os plugins do Kong listados nesse arquivo usando luarocks. Além disso, o script init-kong.sh é copiado para o contêiner e definido como o ponto de entrada.

# Usar a imagem oficial do Kong como base
FROM kong:3

COPY plugins.yaml /plugins.yaml

# Pode ser feio e difícil de entender uma primeira vez
# mas é funcional para add plugins
RUN yq e '.plugins[] | "luarocks install \(.name) \(.version)"' /plugins.yaml | sh

USER root
# Copiar o script para o contêiner e permissão
COPY ./scripts/init-kong.sh /init-kong.sh
RUN chmod +x /init-kong.sh
USER 1000

COPY ./config /etc/kong/config

# Definir o script como o ponto de entrada
ENTRYPOINT ["/init-kong.sh"]

O script init-kong.sh foi mais uma forma de transformar o desenvolvimento local mais próximo de um ambiente produtivo, onde você claramente não quer criar coisas no clickOps, então ele carrega os arquivos das pastas config/plugins e config/services e os configuram no control plane (repare que o data-plane não usa essa imagem customizada) do Kong.

#!/bin/sh

# Para plugins
for file in /etc/kong/config/plugins/*.yaml; do
  kong config db_import $file
done

# Para services
for file in /etc/kong/config/services/*.yaml; do
  kong config db_import $file
done

# Executar o comando original de inicialização do Kong
exec /docker-entrypoint.sh kong docker-start

Docker Compose

O arquivo docker-compose.yaml define vários serviços, incluindo o banco de dados do Kong, o serviço control plane do Kong, o serviço data plane do Kong, um serviço para gerar certificados SSL e um serviço para lidar com migrações do Kong. A comunicação entre o control plane e o data plane é segura (uma exigência do modo hibrido do Kong), usando um certificado SSL gerado no contêiner generate-certs. Não vou entrar em detalhes nas configurações do arquivo, pois elas são bastante autoexplicativas.

version: '3'

volumes:
  certs:

networks:
  kong-net:

services:
  # gera o certificado de comunicação entre data e control plane
  generate-certs:
    image: alpine
    command: sh -c "apk add openssl && openssl req -new -x509 -nodes -newkey ec:<(openssl ecparam -name secp384r1) -keyout /tmp/cluster.key -out /tmp/cluster.crt   -days 1095 -subj "/CN=kong_clustering""
    volumes:
      - certs:/tmp

  kong-migrations:
    image: kong:3
    networks:
        - kong-net
    command: "kong migrations bootstrap"
    environment:
      - KONG_DATABASE=postgres
      - KONG_PG_HOST=kong-database
      - KONG_PG_USER=kong
      - KONG_PG_PASSWORD=kong
    volumes:
      - certs:/certs
    depends_on:
      kong-database:
        condition: service_healthy

  kong-control-plane:
    build: .
    networks:
        - kong-net
    healthcheck:
      test: ["CMD", "kong", "health"]
      interval: 5s
      timeout: 10s
      retries: 10
    environment:
      - KONG_ROLE=control_plane
      - KONG_DATABASE=postgres
      - KONG_PG_HOST=kong-database
      - KONG_PG_USER=kong
      - KONG_PG_PASSWORD=kong
      - KONG_ADMIN_LISTEN=0.0.0.0:8001
      - KONG_CLUSTER_CERT=certs/cluster.crt
      - KONG_CLUSTER_CERT_KEY=certs/cluster.key
      - KONG_ADMIN_GUI_URL=http://localhost:8002
      - KONG_CLUSTER_LISTEN=0.0.0.0:8005
      - KONG_ADMIN_GUI_LISTEN=0.0.0.0:8002
    volumes:
      - certs:/certs
      - ./scripts/init-kong.sh:/init-kong.sh
      - ./config:/etc/kong/config
    ports:
      - 8001:8001
      - 8002:8002
    depends_on:
      generate-certs:
        condition: service_completed_successfully
      kong-migrations:
        condition: service_completed_successfully

  kong-data-plane:
    image: kong:3
    networks:
        - kong-net
    environment:
      - KONG_ROLE=data_plane
      - KONG_DATABASE=off
      - KONG_CLUSTER_CONTROL_PLANE=kong-control-plane:8005
      - KONG_CLUSTER_CERT=certs/cluster.crt
      - KONG_CLUSTER_CERT_KEY=certs/cluster.key
    volumes:
      - certs:/certs
    ports:
      - 8000:8000
      - 8443:8443
    depends_on:
      kong-control-plane:
        condition: service_healthy

  kong-database:
    image: postgres:15-alpine
    networks:
        - kong-net
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "kong"]
      interval: 5s
      timeout: 5s
      retries: 5
    environment:
      POSTGRES_DB: kong
      POSTGRES_USER: kong
      POSTGRES_PASSWORD: kong

Modelo híbrido com Kong

O que é o modelo híbrido?

O modelo híbrido é um recurso do Kong que permite dividir suas instâncias em dois tipos de planos: Control Plane (CP) e Data Plane (DP).

  • Control Plane (CP): É responsável por todo o gerenciamento da sua infraestrutura Kong. Ele mantém a configuração, os plugins e quaisquer outros aspectos que afetem a lógica de roteamento, mas não lida diretamente com o tráfego da API.

  • Data Plane (DP): Este é o plano que efetivamente lida com o tráfego da API. Ele recebe todas as requisições e as roteia com base nas instruções fornecidas pelo Control Plane.

Por que usar o Modelo Híbrido?

  • Escalabilidade: Como o Data Plane e o Control Plane são desacoplados, você pode escalar cada um deles independentemente, de acordo com suas necessidades.

  • Segurança: O Data Plane pode ser exposto à internet, enquanto o Control Plane pode ser mantido em uma rede segura.

  • Gerenciamento Centralizado: Todas as configurações são armazenadas e gerenciadas no Control Plane, tornando mais fácil gerenciar múltiplas instâncias do Data Plane.

Configuração

Serviços e Rotas

Definição de Serviços

Para definir os serviços que o Kong deve gerenciar, você vai utilizar arquivos YAML dentro da pasta config/services/. Cada arquivo deve conter a configuração para um ou mais serviços que você deseja expor via Kong.

Por exemplo, o arquivo config/services/example.yaml pode ter o seguinte conteúdo:

_format_version: "3.0"
_transform: false

services:
- name: meu-servico
  url: https://mockbin.org

Neste exemplo, um serviço chamado meu-servico é definido e aponta para a URL https://mockbin.org. Entenda o serviço como sua API que ficará atrás do API Gateway.

Definição de Rotas

As rotas associadas aos serviços são também configuradas dentro dos arquivos YAML em config/services/. Dentro de cada configuração de serviço, você pode definir múltiplas rotas.

Ajustando o exemplo anterior, o arquivo config/services/example.yaml poderia ser expandido para:

_format_version: "3.0"
_transform: false

services:
- name: meu-servico
  url: https://mockbin.org
  routes:
  - name: rota-para-meu-servico
    paths:
    - "/meu-servico"

Aqui, uma rota chamada rota-para-meu-servico é adicionada ao serviço meu-servico. Qualquer requisição a Kong com o caminho /meu-servico será encaminhada para https://mockbin.org. Rode o projeto com docker compose up e acesse http://localhost:8000/meu-servico no navegador de sua preferência.

Plugins

Instalação de Plugins

O arquivo plugins.yaml na raiz do projeto é utilizado especificamente para a instalação de novos plugins do Kong. Não é usado para ativar ou configurar esses plugins para serviços específicos. Neste arquivo, você deve listar todos os plugins que deseja instalar, bem como as suas versões. Exemplo:

plugins:
  - name: "kong-plugin-rate-limiting"
    version: "2.0.0"

Ao construir sua imagem Docker com este arquivo na raiz, os plugins listados serão instalados.

Ativação e Configuração de Plugins

Para a ativação e configuração de plugins em serviços específicos, você deve utilizar os arquivos YAML dentro da pasta config/plugins/. Cada arquivo YAML nesse diretório deve conter as configurações para um ou mais plugins que você deseja ativar ou configurar.

Por exemplo, um arquivo config/plugins/rate-limit.yaml pode conter:

_format_version: "3.0"
_transform: false

plugins:
- name: rate-limiting
  config:
    second: 5

Esses arquivos são usados para configurar como os plugins funcionarão em relação aos seus serviços, mas não para instalá-los. A instalação, como mencionado, é gerenciada pelo plugins.yaml na raiz do projeto. Existem vários plugins disponíveis no hub da Kong, alguns disponíveis apenas com licenças enterprise.

Resumo

  • Para instalar novos plugins: Use o arquivo plugins.yaml na raiz do projeto.

  • Para configurar e ativar plugins em serviços específicos: Use os arquivos dentro de config/plugins/.

  • Para definir serviços e suas respectivas rotas: Use os arquivos dentro de config/services/.

Essa organização garante que a configuração do seu ambiente Kong seja modular, tornando mais fácil gerenciar serviços e plugins separadamente. E os arquivos da pasta config podem ser usados em conjunto com o decK para criar um fluxo de gitOps para deploy de novas configurações em ambiente produtivo, vale a pena explorar.

Uso

Administração

Uma vez que você tenha inicializado todos os serviços usando o Docker Compose, várias interfaces estarão disponíveis para interação e administração do Kong. A seguir estão as mais relevantes:

  • Kong Admin API: Acessível via http://localhost:8001, esta é a API administrativa que você usará para todas as operações programáticas no Kong. Seja para adicionar novos serviços, rotas ou para ativar plugins, tudo pode ser feito aqui através de chamadas RESTful.

  • Kong Admin GUI: Esta é a interface gráfica do usuário e pode ser acessada através de http://localhost:8002. A GUI oferece uma maneira mais visual e interativa para gerenciar os aspectos do seu gateway API. Ele é especialmente útil para visualizar o fluxo de tráfego, modificar configurações existentes ou adicionar novas funcionalidades de forma mais intuitiva.

Ambas as interfaces são destinadas a administradores e devem ser protegidas adequadamente em ambientes de produção. Se você está apenas começando, a Admin GUI pode ser um excelente ponto de partida para entender como tudo funciona. À medida que você se familiarizar com o sistema, é provável que passe a utilizar a Admin API para integrações mais avançadas e automações.

Consumindo suas APIs públicadas no Kong

Proxy de API do Kong

Após a inicialização bem-sucedida de todos os serviços, o Kong estará pronto para começar a rotear suas solicitações. O ponto de entrada para suas APIs é através do Proxy de API do Kong, que é acessível via http://localhost:8000. Todas as requisições a serem roteadas através do Kong serão enviadas para este endpoint.

O Proxy de API é onde a mágica realmente acontece. Quando uma requisição chega ao proxy, o Kong determina a que serviço a requisição pertence com base nas rotas que você definiu. Em seguida, ele aplica qualquer plugin que você tenha ativado para a rota, o serviço, ou globalmente, antes de encaminhar a requisição ao serviço upstream correspondente.

Aqui estão alguns exemplos de operações que você pode realizar através do Proxy de API:

  • Roteamento de Requisições: Baseado nos caminhos de URL, métodos HTTP, e outros atributos da requisição, o Kong roteará a requisição para o serviço upstream correspondente.

  • Autenticação: Se você ativou um plugin de autenticação, o Kong verificará as credenciais na requisição antes de permitir o acesso ao serviço upstream.

  • Rate Limiting: Se você configurou o rate limiting, o Kong controlará a taxa de requisições para garantir que os limites configurados não sejam excedidos.

  • Logging: Plugins de logging podem ser configurados para registrar as requisições e respostas para ajudar na análise e depuração.

Estas são apenas algumas das muitas funcionalidades que o Kong oferece para ajudar a gerenciar o tráfego de API e garantir que as requisições sejam processadas de forma segura e eficiente. Experimente enviar algumas requisições para http://localhost:8000 e observe como elas são roteadas e processadas com base na configuração do seu Kong.

Conclusão

Com a configuração acima, você tem um ambiente Kong totalmente funcional, pronto para ser expandido com mais serviços, rotas e plugins conforme necessário. O uso do Docker e do Docker Compose facilita a configuração, a execução e o gerenciamento do Kong, tornando-o uma opção atraente para gerenciar suas APIs e microserviços.

Para mais informações e detalhes sobre como expandir e personalizar sua configuração do Kong, você pode referenciar a documentação oficial do Kong. Se chegou até aqui, não esqueça de ativar as notificações e se inscrever no canal :hehe: