什么是 Kubernetes HPA
Kubernetes Horizontal Pod Autoscaler(HPA)是 Kubernetes 的一个自动扩缩容工具,它可以根据 Pod 的 CPU 利用率、内存利用率等指标自动扩缩容 Pod 的数量。HPA 可以帮助我们应对流量波动,提高应用的可用性和稳定性。
什么是 Prometheus
Prometheus 是一种开源的监控解决方案,它可以通过拉取(pull)方式获取应用程序的指标(metrics),并将这些指标存储在本地数据库中。利用 Prometheus 可以对 Kubernetes 中的应用程序进行监控,使我们能够更好的理解应用程序的运行情况,更好地优化应用程序。
HPA 与 Prometheus 如何整合
HPA 与 Prometheus 的整合可以使我们更好地监控应用程序的指标。具体而言,我们可以通过 Prometheus 发现应用程序的指标,HPA 根据这些指标对应用程序进行自动扩缩容。
方式一:基于 Prometheus Operator 的整合
Prometheus Operator 是一个 Kubernetes Operator,它可以自动部署、管理多个 Prometheus 实例和用于服务发现、收集指标的 Exporters。我们可以通过 Prometheus Operator 自动部署启动 Prometheus 服务。同时,Prometheus Operator 支持动态地创建 PrometheusRule 资源,该资源可以指定 Notification 和 Alert 规则,进一步完善监控体系。
可以使用以下 YAML 部署 Prometheus Operator。
// www.javascriptcn.com code example
apiVersion: monitoring.coreos.com/v1
kind: PrometheusOperator
metadata:
name: prometheus-operator
namespace: prometheus-operator
spec:
image: quay.io/prometheus-operator/prometheus-operator:v0.40.0
serviceAccountName: prometheus-operator
serviceAccountNamespace: prometheus-operator
serviceMonitor:
https: true
prometheus:
version: 2.29.2
retention: 12h
serviceAccountName: prometheus
serviceAccountNamespace: prometheus
nodeSelector:
kubernetes.io/os: linux
tolerations:
- key: "node-role.kubernetes.io/master"
effect: "NoSchedule"
- effect: "NoExecute"
operator: "Exists"
alertmanager:
version: 0.22.2
ingress:
enabled: false使用如下命令将上述 YAML 部署到 Kubernetes 中。
kubectl apply -f prometheus-operator.yaml
然后,我们需要定义一个 PrometheusRule 来收集 HPA 与 Prometheus 整合后的指标,如下 YAML。
// www.javascriptcn.com code example
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: hpa
spec:
groups:
- name: "kubernetes"
rules:
- alert: KubeHPAReplicasTooHigh
expr: |
max(avg_over_time(kube_horizontalpodautoscaler_current_replicas{job="{{ .Release.Name }}-kube-state-metrics"}[30m]) / avg_over_time(kube_horizontalpodautoscaler_spec_max_replicas{job="{{ .Release.Name }}-kube-state-metrics"}[30m]))
> 0.9
for: 15m
labels:
severity: warning
annotations:
summary: "{{ .CommonAnnotations.summary }}"
description: "{{ .CommonAnnotations.description }}"使用如下命令将上述 YAML 部署到 Kubernetes 中。
kubectl apply -f prometheus-rule.yaml
最后,我们需要定义一个 Deployment,使用该 Deployment 部署可以自动扩缩容的应用程序,如下 YAML。
// www.javascriptcn.com code example
apiVersion: apps/v1
kind: Deployment
metadata:
name: auto-scaling-app
labels:
app: auto-scaling-app
spec:
replicas: 1
selector:
matchLabels:
app: auto-scaling-app
template:
metadata:
labels:
app: auto-scaling-app
spec:
containers:
- name: auto-scaling-app
image: your-image-repository/auto-scaling-app:latest
ports:
- containerPort: 80
resources:
limits:
cpu: "1"
requests:
cpu: "0.5"
env:
- name: NAME
value: auto-scaling-app
imagePullSecrets:
- name: regcred使用如下命令将上述 YAML 部署到 Kubernetes 中。
kubectl apply -f auto-scaling-app.yaml
方式二:基于 Prometheus Metrics 的整合
除了 Prometheus Operator,Kubernetes 还提供了基于 Prometheus Metrics 的整合方式。该方式需要我们用户实现 /metrics 接口,并将获取到的指标注册到 Prometheus 的 Register 中。之后,我们可以使用 HPA 自动扩缩容应用程序。
下面是一个示例代码:
// www.javascriptcn.com code example
package main
import (
"math/rand"
"net/http"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
cpuLimit = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "app_cpu_limit",
Help: "CPU limit of app in milli-cpu.",
}, []string{"namespace", "pod_name"})
cpuUsage = prometheus.NewGaugeVec(prometheus.GaugeOpts{
Name: "app_cpu_usage",
Help: "CPU usage of app in milli-cpu.",
}, []string{"namespace", "pod_name"})
)
func init() {
prometheus.MustRegister(cpuLimit)
prometheus.MustRegister(cpuUsage)
}
func metricsHandler(w http.ResponseWriter, r *http.Request) {
namespace := r.Header.Get("Namespace")
podName := r.Header.Get("PodName")
w.Header().Set("Content-Type", "text/plain")
w.WriteHeader(http.StatusOK)
rand.Seed(time.Now().UnixNano())
cpuLimit.WithLabelValues(namespace, podName).Set(float64(rand.Intn(100) + 500))
cpuUsage.WithLabelValues(namespace, podName).Set(float64(rand.Intn(500)))
promhttp.Handler().ServeHTTP(w, r)
}
func main() {
http.HandleFunc("/metrics", metricsHandler)
http.ListenAndServe(":8080", nil)
}使用如下命令启动该应用程序:
go run main.go
之后,我们可以定义 HPA,自动扩缩容该应用程序。如下 YAML。
// www.javascriptcn.com code example
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: auto-scaling-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: auto-scaling-app
minReplicas: 1
maxReplicas: 10
metrics:
- type: Pods
pods:
metricName: app_cpu_usage
targetAverageValue: "200m"
- type: Object
object:
metricName: app_cpu_limit
targetAverageValue: "600m"使用如下命令将上述 YAML 部署到 Kubernetes 中。
kubectl apply -f auto-scaling-app-hpa.yaml
完成上述操作之后,现在我们来模拟一下应用程序的流量波动,观察 HPA 自动扩缩容的效果。我们可以通过 kubectl 命令模拟应用程序的流量波动,如下示例。
while true; do curl localhost -H "Host: auto-scaling-app"; sleep 0.5; done
此时,我们可以使用 kubectl 命令查看 HPA 的变化情况,如下示例。
kubectl get hpa -w
可以看到,HPA 随着应用程序的负载变化而自动扩缩容。至此,我们已经完成了 Kubernetes 中的 HPA 与 Prometheus 整合,实现了自动扩缩容的效果。
结语
本文介绍了 Kubernetes 中的 HPA 和 Prometheus,以及它们的整合方式。我们可以根据实际的需求选择相应的整合方式。同时,本文给出了示例代码和部署指南,方便读者进行实践和学习。当然,对于真正的生产环境,我们需要根据实际情况进行定制化和优化,使其更加适合我们的业务需求。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d79525a941bf7134d8ff80