使用 Helm Chart 在 AWS EKS 上部署 Loki 微服务模式全指南
使用 Helm Chart 在 AWS EKS 上部署 Loki 微服务模式全指南【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki本指南基于 Loki 官方 Helm Chart完整演示如何在 AWS 上以微服务Distributed模式部署一个最小可用minimally viable的 Loki 集群包括 EKS 集群与 OIDC 准备、S3 存储桶创建、基于 IAM Role 的安全认证IRSA、Gateway 基础认证Basic Auth配置、Helm Chart 部署与验证以及使用 k6 对部署进行读写压测。读完本文你将掌握一套从零到一、可直接复制落地的 AWS 版 Loki 生产部署方案。本文对应的原始官方文档位于仓库 docs/sources/setup/install/helm/deployment-guides/aws.md文中所有配置示例均可在仓库内 production/helm/loki/values.yaml 中找到对应的 Chart 默认值实现。前置说明与注意事项本指南要求你具备在 AWS 上部署资源的必要工具和权限具体包括EKSAmazon Elastic Kubernetes Service的完整访问权限S3Amazon Simple Storage Service的完整访问权限创建 IAMIdentity Access Management角色与策略的足够权限。Loki 连接 AWS S3 有两种认证方式本指南采用官方推荐的方式通过 IAM Role 授予访问权限即 IRSAIAM Roles for Service Accounts相比将 Access Key / Secret Key 直接写入 Loki 配置更加安全。开始前请先了解以下关键考量IAM Role本指南创建的 IAM Role 是一个基础角色仅允许 Loki 对 S3 存储桶进行读写。你可以根据实际需求补充更细粒度的权限。认证Grafana Loki 自带基础认证层。本示例中 Loki GatewayNGINX通过 Basic Authentication 暴露到公网。NGINX 也可以替换为其他开源反向代理。保留期Retentionvalues.yaml中保留期默认设置为 28 天可按需调整。成本在 AWS 上运行 Loki 会产生费用务必持续监控用量与账单。本指南使用一个简单的 EKS 集群3 个m5.xlarge节点作为演示你可以依据工作负载调整实例类型与节点数。环境准备Prerequisites本地机器需要安装以下工具Helm 3 及以上用于部署 Helm Chart需安装在本地机器上Kubernetes 1.25 或更高版本一个运行在 AWS 上的 Kubernetes 集群快速入门推荐使用 EKSctl 创建kubectl安装并配置在本机用于管理集群可选AWS CLI如果计划用 EKSctl 创建 EKS 集群并在本地修改 IAM 角色与策略则需要安装。EKS 最低配置要求以下 EKS 要求是本指南部署 Loki 所需的最低规格你可以根据 AWS 环境和负载调整插件与实例类型。若自行调整官方不保证本示例配置仍能满足你的需求。本指南使用m5.xlarge实例部署 Loki该实例类型适用于大多数场景。在 EKS 上部署 Loki 的最低要求Kubernetes 版本1.30或以上EKS 集群3 个节点实例类型取决于工作负载生产集群的良好起步配置为m7i.2xlarge。本指南使用的 EKSctl 集群配置文件如下# A simple example of ClusterConfig object: --- apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: INSERT_CLUSTER_NAME region: INSERT_REGION_FOR_CLUSTER version: 1.31 iam: withOIDC: true addons: - name: aws-ebs-csi-driver managedNodeGroups: - name: loki-workers instanceType: m7i.2xlarge desiredCapacity: 3 minSize: 2 maxSize: 3 amiFamily: AmazonLinux2023 iam: withAddonPolicies: ebs: true volumeSize: 80 volumeType: gp3 ebsOptimized: true集群内还必须安装以下插件Amazon EBS CSI Driver让 Kubernetes 能够动态创建和管理 EBS 卷作为应用持久化存储本指南用它为 Loki 提供节点卷CoreDNS为 Kubernetes 集群提供内部 DNS 服务确保服务与 Pod 之间可以通过 DNS 名称通信kube-proxy维护节点上的网络规则使集群内 Pod 与服务之间能够通信。此外必须在 EKS 集群上安装OIDCOpenID Connectprovider这是 IAM 角色与策略正确工作的前提。使用 EKSctl 时可通过以下命令安装提示如果你使用了上述 EKSctl 配置文件创建集群其中iam.withOIDC: true则无需再执行此命令OIDC Provider 会自动安装。eksctl utils associate-iam-oidc-provider --cluster loki --approve创建 S3 存储桶警告不要使用默认桶名chunk、ruler和admin请为每个桶选择唯一名称防止日志数据被意外写入他人 S3 桶参见 Grafana 官方安全更新公告。部署 Loki 前需要创建两个 S3 桶一个存储日志数据chunks另一个存储告警规则ruler。可以通过 AWS 管理控制台或 AWS CLI 创建桶名必须全局唯一。注意GELGrafana Enterprise Logs客户需要第三个桶来存储 admin 数据OSS 用户不需要。aws s3api create-bucket --bucket YOUR CHUNK BUCKET NAME e.g. loki-aws-dev-chunks --region S3 region your account is on, e.g. eu-west-2 --create-bucket-configuration LocationConstraintS3 region your account is on, e.g. eu-west-2 \ aws s3api create-bucket --bucket YOUR RULER BUCKET NAME e.g. loki-aws-dev-ruler --region S3 REGION your account is on, e.g. eu-west-2 --create-bucket-configuration LocationConstraintS3 REGION your account is on, e.g. eu-west-2请将region和bucket名称替换为你期望的值稍后本指南会再次讨论桶策略。定义 IAM 角色与策略将 Loki 连接到 AWS S3 的推荐方法是使用 IAM Role这比将 Access Key / Secret Key 直接存放在 Loki 配置中更安全。角色和策略可以用 AWS CLI 或 AWS 管理控制台创建以下步骤演示使用 AWS CLI 创建。新建一个目录并进入该目录确保所有文件都创建在此目录中。本指南中的所有命令都假定你位于此目录中。创建loki-s3-policy.json文件内容如下{ Version: 2012-10-17, Statement: [ { Sid: LokiStorage, Effect: Allow, Action: [ s3:ListBucket, s3:PutObject, s3:GetObject, s3:DeleteObject ], Resource: [ arn:aws:s3::: CHUNK BUCKET NAME , arn:aws:s3::: CHUNK BUCKET NAME /*, arn:aws:s3::: RULER BUCKET NAME , arn:aws:s3::: RULER BUCKET NAME /* ] } ] }请务必将占位符替换为之前创建的实际桶名。使用 AWS CLI 创建 IAM 策略aws iam create-policy --policy-name LokiS3AccessPolicy --policy-document file://loki-s3-policy.json创建名为trust-policy.json的信任策略文档{ Version: 2012-10-17, Statement: [ { Effect: Allow, Principal: { Federated: arn:aws:iam:: ACCOUNT ID :oidc-provider/oidc.eks.INSERT REGION.amazonaws.com/id/ OIDC ID }, Action: sts:AssumeRoleWithWebIdentity, Condition: { StringEquals: { oidc.eks.INSERT REGION.amazonaws.com/id/ OIDC ID :sub: system:serviceaccount:loki:loki, oidc.eks.INSERT REGION.amazonaws.com/id/ OIDC ID :aud: sts.amazonaws.com } } } ] }请将占位符替换为你的 AWS 账户 ID、区域以及 OIDC ID可在 EKS 集群配置中找到。注意信任条件中绑定了system:serviceaccount:loki:loki即只有loki命名空间下名为loki的 ServiceAccount 才允许代入该角色——这从机制上保证了只有 Loki 自身能访问 S3。使用 AWS CLI 创建 IAM 角色aws iam create-role --role-name LokiServiceAccountRole --assume-role-policy-document file://trust-policy.json将策略附加到角色aws iam attach-role-policy --role-name LokiServiceAccountRole --policy-arn arn:aws:iam::Account ID:policy/LokiS3AccessPolicy请务必将占位符替换为你的 AWS 账户 ID。这一步的机制在 Helm Chart 中对应serviceAccount.annotations的eks.amazonaws.com/role-arn注解——EKS 的 IRSA 功能会据此把角色临时凭证注入到 Loki 的 Pod 中仓库中的 simple-scalable-aws-kube-irsa-values.yaml 即展示了这一注解的标准写法。部署 Helm Chart在部署 Loki Helm Chart 之前需要先向 Helm 添加 Grafana Community Chart 仓库该仓库包含 Loki Helm Chart。添加 Grafana Community Chart 仓库helm repo add grafana-community https://grafana-community.github.io/helm-charts更新 Chart 仓库helm repo update为 Loki 创建命名空间kubectl create namespace loki为 Loki 配置 Basic AuthenticationLoki 默认不附带任何认证。由于我们将 Loki 部署到 AWS 并将 Gateway 暴露到公网官方建议至少添加基础认证。本指南将为 Loki 设置用户名和密码使用htpasswd命令创建.htpasswd文件包含用户名和密码提示如果本地没有htpasswd命令可根据操作系统使用brew、apt-get或yum安装。htpasswd -c .htpasswd username这会创建一个包含指定用户名的.htpasswd文件系统会提示你输入密码。使用.htpasswd文件创建 Kubernetes Secretkubectl create secret generic loki-basic-auth --from-file.htpasswd -n loki这会在loki命名空间中创建一个名为loki-basic-auth的 Secret稍后将在 Helm Chart 配置中引用它。为 Canary 创建canary-basic-authSecretkubectl create secret generic canary-basic-auth \ --from-literalusernameUSERNAME \ --from-literalpasswordPASSWORD \ -n loki我们为 Loki Canary 创建了一个包含用户名和密码的字面量 Secret用于 Canary 向 Loki Gateway 进行认证。请务必将占位符替换为你期望的用户名和密码。从 Chart 源码看Gateway 的认证链路是这样工作的当gateway.basicAuth.enabled为 true 时NGINX 网关配置会写入auth_basic_user_file /etc/nginx/secrets/.htpasswd;见 templates/_helpers.tpl而.htpasswd文件由 templates/gateway/secret-gateway.yaml 渲染的 Secret 挂载若指定了gateway.basicAuth.existingSecret则直接使用该 Secret 中的.htpasswd键即本指南kubectl create secret创建的对象。Loki Helm Chart 配置values.yaml创建一个values.yaml文件选择最适合你需求的配置项。下面是 Loki Helm Chart 在微服务模式下的values.yaml示例loki: schemaConfig: configs: - from: 2024-04-01 store: tsdb object_store: s3 schema: v13 index: prefix: loki_index_ period: 24h storage_config: aws: region: S3 BUCKET REGION # for example, eu-west-2 bucketnames: CHUNK BUCKET NAME # Your actual S3 bucket name, for example, loki-aws-dev-chunks s3forcepathstyle: false ingester: chunk_encoding: snappy pattern_ingester: enabled: true limits_config: allow_structured_metadata: true volume_enabled: true retention_period: 672h # 28 days retention compactor: retention_enabled: true delete_request_store: s3 rulerConfig: enable_api: true alertmanager_url: http://prom:9093 querier: max_concurrent: 4 storage: type: s3 bucketNames: chunks: CHUNK BUCKET NAME # Your actual S3 bucket name (loki-aws-dev-chunks) ruler: RULER BUCKET NAME # Your actual S3 bucket name (loki-aws-dev-ruler) # admin: Insert s3 bucket name # Your actual S3 bucket name (loki-aws-dev-admin) - GEL customers only s3: region: S3 BUCKET REGION # eu-west-2 #insecure: false # s3forcepathstyle: false serviceAccount: create: true annotations: eks.amazonaws.com/role-arn: arn:aws:iam::Account ID:role/LokiServiceAccountRole # The service role you created deploymentMode: Distributed ingester: replicas: 3 zoneAwareReplication: enabled: false querier: replicas: 3 maxUnavailable: 2 queryFrontend: replicas: 2 maxUnavailable: 1 queryScheduler: replicas: 2 distributor: replicas: 3 maxUnavailable: 2 compactor: replicas: 1 indexGateway: replicas: 2 maxUnavailable: 1 patternIngester: enabled: true replicas: 1 ruler: replicas: 1 maxUnavailable: 1 # This exposes the Loki gateway so it can be written to and queried externaly gateway: service: type: LoadBalancer basicAuth: enabled: true existingSecret: loki-basic-auth # Since we are using basic auth, we need to pass the username and password to the canary lokiCanary: extraArgs: - -pass$(LOKI_PASS) - -user$(LOKI_USER) extraEnv: - name: LOKI_PASS valueFrom: secretKeyRef: name: canary-basic-auth key: password - name: LOKI_USER valueFrom: secretKeyRef: name: canary-basic-auth key: username # Disable minio storage minio: enabled: false backend: replicas: 0 read: replicas: 0 write: replicas: 0 singleBinary: replicas: 0注意请务必将配置中的占位符替换为你的实际值。定义一份有效的values.yaml对 Loki 部署至关重要。为了降低误配置风险下面拆解部署到 AWS 时需要重点关注的配置项Loki 配置与 Values 配置的区别values.yaml中名为loki的区块是 Loki 配置文件loki.yaml的直接映射定义了 schema、存储、querier 等 Loki 核心配置chunk 存储的关键配置是loki.storagetype、bucketNames以及loki.storage.s3.region等 provider 设置Chart 会将其映射到 Loki 的common.storage段告诉 Loki 把数据存到哪里。从 Chart 默认值可以看出loki.storage.type默认即为s3且loki.storage.s3.insecure默认为false即使用 HTTPS——参考 production/helm/loki/values.yamlrulerConfig区块定义 ruler 专属设置如enable_api和alertmanager_url。Ruler 的对象存储会自动从loki.storage与loki.storage.bucketNames.ruler推导完整的 Loki 配置项说明可参考仓库文档 docs/sources/setup/install/helm/configure-storage/_index.md 与 docs/sources/setup/install/helm/concepts.md。存储Storage定义 Helm Chart 将数据存放在哪里因为我们使用 Amazon S3将type设为s3将 chunks 与 ruler 的桶名配置为之前创建的实际桶名s3区块指定桶所在区域。服务账户Service AccountserviceAccount区块用于为 Loki ServiceAccount 绑定 IAM 角色即在此处关联之前创建的 IAM 角色通过eks.amazonaws.com/role-arn注解Chart 的serviceAccount.annotations默认值为空需显式填入。Zone-Aware 复制Helm Chart 默认启用 zone-aware ingester 复制会创建三个 Ingester StatefulSetzone-a、zone-b、zone-c以加快滚动发布本指南为了简单起见显式禁用了 zone-aware 复制ingester.zoneAwareReplication.enabled: false。生产环境建议启用它以提升发布韧性。网关Gateway定义 Loki Gateway 的暴露方式本配置中采用LoadBalancer类型的 Service。部署 Loki创建好values.yaml后即可使用 Helm Chart 部署 Loki使用新建的values.yaml文件部署helm install --values values.yaml loki grafana-community/loki -n loki --create-namespace必须创建名为loki的命名空间因为我们的信任策略只允许 IAM 角色被loki命名空间中的lokiServiceAccount 使用。该命名空间是可配置的但如果更改请同步更新你的 ServiceAccount。验证部署kubectl get pods -n loki你应该能看到 Loki 的各 Pod 正在运行NAME READY STATUS RESTARTS AGE loki-canary-crqpg 1/1 Running 0 10m loki-canary-hm26p 1/1 Running 0 10m loki-canary-v9wv9 1/1 Running 0 10m loki-chunks-cache-0 2/2 Running 0 10m loki-compactor-0 1/1 Running 0 10m loki-distributor-78ccdcc9b4-9wlhl 1/1 Running 0 10m loki-distributor-78ccdcc9b4-km6j2 1/1 Running 0 10m loki-distributor-78ccdcc9b4-ptwrb 1/1 Running 0 10m loki-gateway-5f97f78755-hm6mx 1/1 Running 0 10m loki-index-gateway-0 1/1 Running 0 10m loki-index-gateway-1 1/1 Running 0 10m loki-ingester-0 1/1 Running 0 10m loki-ingester-1 1/1 Running 0 10m loki-ingester-2 1/1 Running 0 10m loki-pattern-ingester-0 1/1 Running 0 10m loki-querier-89d4ff448-4vr9b 1/1 Running 0 10m loki-querier-89d4ff448-7nvrf 1/1 Running 0 10m loki-querier-89d4ff448-q89kh 1/1 Running 0 10m loki-query-frontend-678899db5-n5wc4 1/1 Running 0 10m loki-query-frontend-678899db5-tf69b 1/1 Running 0 10m loki-query-scheduler-7d666bf759-9xqb5 1/1 Running 0 10m loki-query-scheduler-7d666bf759-kpb5q 1/1 Running 0 10m loki-results-cache-0 2/2 Running 0 10m loki-ruler-0 1/1 Running 0 10m如你所见微服务模式下各组件distributor、ingester、querier、query-frontend、query-scheduler、index-gateway、compactor、pattern-ingester、ruler、canary 与 gateway均已独立运行各副本数与本指南values.yaml中的deploymentMode: Distributed配置一一对应。查找 Loki Gateway 服务Loki Gateway 服务是一个 LoadBalancer 类型的 Service将 Loki Gateway 暴露到公网你将通过它写入和查询日志。默认情况下 Gateway 使用 NGINX。注意Loki Gateway 服务暴露在公网本教程使用用户名/密码提供基础认证请确保已按上文配置。更多认证方案可参考仓库文档 docs/sources/operations/authentication.md若该文件不存在请以当前仓库 docs 目录实际内容为准。执行以下命令查找 Loki Gateway 服务kubectl get svc -n loki你应该能看到带有外部 IP 地址的 Loki Gateway 服务这就是你写入和查询 Loki 的地址NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE loki-gateway LoadBalancer 10.100.201.74 12345678975675456-1433434453245433545656563.eu-west-2.elb.amazonaws.com 80:30707/TCP 46m恭喜你已经成功使用 Helm Chart 在 AWS 上部署了 Loki。在结束之前让我们测试一下部署。测试 Loki 部署k6 是测试 Loki 部署最快的方式之一它可以同时向 Loki 写入和查询日志。开始使用 k6 的步骤如下在本地机器上安装带 Loki 扩展的 k6xk6-loki。创建aws-test.js文件内容如下import {sleep, check} from k6; import loki from k6/x/loki; /** * URL used for push and query requests * Path is automatically appended by the client * constant {string} */ const username USERNAME; const password PASSWORD; const external_ip EXTERNAL-IP; const credentials ${username}:${password}; const BASE_URL http://${credentials}${external_ip}; /** * Helper constant for byte values * constant {number} */ const KB 1024; /** * Helper constant for byte values * constant {number} */ const MB KB * KB; /** * Instantiate config and Loki client */ const conf new loki.Config(BASE_URL); const client new loki.Client(conf); /** * Define test scenario */ export const options { vus: 10, iterations: 10, }; export default () { // Push request with 10 streams and uncompressed logs between 800KB and 2MB var res client.pushParameterized(10, 800 * KB, 2 * MB); // Check for successful write check(res, { successful write: (res) res.status 204 }); // Pick a random log format from label pool let format randomChoice(conf.labels[format]); // Execute instant query with limit 1 res client.instantQuery(count_over_time({format${format}}[1m]), 1) // Check for successful read check(res, { successful instant query: (res) res.status 200 }); // Execute range query over last 5m and limit 1000 res client.rangeQuery({format${format}}, 5m, 1000) // Check for successful read check(res, { successful range query: (res) res.status 200 }); // Wait before next iteration sleep(1); } /** * Helper function to get random item from array */ function randomChoice(items) { return items[Math.floor(Math.random() * items.length)]; }请将EXTERNAL-IP替换为 Loki Gateway 服务的外部 IP 地址。该脚本会向 Loki 写入日志并从 Loki 查询日志以 800KB 到 2MB 之间的随机大小写入日志并在最近 5 分钟内按随机格式查询日志。脚本中的认证信息以http://user:passhost的 URL 形式内嵌与前面配置的 Basic Authentication 对应。运行测试./k6 run aws-test.js这会运行测试并输出结果你应该能看到测试正在向 Loki 写入日志并从 Loki 查询日志。部署完成后的下一步现在你已经成功在 AWS 上以微服务模式部署了 Loki可以进一步探索向 Loki 发送数据参见 docs/sources/send-data 下的各类接入指南Promtail、Alloy、Fluent Bit、Docker 等仓库中 clients 目录包含对应客户端实现查询 Loki参见 docs/sources/query 下的 LogQL 查询文档运维管理参见 docs/sources/operations 下的存储、压缩、告警、升级等运维指南深入学习 Helm Chart 本身Chart 的完整默认值与每个配置项的注释说明见 production/helm/loki/values.yaml安装微服务模式的更多细节见 docs/sources/setup/install/helm/install-microservices/_index.md。【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考