日志之Loki详细讲解

2024-01-31 01:44
文章标签 讲解 日志 详细 loki

本文主要是介绍日志之Loki详细讲解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1 Loki
    • 1.1 引言
    • 1.2 Loki工作方式
      • 1.2.1 日志解析格式
      • 1.2.2 日志搜集架构模式
      • 1.2.3 Loki部署模式
    • 1.3 服务端部署
      • 1.3.1 AllInOne部署模式
        • 1.3.1.1 k8s部署
        • 1.3.1.2 创建configmap
        • 1.3.1.3 创建持久化存储
        • 1.3.1.4 创建应用
        • 1.3.1.5 验证部署结果
      • 1.3.2 裸机部署
    • 1.4 Promtail部署
      • 1.4.1 k8s部署
        • 1.4.1.1 创建配置文件
        • 1.4.1.2 创建DaemonSet文件
        • 1.4.1.3 创建promtail应用
      • 1.4.2 裸机部署
    • 1.5 数据源
    • 1.6 其他客户端配置
      • 1.6.1 Logstash作为日志收集客户端
    • 1.7 Helm安装
    • 1.8 故障解决方案
      • 1.8.1 502 BadGateWay
      • 1.8.2 Ingester not ready: instance xx:9095 in state JOINING
      • 1.8.3 too many unhealthy instances in the ring
      • 1.8.4 Data source connected

1 Loki

1.1 引言

Loki 是一个轻量级的日志收集、分析的应用,采用的是promtail的方式来获取日志内容并送到loki里面进行存储,最终在grafanadatasource里面添加数据源进行日志的展示、查询。

官方文档:https://kubernetes.io/docs/concepts/security/pod-security-policy

loki的持久化存储支持azure、gcs、s3、swift、local这5中类型,其中常用的是s3、local。另外,它还支持很多种日志搜集类型,像最常用的logstash、fluentbit也在官方支持的列表中。

优点:

  • 支持的客户端,如Promtail,Fluentbit,Fluentd,Vector,Logstash和Grafana Agent
  • 首选代理Promtail,可以多来源提取日志,包括本地日志文件,systemd,Windows事件日志,Docker日志记录驱动程序等
  • 没有日志格式要求,包括JSON,XML,CSV,logfmt,非结构化文本
  • 使用与查询指标相同的语法查询日志
  • 日志查询时允许动态筛选和转换日志行
  • 可以轻松地计算日志中的需要的指标
  • 引入时的最小索引意味着您可以在查询时动态地对日志进行切片和切块,以便在出现新问题时回答它们
  • 云原生支持,使用Prometheus形式抓取数据

各日志收集组件简单对比

名称安装的组件优点
ELK/EFKelasticsearch、logstash, kibana、filebeat、kafka/redis支持自定义grok正则解析复杂日志内容;dashboard支持主富的可视化展示
Lokigrafana、loki、promtail占用资源小;grafana原生支持;查询速度快

1.2 Loki工作方式

1.2.1 日志解析格式

图片
从上面的图中我们可以看到,它在解析日志的时候是以index为主的,index包括时间戳和pod的部分label(其他labelfilenamecontainers等),其余的是日志内容。具体查询效果如下:
在这里插入图片描述
{app="loki",namespace="kube-public"}为索引
在这里插入图片描述

1.2.2 日志搜集架构模式

在这里插入图片描述
在使用过程中,官方推荐使用promtail做为agentDaemonSet方式部署在kubernetesworker节点上搜集日志。另外也可以用上面提到的其他日志收集工具来收取,这篇文章在结尾处会附上其他工具的配置方式。

1.2.3 Loki部署模式

Loki由许多组件微服务构建而成,微服务组件有5个。在这5个里面添加缓存用来把数据放起来加快查询。数据放在共享存储里面配置memberlist_config部分并在实例之间共享状态,将Loki进行无限横向扩展。

在配置完memberlist_config部分后采用轮询的方式查找数据。为了使用方便官方把所有的微服务编译成一个二进制,可以通过命令行参数-target控制,支持all、read、write,我们在部署时根据日志量的大小可以指定不同模式

  • all(读写模式)
    服务启动后,我们做的数据查询、数据写入都是来自这一个节点
    在这里插入图片描述
  • read/write(读写分离模式)
    在读写分离模式下运行时fronted-query查询会将流量转发到read节点上。读节点上保留了querier、ruler、fronted,写节点上保留了distributor、ingester
    在这里插入图片描述
  • 微服务模式运行
    微服务模式运行下,通过不同的配置参数启动为不同的角色,每一个进程都引用它的目标角色服务。
    在这里插入图片描述
