美文网首页专题工作生活
Prometheus高可用Thanos学习(1)-siderca

Prometheus高可用Thanos学习(1)-siderca

作者: 大雄good | 来源:发表于2019-07-02 00:08 被阅读0次

    最近工作中的主要任务都是在业务的高可用上,由于项目中使用到了Promethues,所以也花了一些时间研究了一下Promethues的高可用方案。发现也没有blog告诉怎么去deploy一个Thanos的集群,所以本文也会给出deploy的方法和源文件(本人也是一边试用一边总结,如果理解有错,请帮忙矫正)

    由于Promethues本身仅是一个采样系统,如果做成master-slave模式,存在切换开销,并且增加系统的复杂性。因此官方给出的高可用建议方案如下图,使用多个对等的Promethues,对所有的DataSource均进行采样。这里的Service是K8S的Service,所以理论上访问该Service会随机地访问后端的两个Promethues。

    Prometheus HA

    上面方案中,当其中一个Promethues pod中断时,K8S会将流量仅导向另外一个pod。但是pod中断期间,其无法获取数据,因此当中断的pod恢复之后,在存储端,需要进行sync。可是,何时sync,怎么sync是一个比较复杂的问题,就算能解决这两个问题,实际生产环境中进行文件sync,本身也会存在各式各样的风险。

    所以Thanos就没有使用存储端Sync的方法来保证数据的一致性,而是采用才query端对查询到的数据进行合并。下面会简单介绍一下Thanos的原理。

    1. Thanos基本原理

    基于官方的介绍,我将Thanos的架构简化,仅保存最基本的,我所关心的部分如下, 主要包含3部分:

    1. Thanos Query. 主要是对从Promethues Pod采集来的数据进行merge,提供查询接口给客户端(官方文档上暂时没看到merge的原理,这篇总结之后需要花些时间看源码学习一下);
    2. Thanos SideCar. 将Promethues container的数据进行封装,以提供接口给Thanos Query(实际上SideCar还能提供更多用处,但是这里暂时我们仅关心数据查询,后面再进一步研究,暂时不要图多);
    3. Prometheus Container. 采集数据,通过Remote Read API提供接口给Thanos SideCar
    Thanos.png

    2. Thanos部署

    学习一样新工具,部署和使用是必不可少的,暂时我也没看到网上有现成的thanos部署方法。通过修改官网的demo文件,这里我成功的部署了sidecar和query, 能够实现一个最basic的Promethues高可用集群。你可以直接下载我的源文件部署一个thanos的实验环境。

    2.1 Prometheus和SideCar

    由于涉及的yaml文件比较多,这里我只是截取最重要的部分解释一下, 首先我们创建一个replicas为2的statefulset, 每个pod里面包含一个PromethuesSideCar容器。

    ---
    apiVersion: apps/v1beta1
    kind: StatefulSet
    metadata:
      name: prometheus
      labels:
        app: prometheus
    spec:
      serviceName: "prometheus"
      replicas: 2
      selector:
        matchLabels:
          app: prometheus
      template:
        metadata:
          labels:
            app: prometheus
            # We will use this label to put all StoreAPis
            # under the same headless service for
            # SRV lookup: thanos-store-api.default.svc
            thanos-store-api: "true"
        spec:
          securityContext:
            runAsUser: 1000
            fsGroup: 2000
            runAsNonRoot: true
          serviceAccountName: prometheus
          containers:
          - name: prometheus
            image: quay.io/prometheus/prometheus:v2.6.1
            args:
              - --config.file=/etc/prometheus-shared/prometheus.yaml
              - --storage.tsdb.path=/var/prometheus
              - --web.enable-lifecycle
              # TODO: Make retention shorter once all old blocks will be uploaded (!)
              - --storage.tsdb.retention=2w
              # Disable compaction.
              - --storage.tsdb.min-block-duration=2h
              - --storage.tsdb.max-block-duration=2h
              - --web.enable-admin-api
            ports:
              - name: http-prometheus
                containerPort: 9090
            volumeMounts:
              - name: config-shared
                mountPath: /etc/prometheus-shared
              - name: rules
                mountPath: /etc/prometheus/rules
              - name: prometheus
                mountPath: /var/prometheus
          - name: thanos
            image: improbable/thanos:v0.3.0
            args:
              - sidecar
              - --log.level=debug
              - --tsdb.path=/var/prometheus
              - --prometheus.url=http://localhost:9090
              - --cluster.disable
              - --reloader.config-file=/etc/prometheus/prometheus.yaml.tmpl
              - --reloader.config-envsubst-file=/etc/prometheus-shared/prometheus.yaml
            env:
              - name: POD_NAME
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.name
            ports:
              - name: http-sidecar
                containerPort: 10902
              - name: grpc
                containerPort: 10901
    

    上面可以看到SideCar使用的是10901这个port暴露服务,因此为了让Query能够访问SideCar, 这里我们需要暴露两个Service:

    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: prometheus
      name: sidecar-0
    spec:
      ports:
        - port: 10901
          protocol: TCP
          targetPort: grpc
          name: grpc
          nodePort: 30901
      selector:
        statefulset.kubernetes.io/pod-name: prometheus-0
      type: NodePort
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: prometheus
      name: sidecar-1
    spec:
      ports:
        - port: 10901
          protocol: TCP
          targetPort: grpc
          name: grpc
          nodePort: 30902
      selector:
        statefulset.kubernetes.io/pod-name: prometheus-1
      type: NodePort
    

    2.2 Query

    有了Prometheus的pod,现在我们就可以部署Query的Pod啦, 这里的192.168.56.101是我的实验环境的IP,所以需要您改成自己的IP,3090130902就是之前部署的SideCar的Service:

          containers:
          - name: thanos
            image: improbable/thanos:v0.3.0
            args:
            - query
            - --log.level=debug
            - --query.replica-label=replica
            - --cluster.disable
            # Discover local store APIs using DNS SRV.
            - --store=dnssrv+thanos-store-gateway.default.svc
            # Get remote store APIs by IP:Port.
            - --store=192.168.56.101:30901
            - --store=192.168.56.101:30902
    

    部署完毕之后,我们就可以去访问Query的Service啦,这里我创建的是一个30903的nodePort用来暴露服务, 所以访问该端口192.168.56.101:30903就能看到Thanos的界面啦。这里,我没有勾上deduplication,所以thanos不会帮我合并,所以能够看到prometheus-0prometheus-1的数据。

    nomerge.png
    如果勾上deduplication,结果会根据replica这个label进行合并(简单看了一下源码,如果两个pod都有数据,query会取timestamp更小的结果): merge.png

    小结

    这篇blog简单介绍了thanos,学习的顺序应当是先使用,感受一下,再仔细研究。Thanos另外还有Rule, Compact, Bucket几个重要的模块,后面有时间会再整理一下。

    相关文章

      网友评论

        本文标题:Prometheus高可用Thanos学习(1)-siderca

        本文链接:https://www.haomeiwen.com/subject/xpiocctx.html