将通过LoadBalancer创建的ELB与service进行关联
真正的标题
在AWS创建的Kubernetes集群上应用LoadBalancer服务,并使用Prometheus关联生成的ELB和服务以生成指标。
這樣的人
-
- AWSでkubernetesを使い
-
- 外部との通信にserviceを使い
-
- prometheusを使っている
- (ただEKSのことは知らない)
因为有点长,所以大致上做了什么?
-
- service名とELBを関連付けるために仲を取り持つexporterみたいなものを作った
-
- 既存のexporterと組み合わせてk8sのservice名からELBのメトリクスを取得できるようにした
- 使用例のdeploymentをまとめてみた
长篇的介绍。
选择在kubernetes的service中使用type:LoadBalancer来创建aws的elb时,elb的名称会变成一个随机的字符串,与其他kubernetes端的指标关联起来有些麻烦。
https://github.com/kubernetes/kubernetes/issues/29789
在这里有很多讨论,但最终情况如何呢?
在使用AWS和Kubernetes配合Prometheus时,我认为使用Grafana来可视化指标,将CloudWatch指标和Prometheus分别作为数据源,是比较常见的用法,但偶尔会遇到一些小麻烦和不便。
例如,当重新创建服务时,需要将新创建的elb名称替换掉现有的elb(elb名称会随机生成)。
有时可能希望使用prometheus的度量和cloudwatch的度量进行计算(例如requestCount/podCount)。
第一种方式可能是通过手动操作或脚本来处理。
第二种方式是使用cloudwatch_exporter将cloudwatch指标转换为prometheus指标来处理。
并且这个cloudwatch_exporter有点难用,它只返回config中指定的dimensions项的标签信息。换句话说,就算把cloudwatch的指标信息放入prometheus,最后还是得随机捕捉到生成的elb名称,并与其他资源关联起来。
除此之外,这个cloudwatch_exporter还有一些特殊之处,但那是另一个故事了…
所以,我想到的是,如果能够将这个CloudWatch指标与service-name之类的服务关联起来,那么在重新创建ELB之后就不需要重新设置了,而且使用体验也会更好。
创建必要的东西
首先,有关如何将ELB和服务连接起来的问题,
根据我所了解,从服务创建的ELB似乎默认带有类似下图所示的标记信息。
此外,我稍后会提到,您也可以自由地添加标记。

上面的value是namespace / service-name,
下面的key里包含了cluster名字。(指的是图案的部分)
因为找不到可以将该标签的key-value作为label的prometheus指标与服务关联的exporter,所以我创建了一个简单的工具。
https://github.com/buildsville/elb-tag-pusher
它会获取elb的标签并将指标推送到pushgateway。
我本来想直接创建exporter,但是我不知道如何动态地将tag的key-value作为label标记,所以就有了这种形式。
当您部署这个项目后,您将能够获得此类指标。
aws_elb_tags{
app="elb-tag-pusher",
exported_job="push_elb_tag",
instance="0.0.0.0:9091",
job="kubernetes-pods",
kubernetes_io_cluster_my_cluster_name="owned",
kubernetes_io_service_name="default_test-service",
kubernetes_namespace="default",
kubernetes_node_hostname="ip-0-0-0-0.ap-northeast-1.compute.internal",
kubernetes_node_ip="10.0.13.151",
kubernetes_pod_ip="0.0.0.0",
kubernetes_pod_name="elb-tag-pusher-xxxxxxxxxx-xxxxx",
load_balancer_name="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
pod_template_hash="2709900335"
} 1
pushgateway所附加的标签也被包含在内,但重要的部分是
load_balancer_name="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
kubernetes_io_service_name="default_test-service"
kubernetes_io_cluster_my_cluster_name="owned"
在这附近。
load_balancer_name是ELB的名称,其他的是根据标签进行的命名。
根据上面的图像对比,可以看出符号已经部分替换了。
这是为了适应Prometheus的标签键只能使用“:”和“_”,值不能使用“/”这个规定而采取的权宜之计,实际使用时必须考虑这一点。
使用示例
kube-state-metrics的部署
这将成为我们建立的服务指标的基础。
虽然需要赋予一定的角色,但对配置没有特殊要求,因此部署应该没有问题。
https://github.com/kubernetes/kube-state-metrics
ELB的准备
首先,将service=[服务名称]添加到elb的标签中。
只需在service的注释中添加以下内容,即可自由地添加标签。
service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: 'service=test-service'
通过这种方式,key:service,value:test-service的标签将附加到elb,而elb-tag-pusher将在prometheus的度量中添加一个service=”test-service”的标签。
虽然可以使用label_replace来调整默认情况下附加的标签kubernetes_io_service_name=”default_test-service”,但这种方式明显更简单。
elb-tag-pusher的准备。
我会以这种方式进行部署。
apiVersion: apps/v1
kind: Deployment
metadata:
name: elb-tag-pusher
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: elb-tag-pusher
template:
metadata:
labels:
app: elb-tag-pusher
annotations:
prometheus.io/scrape: 'true'
prometheus.io/port: '9091'
containers:
- image: masahata/elb-tag-pusher:latest
name: elb-tag-pusher
- image: prom/pushgateway:v0.6.0
name: pushgateway
ports:
- containerPort: 9091
请授予以下权限。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:DescribeTags"
],
"Resource": "*"
}
]
}
请在节点上分配角色,将`.aws/credentials`放置于`container`的环境变量中,以设置帐户。
准备CloudWatch Exporter
请设置配置文件以便获取ELB的指标,并进行部署。我们将以请求数和延迟作为示例来获取。
region: ap-northeast-1
delay_seconds: 60
range_seconds: 60
metrics:
- aws_namespace: AWS/ELB
aws_metric_name: RequestCount
aws_dimensions: [LoadBalancerName]
aws_dimension_select_regex:
LoadBalancerName: ["[0-9a-f]{32}"]
aws_statistics: [Sum]
- aws_namespace: AWS/ELB
aws_metric_name: Latency
aws_dimensions: [LoadBalancerName]
aws_dimension_select_regex:
LoadBalancerName: ["[0-9a-f]{32}"]
aws_statistics: [Average]
由于延迟秒数(delay_seconds)和范围秒数(range_seconds)是比较繁琐的项目,因此会根据使用方法进行相应的设置。
获取度量标准
如果到目前为止能够正常运行,那么这样的promQL。
kube_service_info
* on(service) group_left(load_balancer_name) aws_elb_tags{service=~".+"}
* on(load_balancer_name) group_left() aws_elb_request_count_sum
所以,我认为可以获取度量标准。
{
app="kube-state-metrics",
cluster_ip="0.0.0.0",
instance="0.0.0.0:8080",
job="kubernetes-pods",
kubernetes_namespace="default",
kubernetes_node_hostname="ip-0-0-0-0.ap-northeast-1.compute.internal",
kubernetes_node_ip="0.0.0.0",
kubernetes_pod_ip="0.0.0.0",
kubernetes_pod_name="kube-state-metrics-dc9bb7b77-xdg69",
load_balancer_name="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
namespace="default",
pod_template_hash="999999999"
service="test-service"
} 15
如果没有对 ELB 进行访问,就无法获取 cloudwatch_exporter 的指标,因此也无法获取这些指标。
可以选择将其作为prometheus的录制规则,这样就不会太长而繁琐。
groups:
- name: kube_service_extra.rules
rules:
- record: kube_service_request_count
expr: kube_service_info * on(service) group_left(load_balancer_name) aws_elb_tags{service=~".+"} * on(load_balancer_name) group_left() aws_elb_request_count_sum
- record: kube_service_latency_seconds
expr: kube_service_info * on(service) group_left(load_balancer_name) aws_elb_tags{service=~".+"} * on(load_balancer_name) group_left() aws_elb_latency_average
现在可以根据服务名称获取ELB的指标。
即使重新创建服务并更改了ELB,只要标签保持相同,就不必担心。
最后稍微
以上内容的示例YAML已放置在https://github.com/buildsville/elb-tag-pusher/tree/master/sample。
如果使用 https://github.com/DirectXMan12/k8s-prometheus-adapter,我认为它也可以用于自动调整的指标。
然而,由于cloudwatch_exporter会有些许延迟,所以在需要迅速响应的情况下可能会稍微有些困难。
我本来也想写一些关于这方面的,但是会变得太长,所以这次就到这里吧。