组件名称功能
分发器/调度器(distributor)验证数据合规:数据排序; hash一致性, QPS限制, 转发,数据副本保证不丢失
收集器(ingester)时间戳排序: 文件系统支持: WAL预写
查询前端 (query frontend)提供页面操作,向后端存储发出数据查询;查询队列 (query-queueing) 能够防止大数据量查询时触发0OM;查询分割 (query-split) 可以分割大批量查询最后进行数据聚台
查询器Querier使用loggl语言在后端存储中查询日志
缓存将查询到的日志缓存起来共后续使用,如果数据不完整重新查询缺失的数据

1.3 服务端部署

在部署之前需要准备好一个k8s集群才行哦

应用镜像
lokigrafana/loki:2.5.0
promtailgrafana/promtail:2.5.0

1.3.1 AllInOne部署模式

1.3.1.1 k8s部署

我们从github上下载的程序是没有配置文件的,需要提前将文件准备一份。这里提供了一份完整的allInOne配置文件,部分内容进行了优化。

配置文件内容如下所示

auth_enabled: false
target: all
ballast_bytes: 20480
server:grpc_listen_port: 9095http_listen_port: 3100graceful_shutdown_timeout: 20sgrpc_listen_address: "0.0.0.0"grpc_listen_network: "tcp"grpc_server_max_concurrent_streams: 100grpc_server_max_recv_msg_size: 4194304grpc_server_max_send_msg_size: 4194304http_server_idle_timeout: 2mhttp_listen_address: "0.0.0.0"http_listen_network: "tcp"http_server_read_timeout: 30shttp_server_write_timeout: 20slog_source_ips_enabled: true# http_path_prefix如果需要更改,在推送日志的时候前缀都需要加指定的内容# http_path_prefix: "/"register_instrumentation: truelog_format: jsonlog_level: info
distributor:ring:heartbeat_timeout: 3skvstore:prefix: collectors/store: memberlist# 需要提前创建好consul集群#   consul:#     http_client_timeout: 20s#     consistent_reads: true#     host: 127.0.0.1:8500#     watch_burst_size: 2#     watch_rate_limit: 2
querier:engine:max_look_back_period: 20s timeout: 3m0s extra_query_delay: 100ms max_concurrent: 10 multi_tenant_queries_enabled: truequery_ingester_only: falsequery_ingesters_within: 3h0m0squery_store_only: falsequery_timeout: 5m0stail_max_duration: 1h0s
query_scheduler:max_outstanding_requests_per_tenant: 2048grpc_client_config:max_recv_msg_size: 104857600max_send_msg_size: 16777216grpc_compression: gziprate_limit: 0rate_limit_burst: 0backoff_on_ratelimits: falsebackoff_config:min_period: 50msmax_period: 15smax_retries: 5 use_scheduler_ring: truescheduler_ring:kvstore:store: memberlistprefix: "collectors/"heartbeat_period: 30sheartbeat_timeout: 1m0s# 默认第一个网卡的名称# instance_interface_names# instance_addr: 127.0.0.1# 默认server.grpc-listen-portinstance_port: 9095
frontend:max_outstanding_per_tenant: 4096querier_forget_delay: 1h0scompress_responses: truelog_queries_longer_than: 2m0smax_body_size: 104857600query_stats_enabled: truescheduler_dns_lookup_period: 10s scheduler_worker_concurrency: 15
query_range:align_queries_with_step: truecache_results: trueparallelise_shardable_queries: truemax_retries: 3results_cache:cache:enable_fifocache: falsedefault_validity: 30s background:writeback_buffer: 10000redis:endpoint: 127.0.0.1:6379timeout: 1sexpiration: 0s db: 9pool_size: 128 password: 1521Qyx6^tls_enabled: falsetls_insecure_skip_verify: trueidle_timeout: 10s max_connection_age: 8h
ruler:enable_api: trueenable_sharding: truealertmanager_refresh_interval: 1mdisable_rule_group_label: falseevaluation_interval: 1m0sflush_period: 3m0sfor_grace_period: 20m0sfor_outage_tolerance: 1h0snotification_queue_capacity: 10000notification_timeout: 4spoll_interval: 10m0squery_stats_enabled: trueremote_write:config_refresh_period: 10senabled: falseresend_delay: 2m0srule_path: /rulerssearch_pending_for: 5m0sstorage:local:directory: /data/loki/rulerstype: configdbsharding_strategy: defaultwal_cleaner:period:  240hmin_age: 12h0m0swal:dir: /data/loki/ruler_walmax_age: 4h0m0smin_age: 5m0struncate_frequency: 1h0m0sring:kvstore:store: memberlistprefix: "collectors/"heartbeat_period: 5sheartbeat_timeout: 1m0s# instance_addr: "127.0.0.1"# instance_id: "miyamoto.en0"# instance_interface_names: ["en0","lo0"]instance_port: 9500num_tokens: 100
ingester_client:pool_config:health_check_ingesters: falseclient_cleanup_period: 10s remote_timeout: 3sremote_timeout: 5s 
ingester:autoforget_unhealthy: truechunk_encoding: gzipchunk_target_size: 1572864max_transfer_retries: 0sync_min_utilization: 3.5sync_period: 20sflush_check_period: 30s flush_op_timeout: 10m0schunk_retain_period: 1m30schunk_block_size: 262144chunk_idle_period: 1h0smax_returned_stream_errors: 20concurrent_flushes: 3index_shards: 32max_chunk_age: 2h0m0squery_store_max_look_back_period: 3h30m30swal:enabled: truedir: /data/loki/wal flush_on_shutdown: truecheckpoint_duration: 15mreplay_memory_ceiling: 2GBlifecycler:ring:kvstore:store: memberlistprefix: "collectors/"heartbeat_timeout: 30s replication_factor: 1num_tokens: 128heartbeat_period: 5s join_after: 5s observe_period: 1m0s# interface_names: ["en0","lo0"]final_sleep: 10s min_ready_duration: 15s
storage_config:boltdb:directory: /data/loki/boltdb boltdb_shipper:active_index_directory: /data/loki/active_indexbuild_per_tenant_index: truecache_location: /data/loki/cache cache_ttl: 48hresync_interval: 5mquery_ready_num_days: 5index_gateway_client:grpc_client_config:filesystem:directory: /data/loki/chunks
chunk_store_config:chunk_cache_config:enable_fifocache: truedefault_validity: 30sbackground:writeback_buffer: 10000redis:endpoint: 192.168.3.56:6379timeout: 1sexpiration: 0s db: 8 pool_size: 128 password: 1521Qyx6^tls_enabled: falsetls_insecure_skip_verify: trueidle_timeout: 10s max_connection_age: 8hfifocache:ttl: 1hvalidity: 30m0smax_size_items: 2000max_size_bytes: 500MBwrite_dedupe_cache_config:enable_fifocache: truedefault_validity: 30s background:writeback_buffer: 10000redis:endpoint: 127.0.0.1:6379timeout: 1sexpiration: 0s db: 7pool_size: 128 password: 1521Qyx6^tls_enabled: falsetls_insecure_skip_verify: trueidle_timeout: 10s max_connection_age: 8hfifocache:ttl: 1hvalidity: 30m0smax_size_items: 2000max_size_bytes: 500MBcache_lookups_older_than: 10s 
# 压缩碎片索引
compactor:shared_store: filesystemshared_store_key_prefix: index/working_directory: /data/loki/compactorcompaction_interval: 10m0sretention_enabled: trueretention_delete_delay: 2h0m0sretention_delete_worker_count: 150delete_request_cancel_period: 24h0m0smax_compaction_parallelism: 2# compactor_ring:
frontend_worker:match_max_concurrent: trueparallelism: 10dns_lookup_duration: 5s 
# runtime_config 这里没有配置任何信息
# runtime_config:
common:storage:filesystem:chunks_directory: /data/loki/chunksfules_directory: /data/loki/rulersreplication_factor: 3persist_tokens: false# instance_interface_names: ["en0","eth0","ens33"]
analytics:reporting_enabled: false
limits_config:ingestion_rate_strategy: globalingestion_rate_mb: 100ingestion_burst_size_mb: 18max_label_name_length: 2096max_label_value_length: 2048max_label_names_per_series: 60enforce_metric_name: truemax_entries_limit_per_query: 5000reject_old_samples: truereject_old_samples_max_age: 168hcreation_grace_period: 20m0smax_global_streams_per_user: 5000unordered_writes: truemax_chunks_per_query: 200000max_query_length: 721hmax_query_parallelism: 64 max_query_series: 700cardinality_limit: 100000max_streams_matchers_per_query: 1000 max_concurrent_tail_requests: 10 ruler_evaluation_delay_duration: 3s ruler_max_rules_per_rule_group: 0ruler_max_rule_groups_per_tenant: 0retention_period: 700hper_tenant_override_period: 20s max_cache_freshness_per_query: 2m0smax_queriers_per_tenant: 0per_stream_rate_limit: 6MBper_stream_rate_limit_burst: 50MBmax_query_lookback: 0ruler_remote_write_disabled: falsemin_sharding_lookback: 0ssplit_queries_by_interval: 10m0smax_line_size: 30mbmax_line_size_truncate: falsemax_streams_per_user: 0# memberlist_conig模块配置gossip用于在分发服务器、摄取器和查询器之间发现和连接。
# 所有三个组件的配置都是唯一的,以确保单个共享环。
# 至少定义了1个join_members配置后,将自动为分发服务器、摄取器和ring 配置memberlist类型的kvstore
memberlist:randomize_node_name: truestream_timeout: 5s retransmit_factor: 4join_members:- 'loki-memberlist'abort_if_cluster_join_fails: trueadvertise_addr: 0.0.0.0advertise_port: 7946bind_addr: ["0.0.0.0"]bind_port: 7946compression_enabled: truedead_node_reclaim_time: 30sgossip_interval: 100msgossip_nodes: 3gossip_to_dead_nodes_time: 3# join:leave_timeout: 15sleft_ingesters_timeout: 3m0s max_join_backoff: 1m0smax_join_retries: 5message_history_buffer_bytes: 4096min_join_backoff: 2s# node_name: miyamotopacket_dial_timeout: 5spacket_write_timeout: 5s pull_push_interval: 100msrejoin_interval: 10stls_enabled: falsetls_insecure_skip_verify: true
schema_config:configs:- from: "2020-10-24"index:period: 24hprefix: index_object_store: filesystemschema: v11store: boltdb-shipperchunks:period: 168hrow_shards: 32
table_manager:retention_deletes_enabled: falseretention_period: 0sthroughput_updates_disabled: falsepoll_interval: 3m0screation_grace_period: 20mindex_tables_provisioning:provisioned_write_throughput: 1000provisioned_read_throughput: 500inactive_write_throughput: 4inactive_read_throughput: 300inactive_write_scale_lastn: 50 enable_inactive_throughput_on_demand_mode: trueenable_ondemand_throughput_mode: trueinactive_read_scale_lastn: 10 write_scale:enabled: truetarget: 80# role_arn:out_cooldown: 1800min_capacity: 3000max_capacity: 6000in_cooldown: 1800inactive_write_scale:enabled: truetarget: 80out_cooldown: 1800min_capacity: 3000max_capacity: 6000in_cooldown: 1800read_scale:enabled: truetarget: 80out_cooldown: 1800min_capacity: 3000max_capacity: 6000in_cooldown: 1800inactive_read_scale:enabled: truetarget: 80out_cooldown: 1800min_capacity: 3000max_capacity: 6000in_cooldown: 1800chunk_tables_provisioning:enable_inactive_throughput_on_demand_mode: trueenable_ondemand_throughput_mode: trueprovisioned_write_throughput: 1000provisioned_read_throughput: 300inactive_write_throughput: 1inactive_write_scale_lastn: 50inactive_read_throughput: 300inactive_read_scale_lastn: 10write_scale:enabled: truetarget: 80out_cooldown: 1800min_capacity: 3000max_capacity: 6000in_cooldown: 1800inactive_write_scale:enabled: truetarget: 80out_cooldown: 1800min_capacity: 3000max_capacity: 6000in_cooldown: 1800read_scale:enabled: truetarget: 80out_cooldown: 1800min_capacity: 3000max_capacity: 6000in_cooldown: 1800inactive_read_scale:enabled: truetarget: 80out_cooldown: 1800min_capacity: 3000max_capacity: 6000in_cooldown: 1800
tracing:enabled: true

