
使用 Tanka/Ksonnet 在 Kubernetes 上部署 Loki微服务架构、多可用区 Ingester 与生产级配置详解【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki导读本文以 production/ksonnet/README.md 为核心系统讲解如何基于 TankaKsonnet 的继任者以声明式 Jsonnet 方式在 Kubernetes 上部署 Loki。文章覆盖 Tanka 环境初始化、jb依赖安装、loki gateway的完整配置清单存储后端、TSDB Schema、认证网关、微服务各组件资源规格以及 README 中专门给出的多可用区MultizoneIngester 配置——这是面向生产环境高可用部署的关键能力。读完本文你将掌握用tk apply一键交付整套 Loki 微服务集群并理解multi_zone_ingester_*系列参数背后真实的调度、副本与迁移语义。背景从 Ksonnet 到 Tanka为什么 Loki 官方仍然维护 ksonnet 目录Loki 在production/ksonnet目录下保留了一套完整的Jsonnet 部署清单loki.libsonnet它由 Grafana Labs 以 Ksonnet 时代的 Jsonnet 库形式维护。虽然 Ksonnet 项目本身已停止维护但官方 Tanka 安装文档 明确指出Tanka 是 Ksonnet 的重新实现并且被 Grafana Labs 用来在生产环境运行 Grafana Loki。因此这套 ksonnet 库是Tanka 部署 Loki的一等公民资源而非历史遗留。Tanka 部署的运行模式是microservices mode微服务模式即每个 Loki 组件distributor、ingester、querier、query-frontend、query-scheduler、ruler、compactor、index-gateway 等以独立 Deployment/StatefulSet 运行与单二进制模式相对。从 loki.libsonnet 的组合顺序可以看到完整的服务拓扑(import distributor.libsonnet) (import ingester.libsonnet) (import querier.libsonnet) (import query-frontend.libsonnet) (import ruler.libsonnet) (import query-scheduler.libsonnet) (import memcached.libsonnet) (import overrides-exporter.libsonnet) (import index-gateway.libsonnet) (import shipper.libsonnet) (import compactor.libsonnet) (import multi-zone.libsonnet) (import memberlist.libsonnet) 前置条件Tanka 与 jsonnet-bundler 的安装官方要求Tanka v0.31.0 或更高版本用于tk env系列命令以及jbjsonnet-bundlerv0.6.0 或更高版本来拉取 Jsonnet 依赖。在配置仓库中初始化一个 Tanka 应用mkdir application name cd application name tk init tk env add environments/loki --namespaceloki --serverKubernetes API server其中--server指向 Kube API Server 地址如https://localhost:6443。tk env add会生成environments/loki/环境目录后续所有 Jsonnet 清单都写在这个目录下的main.jsonnet中。认证提示Loki 本身不内置任何认证层官方文档明确说明。必须在前置部署一个反向代理做认证如 nginx防止未授权访问。ksonnet 库中的gateway模块正是为这一目的设计的详见下文网关gateway模块。拉取 Loki 模块依赖jb init # 如果已经执行过 tk init 则可跳过 jb install github.com/grafana/loki/production/ksonnet/lokimainjb install会把 Loki 的 ksonnet 库及其传递依赖ksonnet-util、kausal 库、consul mixin、jaeger-agent-mixin 等见 production/ksonnet/loki/jsonnetfile.json安装到vendor/目录。最小可用配置loki gateway 组合编辑environments/loki/main.jsonnet将官方示例作为起点。下面是与 Tanka 官方文档一致的完整清单并补充了各字段的取值说明local gateway import loki/gateway.libsonnet; local loki import loki/loki.libsonnet; loki gateway { _config:: { namespace: loki, htpasswd_contents: loki:$apr1$H4yGiGNg$ssl5/NymaGFRUvxIV1Nyr., // 使用 TSDB shipper using_tsdb_shipper: true // 对象存储后端三选一s3、gcs、azure storage_backend: s3, // S3 变量storage_backend s3 时使用 s3_access_key: key, s3_secret_access_key: secret access key, s3_address: url, s3_bucket_name: loki-chunks, s3_bucket_region: us-east-1, s3_path_style: false, // GCS 变量storage_backend gcs 时使用 // gcs_bucket_name: loki-chunks, // Azure 变量storage_backend azure 时使用 // azure_container_name: loki-chunks, // azure_account_name: account, // azure_account_key: key, // TSDB 索引存储配置 loki: { schema_config: { configs: [{ from: YYYY-MM-DD, store: tsdb, object_store: $._config.storage_backend, schema: v13, index: { prefix: %s_index_ % $._config.table_prefix, period: %dh % $._config.index_period_hours, }, }], }, }, replication_factor: 3, memberlist_ring_enabled: true, }, }关键配置项的语义配置项默认值 / 取值范围说明namespace必填config.libsonnet 中error must define namespaceKubernetes 命名空间也是 Service DNS 名的组成部分storage_backend必填s3/gcs/azure决定object_store_config与thanos_object_store_config的生成分支见 config.libsonnets3_path_stylefalse是否使用 path-style 访问 S3自建 MinIO 等兼容对象存储通常需设为truereplication_factor默认3Ingester ring 副本因子直接注入loki.ingester.lifecycler.ring.replication_factormemberlist_ring_enabled默认false为所有 ring 启用 memberlist 而不再依赖 Consul详见下文using_tsdb_shippertrueTSDB shipper 模式同时自动将 querier 切换为有状态部署shipper.libsonnet 中stateful_queriers强制为trueindex_period_hours默认24索引表周期1 天schema_config中period字段由它生成table_prefix默认取namespace索引表名前缀关于from日期的生产建议Tanka 官方文档特别强调schema_config.configs[0].from表示该 schema 生效的第一天建议设置为当前日期前 7 天以内例如今天2021-01-15就设2021-01-08。原因是 Loki 默认只接受过去 1 周168h内的日志由reject_old_samples_max_age控制见 config.libsonnet 中的reject_old_samples: true与reject_old_samples_max_age: 168h。同时官方建议新装环境统一采用 TSDBstore: tsdb、schema: v13。对象存储配置的三套后端config.libsonnet 根据storage_backend自动生成object_store_configS3拼接s3://access_key:secretaddress/bucket形式的 endpoint URL若s3_access_key为空则生成无凭证 URLs3_bucket_region非空时附带region。s3forcepathstyle由s3_path_style控制。GCSgcs.bucket_name来自gcs_bucket_name且该字段在 config.libsonnet 中声明为必填error must specify GCS bucket name。Azureazure.container_name/account_name必填account_key非空才写入官方注释建议通过环境变量注入密钥而非明文写入清单。若设置use_thanos_objstore: true则会额外生成thanos_object_store_config并注入storage_config.object_store这也是 config.libsonnet 中use_thanos_objstore分支的用途。部署、预览与清理配置完成后执行tk show environments/loki # 渲染出即将部署的全部 Kubernetes 清单 tk apply environments/loki # 部署到集群 tk delete environments/loki # 从集群删除环境tk show可先输出 YAML 供审查所有清单由loki.libsonnet组合出的组件gateway Deployment、distributor/querier Deployment、ingester StatefulSet、各 Service、PDB、ConfigMap、memcached、consul/memberlist 等构成。微服务组件的资源规格与高可用设计各组件清单直接给出生产级默认参数可结合源码核对ingesteringester.libsonnetStatefulSet 3 副本挂载ingester-data默认10GifastStorageClass与ingester-wal默认150Gi两块 PVC请求1 CPU/7Gi、限制2 CPU/14GiTerminationGracePeriodSeconds 480080 分钟以保障 TSDB block 与 WAL 落盘readiness 探针走/ready。distributordistributor.libsonnetDeployment 3 副本请求500m/2500Mi默认启用 TopologySpreadConstraintskubernetes.io/hostnamemaxSkew1ScheduleAnyway均匀打散PDBmaxUnavailable1。querierquerier.libsonnet默认 Deployment 3 副本在 TSDB shipper 模式下由 shipper.libsonnet 强制转为 StatefulSet并为/data/tsdb-index、/data/tsdb-cache挂载querier-dataPVC。query-frontend / query-scheduler / ruler / compactor / index-gateway / memcached分别由 query-frontend.libsonnet、query-scheduler.libsonnet、ruler.libsonnet、compactor.libsonnet、index-gateway.libsonnet、memcached.libsonnet 定义。缓存默认接入 memcachedchunk cache 与 query-range results cache 均指向memcached.namespace.svc.cluster.local。多可用区 IngesterMultizone IngestersREADME 的核心专题production/ksonnet/README.md 除指向 Tanka 安装文档外专门给出多可用区 Ingester 的配置片段。这是 ksonnet 库面向生产高可用场景的核心能力将 ingester 拆分为zone-a、zone-b、zone-c三个分区实现可用区感知复制zone-aware replication——当单个可用区故障时写入与查询仍可通过其余区完成。官方给出的配置片段_config: { multi_zone_ingester_enabled: false, multi_zone_ingester_migration_enabled: false, multi_zone_ingester_replicas: 0, multi_zone_ingester_max_unavailable: 25, }注意README 中的数值为示意/默认态——enabled: false表示默认关闭该特性启用时请按下文语义显式设置。参数语义与源码实现multi-zone.libsonnet参数默认值语义multi_zone_ingester_enabledfalse是否启用多可用区 ingester。启用后默认ingester_statefulset/ingester_service被移除替换为三个 zone 的 StatefulSetmulti_zone_ingester_migration_enabledfalse迁移模式。为true时保留默认ingesterStatefulSet 与 Service且 PDB 被设为maxUnavailable0迁移期间不允许 Kubernetes 终止任何 ingester 副本multi_zone_ingester_replicas3三个 zone 的副本总数每个 zone 实际副本数 ceil(replicas / 3)见newIngesterZoneStatefulSetmulti_zone_ingester_max_unavailablemax(1, floor(replicas/9))滚动发布时允许的最大不可用副本数写入rollout-max-unavailableannotation由 rollout-operator 消费multi_zone_ingester_replication_write_path_enabled/..._read_path_enabled均true分别控制写入distributor/ruler与读取querier路径是否注入distributor.zone-awareness-enabled: true开启 zone-aware 复制multi_zone_ingester_use_topology_spreadfalse为 zone StatefulSet 添加 TopologySpreadConstraintskubernetes.io/hostnamemaxSkewmulti_zone_ingester_topology_spread_max_skewwhenUnsatisfiablemulti_zone_ingester_topology_spread_when_unsatisfiablemulti_zone_ingester_name_prefixingester-zonezone StatefulSet 命名前缀生成ingester-zone-a/b/cmulti_zone_ingester_exclude_defaultfalse为true时向 distributor/ruler 注入distributor.excluded-zones: zone-default将默认 zone 排除在复制之外multi_zone_default_ingester_zonefalse为true时给默认 ingester 容器注入ingester.availability-zone: zone-default三个 zone 的生成逻辑从 multi-zone.libsonnet 的源码结构可以看到每个 zonea/b/c生成三件套StatefulSetingester-zone-zone、headless ServiceClusterIP: None仅为提供 StatefulSet 的网络身份、容器通过ingester.availability-zone: zone-zone标志区分。zone StatefulSet 使用updateStrategy.type: OnDeleterollout-group: ingester标签 rollout-max-unavailableannotation并配套ingester-rollout-pdbmaxUnavailable1交由rollout-operator做滚动发布管理rollout-operator.libsonnet 中 DeploymentMaxSurge0 / MaxUnavailable1保证同一时刻只有一个 operator 在运行。默认启用 podAntiAffinity同 zone 的多个副本可以调度到同一节点但不同 zone 的副本不允许同节点matchExpressionsrollout-group in [ingester]且name notin [当前zone名]topologyKey 为 hostname。这样单节点故障只影响一个 zone。启用 zone-aware 复制后distributor/querier/ruler 均注入distributor.zone-awareness-enabled: true对应 Loki 的distributor.zone-awareness-enabled配置实现复制时优先选择不同 zone 的 ingester 副本。迁移路径从单区到多可用区multi-zone.libsonnet 对ingester_statefulset、ingester_service、ingester_pdb的覆盖逻辑给出了清晰的迁移语义初始状态multi_zone_ingester_enabled: false运行默认ingesterStatefulSet。开启迁移multi_zone_ingester_enabled: true且multi_zone_ingester_migration_enabled: true—— 旧ingesterStatefulSet/Service 继续保留PDB 强制maxUnavailable0同时三个 zone 的 StatefulSet 开始创建数据逐步复制。迁移完成multi_zone_ingester_migration_enabled: false—— 默认ingesterStatefulSet/Service/PDB 被移除流量完全由三个 zone 接管。Ring 后端memberlist 与 Consul 的选择config.libsonnet 默认使用 Consul 作为所有 ringingester/distributor/ruler/pattern-ingester的 KV store当memberlist_ring_enabled: true时memberlist.libsonnet 会将所有 ring 切换为 memberlist并通过 headless Servicegossip-ring.namespace.svc.cluster.local:7946DNSSRV发现 gossip 成员为 distributor/ingester/querier/ruler/compactor/query-scheduler/index-gateway 追加gossip-ring端口7946与loki_gossip_member: true标签提供memberlist_cluster_label默认cluster.namespace与校验开关防止跨集群 gossip 串扰若未启用 migration则彻底移除 consul 的 Deployment/Service/ConfigMap/RBAC 资源。若从 Consul 平滑迁移到 memberlistmemberlist.libsonnet 还内置了multikv_migration_enabled/multikv_primary/multikv_secondary/multikv_mirror_enabled等参数支持 primary-secondary 双 KV 存储的五步滚动迁移先 multi 镜像、再交换主从、最后拆除。网关gateway模块认证与路由gateway.libsonnet 生成一个基于nginx:1.15.1-alpine的 3 副本 Deploymentgateway-secret 存放 htpasswdgateway-config 渲染 nginx.conf负责对外统一入口并完成 Basic Auth 与租户头注入location /api/prom/push与location /loki/api/v1/push→distributor写入路径location /api/prom/tail与location /loki/api/v1/tail→querierWebSocket 升级支持其余~ /api/prom/.*与~ /loki/api/.*→query-frontend查询路径每个请求注入X-Scope-OrgID默认租户1可用gateway_tenant_id覆盖支持gateway_server_snippet追加自定义 server 指令。日志采集Grafana AlloyTanka 文档推荐的日志采集组件是 Grafana Alloy替代已归档的 promtail。在 Kubernetes 中安装 Alloy 后将采集到的日志通过 gateway 的/loki/api/v1/push或/api/prom/push推送到本部署的 distributor 即可具体安装步骤参见 Tanka 文档中引用的 Alloy 安装指南。生产落地清单Checklistnamespace与storage_backends3/gcs/azure必须显式设置否则 Jsonnet 求值直接报错见 config.libsonnet 中的error断言。新装环境使用 TSDBstore: tsdb、schema: v13并设置using_tsdb_shipper: true。schema_config.configs[0].from设为当前日期 7 天内与reject_old_samples_max_age: 168h保持一致。生产开启memberlist_ring_enabled: true免去 Consul 运维负担如已有 Consul 依赖按 memberlist 迁移五步走。多可用区需求置multi_zone_ingester_enabled: true按需调multi_zone_ingester_replicas与multi_zone_ingester_max_unavailable先以migration_enabled: true过渡再切换。前置反向代理认证gateway 已内置 htpasswd nginx牢记 Loki 无内置认证。参考资源仓库内官方 Tanka 安装文档docs/sources/setup/install/tanka.mdksonnet 入口组合production/ksonnet/loki/loki.libsonnet全局配置与默认值production/ksonnet/loki/config.libsonnet多可用区实现production/ksonnet/loki/multi-zone.libsonnetRing/memberlist 迁移production/ksonnet/loki/memberlist.libsonnet网关 nginx 配置production/ksonnet/loki/gateway.libsonnet组件规格ingester / querier / distributor 见 production/ksonnet/loki/ingester.libsonnet、production/ksonnet/loki/querier.libsonnet、production/ksonnet/loki/distributor.libsonnet【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考