直观: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 />

  注意 :

  创建配置图

  说明:将上述内容写入一个文件-&gt; 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-&gt;Setting-&gt;DataSources-&gt;AddDataSource-&gt;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

  你可能还喜欢

  点击下图阅读

  云原生是一种信念

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线