直观:seo优化数据分析工具哪一个较好用?
优采云 发布时间: 2022-10-27 18:28直观:seo优化数据分析工具哪一个较好用?
考虑到我自己的网站优化经验,这个网站第三方统计已经被大量使用,主流统计也被大量使用。51la 和 googleanalytics 是我上次访问该站点时使用的 网站统计数据。后来,我发现谷歌分析非常强大。当然,我从不怀疑谷歌的技术。是的,所以我加入了 Google Analytics 并申请了 Google Adsense。
后来谷歌退出中国市场时,经常出现无法打开谷歌分析的情况,逐渐更换了CNZZ统计工具。后来百度推出百度统计,并在百度站长平台上暗示,所有站长都与SEO、百度统计和网站收录相关。对于网站的SEO效果,也将百度的统计数据链接到网站。
现在哪个统计工具更适合这个网站?对我来说,这四种统计工具都有自己的优势。在这里,说说我经常使用51la、Google Analytics、CNZZ和百度统计的经验。
1、使用上的人性化
这四种统计工具的易用性几乎相同。他们可以设置管理密码、查看密码并设置允许公开统计、隐藏统计的功能。统计代码可以在DIY中自由展示,初学者一眼就能看懂操作菜单。
相比之下,51la 的界面更小更精致。在查看关键词时,51la统计可以直接点击关键词后面的[go]进入网站的链接,这样网站管理员可以直接看到即将到来的网站。
谷歌分析的整体感觉还是比较深的,不能一下子接受,不太符合中国站长的口味。
CNZZ界面上有很多广告,但我们已经习惯了。操作比较简单,给人的感觉比较大气一点,配色也比较舒服,但是我讨厌右边的广告。要查看CNZZ中的关键字,您需要点击右侧。,然后点击关键词右侧的查看,点击网站返回初始页面。在易用性方面,51la略胜一筹。
百度统计界面简洁清新,没有广告。报表的折叠图和饼图闪动美观,尤其是小时对比图的简介页。毕竟百度服务器多,带宽大,所以易用性和易用性,优邦云认为百度统计胜出。
2、基本功能对比
CNZZ和百度统计有多种隐藏图标的样式选项,但51la只有一种。
CNZZ和百度统计可以用JS文件调用,51la不能用JS调用隐藏图标,数据不准确,会造成页面混乱。
51la页面可以自己DIY。可以根据自己的喜好设置在导航栏的左侧,也可以默认设置在顶部。CNZZ是固定宽屏导航栏上方的显示界面。界面布局方面,我有点喜欢51LA的刷新界面,CNZZ统计的标题广告不是很漂亮,右边的SID广告还在。
三、基本统计数据指标
数据指标是所有数据的基础,反映了流量分析的广度。
CNZZ报告的指标如下:
(1)时间分析:PV、独立访客、IP、人均浏览量、新增独立访客、人均浏览量。
(2) 搜索引擎搜索词:搜索次数、关键词数、独立访问者、IP、人均搜索次数。
(3)入站页面域名:访问次数、独立访问者、IP、新独立访问者、新访问者浏览数、网站访问总数。
(4)域名和页面:流量、唯一流量、IP、人均流量、平均停留时间、跳出率、进入人数、离开人数。
(5) 区域浏览器等:浏览次数、独立访客、IP、人均浏览次数、平均停留时间。
优化的解决方案:轻量级云原生日志收集方案 Loki
❝
本文转自掘金,原文:版权归原作者所有。欢迎投稿,请加微信好友:cloud-native-yang
您好,很高兴为您介绍掘金开发者平台上的轻量级kubernetes日志采集解决方案。我自己在生产环境中使用过这个解决方案。令我惊讶的是,与 ELK 方案相比,它在 Kubernetes 中占用的资源确实微不足道。那就跟着这个文章开始学习吧……
为什么使用 Loki
本文章重点介绍grafana开发的loki日志采集应用。Loki 是一个轻量级的日志采集和分析应用程序。它使用 promtail 获取日志内容并将其发送到 loki 进行存储。最后在grafana的数据源中添加一个数据源,用于日志展示和查询。
Loki 的持久化存储支持 azure、gcs、s3、swift、local 5 种类型,其中 s3 和 local 比较常用。此外,它还支持多种类型的日志采集,比如最常用的logstash和fluentbit也在官方支持列表中。
那么它有哪些优势呢?各个日志采集组件的优势,简单比较按名称安装的组件
麋鹿/EFK
弹性搜索、logstash、kibana、filebeat、kafka/redis
支持自定义grok定期分析复杂日志内容;仪表盘支持丰富的可视化展示
洛基
格拉法纳,洛基,promtail
占地面积小;原生支持 grafana;查询速度快;
Loki 的工作原理 日志解析格式
从上图我们可以看出,在解析日志的时候主要是基于索引。index 包括 pod 的时间戳和一些标签(其他标签是文件名、容器等),剩下的就是日志内容。具体查询效果如下:
{app="loki",namespace="kube-public"} 是索引。
日志采集架构模式
在使用过程中,官方推荐使用promtail作为代理,以DaemonSet方式采集kubernetes的worker节点上的日志。此外,您还可以使用上面提到的其他日志采集工具进行采集。这个文章最后会附上其他工具的配置方法。
Loki 部署模式有哪些?
Loki 是用许多组件微服务构建的,有 5 个微服务组件。在这 5 个中添加缓存,将数据放在一起以加快查询速度。数据放置在共享存储中,并且配置了 memberlist_config 部分并在实例之间共享状态,从而允许 Loki 无限扩展。配置 memberlist_config 部分后,使用轮询查找数据。为了使用方便,官方将所有微服务编译成二进制,可以通过命令行参数-target控制,支持all、read、write。我们可以在部署时根据日志卷的大小指定不同的模式。
全部(读写模式)
服务启动后,我们所做的所有数据查询和数据写入都来自这个节点。请参见下图:
读/写(读写分离模式)
在读写拆分模式下运行时,前端查询查询将流量转发到读取节点。querier、ruler、fronted在读节点上保留,distributor和ingester在写节点上保留。
以微服务模式运行
在微服务模式下,通过不同的配置参数启动不同的角色,每个进程引用其目标角色服务。
组件名称功能
分销商/调度器(分销商)
验证数据合规性;数据排序;哈希一致性;QPS 限制;转发;数据拷贝保证不丢失
采集器(摄取器)
时间戳排序;文件系统支持;WAL 预写;
查询前端
提供页面操作,向后端存储发送数据查询;query-queueing 可以防止在大容量查询时触发OOM;query-split 可以拆分大批量查询,最后进行数据聚合
查询者
使用logql语言查询后端存储中的日志
缓存
将查询到的日志缓存起来以备后用,如果数据不全,重新查询丢失的数据
大显身手的服务器端部署
上面我们已经谈了很多关于 loki 及其工作模式的内容。您还必须预料到它将如何部署,对吧?!关于如何部署,在哪里部署,部署后如何使用的问题,都会浮现在你的脑海中。部署前需要准备一个 k8s 集群。那就好,那就耐心的往下看吧……
应用图像
洛基
格拉法纳/洛基:2.5.0
促销
格拉法纳/promtail:2.5.0
AllInOne部署方式①k8s部署
我们从github下载的程序没有配置文件,需要提前准备一份文件。此处提供了完整的 allInOne 配置文件,并进行了一些优化。
配置文件内容如下
auth_enabled: false<br />target: all<br />ballast_bytes: 20480<br />server:<br /> grpc_listen_port: 9095<br /> http_listen_port: 3100<br /> graceful_shutdown_timeout: 20s<br /> grpc_listen_address: "0.0.0.0"<br /> grpc_listen_network: "tcp"<br /> grpc_server_max_concurrent_streams: 100<br /> grpc_server_max_recv_msg_size: 4194304<br /> grpc_server_max_send_msg_size: 4194304<br /> http_server_idle_timeout: 2m<br /> http_listen_address: "0.0.0.0"<br /> http_listen_network: "tcp"<br /> http_server_read_timeout: 30s<br /> http_server_write_timeout: 20s<br /> log_source_ips_enabled: true<br /> ## http_path_prefix如果需要更改,在推送日志的时候前缀都需要加指定的内容<br /> ## http_path_prefix: "/"<br /> register_instrumentation: true<br /> log_format: json<br /> log_level: info<br />distributor:<br /> ring:<br /> heartbeat_timeout: 3s<br /> kvstore:<br /> prefix: collectors/<br /> store: memberlist<br /> ## 需要提前创建好consul集群<br /> ## consul:<br /> ## http_client_timeout: 20s<br /> ## consistent_reads: true<br /> ## host: 127.0.0.1:8500<br /> ## watch_burst_size: 2<br /> ## watch_rate_limit: 2<br />querier:<br /> engine:<br /> max_look_back_period: 20s <br /> timeout: 3m0s <br /> extra_query_delay: 100ms <br /> max_concurrent: 10 <br /> multi_tenant_queries_enabled: true<br /> query_ingester_only: false<br /> query_ingesters_within: 3h0m0s<br /> query_store_only: false<br /> query_timeout: 5m0s<br /> tail_max_duration: 1h0s<br />query_scheduler:<br /> max_outstanding_requests_per_tenant: 2048<br /> grpc_client_config:<br /> max_recv_msg_size: 104857600<br /> max_send_msg_size: 16777216<br /> grpc_compression: gzip<br /> rate_limit: 0<br /> rate_limit_burst: 0<br /> backoff_on_ratelimits: false<br /> backoff_config:<br /> min_period: 50ms<br /> max_period: 15s<br /> max_retries: 5 <br /> use_scheduler_ring: true<br /> scheduler_ring:<br /> kvstore:<br /> store: memberlist<br /> prefix: "collectors/"<br /> heartbeat_period: 30s<br /> heartbeat_timeout: 1m0s<br /> ## 默认第一个网卡的名称<br /> ## instance_interface_names<br /> ## instance_addr: 127.0.0.1<br /> ## 默认server.grpc-listen-port<br /> instance_port: 9095<br />frontend:<br /> max_outstanding_per_tenant: 4096<br /> querier_forget_delay: 1h0s<br /> compress_responses: true<br /> log_queries_longer_than: 2m0s<br /> max_body_size: 104857600<br /> query_stats_enabled: true<br /> scheduler_dns_lookup_period: 10s <br /> scheduler_worker_concurrency: 15<br />query_range:<br /> align_queries_with_step: true<br /> cache_results: true<br /> parallelise_shardable_queries: true<br /> max_retries: 3<br /> results_cache:<br /> cache:<br /> enable_fifocache: false<br /> default_validity: 30s <br /> background:<br /> writeback_buffer: 10000<br /> redis:<br /> endpoint: 127.0.0.1:6379<br /> timeout: 1s<br /> expiration: 0s <br /> db: 9<br /> pool_size: 128 <br /> password: 1521Qyx6^<br /> tls_enabled: false<br /> tls_insecure_skip_verify: true<br /> idle_timeout: 10s <br /> max_connection_age: 8h<br />ruler:<br /> enable_api: true<br /> enable_sharding: true<br /> alertmanager_refresh_interval: 1m<br /> disable_rule_group_label: false<br /> evaluation_interval: 1m0s<br /> flush_period: 3m0s<br /> for_grace_period: 20m0s<br /> for_outage_tolerance: 1h0s<br /> notification_queue_capacity: 10000<br /> notification_timeout: 4s<br /> poll_interval: 10m0s<br /> query_stats_enabled: true<br /> remote_write:<br /> config_refresh_period: 10s<br /> enabled: false<br /> resend_delay: 2m0s<br /> rule_path: /rulers<br /> search_pending_for: 5m0s<br /> storage:<br /> local:<br /> directory: /data/loki/rulers<br /> type: configdb<br /> sharding_strategy: default<br /> wal_cleaner:<br /> period: 240h<br /> min_age: 12h0m0s<br /> wal:<br /> dir: /data/loki/ruler_wal<br /> max_age: 4h0m0s<br /> min_age: 5m0s<br /> truncate_frequency: 1h0m0s<br /> ring:<br /> kvstore:<br /> store: memberlist<br /> prefix: "collectors/"<br /> heartbeat_period: 5s<br /> heartbeat_timeout: 1m0s<br /> ## instance_addr: "127.0.0.1"<br /> ## instance_id: "miyamoto.en0"<br /> ## instance_interface_names: ["en0","lo0"]<br /> instance_port: 9500<br /> num_tokens: 100<br />ingester_client:<br /> pool_config:<br /> health_check_ingesters: false<br /> client_cleanup_period: 10s <br /> remote_timeout: 3s<br /> remote_timeout: 5s <br />ingester:<br /> autoforget_unhealthy: true<br /> chunk_encoding: gzip<br /> chunk_target_size: 1572864<br /> max_transfer_retries: 0<br /> sync_min_utilization: 3.5<br /> sync_period: 20s<br /> flush_check_period: 30s <br /> flush_op_timeout: 10m0s<br /> chunk_retain_period: 1m30s<br /> chunk_block_size: 262144<br /> chunk_idle_period: 1h0s<br /> max_returned_stream_errors: 20<br /> concurrent_flushes: 3<br /> index_shards: 32<br /> max_chunk_age: 2h0m0s<br /> query_store_max_look_back_period: 3h30m30s<br /> wal:<br /> enabled: true<br /> dir: /data/loki/wal <br /> flush_on_shutdown: true<br /> checkpoint_duration: 15m<br /> replay_memory_ceiling: 2GB<br /> lifecycler:<br /> ring:<br /> kvstore:<br /> store: memberlist<br /> prefix: "collectors/"<br /> heartbeat_timeout: 30s <br /> replication_factor: 1<br /> num_tokens: 128<br /> heartbeat_period: 5s <br /> join_after: 5s <br /> observe_period: 1m0s<br /> ## interface_names: ["en0","lo0"]<br /> final_sleep: 10s <br /> min_ready_duration: 15s<br />storage_config:<br /> boltdb:<br /> directory: /data/loki/boltdb <br /> boltdb_shipper:<br /> active_index_directory: /data/loki/active_index<br /> build_per_tenant_index: true<br /> cache_location: /data/loki/cache <br /> cache_ttl: 48h<br /> resync_interval: 5m<br /> query_ready_num_days: 5<br /> index_gateway_client:<br /> grpc_client_config:<br /> filesystem:<br /> directory: /data/loki/chunks<br />chunk_store_config:<br /> chunk_cache_config:<br /> enable_fifocache: true<br /> default_validity: 30s<br /> background:<br /> writeback_buffer: 10000<br /> redis:<br /> endpoint: 192.168.3.56:6379<br /> timeout: 1s<br /> expiration: 0s <br /> db: 8 <br /> pool_size: 128 <br /> password: 1521Qyx6^<br /> tls_enabled: false<br /> tls_insecure_skip_verify: true<br /> idle_timeout: 10s <br /> max_connection_age: 8h<br /> fifocache:<br /> ttl: 1h<br /> validity: 30m0s<br /> max_size_items: 2000<br /> max_size_bytes: 500MB<br /> write_dedupe_cache_config:<br /> enable_fifocache: true<br /> default_validity: 30s <br /> background:<br /> writeback_buffer: 10000<br /> redis:<br /> endpoint: 127.0.0.1:6379<br /> timeout: 1s<br /> expiration: 0s <br /> db: 7<br /> pool_size: 128 <br /> password: 1521Qyx6^<br /> tls_enabled: false<br /> tls_insecure_skip_verify: true<br /> idle_timeout: 10s <br /> max_connection_age: 8h<br /> fifocache:<br /> ttl: 1h<br /> validity: 30m0s<br /> max_size_items: 2000<br /> max_size_bytes: 500MB<br /> cache_lookups_older_than: 10s <br />## 压缩碎片索引<br />compactor:<br /> shared_store: filesystem<br /> shared_store_key_prefix: index/<br /> working_directory: /data/loki/compactor<br /> compaction_interval: 10m0s<br /> retention_enabled: true<br /> retention_delete_delay: 2h0m0s<br /> retention_delete_worker_count: 150<br /> delete_request_cancel_period: 24h0m0s<br /> max_compaction_parallelism: 2<br /> ## compactor_ring:<br />frontend_worker:<br /> match_max_concurrent: true<br /> parallelism: 10<br /> dns_lookup_duration: 5s <br />## runtime_config 这里没有配置任何信息<br />## runtime_config:<br />common:<br /> storage:<br /> filesystem:<br /> chunks_directory: /data/loki/chunks<br /> fules_directory: /data/loki/rulers<br /> replication_factor: 3<br /> persist_tokens: false<br /> ## instance_interface_names: ["en0","eth0","ens33"]<br />analytics:<br /> reporting_enabled: false<br />limits_config:<br /> ingestion_rate_strategy: global<br /> ingestion_rate_mb: 100<br /> ingestion_burst_size_mb: 18<br /> max_label_name_length: 2096<br /> max_label_value_length: 2048<br /> max_label_names_per_series: 60<br /> enforce_metric_name: true<br /> max_entries_limit_per_query: 5000<br /> reject_old_samples: true<br /> reject_old_samples_max_age: 168h<br /> creation_grace_period: 20m0s<br /> max_global_streams_per_user: 5000<br /> unordered_writes: true<br /> max_chunks_per_query: 200000<br /> max_query_length: 721h<br /> max_query_parallelism: 64 <br /> max_query_series: 700<br /> cardinality_limit: 100000<br /> max_streams_matchers_per_query: 1000 <br /> max_concurrent_tail_requests: 10 <br /> ruler_evaluation_delay_duration: 3s <br /> ruler_max_rules_per_rule_group: 0<br /> ruler_max_rule_groups_per_tenant: 0<br /> retention_period: 700h<br /> per_tenant_override_period: 20s <br /> max_cache_freshness_per_query: 2m0s<br /> max_queriers_per_tenant: 0<br /> per_stream_rate_limit: 6MB<br /> per_stream_rate_limit_burst: 50MB<br /> max_query_lookback: 0<br /> ruler_remote_write_disabled: false<br /> min_sharding_lookback: 0s<br /> split_queries_by_interval: 10m0s<br /> max_line_size: 30mb<br /> max_line_size_truncate: false<br /> max_streams_per_user: 0<br /><br />## memberlist_conig模块配置gossip用于在分发服务器、摄取器和查询器之间发现和连接。<br />## 所有三个组件的配置都是唯一的,以确保单个共享环。<br />## 至少定义了1个join_members配置后,将自动为分发服务器、摄取器和ring 配置memberlist类型的kvstore<br />memberlist:<br /> randomize_node_name: true<br /> stream_timeout: 5s <br /> retransmit_factor: 4<br /> join_members:<br /> - 'loki-memberlist'<br /> abort_if_cluster_join_fails: true<br /> advertise_addr: 0.0.0.0<br /> advertise_port: 7946<br /> bind_addr: ["0.0.0.0"]<br /> bind_port: 7946<br /> compression_enabled: true<br /> dead_node_reclaim_time: 30s<br /> gossip_interval: 100ms<br /> gossip_nodes: 3<br /> gossip_to_dead_nodes_time: 3<br /> ## join:<br /> leave_timeout: 15s<br /> left_ingesters_timeout: 3m0s <br /> max_join_backoff: 1m0s<br /> max_join_retries: 5<br /> message_history_buffer_bytes: 4096<br /> min_join_backoff: 2s<br /> ## node_name: miyamoto<br /> packet_dial_timeout: 5s<br /> packet_write_timeout: 5s <br /> pull_push_interval: 100ms<br /> rejoin_interval: 10s<br /> tls_enabled: false<br /> tls_insecure_skip_verify: true<br />schema_config:<br /> configs:<br /> - from: "2020-10-24"<br /> index:<br /> period: 24h<br /> prefix: index_<br /> object_store: filesystem<br /> schema: v11<br /> store: boltdb-shipper<br /> chunks:<br /> period: 168h<br /> row_shards: 32<br />table_manager:<br /> retention_deletes_enabled: false<br /> retention_period: 0s<br /> throughput_updates_disabled: false<br /> poll_interval: 3m0s<br /> creation_grace_period: 20m<br /> index_tables_provisioning:<br /> provisioned_write_throughput: 1000<br /> provisioned_read_throughput: 500<br /> inactive_write_throughput: 4<br /> inactive_read_throughput: 300<br /> inactive_write_scale_lastn: 50 <br /> enable_inactive_throughput_on_demand_mode: true<br /> enable_ondemand_throughput_mode: true<br /> inactive_read_scale_lastn: 10 <br /> write_scale:<br /> enabled: true<br /> target: 80<br /> ## role_arn:<br /> out_cooldown: 1800<br /> min_capacity: 3000<br /> max_capacity: 6000<br /> in_cooldown: 1800<br /> inactive_write_scale:<br /> enabled: true<br /> target: 80<br /> out_cooldown: 1800<br /> min_capacity: 3000<br /> max_capacity: 6000<br /> in_cooldown: 1800<br /> read_scale:<br /> enabled: true<br /> target: 80<br /> out_cooldown: 1800<br /> min_capacity: 3000<br /> max_capacity: 6000<br /> in_cooldown: 1800<br /> inactive_read_scale:<br /> enabled: true<br /> target: 80<br /> out_cooldown: 1800<br /> min_capacity: 3000<br /> max_capacity: 6000<br /> in_cooldown: 1800<br /> chunk_tables_provisioning:<br /> enable_inactive_throughput_on_demand_mode: true<br /> enable_ondemand_throughput_mode: true<br /> provisioned_write_throughput: 1000<br /> provisioned_read_throughput: 300<br /> inactive_write_throughput: 1<br /> inactive_write_scale_lastn: 50<br /> inactive_read_throughput: 300<br /> inactive_read_scale_lastn: 10<br /> write_scale:<br /> enabled: true<br /> target: 80<br /> out_cooldown: 1800<br /> min_capacity: 3000<br /> max_capacity: 6000<br /> in_cooldown: 1800<br /> inactive_write_scale:<br /> enabled: true<br /> target: 80<br /> out_cooldown: 1800<br /> min_capacity: 3000<br /> max_capacity: 6000<br /> in_cooldown: 1800<br /> read_scale:<br /> enabled: true<br /> target: 80<br /> out_cooldown: 1800<br /> min_capacity: 3000<br /> max_capacity: 6000<br /> in_cooldown: 1800<br /> inactive_read_scale:<br /> enabled: true<br /> target: 80<br /> out_cooldown: 1800<br /> min_capacity: 3000<br /> max_capacity: 6000<br /> in_cooldown: 1800<br />tracing:<br /> enabled: true<br />复制代码<br />
注意 :
创建配置图
说明:将上述内容写入一个文件-> loki-all.yaml,并作为configmap写入k8s集群。可以使用以下命令创建它:
$ kubectl create configmap --from-file ./loki-all.yaml loki-all<br />
可以通过命令查看创建的configmap。详情见下图。
创建持久存储
在 k8s 中,我们的数据需要持久化。Loki 采集的日志信息对业务至关重要,因此需要在容器重启时保留日志。然后你需要使用pv和pvc。后端存储可以使用nfs、glusterfs、hostPath、azureDisk、cephfs等20种支持类型,这里因为没有对应的环境,所以采用hostPath方式。
apiVersion: v1<br />kind: PersistentVolume<br />metadata:<br /> name: loki<br /> namespace: default<br />spec:<br /> hostPath:<br /> path: /glusterfs/loki<br /> type: DirectoryOrCreate<br /> capacity:<br /> storage: 1Gi<br /> accessModes:<br /> - ReadWriteMany<br />---<br />apiVersion: v1<br />kind: PersistentVolumeClaim<br />metadata:<br /> name: loki<br /> namespace: default<br />spec:<br /> accessModes:<br /> - ReadWriteMany<br /> resources:<br /> requests:<br /> storage: 1Gi<br /> volumeName: loki<br />
创建应用
准备好k8s StatefulSet部署文件后,就可以直接在集群中创建应用了。
apiVersion: apps/v1<br />kind: StatefulSet<br />metadata:<br /> labels:<br /> app: loki<br /> name: loki<br /> namespace: default<br />spec:<br /> podManagementPolicy: OrderedReady<br /> replicas: 1<br /> selector:<br /> matchLabels:<br /> app: loki<br /> template:<br /> metadata:<br /> annotations:<br /> prometheus.io/port: http-metrics<br /> prometheus.io/scrape: "true"<br /> labels:<br /> app: loki<br /> spec:<br /> containers:<br /> - args:<br /> - -config.file=/etc/loki/loki-all.yaml<br /> image: grafana/loki:2.5.0<br /> imagePullPolicy: IfNotPresent<br /> livenessProbe:<br /> failureThreshold: 3<br /> httpGet:<br /> path: /ready<br /> port: http-metrics<br /> scheme: HTTP<br /> initialDelaySeconds: 45<br /> periodSeconds: 10<br /> successThreshold: 1<br /> timeoutSeconds: 1<br /> name: loki<br /> ports:<br /> - containerPort: 3100<br /> name: http-metrics<br /> protocol: TCP<br /> - containerPort: 9095<br /> name: grpc<br /> protocol: TCP<br /> - containerPort: 7946<br /> name: memberlist-port<br /> protocol: TCP<br /> readinessProbe:<br /> failureThreshold: 3<br /> httpGet:<br /> path: /ready<br /> port: http-metrics<br /> scheme: HTTP<br /> initialDelaySeconds: 45<br /> periodSeconds: 10<br /> successThreshold: 1<br /> timeoutSeconds: 1<br /> resources:<br /> requests:<br /> cpu: 500m<br /> memory: 500Mi<br /> limits:<br /> cpu: 500m<br /> memory: 500Mi<br /> securityContext:<br /> readOnlyRootFilesystem: true<br /> volumeMounts:<br /> - mountPath: /etc/loki<br /> name: config<br /> - mountPath: /data<br /> name: storage<br /> restartPolicy: Always<br /> securityContext:<br /> fsGroup: 10001<br /> runAsGroup: 10001<br /> runAsNonRoot: true<br /> runAsUser: 10001<br /> serviceAccount: loki<br /> serviceAccountName: loki<br /> volumes:<br /> - emptyDir: {}<br /> name: tmp<br /> - name: config<br /> configMap:<br /> name: loki<br /> - persistentVolumeClaim:<br /> claimName: loki<br /> name: storage<br />---<br />kind: Service<br />apiVersion: v1<br />metadata:<br /> name: loki-memberlist<br /> namespace: default<br />spec:<br /> ports:<br /> - name: loki-memberlist<br /> protocol: TCP<br /> port: 7946<br /> targetPort: 7946<br /> selector:<br /> kubepi.org/name: loki<br />---<br />kind: Service<br />apiVersion: v1<br />metadata:<br /> name: loki<br /> namespace: default<br />spec:<br /> ports:<br /> - name: loki<br /> protocol: TCP<br /> port: 3100<br /> targetPort: 3100<br /> selector:<br /> kubepi.org/name: loki<br />
在上面的配置文件中,我添加了一些 pod 级别的安全策略。这些安全策略还有集群级别的 PodSecurityPolicy 来防止整个集群因为漏洞而崩溃。集群级psp请参考官方文档[1]。
验证部署结果
当你看到上面的 Running 状态时,你可以使用 API 查看分发器是否正常工作。显示Active时,日志流会正常分发到采集器(ingester)。
② 裸机部署
将loki放到系统的/bin/目录下,准备grafana-loki.service控制文件重新加载系统服务列表
[Unit]<br />Description=Grafana Loki Log Ingester<br />Documentation=https://grafana.com/logs/<br />After=network-online.target<br /><br />[Service]<br />ExecStart=/bin/loki --config.file /etc/loki/loki-all.yaml<br />ExecReload=/bin/kill -s HUP $MAINPID<br />ExecStop=/bin/kill -s TERM $MAINPID<br /><br />[Install]<br />WantedBy=multi-user.target<br />
重新加载系统列表命令,由系统直接自动管理服务:
$ systemctl daemon-reload<br />## 启动服务<br />$ systemctl start grafana-loki<br />## 停止服务<br />$ systemctl stop grafana-loki<br />## 重载应用<br />$ systemctl reload grafana-loki<br />
Promtail部署如火如荼
在部署客户端采集日志时,还需要创建配置文件,按照上面创建服务器的步骤操作即可。不同的是需要将日志内容推送到服务器
① k8s部署创建配置文件
server:<br /> log_level: info<br /> http_listen_port: 3101<br />clients:<br /> - url: http://loki:3100/loki/api/v1/push<br />positions:<br /> filename: /run/promtail/positions.yaml<br />scrape_configs:<br /> - job_name: kubernetes-pods<br /> pipeline_stages:<br /> - cri: {}<br /> kubernetes_sd_configs:<br /> - role: pod<br /> relabel_configs:<br /> - source_labels:<br /> - __meta_kubernetes_pod_controller_name<br /> regex: ([0-9a-z-.]+?)(-[0-9a-f]{8,10})?<br /> action: replace<br /> target_label: __tmp_controller_name<br /> - source_labels:<br /> - __meta_kubernetes_pod_label_app_kubernetes_io_name<br /> - __meta_kubernetes_pod_label_app<br /> - __tmp_controller_name<br /> - __meta_kubernetes_pod_name<br /> regex: ^;*([^;]+)(;.*)?$<br /> action: replace<br /> target_label: app<br /> - source_labels:<br /> - __meta_kubernetes_pod_label_app_kubernetes_io_instance<br /> - __meta_kubernetes_pod_label_release<br /> regex: ^;*([^;]+)(;.*)?$<br /> action: replace<br /> target_label: instance<br /> - source_labels:<br /> - __meta_kubernetes_pod_label_app_kubernetes_io_component<br /> - __meta_kubernetes_pod_label_component<br /> regex: ^;*([^;]+)(;.*)?$<br /> action: replace<br /> target_label: component<br /> - action: replace<br /> source_labels:<br /> - __meta_kubernetes_pod_node_name<br /> target_label: node_name<br /> - action: replace<br /> source_labels:<br /> - __meta_kubernetes_namespace<br /> target_label: namespace<br /> - action: replace<br /> replacement: $1<br /> separator: /<br /> source_labels:<br /> - namespace<br /> - app<br /> target_label: job<br /> - action: replace<br /> source_labels:<br /> - __meta_kubernetes_pod_name<br /> target_label: pod<br /> - action: replace<br /> source_labels:<br /> - __meta_kubernetes_pod_container_name<br /> target_label: container<br /> - action: replace<br /> replacement: /var/log/pods/*$1/*.log<br /> separator: /<br /> source_labels:<br /> - __meta_kubernetes_pod_uid<br /> - __meta_kubernetes_pod_container_name<br /> target_label: __path__<br /> - action: replace<br /> regex: true/(.*)<br /> replacement: /var/log/pods/*$1/*.log<br /> separator: /<br /> source_labels:<br /> - __meta_kubernetes_pod_annotationpresent_kubernetes_io_config_hash<br /> - __meta_kubernetes_pod_annotation_kubernetes_io_config_hash<br /> - __meta_kubernetes_pod_container_name<br /> target_label: __path__<br />
用同样的方法创建一个收录上述内容的configMap
创建 DaemonSet 文件
Promtail 是一个无状态的应用程序,不需要持久化存储,只需要部署到集群中即可。准备 DaemonSets 来创建文件还是一样的。
kind: DaemonSet<br />apiVersion: apps/v1<br />metadata:<br /> name: promtail<br /> namespace: default<br /> labels:<br /> app.kubernetes.io/instance: promtail<br /> app.kubernetes.io/name: promtail<br /> app.kubernetes.io/version: 2.5.0<br />spec:<br /> selector:<br /> matchLabels:<br /> app.kubernetes.io/instance: promtail<br /> app.kubernetes.io/name: promtail<br /> template:<br /> metadata:<br /> labels:<br /> app.kubernetes.io/instance: promtail<br /> app.kubernetes.io/name: promtail<br /> spec:<br /> volumes:<br /> - name: config<br /> configMap:<br /> name: promtail<br /> - name: run<br /> hostPath:<br /> path: /run/promtail<br /> - name: containers<br /> hostPath:<br /> path: /var/lib/docker/containers<br /> - name: pods<br /> hostPath:<br /> path: /var/log/pods<br /> containers:<br /> - name: promtail<br /> image: docker.io/grafana/promtail:2.3.0<br /> args:<br /> - '-config.file=/etc/promtail/promtail.yaml'<br /> ports:<br /> - name: http-metrics<br /> containerPort: 3101<br /> protocol: TCP<br /> env:<br /> - name: HOSTNAME<br /> valueFrom:<br /> fieldRef:<br /> apiVersion: v1<br /> fieldPath: spec.nodeName<br /> volumeMounts:<br /> - name: config<br /> mountPath: /etc/promtail<br /> - name: run<br /> mountPath: /run/promtail<br /> - name: containers<br /> readOnly: true<br /> mountPath: /var/lib/docker/containers<br /> - name: pods<br /> readOnly: true<br /> mountPath: /var/log/pods<br /> readinessProbe:<br /> httpGet:<br /> path: /ready<br /> port: http-metrics<br /> scheme: HTTP<br /> initialDelaySeconds: 10<br /> timeoutSeconds: 1<br /> periodSeconds: 10<br /> successThreshold: 1<br /> failureThreshold: 5<br /> imagePullPolicy: IfNotPresent<br /> securityContext:<br /> capabilities:<br /> drop:<br /> - ALL<br /> readOnlyRootFilesystem: false<br /> allowPrivilegeEscalation: false<br /> restartPolicy: Always<br /> serviceAccountName: promtail<br /> serviceAccount: promtail<br /> tolerations:<br /> - key: node-role.kubernetes.io/master<br /> operator: Exists<br /> effect: NoSchedule<br /> - key: node-role.kubernetes.io/control-plane<br /> operator: Exists<br /> effect: NoSchedule<br />
创建一个 promtail 应用程序
$ kubectl apply -f promtail.yaml<br />
使用上面的命令创建后,可以看到服务已经创建好了。下一步是添加一个 DataSource 来查看 Grafana 中的数据。
② 裸机部署
如果是裸机部署,需要对上面的配置文件稍作改动,可以更改客户端的地址,文件存放在/etc/loki/,例如改成:
clients:<br /> - url: http://ipaddress:port/loki/api/v1/push<br />
添加系统启动配置,服务配置文件存放位置/usr/lib/systemd/system/loki-promtail.service内容如下
[Unit]<br />Description=Grafana Loki Log Ingester<br />Documentation=https://grafana.com/logs/<br />After=network-online.target<br /><br />[Service]<br />ExecStart=/bin/promtail --config.file /etc/loki/loki-promtail.yaml<br />ExecReload=/bin/kill -s HUP $MAINPID<br />ExecStop=/bin/kill -s TERM $MAINPID<br /><br />[Install]<br />WantedBy=multi-user.target<br />
启动方法同上面的服务器部署内容
Loki 在 DataSource 添加数据源
具体步骤:Grafana->Setting->DataSources->AddDataSource->Loki
注意:http的URL地址,应用和服务部署在哪个namespace中,需要指定其FQDN地址,格式为ServiceName.namespace。如果默认是默认下,创建的端口号是3100,则需要填写:3100。这里为什么不写IP地址,写服务名,因为k8s集群中有dns服务器会自动解决这个地址。
查找日志信息
页面 display.png 其他客户端配置Logstash为日志采集客户端安装插件
启动 Logstash 后,我们需要安装一个插件。可以通过该命令安装loki的输出插件。安装完成后,可以在logstash的输出中添加信息。
$ bin/logstash-plugin install logstash-output-loki<br />
添加测试配置
完整的logstash配置信息可以参考官网LogstashConfigFile[2]给出的内容
output {<br /> loki {<br /> [url => "" | default = none | required=true]<br /> [tenant_id => string | default = nil | required=false]<br /> [message_field => string | default = "message" | required=false]<br /> [include_fields => array | default = [] | required=false]<br /> [batch_wait => number | default = 1(s) | required=false]<br /> [batch_size => number | default = 102400(bytes) | required=false]<br /> [min_delay => number | default = 1(s) | required=false]<br /> [max_delay => number | default = 300(s) | required=false]<br /> [retries => number | default = 10 | required=false]<br /> [username => string | default = nil | required=false]<br /> [password => secret | default = nil | required=false]<br /> [cert => path | default = nil | required=false]<br /> [key => path | default = nil| required=false]<br /> [ca_cert => path | default = nil | required=false]<br /> [insecure_skip_verify => boolean | default = false | required=false]<br /> }<br />}<br />
或者使用logstash的http输出模块,配置如下:
output {<br /> http {<br /> format => "json"<br /> http_method => "post"<br /> content_type => "application/json"<br /> connect_timeout => 10<br /> url => "http://loki:3100/loki/api/v1/push"<br /> message => '"message":"%{message}"}'<br /> }<br />}<br />
头盔安装
如果您想轻松安装,可以使用 helm 安装。helm 封装了所有安装步骤,简化了安装步骤。对于想进一步了解 k8s 的人来说,helm 并不适合。因为是封装后自动执行的,所以k8s管理员不知道各个组件是如何相互依赖的,可能会造成误解。废话不多说,开始 helm 安装
添加回购源
$ helm repo add grafana https://grafana.github.io/helm-charts<br />
更新源
$ helm repo update<br />
部署默认配置
$ helm upgrade --install loki grafana/loki-simple-scalable<br />
自定义命名空间
$ helm upgrade --install loki --namespace=loki grafana/loki-simple-scalable<br />
自定义配置信息
$ helm upgrade --install loki grafana/loki-simple-scalable --set "key1=val1,key2=val2,..."<br />
故障排除 502 BadGateWayIngester not ready: instance xx:9095 in state JOININGtoo many unhealthy instances in the ringData source connected, but no label received. 验证 Loki 和 Promtail 是否配置正确参考链接 [1]
官方文档:%3A%2F%2Fkubernetes.io%2Fdocs%2Fconcepts%2Fsecurity%2Fpod-security-policy%2F
[2]
LogstashConfigFile:%3A%2F%2F%2Fguide%2Fen%2Flogstash%2Fcurrent%2Fconfiguration-file-structure.html
[3]
配置文件参考 1:%3A%2F%%2Fdocs%2Floki%2Flatest%2Fconfiguration%2F%23server
你可能还喜欢
点击下图阅读
云原生是一种信念