Use APISIX, Prometheus e KEDA para escalar aplicações elasticamente no Kubernetes
February 17, 2023
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.
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.
- prometheus plugins | Apache APISIX®
- How to access Apache APISIX Prometheus metrics on Kubernetes | Apache APISIX®
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.