Use APISIX, Prometheus e KEDA para escalar aplicações elasticamente no Kubernetes

Jintao Zhang

Jintao Zhang

February 17, 2023

Technology

Introdução

A quantidade de tráfego que entra em uma aplicação varia de tempos em tempos. Por exemplo, uma aplicação de compras online é muito mais movimentada durante a temporada de festas do que em dias normais. Ser capaz de ajustar a capacidade da aplicação com base no tráfego proporcionará experiências e serviços muito melhores aos usuários.

Apache APISIX é um gateway de API de alta performance nativo da nuvem que pode fornecer métricas significativas para determinar se as aplicações precisam ser dimensionadas. Ele é um middleware que processa todo o tráfego enviado para as aplicações upstream e, portanto, pode coletar dados de tráfego durante o processo.

Para realizar o dimensionamento elástico, o KEDA será usado como controlador, e o Prometheus será usado para buscar as métricas fornecidas pelo APISIX.

usando KEDA para autodimensionamento

Como Usar o Prometheus Scaler no KEDA

KEDA é um autodimensionador baseado em eventos no Kubernetes, que pode configurar vários scalers. Neste artigo, o Prometheus scaler será usado para obter as métricas expostas pelo APISIX.

Implantar o KEDA

A implantação do KEDA é relativamente simples, basta adicionar o repositório Helm correspondente e instalá-lo.

(MoeLove) ➜ helm repo add kedacore https://kedacore.github.io/charts
"kedacore" foi adicionado aos seus repositórios
(MoeLove) ➜ helm repo update kedacore
Aguarde enquanto buscamos as últimas atualizações dos seus repositórios de gráficos...
...Atualização do repositório "kedacore" concluída com sucesso
Atualização concluída. ⎈Feliz Helm!⎈
(MoeLove) ➜ helm install keda kedacore/keda --namespace keda --create-namespace
NAME: keda
ÚLTIMA IMPLANTAÇÃO: Qui Jan 19 00:01:00 2023
NAMESPACE: keda
STATUS: implantado
REVISÃO: 1
SUÍTE DE TESTES: Nenhum

Após a instalação, o Pod tem um status Running, indicando que foi instalado com sucesso.

(MoeLove) ➜ kubectl -n keda get pods
NAME                                               READY   STATUS    RESTARTS   AGE
keda-operator-metrics-apiserver-6d4db7dcff-ck9qg   1/1     Running   0          36s
keda-operator-5dd4748dcd-k8jjz                     1/1     Running   0          36s

Implantar o Prometheus

Aqui usamos o Prometheus Operator para implantar o Prometheus. O Prometheus Operator pode nos ajudar a implantar rapidamente a instância do Prometheus no Kubernetes e adicionar as regras de monitoramento por meio de configuração declarativa.

Complete a instalação do Prometheus Operator seguindo os passos abaixo.

(MoeLove) ➜ https://github.com/prometheus-operator/prometheus-operator/releases/download/v0.62.0/bundle.yaml
(MoeLove) ➜ kubectl apply --server-side -f bundle.yaml
customresourcedefinition.apiextensions.k8s.io/alertmanagerconfigs.monitoring.coreos.com aplicado no lado do servidor
customresourcedefinition.apiextensions.k8s.io/alertmanagers.monitoring.coreos.com aplicado no lado do servidor
customresourcedefinition.apiextensions.k8s.io/podmonitors.monitoring.coreos.com aplicado no lado do servidor
customresourcedefinition.apiextensions.k8s.io/probes.monitoring.coreos.com aplicado no lado do servidor
customresourcedefinition.apiextensions.k8s.io/prometheuses.monitoring.coreos.com aplicado no lado do servidor
customresourcedefinition.apiextensions.k8s.io/prometheusrules.monitoring.coreos.com aplicado no lado do servidor
customresourcedefinition.apiextensions.k8s.io/servicemonitors.monitoring.coreos.com aplicado no lado do servidor
customresourcedefinition.apiextensions.k8s.io/thanosrulers.monitoring.coreos.com aplicado no lado do servidor
clusterrolebinding.rbac.authorization.k8s.io/prometheus-operator aplicado no lado do servidor
clusterrole.rbac.authorization.k8s.io/prometheus-operator aplicado no lado do servidor
deployment.apps/prometheus-operator aplicado no lado do servidor
serviceaccount/prometheus-operator aplicado no lado do servidor
service/prometheus-operator aplicado no lado do servidor

Em seguida, use o seguinte como configuração para o Prometheus e aplique-o ao cluster Kubernetes.

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: prometheus
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus
rules:
- apiGroups: [""]
  resources:
  - nodes
  - nodes/metrics
  - services
  - endpoints
  - pods
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources:
  - configmaps
  verbs: ["get"]
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses
  verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
  verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus
subjects:
- kind: ServiceAccount
  name: prometheus
  namespace: default
---
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  name: prometheus
spec:
  serviceAccountName: prometheus
  serviceMonitorSelector:
    matchLabels:
      app: apisix
  serviceMonitorNamespaceSelector:
    matchLabels:
      team: apisix
  resources:
    requests:
      memory: 400Mi
  enableAdminAPI: false
---
apiVersion: v1
kind: Service
metadata:
  name: prometheus
spec:
  type: LoadBalancer
  ports:
  - name: web
    port: 9090
    protocol: TCP
    targetPort: web
  selector:
    prometheus: prometheus

