将通过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似乎默认带有类似下图所示的标记信息。
此外,我稍后会提到,您也可以自由地添加标记。

スクリーンショット 2018-11-24 21.07.47.png

上面的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会有些许延迟,所以在需要迅速响应的情况下可能会稍微有些困难。

我本来也想写一些关于这方面的,但是会变得太长,所以这次就到这里吧。

广告
将在 10 秒后关闭
bannerAds