注意

  • ingester.lifecycler.ring.replication_factor 的值在单实例的情况下为1
  • ingester.lifecycler.min_ready_duration的值为15s,在启动后默认会显示15秒将状态变为ready
    在这里插入图片描述
  • memberlist.node_name的值可以不用设置,默认是当前主机的名称
  • memberlist.join_members是一个列表,在有多个实例的情况下需要添加各个节点的主机名/IP地址。在k8s里面可以设置成一个service绑定到StatefulSets
  • query_range.results_cache.cache.enable_fifocache建议设置为false,我这里设置成了true
  • instance_interface_names是一个列表,默认的为["en0","eth0"],可以根据需要设置对应的网卡名称,一般不需要进行特殊设置。
1.3.1.2 创建configmap

将上面的内容写入到一个文件——>loki-all.yaml,把它作为一个configmap写入k8s集群。可以使用如下命令创建:

kubectl create configmap --from-file ./loki-all.yaml loki-all

可以通过命令查看到已经创建好的configmap,具体操作详见下图
在这里插入图片描述

1.3.1.3 创建持久化存储

在k8s里面我们的数据是需要进行持久化的。Loki收集起来的日志信息对于业务来说是至关重要的,因此需要在容器重启的时候日志能够保留下来。
那么就需要用到pv、pvc,后端存储可以使用nfs、glusterfs、hostPath、azureDisk、cephfs等20种支持类型,这里因为没有对应的环境就采用了hostPath方式。