Após aplicar ao cluster Kubernetes, você pode ver que uma instância do Prometheus foi criada no namespace default. Como configuramos o Prometheus com TYPE LoadBalancer, os usuários podem acessar diretamente o Prometheus através do IP público do LoadBalancer.

(MoeLove) ➜ kubectl get svc
NAME                  TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)          AGE
kubernetes            ClusterIP      10.43.0.1       <none>         443/TCP          96m
prometheus-operator   ClusterIP      None            <none>         8080/TCP         92m
prometheus-operated   ClusterIP      None            <none>         9090/TCP         41m
prometheus            LoadBalancer   10.43.125.194   216.6.66.66    9090:30099/TCP   41m

Como Implantar o Gateway de API e Habilitar o Monitoramento

Em seguida, implante o controlador de Ingress do APISIX e use o Prometheus para coleta de métricas.

O método é semelhante para usuários que usam apenas o APISIX em vez do controlador de Ingress do APISIX. Não explicaremos isso separadamente aqui.

Aqui, o Helm é usado para implantação, e o controlador de Ingress do APISIX e o APISIX podem ser implantados simultaneamente no cluster.

(MoeLove) ➜ helm repo add apisix https://charts.apiseven.com
"apisix" já existe com a mesma configuração, pulando
(MoeLove) ➜ helm repo update apisix
Aguarde enquanto buscamos as últimas atualizações dos seus repositórios de gráficos...
...Atualização do repositório "apisix" concluída com sucesso
Atualização concluída. ⎈Feliz Helm!⎈
(MoeLove) ➜ helm upgrade --install apisix apisix/apisix --create-namespace  --namespace apisix --set gateway.type=LoadBalancer --set ingress-controller.enabled=true --set ingress-controller.config.apisix.serviceNamespace=apisix
Release "apisix" foi atualizado. Feliz Helm!
NAME: apisix
ÚLTIMA IMPLANTAÇÃO: Qui Jan 19 02:11:23 2023
NAMESPACE: apisix
STATUS: implantado
REVISÃO: 1
SUÍTE DE TESTES: Nenhum
NOTAS:
1. Obtenha a URL da aplicação executando estes comandos:
     OBSERVAÇÃO: Pode levar alguns minutos para que o IP do LoadBalancer esteja disponível.
           Você pode acompanhar o status executando 'kubectl get --namespace apisix svc -w apisix-gateway'
  export SERVICE_IP=$(kubectl get svc --namespace apisix apisix-gateway --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}")
  echo http://$SERVICE_IP:80

Em seguida, habilite o plugin do Prometheus no APISIX. Consulte os dois documentos a seguir para métodos de configuração específicos e parâmetros relacionados.

Uma vez habilitado, o Prometheus pode capturar as métricas expostas pelo APISIX criando um recurso ServiceMonitor.

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: example-app
  labels:
    app: apisix
spec:
  selector:
    matchLabels:
      app: apisix
  endpoints:
  - port: web

Verificar a Capacidade de Dimensionamento Elástico da Aplicação

Primeiro, crie uma aplicação.

(MoeLove) ➜ kubectl create deploy httpbin --image=kennethreitz/httpbin --port=80
deployment.apps/httpbin criado
(MoeLove) ➜ kubectl expose deploy httpbin --port 80

Crie as seguintes regras de roteamento e aplique-as ao cluster Kubernetes para encaminhar as solicitações através do APISIX.

apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  name: httpserver-route
spec:
  http:
  - name: rule1
    match:
      hosts:
      - local.httpbin.org
      paths:
      - /*
    backends:
       - serviceName: httpbin
         servicePort: 80

Em seguida, crie um ScaledObject do KEDA e configure as configurações relacionadas ao Prometheus.

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: prometheus-scaledobject
  namespace: default
spec:
  scaleTargetRef:
    name: httpbin
  triggers:
  - type: prometheus
    metadata:
      serverAddress: http://prometheus.default.svc:9090
      metricName: apisix_http_status
      threshold: '10'
      query: sum(rate(apisix_http_status{route="httpserver-route"}[1m]))

A configuração acima significa que sum(rate(apisix_http_status{route="httpserver-route"}[1m])) será usada como expressão de consulta, e se o resultado atingir 10, a expansão começará. (A configuração aqui é apenas para fins de demonstração, por favor, modifique-a de acordo com sua própria situação). Em seguida, fazemos solicitações contínuas ao serviço httpbin através do curl.

Mais tarde, se verificarmos os pods da aplicação, você verá que ela foi autodimensionada para dois pelo KEDA.

(MoeLove) ➜ kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
httpbin-d46d778d7-chtdw   1/1     Running   0          12m
httpbin-d46d778d7-xanbj   1/1     Running   0          10s

Quando a aplicação fica ociosa após algum tempo, descobriremos que o número de pods foi automaticamente reduzido de volta para uma instância.

(MoeLove) ➜ kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
httpbin-d46d778d7-chtdw   1/1     Running   0          32m

Resumo

O KEDA usa o Prometheus como um scaler para coletar as métricas expostas pelo APISIX. Como todo o tráfego passa primeiro pelo APISIX, obter estatísticas no lado do APISIX será muito mais simples e conveniente.

Quando o volume de solicitações de negócios aumenta, a aplicação será automaticamente expandida, e quando o volume de solicitações de negócios diminui, a aplicação será automaticamente contraída.

Esse método pode aliviar operações manuais de expansão/redução em muitos ambientes de produção para garantir a melhor experiência do usuário.

Tags: