<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          使用讀寫分離模式擴展 Grafana Loki

          共 26142字,需瀏覽 53分鐘

           ·

          2022-06-18 00:27

          Loki 由多個微服務組件構建而成,可以作為一個可水平擴展的分布式系統(tǒng)運行,Loki 的獨特設計可以將整個分布式系統(tǒng)的代碼編譯成單個二進制或 Docker 映像,單個二進制文件的行為由 -target 命令行標志控制。

          單體模式

          最簡單的操作模式是設置 -target=all,這是默認的方式,不需要指定,這就是單體模式,它以單個二進制文件或 Docker 映像的形式在單個進程中運行 Loki 的所有微服務組件。

          單體模式對于快速開始使用 Loki 以及每天數(shù)據(jù)量約100GB的讀寫量非常有用。將單體模式部署水平擴展至更多實例可以通過使用共享對象存儲,配置 memberlist_config 屬性在所有實例之間共享狀態(tài)。

          可以通過使用 memberlist_config 配置和共享對象存儲運行兩個 Loki 實例來配置高可用性。以循環(huán)方式將流量路由到所有 Loki 實例。并行查詢受限于實例數(shù)量和定義的查詢并行度。

          單體模式的安裝非常簡單,直接使用 grafana/loki-stack 這個 Helm Chart 包安裝即可。

          讀寫分離模式

          如果你每天的日志量超過幾百 GB,或者你想進行讀寫分離,Loki 提供了簡單的可擴展部署模式。這種部署模式可以擴展到每天數(shù) TB 甚至更多的日志。

          在這種模式下,Loki 的組件微服務被綁定到兩個目標中:-target=read-target=write,BoltDB compactor 服務將作為讀取目標的一部分運行。

          分離讀寫路徑有以下優(yōu)點:

          • 通過提供專用節(jié)點提高寫入路徑的可用性
          • 可單獨擴展讀取路徑以按需添加/刪除查詢性能

          這種讀寫分離的模式需要在 Loki 前面有一個負載均衡器,它將 /loki/api/v1/push 流量路由到寫入節(jié)點,所有其他請求都轉到讀取節(jié)點,流量應該以循環(huán)方式發(fā)送。

          安裝

          我們同樣使用 Helm Chart 進行安裝,首先獲取讀寫分離模型的 Chart 包:

          $ helm repo add grafana https://grafana.github.io/helm-charts
          $ helm pull grafana/loki-simple-scalable --untar --version 1.4.1
          $ cd loki-simple-scalable

          該 Chart 包支持下表中顯示的組件,Ingester、distributor、querier 和 query-frontend 都會安裝,其他組件是可選的。

          Loki組件是否可選是否默認開啟
          gateway??
          write?n/a
          read?n/a

          這里我們使用 MinIO 來作為遠程數(shù)據(jù)存儲,分別配置讀和寫的 Loki 實例副本數(shù)為2,為了在 Loki 前面添加一個負載均衡器,需要開啟 Gateway,對應的 Values 文件如下所示:

          # ci/minio-values.yaml
          loki:
            commonConfig:
              path_prefix: /var/loki
              replication_factor: 2
            authEnabled: false

          # Configuration for the write
          write:
            # -- Number of replicas for the write
            replicas: 3
            affinity: |
              podAntiAffinity:
                preferredDuringSchedulingIgnoredDuringExecution:
                  - weight: 1
                    podAffinityTerm:
                      labelSelector:
                        matchLabels:
                          {{- include "loki.writeSelectorLabels" . | nindent 12 }}
                      topologyKey: kubernetes.io/hostname
            persistence:
              size: 1Gi
              storageClass: local-path

          # Configuration for the read node(s)
          read:
            # -- Number of replicas for the read
            replicas: 3
            affinity: |
              podAntiAffinity:
                preferredDuringSchedulingIgnoredDuringExecution:
                  - weight: 1
                    podAffinityTerm:
                      labelSelector:
                        matchLabels:
                          {{- include "loki.readSelectorLabels" . | nindent 12 }}
                      topologyKey: kubernetes.io/hostname
            persistence:
              size: 1Gi
              storageClass: local-path

          # Configuration for the gateway
          gateway:
            # -- Specifies whether the gateway should be enabled
            enabled: true
          # -------------------------------------
          # Configuration for `minio` child chart
          # -------------------------------------
          minio:
            enabled: true
            accessKey: enterprise-logs
            secretKey: supersecret
            service:
              type: NodePort
              nodePort: 32000
            buckets:
              - name: chunks
                policy: none
                purge: false
              - name: ruler
                policy: none
                purge: false
              - name: admin
                policy: none
                purge: false
            persistence:
              size: 1Gi
              storageClass: local-path
            resources:
              requests:
                cpu: 100m
                memory: 256Mi

          然后使用上面的 values 文件來安裝讀寫分離模式的 Loki:

          $ helm upgrade --install loki -n logging -f ci/minio-values.yaml .
          Release "loki" does not exist. Installing it now.
          NAME: loki
          LAST DEPLOYED: Fri Jun 17 14:53:20 2022
          NAMESPACE: logging
          STATUS: deployed
          REVISION: 1
          TEST SUITE: None
          NOTES:
          ***********************************************************************
           Welcome to Grafana Loki
           Chart version: 1.4.1
           Loki version: 2.5.0
          ***********************************************************************

          Installed components:
          * gateway
          * read
          * write

          This chart requires persistence and object storage to work correctly.
          Queries will not work unless you provide a `loki.config.common.storage` section with
          a valid object storage (and the default `filesystem` storage set to `null`), as well
          as a valid `loki.config.schema_config.configs` with an `object_store` that
          matches the common storage section.

          For example, to use MinIO as your object storage backend:

          loki:
            config:
              common:
                storage:
                  filesystem: null
                  s3:
                    endpoint: minio.minio.svc.cluster.local:9000
                    insecure: true
                    bucketnames: loki-data
                    access_key_id: loki
                    secret_access_key: supersecret
                    s3forcepathstyle: true
              schema_config:
                configs:
                  - from: "2020-09-07"
                    store: boltdb-shipper
                    object_store: s3
                    schema: v11
                    index:
                      period: 24h
                      prefix: loki_index_

          安裝完成后查看 Pod 狀態(tài)是否正常:

          $ kubectl get pods -n logging
          NAME                            READY   STATUS    RESTARTS   AGE
          loki-gateway-67f76958d7-bq46l   1/1     Running   0          91m
          loki-minio-87c9bc6f5-jxdcn      1/1     Running   0          70m
          loki-read-0                     1/1     Running   0          81s
          loki-read-1                     1/1     Running   0          81s
          loki-read-2                     1/1     Running   0          81s
          loki-write-0                    1/1     Running   0          81s
          loki-write-1                    1/1     Running   0          81s
          loki-write-2                    1/1     Running   0          81s

          可以看到分別部署了兩個副本的 write 和 read 的 Loki,另外還有一個 gateway 的 Pod,gateway 實際上就是一個 nginx 應用,用來將 /loki/api/v1/push 請求路由到 write 節(jié)點去,我們可以查看 gateway 的配置來驗證:

          $ kubectl get cm -n logging loki-gateway -o yaml
          apiVersion: v1
          data:
            nginx.conf: |
              worker_processes  5;  ## Default: 1
              error_log  /dev/stderr;
              pid        /tmp/nginx.pid;
              worker_rlimit_nofile 8192;

              events {
                worker_connections  4096;  ## Default: 1024
              }

              http {
                client_body_temp_path /tmp/client_temp;
                proxy_temp_path       /tmp/proxy_temp_path;
                fastcgi_temp_path     /tmp/fastcgi_temp;
                uwsgi_temp_path       /tmp/uwsgi_temp;
                scgi_temp_path        /tmp/scgi_temp;

                default_type application/octet-stream;
                log_format   main '$remote_addr - $remote_user [$time_local]  $status '
                      '"$request" $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
                access_log   /dev/stderr  main;

                sendfile     on;
                tcp_nopush   on;
                resolver kube-dns.kube-system.svc.cluster.local;

                server {
                  listen             8080;

                  location = / {
                    return 200 'OK';
                    auth_basic off;
                  }

                  location = /api/prom/push {
                    proxy_pass       http://loki-write.logging.svc.cluster.local:3100$request_uri;
                  }

                  location = /api/prom/tail {
                    proxy_pass       http://loki-read.logging.svc.cluster.local:3100$request_uri;
                    proxy_set_header Upgrade $http_upgrade;
                    proxy_set_header Connection "upgrade";
                  }

                  location ~ /api/prom/.* {
                    proxy_pass       http://loki-read.logging.svc.cluster.local:3100$request_uri;
                  }

                  location = /loki/api/v1/push {
                    proxy_pass       http://loki-write.logging.svc.cluster.local:3100$request_uri;
                  }

                  location = /loki/api/v1/tail {
                    proxy_pass       http://loki-read.logging.svc.cluster.local:3100$request_uri;
                    proxy_set_header Upgrade $http_upgrade;
                    proxy_set_header Connection "upgrade";
                  }

                  location ~ /loki/api/.* {
                    proxy_pass       http://loki-read.logging.svc.cluster.local:3100$request_uri;
                  }
                }
              }
          kind: ConfigMap
          metadata:
            annotations:
              meta.helm.sh/release-name: loki
              meta.helm.sh/release-namespace: logging
            creationTimestamp: "2022-06-17T06:53:22Z"
            labels:
              app.kubernetes.io/component: gateway
              app.kubernetes.io/instance: loki
              app.kubernetes.io/managed-by: Helm
              app.kubernetes.io/name: loki
              app.kubernetes.io/version: 2.5.0
              helm.sh/chart: loki-simple-scalable-1.4.1
            name: loki-gateway
            namespace: logging
            resourceVersion: "4968787"
            uid: ba9ba1c0-8561-41cb-8b55-287f352b5ee8

          上面就是一個典型的 Nginx 配置,從配置可以看出會把請求 /api/prom/push/loki/api/v1/push 這兩個 Push API 代理到 http://loki-write.logging.svc.cluster.local:3100$request_uri;,也就是上面的兩個 loki-write 節(jié)點,而讀取相關的接口被代理到 loki-read 節(jié)點,然后 loki-write 啟動參數(shù)配置 -target=writeloki-read 啟動參數(shù)配置 -target=read,這樣去實現(xiàn)讀寫分離。不過讀寫的應用是共享同一個配置文件的,如下所示:

          $ kubectl get cm -n logging loki -o yaml
          apiVersion: v1
          data:
            config.yaml: |
              auth_enabled: false
              common:
                path_prefix: /var/loki
                replication_factor: 2
                storage:
                  s3:
                    access_key_id: enterprise-logs
                    bucketnames: chunks
                    endpoint: loki-minio.logging.svc:9000
                    insecure: true
                    s3forcepathstyle: true
                    secret_access_key: supersecret
              limits_config:
                enforce_metric_name: false
                max_cache_freshness_per_query: 10m
                reject_old_samples: true
                reject_old_samples_max_age: 168h
                split_queries_by_interval: 15m
              memberlist:
                join_members:
                - loki-memberlist
              ruler:
                storage:
                  s3:
                    bucketnames: ruler
              schema_config:
                configs:
                - from: "2022-06-17"
                  index:
                    period: 24h
                    prefix: loki_index_
                  object_store: s3
                  schema: v12
                  store: boltdb-shipper
              server:
                grpc_listen_port: 9095
                http_listen_port: 3100
          ......

          其中 common.storage.s3  指定的是 MinIO 的相關配置,通過 memberlist.join_members 來指定成員,其實就是所有的讀寫節(jié)點:

          $ kubectl get svc loki-memberlist -n logging -o wide
          NAME              TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE   SELECTOR
          loki-memberlist   ClusterIP   None         <none>        7946/TCP   54m   app.kubernetes.io/instance=loki,app.kubernetes.io/name=loki,app.kubernetes.io/part-of=memberlist
          $ kubectl get pods -n logging -l app.kubernetes.io/part-of=memberlist
          NAME           READY   STATUS    RESTARTS   AGE
          loki-read-0    1/1     Running   0          32s
          loki-read-1    1/1     Running   0          72s
          loki-read-2    1/1     Running   0          115s
          loki-write-0   1/1     Running   0          4s
          loki-write-1   1/1     Running   0          55s
          loki-write-2   1/1     Running   0          116s

          到這里我們就完成了 Loki 讀寫分離模式的部署。

          Promtail寫數(shù)據(jù)

          為了驗證應用是否正常,接下來我們再安裝 Promtail 和 Grafana 來進行數(shù)據(jù)的讀寫。

          獲取 promtail 的 Chart 包并解壓:

          $ helm pull grafana/promtail --untar
          $ cd promtail

          創(chuàng)建一個如下所示的 values 文件:

          # ci/simple-values.yaml
          rbac:
            pspEnabled: false
          config:
            lokiAddress: http://loki-gateway/loki/api/v1/push

          注意我們需要將 Promtail 中配置的 Loki 地址為 http://loki-gateway/loki/api/v1/push,這樣就是 Promtail 將日志數(shù)據(jù)首先發(fā)送到 Gateway 上面去,然后 Gateway 根據(jù)我們的 Endpoints 去轉發(fā)給 write 節(jié)點,使用上面的 values 文件來安裝 Promtail:

          $ helm upgrade --install promtail -n logging -f ci/simple-values.yaml .
          Release "promtail" does not exist. Installing it now.
          NAME: promtail
          LAST DEPLOYED: Fri Jun 17 16:01:08 2022
          NAMESPACE: logging
          STATUS: deployed
          REVISION: 1
          TEST SUITE: None
          NOTES:
          ***********************************************************************
           Welcome to Grafana Promtail
           Chart version: 5.1.0
           Promtail version: 2.5.0
          ***********************************************************************

          Verify the application is working by running these commands:

          * kubectl --namespace logging port-forward daemonset/promtail 3101
          * curl http://127.0.0.1:3101/metrics

          正常安裝完成后會在每個節(jié)點上運行一個 promtail:

          $ kubectl get pods -n logging -l app.kubernetes.io/name=promtail
          NAME             READY   STATUS    RESTARTS   AGE
          promtail-5r9hl   1/1     Running   0          2m25s
          promtail-85mk4   1/1     Running   0          2m25s
          promtail-qlfnv   1/1     Running   0          2m25s

          正常 promtail 就已經(jīng)在開始采集所在節(jié)點上的所有容器日志了,然后將日志數(shù)據(jù) Push 給 gateway,gateway 轉發(fā)給 write 節(jié)點,我們可以查看 gateway 的日志:

          $ kubectl logs -f loki-gateway-67f76958d7-bq46l -n logging
          10.244.1.170 - - [17/Jun/2022:08:09:03 +0000]  204 "POST /loki/api/v1/push HTTP/1.1" 0 "-" "promtail/2.5.0" "-"
          10.244.1.170 - - [17/Jun/2022:08:09:04 +0000]  204 "POST /loki/api/v1/push HTTP/1.1" 0 "-" "promtail/2.5.0" "-"
          10.244.2.205 - - [17/Jun/2022:08:09:05 +0000]  204 "POST /loki/api/v1/push HTTP/1.1" 0 "-" "promtail/2.5.0" "-"
          ......

          可以看到 gateway 現(xiàn)在在一直接接收著 /loki/api/v1/push 的請求,也就是 promtail 發(fā)送過來的,正常來說現(xiàn)在日志數(shù)據(jù)已經(jīng)分發(fā)給 write 節(jié)點了,write 節(jié)點將數(shù)據(jù)存儲在了 minio 中,可以去查看下 minio 中已經(jīng)有日志數(shù)據(jù)了,前面安裝的時候為 minio 服務指定了一個 32000 的 NodePort 端口:

          登錄信息為:

          • accessKey: enterprise-logs
          • secretKey: supersecret

          可以看到 minio 的 chunks 這個 bucket 中并沒有日志數(shù)據(jù),這是因為上面我們創(chuàng)建的 bucket 默認只有讀取的權限,我們可以將該 bucket 修改為具有讀寫的權限:

          正常修改后就會產(chǎn)生一個 fake 的目錄了,這是默認沒有提供多租戶的數(shù)據(jù)目錄,該目錄下面存儲著日志的 chunk 數(shù)據(jù):

          這是 Loki 日志的寫入的路徑。

          Grafana讀數(shù)據(jù)

          下面我們來驗證下讀取路徑,安裝 Grafana 對接 Loki:

          $ helm pull grafana/grafana --untar
          $ cd grafana

          創(chuàng)建如下所示的 values 配置文件:

          # ci/simple-values.yaml
          service:
            type: NodePort
            nodePort: 32001
          rbac:
            pspEnabled: false
          persistence:
            enabled: true
            storageClassName: local-path
            accessModes:
              - ReadWriteOnce
            size: 1Gi

          直接使用上面的 values 文件安裝 Grafana:

          $ helm upgrade --install grafana -n logging -f ci/simple-values.yaml .
          Release "grafana" has been upgraded. Happy Helming!
          NAME: grafana
          LAST DEPLOYED: Fri Jun 17 17:00:24 2022
          NAMESPACE: logging
          STATUS: deployed
          REVISION: 2
          NOTES:
          1. Get your 'admin' user password by running:

             kubectl get secret --namespace logging grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

          2. The Grafana server can be accessed via port 80 on the following DNS name from within your cluster:

             grafana.logging.svc.cluster.local

             Get the Grafana URL to visit by running these commands in the same shell:
          export NODE_PORT=$(kubectl get --namespace logging -o jsonpath="{.spec.ports[0].nodePort}" services grafana)
               export NODE_IP=$(kubectl get nodes --namespace logging -o jsonpath="{.items[0].status.addresses[0].address}")
               echo http://$NODE_IP:$NODE_PORT


          3. Login with the password from step 1 and the username: admin

          可以通過上面提示中的命令獲取登錄密碼:

          $ kubectl get secret --namespace logging grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

          然后使用上面的密碼和 admin 用戶名登錄 Grafana:

          登錄后進入 Grafana 添加一個數(shù)據(jù)源,這里需要注意要填寫 gateway 的地址 http://loki-gateway

          保存數(shù)據(jù)源后,可以進入 Explore 頁面過濾日志,比如我們這里來實時查看 gateway 這個應用的日志,如下圖所示:

          如果你能看到最新的日志數(shù)據(jù)那說明我們部署成功了讀寫分離模式的 Loki,讀寫分離模式可以大大提高 Loki 的性能和容量,如果這種模式還不能滿足你的數(shù)據(jù)量,那么可以使用微服務模式來部署 Loki 了,未完待續(xù)......

          瀏覽 106
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产在线拍揄自揄拍无码男男 | 福利在线视频中文 | 久久亚洲精品影院 | 99爱免费视频 | www.91AV在线免费观看 |