apiVersion: v1
kind: PersistentVolume
metadata:name: lokinamespace: default
spec:hostPath:path: /glusterfs/lokitype: DirectoryOrCreatecapacity:storage: 1GiaccessModes:- ReadWriteMany
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: lokinamespace: default
spec:accessModes:- ReadWriteManyresources:requests:storage: 1GivolumeName: loki
1.3.1.4 创建应用

准备好k8s的StatefulSet部署文件后就可以直接在集群里面创建应用了。

apiVersion: apps/v1
kind: StatefulSet
metadata:labels:app: lokiname: lokinamespace: default
spec:podManagementPolicy: OrderedReadyreplicas: 1selector:matchLabels:app: lokitemplate:metadata:annotations:prometheus.io/port: http-metricsprometheus.io/scrape: "true"labels:app: lokispec:containers:- args:- -config.file=/etc/loki/loki-all.yamlimage: grafana/loki:2.5.0imagePullPolicy: IfNotPresentlivenessProbe:failureThreshold: 3httpGet:path: /readyport: http-metricsscheme: HTTPinitialDelaySeconds: 45periodSeconds: 10successThreshold: 1timeoutSeconds: 1name: lokiports:- containerPort: 3100name: http-metricsprotocol: TCP- containerPort: 9095name: grpcprotocol: TCP- containerPort: 7946name: memberlist-portprotocol: TCPreadinessProbe:failureThreshold: 3httpGet:path: /readyport: http-metricsscheme: HTTPinitialDelaySeconds: 45periodSeconds: 10successThreshold: 1timeoutSeconds: 1resources:requests:cpu: 500mmemory: 500Milimits:cpu: 500mmemory: 500MisecurityContext:readOnlyRootFilesystem: truevolumeMounts:- mountPath: /etc/lokiname: config- mountPath: /dataname: storagerestartPolicy: AlwayssecurityContext:fsGroup: 10001runAsGroup: 10001runAsNonRoot: truerunAsUser: 10001serviceAccount: lokiserviceAccountName: lokivolumes:- emptyDir: {}name: tmp- name: configconfigMap:name: loki- persistentVolumeClaim:claimName: lokiname: storage
---
kind: Service
apiVersion: v1
metadata:name: loki-memberlistnamespace: default
spec:ports:- name: loki-memberlistprotocol: TCPport: 7946targetPort: 7946selector:kubepi.org/name: loki
---
kind: Service
apiVersion: v1
metadata:name: lokinamespace: default
spec:ports:- name: lokiprotocol: TCPport: 3100targetPort: 3100selector:kubepi.org/name: loki

