Redian新闻
>
如何使用Kubernetes实现应用程序的弹性伸缩

如何使用Kubernetes实现应用程序的弹性伸缩

公众号新闻

作者张晋涛,API7.ai 云原生技术专家,Apache APISIX PMC 成员,Apache APISIX Ingress Controller 项目维护者。


介绍 



通常情况下,每个应用可以承载的压力都是固定的,我们可以通过提前进行压测来了解单应用程序副本的负载能力。如果在业务高峰,或者业务的请求压力增加时候,对应用进行横向扩容可以保证更好的为用户提供服务。

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

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


KEDA 中如何使用 Prometheus 实现伸缩 


KEDA[1] 是一个 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®[2]

  • How to access Apache APISIX Prometheus metrics on Kubernetes | Apache APISIX®[3]

开启后,便可以通过创建 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 侧进行数据统计更加简单方便。

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


[1] KEDA: https://keda.sh/

[2] prometheus plugins | Apache APISIX®: https://apisix.apache.org/docs/apisix/plugins/prometheus/

[3] How to access Apache APISIX Prometheus metrics on Kubernetes | Apache APISIX®: https://apisix.apache.org/docs/ingress-controller/tutorials/how-to-access-Apache-APISIX-Prometheus-Metrics-on-k8s/


往期推荐



开源的文件传输工具,简单好用

用Edge下载Chrome?微软“拉横幅”回应:达咩!

Ambient:Rust编写的高性能多人游戏引擎



这里有最新开源资讯、软件更新、技术干货等内容

点这里 ↓↓↓ 记得 关注✔ 标星⭐ 哦

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
豆瓣评分8.9!300页Kubernetes学习手册,全是核心知识!一款利器 ,持续分析 Kubernetes 中服务的性能Medium的Kubernetes基础设施今年第一个版本 Kubernetes 1.27,发布啦!揭秘 ChatGPT 背后的技术栈:OpenAI 如何将 Kubernetes 扩展到了 7500 个节点一文读懂Kubernetes存储设计疫情一波未平一波又起如何逐步安装 Kubernetes(k8s)指标服务器 | Linux 中国帮助大语言模型集成到应用程序的「Fixie」公司获得1700万美元融资|Chat AI脸书iOS应用程序的十年历程Kubernetes 上 Java 应用的最佳实践Endless OS 5.0:带有 Wayland 和丰富应用程序的最佳 GNOME 桌面 | Linux 中国如何优雅限制 Kubernetes 集群中文件描述符与线程数量楼下说“明年可能是美国对中国发起总攻的时刻”,我当然乐见,可是无论如何都都感受不到美国在准备什么涅?帮助大语言模型集成到应用程序的「Fixie」公司获得1700万美元融资|早起看早期破茧成蝶 - Serverless Kubernetes 的思考与征程(二)报告称Kubernetes 安全大量使用开源解决方案不谈战争谈音乐——普罗科菲耶夫(3)2022年回顾:Kubernetes盛行之年这个世界会好吗用 Tekton 在 Kubernetes 中编写你的第一条 CI/CD 流水线 | Linux 中国谷歌云推出配置管理仪表板,简化 Kubernetes 集群管理在混合云下,我们将Kubernetes与Fluid结合后性能提升了30%手把手教你基于 Kubernetes 实现 CI/CD 配置Kubernetes Operator 最佳实践硬核!Kubernetes 网络排错“狂飙”级指南,运维请收好15 个 Kubernetes 最佳实践Kubernetes 中 Ceph、LINSTOR、Mayastor 和 Vitastor 存储性能对比为Kubernetes集群部署一个ChatGPT机器人Kubernetes 调查报告:配置不当可能导致安全问题从修复 Kubernetes 集群中,我学到了什么使用 Kubespray 安装 Kubernetes 集群 | Linux 中国详解使用Dex实现Kubernetes身份验证被国内全网404的网易视频如何使用机器学习来有效管理 Kubernetes 资源
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。