乐趣区

关于后端:如何使用-Kubernetes-实现应用程序的弹性伸缩

本篇文章利用 KEDA 应用 Prometheus 采集 APISIX 裸露进去的指标作为伸缩器,进而实现基于流量的应用程序弹性伸缩。

作者张晋涛,API7.ai 云原生工程师,Apache APISIX PMC。

原文链接

介绍

通常状况下,每个利用能够承载的压力都是固定的,咱们能够通过提前进行压测来理解单应用程序正本的负载能力。如果在业务顶峰,或者业务的申请压力减少时候,对利用进行横向扩容能够保障更好的为用户提供服务。

Apache APISIX 是一个高性能的云原生 API 网关,所有发送到上游应用程序的流量都将通过 APISIX,所以咱们能够依据 APISIX 提供的流量指标,来判断应用程序是否须要进行弹性伸缩。

本文中将应用 KEDA 作为弹性伸缩的管制组件,用 Prometheus 采集 APISIX 提供的流量指标来进行利用的弹性伸缩。

KEDA 中如何应用 Prometheus 实现伸缩

KEDA 是一个 Kubernetes 中基于事件的主动伸缩组件,能够配置多种伸缩器。本文将应用 Prometheus 作为伸缩器,获取 APISIX 裸露进去的 metrics(指标)并进行应用程序的扩缩容。

部署 KEDA

KEDA 的部署比较简单,增加对应的 Helm repo 并进行装置即可。

(MoeLove) ➜ helm repo add kedacore https://kedacore.github.io/charts
"kedacore" has been added to your repositories
(MoeLove) ➜ helm repo update kedacore
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "kedacore" chart repository
Update Complete. ⎈Happy Helming!⎈
(MoeLove) ➜ helm install keda kedacore/keda --namespace keda --create-namespace
NAME: keda
LAST DEPLOYED: Thu Jan 19 00:01:00 2023
NAMESPACE: keda
STATUS: deployed
REVISION: 1
TEST SUITE: None

在装置实现后,Pod 处于 Running 状态,示意曾经失常装置。

(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

接下来部署 Prometheus。

部署 Prometheus

此处咱们应用 Prometheus Operator 来进行 Prometheus 的部署。Prometheus Operator 能够帮忙咱们在 Kubernetes 中疾速部署 Prometheus 实例,以及通过申明式配置的形式增加监控规定。

通过如下步骤实现 Prometheus Operator 的装置。

(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 serverside-applied
customresourcedefinition.apiextensions.k8s.io/alertmanagers.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/podmonitors.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/probes.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/prometheuses.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/prometheusrules.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/servicemonitors.monitoring.coreos.com serverside-applied
customresourcedefinition.apiextensions.k8s.io/thanosrulers.monitoring.coreos.com serverside-applied
clusterrolebinding.rbac.authorization.k8s.io/prometheus-operator serverside-applied
clusterrole.rbac.authorization.k8s.io/prometheus-operator serverside-applied
deployment.apps/prometheus-operator serverside-applied
serviceaccount/prometheus-operator serverside-applied
service/prometheus-operator serverside-applied

而后应用如下配置作为 Prometheus 实例的配置,而后将其利用到 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

利用后,则能够看到在 default namespace 下创立了 Prometheus 实例。因为上述配置中创立了 LoadBalancer 类型的 Service,所以能够间接通过 LoadBalancer 的公网 IP 进行 Prometheus 的拜访。

(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

如何部署网关并开启监控

接下来部署 APISIX Ingress,并应用 Prometheus 进行 metrics 采集。

如果用户没有应用 APISIX Ingress,而是仅仅应用了 APISIX,操作方法也是相似的。 这里不再离开介绍。

此处应用 Helm 进行部署,能够同时将 APISIX Ingress controller 和 APISIX 部署到集群中。

(MoeLove) ➜ helm repo add apisix https://charts.apiseven.com
"apisix" already exists with the same configuration, skipping
(MoeLove) ➜ helm repo update apisix
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "apisix" chart repository
Update Complete. ⎈Happy Helming!⎈
(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" has been upgraded. Happy Helming!
NAME: apisix
LAST DEPLOYED: Thu Jan 19 02:11:23 2023
NAMESPACE: apisix
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:
     NOTE: It may take a few minutes for the LoadBalancer IP to be available.
           You can watch the status of by running '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

接下来开启 APISIX 的 prometheus 插件,具体的配置办法和相干参数能够参考如下两篇文档。

  • prometheus plugins | Apache APISIX®
  • How to access Apache APISIX Prometheus metrics on Kubernetes | Apache APISIX®

开启后,便能够通过创立 ServiceMonitor 资源,让 Prometheus 抓取 APISIX 暴露出的 metrics 了。

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

验证利用弹性伸缩能力

此处将创立一个示例利用。

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

创立如下路由规定,利用到 Kubernetes 集群后,则可通过 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

接下来,创立 KEDA 的 ScaledObject,配置 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]))

上述参数示意通过 sum(rate(apisix_http_status{route="httpserver-route"}[1m])) 作为查问表达式,如果后果能达到 10, 则开始进行扩容(此处配置仅用于本文中的示例应用,生产环境请依照理论状况进行批改)。

而后,咱们通过 curl 向 httpbin 服务收回间断申请,再次查看示例利用的 Pod 曾经变成两个,证实 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

待一段时间无申请后,再次查看发现 Pod 的数量主动缩减为一个,证实主动缩容也实现了。

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

总结

本篇文章利用 KEDA 应用 Prometheus 采集 APISIX 裸露进去的指标作为伸缩器,进而实现基于流量的应用程序弹性伸缩。因为所有流量都会先通过 APISIX,所以在 APISIX 侧进行数据统计更加简略不便。

在业务申请量上来后,应用程序将进行自动化的扩容,当业务低谷的时候,则会主动的缩容。这能够在缓解很多生产环境下的手动扩 / 缩容操作,以保障用户的服务体验。

对于 API7.ai 与 APISIX

API7.ai 是一家提供 API 解决和剖析的开源根底软件公司,于 2019 年开源了新一代云原生 API 网关 — APISIX 并捐献给 Apache 软件基金会。尔后,API7.ai 始终踊跃投入反对 Apache APISIX 的开发、保护和社区经营。与千万贡献者、使用者、支持者一起做出世界级的开源我的项目,是 API7.ai 致力的指标。

退出移动版