在上面的配置文件中我添加了一些pod级别的安全策略,这些安全策略还有集群级别的PodSecurityPolicy,防止因为漏洞的原因造成集群的整个崩溃

1.3.1.5 验证部署结果

在这里插入图片描述

当看到上面的Running状态时可以通过API的方式看一下分发器是不是正常工作,当显示Active时正常才会正常分发日志流到收集器(ingester
在这里插入图片描述

1.3.2 裸机部署

loki放到系统的/bin/目录下,准备grafana-loki.service控制文件重载系统服务列表

[Unit]
Description=Grafana Loki Log Ingester
Documentation=https://grafana.com/logs/
After=network-online.target[Service]
ExecStart=/bin/loki --config.file /etc/loki/loki-all.yaml
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID[Install]
WantedBy=multi-user.target

重载系统列表命令,可以直接系统自动管理服务:

systemctl daemon-reload
# 启动服务
systemctl start grafana-loki
# 停止服务
systemctl stop grafana-loki
# 重载应用
systemctl reload grafana-loki

1.4 Promtail部署

部署客户端收集日志时也需要创建一个配置文件,按照上面创建服务端的步骤创建。不同的是需要把日志内容push到服务端

1.4.1 k8s部署

1.4.1.1 创建配置文件
server:log_level: infohttp_listen_port: 3101
clients:- url: http://loki:3100/loki/api/v1/push
positions:filename: /run/promtail/positions.yaml
scrape_configs:- job_name: kubernetes-podspipeline_stages:- cri: {}kubernetes_sd_configs:- role: podrelabel_configs:- source_labels:- __meta_kubernetes_pod_controller_nameregex: ([0-9a-z-.]+?)(-[0-9a-f]{8,10})?action: replacetarget_label: __tmp_controller_name- source_labels:- __meta_kubernetes_pod_label_app_kubernetes_io_name- __meta_kubernetes_pod_label_app- __tmp_controller_name- __meta_kubernetes_pod_nameregex: ^;*([^;]+)(;.*)?$action: replacetarget_label: app- source_labels:- __meta_kubernetes_pod_label_app_kubernetes_io_instance- __meta_kubernetes_pod_label_releaseregex: ^;*([^;]+)(;.*)?$action: replacetarget_label: instance- source_labels:- __meta_kubernetes_pod_label_app_kubernetes_io_component- __meta_kubernetes_pod_label_componentregex: ^;*([^;]+)(;.*)?$action: replacetarget_label: component- action: replacesource_labels:- __meta_kubernetes_pod_node_nametarget_label: node_name- action: replacesource_labels:- __meta_kubernetes_namespacetarget_label: namespace- action: replacereplacement: $1separator: /source_labels:- namespace- apptarget_label: job- action: replacesource_labels:- __meta_kubernetes_pod_nametarget_label: pod- action: replacesource_labels:- __meta_kubernetes_pod_container_nametarget_label: container- action: replacereplacement: /var/log/pods/*$1/*.logseparator: /source_labels:- __meta_kubernetes_pod_uid- __meta_kubernetes_pod_container_nametarget_label: __path__- action: replaceregex: true/(.*)replacement: /var/log/pods/*$1/*.logseparator: /source_labels:- __meta_kubernetes_pod_annotationpresent_kubernetes_io_config_hash- __meta_kubernetes_pod_annotation_kubernetes_io_config_hash- __meta_kubernetes_pod_container_nametarget_label: __path__

用上面的内容创建一个configMap,方法同上

1.4.1.2 创建DaemonSet文件

Promtail是一个无状态应用不需要进行持久化存储只需要部署到集群里面就可以了,还是同样的准备DaemonSets创建文件。

kind: DaemonSet
apiVersion: apps/v1
metadata:name: promtailnamespace: defaultlabels:app.kubernetes.io/instance: promtailapp.kubernetes.io/name: promtailapp.kubernetes.io/version: 2.5.0
spec:selector:matchLabels:app.kubernetes.io/instance: promtailapp.kubernetes.io/name: promtailtemplate:metadata:labels:app.kubernetes.io/instance: promtailapp.kubernetes.io/name: promtailspec:volumes:- name: configconfigMap:name: promtail- name: runhostPath:path: /run/promtail- name: containershostPath:path: /var/lib/docker/containers- name: podshostPath:path: /var/log/podscontainers:- name: promtailimage: docker.io/grafana/promtail:2.3.0args:- '-config.file=/etc/promtail/promtail.yaml'ports:- name: http-metricscontainerPort: 3101protocol: TCPenv:- name: HOSTNAMEvalueFrom:fieldRef:apiVersion: v1fieldPath: spec.nodeNamevolumeMounts:- name: configmountPath: /etc/promtail- name: runmountPath: /run/promtail- name: containersreadOnly: truemountPath: /var/lib/docker/containers- name: podsreadOnly: truemountPath: /var/log/podsreadinessProbe:httpGet:path: /readyport: http-metricsscheme: HTTPinitialDelaySeconds: 10timeoutSeconds: 1periodSeconds: 10successThreshold: 1failureThreshold: 5imagePullPolicy: IfNotPresentsecurityContext:capabilities:drop:- ALLreadOnlyRootFilesystem: falseallowPrivilegeEscalation: falserestartPolicy: AlwaysserviceAccountName: promtailserviceAccount: promtailtolerations:- key: node-role.kubernetes.io/masteroperator: Existseffect: NoSchedule- key: node-role.kubernetes.io/control-planeoperator: Existseffect: NoSchedule
1.4.1.3 创建promtail应用
kubectl apply -f promtail.yaml

使用上面这个命令创建后就可以看到服务已经创建好了。接下来就是在Grafana里面添加DataSource查看数据了。
在这里插入图片描述

1.4.2 裸机部署

如果是裸机部署的情况下,需要对上面的配置文件做一下稍微的改动,更改clients的地址就可以,文件存放到/etc/loki/下,例如改成:

clients:- url: http://ipaddress:port/loki/api/v1/push

添加系统开机启动配置,service配置文件存放位置/usr/lib/systemd/system/loki-promtail.service内容如下

[Unit]
Description=Grafana Loki Log Ingester
Documentation=https://grafana.com/logs/
After=network-online.target[Service]
ExecStart=/bin/promtail --config.file /etc/loki/loki-promtail.yaml
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID[Install]
WantedBy=multi-user.target

启动方式同上面服务端部署内容

1.5 数据源

添加数据源,具体步骤: Grafana->Setting->DataSources->AddDataSource->Loki

注意httpURL地址,应用、服务部署在哪个namespace下,就需要指定它的FQDN地址,它的格式是ServiceName.namespace。如果默认在default下、创建的端口号是3100,就需要填写为http://loki:3100,这里为什么不写IP地址而写成服务的名字,是因为在k8s集群里面有个dns服务器会自动解析这个地址。
在这里插入图片描述

查找日志信息
在这里插入图片描述

1.6 其他客户端配置

1.6.1 Logstash作为日志收集客户端

在启动Logstash后我们需要安装一个插件,可以通过这个命令安装loki的输出插件,安装完成之后可以在logstashoutput中添加信息。

bin/logstash-plugin install logstash-output-loki

添加配置进行测试
完整的logstash配置信息,可以参考官网给出的内容LogstashConfigFile

output {loki {[url => "" | default = none | required=true][tenant_id => string | default = nil | required=false][message_field => string | default = "message" | required=false][include_fields => array | default = [] | required=false][batch_wait => number | default = 1(s) | required=false][batch_size => number | default = 102400(bytes) | required=false][min_delay => number | default = 1(s) | required=false][max_delay => number | default = 300(s) | required=false][retries => number | default = 10 | required=false][username => string | default = nil | required=false][password => secret | default = nil | required=false][cert => path | default = nil | required=false][key => path | default = nil| required=false][ca_cert => path | default = nil | required=false][insecure_skip_verify => boolean | default = false | required=false]}
}

或者采用logstashhttp输出模块,配置如下:

output {http {format => "json"http_method => "post"content_type => "application/json"connect_timeout => 10url => "http://loki:3100/loki/api/v1/push"message => '"message":"%{message}"}'}
}

1.7 Helm安装

如果想简便安装的话,可以采用helm来安装。helm将所有的安装步骤都进行了封装,简化了安装步骤。

对于想详细了解k8s的人来说,helm不太适合。因为它封装后自动执行,k8s管理员不知道各组件之间是如何依赖的,可能会造成误区。

废话不多说,下面开始helm安装:

  • 添加repo源
    helm repo add grafana https://grafana.github.io/helm-charts
  • 更新源
    helm repo update
  • 部署
    默认配置
    helm upgrade --install loki grafana/loki-simple-scalable
    自定义namespace
    helm upgrade --install loki --namespace=loki grafana/loki-simple-scalable
    自定义配置信息
    helm upgrade --install loki grafana/loki-simple-scalable --set "key1=val1,key2=val2,..."

1.8 故障解决方案

1.8.1 502 BadGateWay

loki的地址填写不正确
在k8s里面,地址填写错误造成了502。检查一下loki的地址是否是以下内容:

http://LokiServiceName
http://LokiServiceName.namespace
http://LokiServiceName.namespace:ServicePort

grafana和loki在不同的节点上,检查一下节点间网络通信状态、防火墙策略

1.8.2 Ingester not ready: instance xx:9095 in state JOINING

耐心等待一会,因为是allInOne模式程序启动需要一定的时间。

1.8.3 too many unhealthy instances in the ring

ingester.lifecycler.replication_factor改为1,是因为这个设置不正确造成的。这个在启动的时候会设置为多个复制源,但当前只部署了一个所以在查看label的时候提示这个

1.8.4 Data source connected

Data source connected, but no labels received. Verify that Loki and Promtail is configured properly

  • promtail无法将收集到的日志发送给loki,许可检查一下promtail的输出是不是正常
  • promtail在loki还没有准备就绪的时候把日志发送过来了,但loki没有接收到。如果需要重新接收日志,需要删除positions.yaml文件,具体路径可以用find查找一下位置
  • promtail忽略了目标日志文件或者配置文件错误造成的无法正常启动
  • promtail无法在指定的位置发现日志文件

这篇关于日志之Loki详细讲解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/662213

相关文章

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

flume系列之:查看flume系统日志、查看统计flume日志类型、查看flume日志

遍历指定目录下多个文件查找指定内容 服务器系统日志会记录flume相关日志 cat /var/log/messages |grep -i oom 查找系统日志中关于flume的指定日志 import osdef search_string_in_files(directory, search_string):count = 0

我在移动打工的日志

客户:给我搞一下录音 我:不会。不在服务范围。 客户:是不想吧 我:笑嘻嘻(气笑) 客户:小姑娘明明会,却欺负老人 我:笑嘻嘻 客户:那我交话费 我:手机号 客户:给我搞录音 我:不会。不懂。没搞过。 客户:那我交话费 我:手机号。这是电信的啊!!我这是中国移动!! 客户:我不管,我要充话费,充话费是你们的 我:可是这是移动!!中国移动!! 客户:我这是手机号 我:那又如何,这是移动!你是电信!!

沁恒CH32在MounRiver Studio上环境配置以及使用详细教程

目录 1.  RISC-V简介 2.  CPU架构现状 3.  MounRiver Studio软件下载 4.  MounRiver Studio软件安装 5.  MounRiver Studio软件介绍 6.  创建工程 7.  编译代码 1.  RISC-V简介         RISC就是精简指令集计算机(Reduced Instruction SetCom

arduino ide安装详细步骤

​ 大家好,我是程序员小羊! 前言: Arduino IDE 是一个专为编程 Arduino 微控制器设计的集成开发环境,使用起来非常方便。下面将介绍如何在不同平台上安装 Arduino IDE 的详细步骤,包括 Windows、Mac 和 Linux 系统。 一、在 Windows 上安装 Arduino IDE 1. 下载 Arduino IDE 打开 Arduino 官网

GPT系列之:GPT-1,GPT-2,GPT-3详细解读

一、GPT1 论文:Improving Language Understanding by Generative Pre-Training 链接:https://cdn.openai.com/research-covers/languageunsupervised/language_understanding_paper.pdf 启发点:生成loss和微调loss同时作用,让下游任务来适应预训

多路转接之select(fd_set介绍,参数详细介绍),实现非阻塞式网络通信

目录 多路转接之select 引入 介绍 fd_set 函数原型 nfds readfds / writefds / exceptfds readfds  总结  fd_set操作接口  timeout timevalue 结构体 传入值 返回值 代码 注意点 -- 调用函数 select的参数填充  获取新连接 注意点 -- 通信时的调用函数 添加新fd到

【详细介绍一下GEE】

GEE(Google Earth Engine)是一个强大的云计算平台,它允许用户处理和分析大规模的地球科学数据集,如卫星图像、气候模型输出等。以下是对GEE用法的详细介绍: 一、平台访问与账户设置 访问GEE平台: 用户可以通过访问Google Earth Engine的官方网站来开始使用GEE。 创建账户: 用户需要注册并登录Google账户,然后申请访问GEE平台。申请过程可能需要提

Detectorn2预训练模型复现:数据准备、训练命令、日志分析与输出目录

Detectorn2预训练模型复现:数据准备、训练命令、日志分析与输出目录 在深度学习项目中,目标检测是一项重要的任务。本文将详细介绍如何使用Detectron2进行目标检测模型的复现训练,涵盖训练数据准备、训练命令、训练日志分析、训练指标以及训练输出目录的各个文件及其作用。特别地,我们将演示在训练过程中出现中断后,如何使用 resume 功能继续训练,并将我们复现的模型与Model Zoo中的

专题二_滑动窗口_算法专题详细总结

目录 滑动窗口,引入: 滑动窗口,本质:就是同向双指针; 1.⻓度最⼩的⼦数组(medium) 1.解析:给我们一个数组nums,要我们找出最小子数组的和==target,首先想到的就是暴力解法 1)暴力: 2)优化,滑动窗口: 1.进窗口 2.出窗口 3.更新值 2.⽆重复字符的最⻓⼦串(medium) 1)仍然是暴力解法: 2)优化: 进窗口:hash[s[rig