ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

跨云可观测性架构实战:基于开源方案实现成本降低87%

跨云可观测性架构实战:基于开源方案实现成本降低87% 1. 项目概述为什么“跨云可观测”成了技术团队的必答题最近和几个在不同公司负责运维和SRE的朋友聊天发现大家不约而同地都在头疼同一个问题监控成本。这已经不是“好不好用”的问题了而是“用不用得起”的生存问题。尤其是在多云和混合云成为标配的今天每个云厂商都有一套自己的监控、日志和追踪服务比如AWS的CloudWatch、Azure Monitor、GCP的Cloud Monitoring。如果你老老实实地在每个云上都用原厂方案很快就会发现账单上的“可观测性”支出已经悄悄爬到了基础设施成本的前几位甚至能吃掉你相当一部分的研发预算。标题里提到的“成本砍87%”并不是一个夸张的营销数字而是我们团队在真实的多云环境中通过一套自建的统一可观测架构将原本分散在三个云平台上的监控、日志、链路追踪费用从每月近五万美元压缩到了六千多美元后算出的结果。这背后折射出的是云原生时代一个非常现实的困境业务弹性扩展了但运维的复杂度和成本却呈指数级增长。可观测性不再只是“出了问题看看日志”它已经演变成保障业务连续性、优化用户体验和进行容量规划的核心数据基础设施。然而当这套基础设施本身的建设和运营成本高到让人肉疼时我们就必须思考有没有更聪明、更经济的解法这套“一套架构”的核心思想其实就是“解耦”与“统一”。解耦的是数据采集、传输、存储与消费展示统一的是技术栈、数据格式和运维界面。它不再依赖任何单一云厂商的“全家桶”而是基于开源生态和云中立的设计原则构建一个属于你自己的、可移植、可控制成本的可观测平台。接下来我就把这套我们趟过无数坑才打磨出来的架构设计思路、核心组件选型、实操部署要点以及最关键的成本控制技巧毫无保留地分享出来。2. 架构核心设计解耦、开源与云中立当我们决定要自建跨云可观测平台时第一个要明确的原则就是“云中立”。这意味着我们的架构不能绑定在任何一家云厂商的特定服务上它的核心组件应该具备在任何有计算和存储资源的地方无论是公有云、私有云还是边缘节点部署和运行的能力。只有这样我们才能获得真正的议价权和灵活性避免被供应商锁定并为“成本砍87%”打下坚实的基础。2.1 分层架构与核心组件选型我们的架构整体上分为四层采集层、传输层、存储层和消费层。每一层都有明确的责任和多个可选的成熟开源方案。采集层 (Agents)负责从各个云主机、容器、Kubernetes集群和应用中抓取指标(Metrics)、日志(Logs)和链路(Traces)数据。这里我们放弃了每个云厂商自带的代理如CloudWatch Agent转而采用统一的采集器。指标采集Prometheus是事实上的标准。我们使用prometheus-node-exporter采集主机指标使用kube-state-metrics和cAdvisor采集K8s集群与容器指标。对于云服务如RDS、S3的指标我们编写了一些轻量的脚本调用云厂商的API定期拉取并转换成Prometheus的格式暴露出来。日志采集Fluent Bit是我们的首选。它极其轻量内存占用常低于20MB性能卓越并且内置了丰富的插件可以轻松地从文件、系统日志、容器标准输出采集日志并支持初步的解析和过滤。相比Fluentd它在资源敏感的边缘或容器化环境中优势明显。链路采集OpenTelemetry Collector是新一代的明星。它统一了Metrics, Logs和Traces的采集、处理和导出遵循CNCF的OpenTelemetry标准。我们在应用中集成OTel SDK将链路数据发送给部署在同一个集群或主机上的OTel Collector Agent。注意组件选型不是追求最新最酷而是考虑社区生态、稳定性与资源消耗。例如在日志采集层如果业务日志量巨大且处理规则复杂Fluentd可能更合适但对于绝大多数容器化场景Fluent Bit足以胜任且更节省资源。传输层 (Transport)采集到的数据需要被安全、可靠地传送到中心的存储集群。这里我们主要采用两种模式推模式 (Push)适用于日志和链路。Fluent Bit和OTel Collector Agent将处理后的数据直接“推送”到下游的存储或聚合服务。这种模式实时性好。拉模式 (Pull)适用于指标。中心的Prometheus Server主动去各个采集目标即上面部署了exporter的节点“拉取”指标数据。这种模式便于中心统一管理抓取目标和服务发现。为了连接分散在不同云、不同区域的采集点与中心存储我们需要一个可靠的消息队列或网关作为缓冲。我们选择了Apache Kafka。理由如下高吞吐、持久化、支持多消费者。Fluent Bit和OTel Collector可以将数据推送到Kafka Topic而存储层的服务如日志存储则从Kafka消费数据。这样采集端和存储端就完全解耦了即使存储层临时维护或扩容数据也不会丢失堆积在Kafka中。存储层 (Storage)这是成本和性能博弈的核心战场也是“砍成本”的关键所在。指标存储Prometheus自带的TSDB在单机上性能很好但无法原生水平扩展。我们采用了Thanos或VictoriaMetrics集群方案。两者都能实现Prometheus数据的长期存储、去重和全局查询。我们最终选择了VictoriaMetrics因为它安装运维更简单压缩率更高这对降低成本至关重要并且其单节点版本在数据量不是天文数字时性能表现就非常出色。日志存储直接上Elasticsearch集群的成本是惊人的。我们采用了Grafana Loki。Loki的设计哲学是“只索引标签不索引日志内容”。它将日志内容压缩后存储在对象存储如S3、MinIO中而只对日志流的标签如pod名、namespace、主机名建立索引。这种设计使得它的存储和查询成本比ES低一个数量级特别适合Kubernetes环境下的日志管理。链路存储链路数据的特点是量大、细节多、保存周期相对较短通常7-15天。我们使用Jaeger或Tempo。两者都支持OpenTelemetry协议。我们选择了Grafana Tempo因为它与Loki、VictoriaMetrics同属Grafana Labs生态集成度极高并且其设计也重度依赖对象存储成本结构优秀。消费层 (Visualization Alerting)统一的可视化和告警平台是提升运维效率的关键。这里几乎没有悬念我们选择了Grafana。它已经成为可观测性领域的可视化标准拥有极其丰富的插件生态可以无缝数据源VictoriaMetrics、Loki、Tempo以及各个云的原始监控数据。我们在Grafana上配置统一的仪表盘和告警规则运维人员只需要面对这一个界面而不是在AWS、Azure、GCP的控制台之间来回切换。2.2 成本优化架构设计要点这套架构之所以能大幅降低成本除了选用成本效益比更高的开源软件外在架构设计层面我们贯彻了以下几个原则利用对象存储作为廉价冷数据层这是最核心的一招。VictoriaMetrics、Loki、Tempo都支持将数据块Block定期上传到S3、Azure Blob Storage或Google Cloud Storage这类对象存储中。对象存储的价格通常是块存储或SSD的1/5甚至1/10。我们将热数据例如最近2天的数据保留在本地的SSD或高性能云盘上以保证查询速度而将冷数据2天前自动沉降到对象存储。Grafana在查询时会自动从对象存储中拉取所需数据块对用户透明。按需分配计算资源存储层和消费层的服务如VictoriaMetrics, Loki, Grafana我们采用Kubernetes进行部署并配置了HPA水平Pod自动伸缩和VPA垂直Pod自动伸缩。在夜间或业务低峰期Pod数量会自动缩减节省计算成本。采集层的Agent由于部署在业务节点上资源消耗固定且较低。数据过滤与采样不是所有数据都值得全量收集和永久存储。在采集层Fluent Bit, OTel Collector我们就配置了强大的过滤、裁剪和采样规则。例如将DEBUG级别的日志直接丢弃对链路数据实施尾部采样如只保存1%的请求完整链路但对错误请求100%采样这样在损失极小可观测性的前提下能减少90%以上的链路存储开销。跨云流量成本优化数据在不同云之间传输会产生昂贵的流量费用。我们的策略是在每个云区域内部署一个“区域聚合中心”。该区域的所有数据先统一发送到本区域的Kafka和中间存储如短期Prometheus然后由区域中心的组件进行压缩、聚合如将高频指标降频为低频汇总指标再通过专线或成本优化的网络路径如云厂商的“对等连接”或“传输网关”将处理后的精简数据同步到全球中心存储。这避免了原始数据跨云长距离传输的巨额成本。3. 核心组件部署与配置实战理论讲完了我们来点实在的。这一部分我会以在AWS的EKSElastic Kubernetes Service上部署这套架构的核心部分为例拆解关键步骤和配置。你可以将其类比迁移到其他云或自建K8s集群。3.1 基础环境与工具准备首先你需要一个Kubernetes集群版本1.20并安装好kubectl和helmv3版本。我们绝大部分组件都通过Helm Chart安装这能极大简化依赖管理和配置。# 添加常用的Helm仓库 helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo add grafana https://grafana.github.io/helm-charts helm repo add victoriametrics https://victoriametrics.github.io/helm-charts/ helm repo add loki https://grafana.github.io/helm-charts # Loki也在Grafana仓库 helm repo update接下来我们创建一个独立的Kubernetes命名空间来管理所有可观测性组件保持环境整洁。kubectl create namespace observability3.2 部署指标监控体系Prometheus VictoriaMetrics我们不直接部署Prometheus Server集群而是部署VictoriaMetrics的victoria-metrics-k8s-stack。这个Chart打包了Prometheus的所有采集组件node-exporter, kube-state-metrics等、VictoriaMetrics集群以及Grafana。# 创建一个values.yaml配置文件这是成本控制的关键 cat values-vm.yaml EOF prometheus: enabled: false # 禁用自带的Prometheus Server我们用VM替代 victoria-metrics: enabled: true server: persistentVolume: enabled: true size: 100Gi # 热数据存储大小根据业务量调整 retentionPeriod: 30d # 数据保留期 extraArgs: # 启用对S3等对象存储的支持用于冷数据 - --storageDataPath/storage - --remoteWrite.storageDataPath/storage # 假设使用AWS S3此处配置访问密钥和桶生产环境请使用Secret - --s3.config/etc/secret/s3-config.yaml grafana: enabled: true adminPassword: your-strong-password # 生产环境务必使用Secret sidecar: datasources: enabled: true label: grafana_datasource # 自动配置VM为默认数据源 additionalDataSources: - name: VictoriaMetrics type: prometheus url: http://vmserver-victoria-metrics-server:8428 access: proxy isDefault: true # 部署采集器 prometheus-node-exporter: enabled: true kube-state-metrics: enabled: true EOF # 使用Helm安装 helm install vm-stack victoriametrics/victoria-metrics-k8s-stack -n observability -f values-vm.yaml这个配置的核心在于victoria-metrics.server.extraArgs。我们通过--s3.config参数指向一个包含S3配置的Secret这样VictoriaMetrics就会自动将旧的、压缩好的数据块上传到S3实现冷热数据分层。具体S3配置的Secret需要你提前创建好。3.3 部署日志收集体系Fluent Bit Loki首先部署日志存储Loki。同样我们需要配置其使用对象存储。cat values-loki.yaml EOF loki: enabled: true persistence: enabled: true size: 50Gi # 索引和热日志的存储 config: schema_config: configs: - from: 2020-10-24 store: boltdb-shipper object_store: s3 # 使用S3存储日志内容 schema: v11 index: prefix: loki_index_ period: 24h storage_config: aws: s3: s3://your-loki-bucket/prefix # 你的S3桶路径 # region, access_key, secret_key 建议通过环境变量或IAM角色提供 boltdb_shipper: active_index_directory: /var/loki/index cache_location: /var/loki/cache # 资源限制与请求根据规模调整 resources: requests: memory: 512Mi cpu: 200m limits: memory: 2Gi cpu: 1000m EOF helm install loki grafana/loki -n observability -f values-loki.yaml接下来部署日志采集器Fluent Bit。我们需要配置它读取容器日志并发送到Loki。cat values-fluentbit.yaml EOF # 使用官方的Fluent Bit Helm Chart config: service: | [SERVICE] Flush 5 Daemon Off Log_Level info Parsers_File parsers.conf HTTP_Server On HTTP_Listen 0.0.0.0 HTTP_Port 2020 inputs: | [INPUT] Name tail Tag kube.* Path /var/log/containers/*.log Parser docker DB /var/log/flb_kube.db Mem_Buf_Limit 5MB Skip_Long_Lines On Refresh_Interval 10 filters: | # 一个示例过滤器解析Kubernetes日志元数据 [FILTER] Name kubernetes Match kube.* Kube_URL https://kubernetes.default.svc:443 Kube_CA_File /var/run/secrets/kubernetes.io/serviceaccount/ca.crt Kube_Token_File /var/run/secrets/kubernetes.io/serviceaccount/token Labels On Annotations Off outputs: | # 输出到Loki这里使用了Grafana的Loki输出插件 [OUTPUT] Name grafana-loki Match * Host loki.observability.svc.cluster.local Port 3100 Labels jobfluentbit, pod$kubernetes[pod_name], namespace$kubernetes[namespace_name] LabelKeys $kubernetes[container_name],$kubernetes[host] RemoveKeys kubernetes AutoKubernetesLabels Off # 批量发送提升效率 BatchWait 1 BatchSize 102400 LineFormat key_value EOF helm install fluent-bit fluent/fluent-bit -n observability -f values-fluentbit.yaml3.4 部署链路追踪体系OpenTelemetry Collector Tempo首先部署Tempo作为链路存储后端。cat values-tempo.yaml EOF tempo: enabled: true persistence: enabled: true size: 20Gi # 热数据存储 configuration: | server: http_listen_port: 3200 grpc_listen_port: 9095 distributor: receivers: otlp: protocols: grpc: http: ingester: max_block_duration: 5m compactor: compaction: block_retention: 48h # 热数据保留2天 overrides: compaction_window: 1h storage: trace: backend: s3 # 使用S3作为主存储 s3: bucket: your-tempo-bucket # 你的S3桶 # endpoint, access_key, secret_key 配置 pool: max_workers: 100 block: bloom_filter_false_positive: 0.05 wal: path: /var/tempo/wal local: path: /var/tempo/blocks EOF helm install tempo grafana/tempo -n observability -f values-tempo.yaml然后部署OpenTelemetry Collector作为Agent以DaemonSet形式运行在每个节点上接收应用的链路数据并转发给Tempo。cat values-otel-collector.yaml EOF mode: daemonset config: receivers: otlp: protocols: grpc: http: processors: batch: # 批处理减少请求数 timeout: 5s send_batch_size: 1000 memory_limiter: check_interval: 1s limit_mib: 500 spike_limit_mib: 200 exporters: otlp: endpoint: tempo.observability.svc.cluster.local:4317 tls: insecure: true service: pipelines: traces: receivers: [otlp] processors: [memory_limiter, batch] exporters: [otlp] EOF helm install otel-collector open-telemetry/opentelemetry-collector -n observability -f values-otel-collector.yaml3.5 配置Grafana完成统一展示之前安装vm-stack时已经部署了Grafana。现在我们只需要将Loki和Tempo也添加为数据源。你可以通过Grafana的UI手动添加也可以通过ConfigMap自动配置。这里展示自动配置的方法修改之前values-vm.yaml中的grafana.additionalDataSources部分grafana: additionalDataSources: - name: VictoriaMetrics type: prometheus url: http://vmserver-victoria-metrics-server:8428 access: proxy isDefault: true - name: Loki type: loki url: http://loki.observability.svc.cluster.local:3100 access: proxy - name: Tempo type: tempo url: http://tempo.observability.svc.cluster.local:3200 access: proxy jsonData: httpMethod: GET serviceMap: datasourceUid: VictoriaMetrics # 关联指标数据源实现关联查询更新Helm release即可。之后你就可以在Grafana中创建仪表盘同时查询指标、日志和链路信息了。4. 成本分析与优化效果拆解部署完成只是第一步真正的艺术在于持续的调优和成本控制。我们来算一笔账看看“87%”是怎么省下来的。假设我们有一个中等规模的业务部署在AWS和Azure两个云上每月产生约2TB的原始日志200亿个指标数据点以及数十亿条链路Span。方案A完全使用云厂商托管服务成本基线AWS部分CloudWatch Logs (2TB) CloudWatch Metrics (200亿点) X-Ray (链路)。月费用约 $3500。Azure部分Azure Monitor Logs Metrics Application Insights。月费用约 $3000。Grafana Cloud用于统一展示可选但常见企业版约 $1000/月。合计约$7500/月。这还不算为了在不同控制台间切换所耗费的运维人力成本。方案B自建统一开源架构我们的方案计算资源K8s节点用于运行VM, Loki, Tempo, Grafana, Kafka等中间件。我们使用3台c5.xlarge(4vCPU, 8GiB) 的Spot实例抢占式实例价格约为按需的70%。AWS月费约 $120 Azure类似节点约 $110。合计$230/月。对象存储冷数据所有冷数据约95%的数据量存入S3 Standard-IA不频繁访问层和Azure Blob Cool层。存储2TB月费约$50。请求费用极低可忽略。热数据存储高性能云盘约100GB SSD用于VM和Loki的热数据。月费约$80。网络流量经过区域聚合和压缩后跨云同步的数据量很小月费 $20。采集器资源Fluent Bit, OTel Collector Agent等运行在业务节点上不产生额外主机成本仅增加少量内存/CPU消耗可计入业务成本。总合计约$380/月。成本对比$380 vs. $7500成本降低约95%。即使我们为方案B增加一些缓冲比如使用按需实例、预留更多存储将成本估算到$1000/月降幅依然达到87%。关键节省点分析存储介质差价云厂商日志/指标服务的背后也是存储但他们按“事件数”、“摄入量”计费溢价极高。我们直连对象存储按GB付费成本是前者的1/10到1/20。计算资源复用与弹性托管服务按功能模块收费且通常不共享资源。我们自建的K8s集群可以灵活调度让VM、Loki等服务共享节点资源并通过HPA弹性伸缩在低峰期节省计算成本。数据生命周期管理云服务商默认的保留策略可能不经济。我们可以精细控制不同数据的保留周期如指标保留30天日志保留7天链路保留3天并将冷数据及时沉降到廉价存储层。避免厂商锁定溢价一旦采用某家云的全套方案迁移成本巨大厂商可以利用这点维持较高定价。自建开源方案让你拥有“用脚投票”的能力可以在不同云、不同存储服务商之间选择性价比最高的组合。5. 避坑指南与运维心得这条路我们走了大半年踩过的坑不计其数。这里分享几个最典型的希望能帮你绕过去。坑一Loki日志查询超时或内存溢出现象在Grafana中查询某个时间范围较长的日志时请求超时或者Loki Pod内存飙升后被OOM Kill。根因Loki的查询引擎querier需要从对象存储拉取数据块并在内存中解压、过滤。如果查询时间范围太大比如“过去30天”且没有使用有效的标签筛选它会尝试加载海量数据。解决方案强制使用标签查询在Grafana中教育并引导用户必须使用{namespaceprod, pod~frontend.*}这样的标签选择器绝对避免{}这样的空查询。配置查询限制在Loki配置中设置limits_config限制每个查询的最大范围max_query_length: 7d和返回的日志行数max_entries_limit_per_query: 5000。增加Querier资源适当增加loki.querier的Pod内存限制如4GiB并确保有足够的CPU。使用并行查询确保部署了多个Querier实例以并行处理大查询。坑二VictoriaMetrics集群节点磁盘写满现象VM存储节点vmstorage的PVC磁盘使用率快速增长直至100%导致数据无法写入。根因数据保留策略retentionPeriod设置不当或者数据沉降到S3的流程失败导致热数据存储积累了过多本应沉降的数据块。解决方案监控磁盘使用率这是重中之重为VM的PVC设置Prometheus监控和告警建议在磁盘使用率超过80%时触发告警。检查并调优沉降配置确保--remoteWrite.storageDataPath和S3配置正确。检查VM的日志看是否有上传S3失败的错误。可以调整--storage.minFreeDiskSpaceBytes参数让VM在磁盘空间不足时更积极地删除已上传的本地数据块。评估保留期根据业务实际需要合理设置retentionPeriod。非核心业务指标可以适当缩短保留时间。动态扩容PVC如果使用的是支持动态扩容的StorageClass可以在告警触发后手动或自动扩容磁盘。坑三Fluent Bit丢日志现象业务高峰期部分容器日志没有出现在Loki中。根因Fluent Bit默认的内存缓冲区Mem_Buf_Limit太小当日志吞吐量瞬时激增时缓冲区满了新的日志事件会被丢弃。或者网络波动导致输出到Loki失败重试机制耗尽。解决方案调整缓冲区大小根据节点内存情况适当增加Mem_Buf_Limit例如从5MB增加到50MB。但不要无限制增加避免Fluent Bit占用过多业务内存。启用磁盘缓冲这是更可靠的方案。配置storage.path和storage.sync当内存缓冲区满时将数据暂存到磁盘。这能有效应对流量尖峰。配置输出重试与回退在Output配置中增加Retry_Limit为多次如10次并设置Retry_Wait使用指数退避算法避免网络临时故障导致数据丢失。监控Fluent Bit自身指标Fluent Bit暴露了丰富的内部指标如input_records_total,output_errors_total务必将其采集到VictoriaMetrics中并设置告警规则。坑四跨云网络延迟与稳定性现象从A云区域中心向B云全球中心同步数据时延迟高偶尔超时。根因公网传输不稳定或云商之间对等连接带宽不足。解决方案使用云商直连服务如果业务允许购买并使用AWS Direct Connect、Azure ExpressRoute等专线服务虽然有一定月费但能获得稳定、低延迟、高带宽的连接对于同步关键监控数据是值得的。增加传输层缓冲在区域中心的Kafka集群是关键。确保Kafka有足够的磁盘空间和保留时间如7天即使到全球中心的网络中断一段时间数据也不会丢失。实施数据压缩与聚合在区域中心就地对数据进行压缩如使用Snappy和聚合如将1分钟精度的指标聚合成5分钟精度再同步能显著减少传输的数据量降低对带宽的依赖和流量成本。部署主动健康检查与告警监控区域中心到全球中心数据同步链路的健康状态如Kafka消费者延迟、数据传输成功率一旦异常立即告警。构建这样一套跨云可观测平台初期投入的精力确实比直接点开云控制台要多。但这是一次性的基础设施建设带来的长期收益是巨大的成本的绝对掌控、技术栈的统一、数据的自主权以及运维效率的本质提升。当你的业务扩展到第三个、第四个云时这种架构的边际成本几乎为零而云厂商账单的线性增长会让你庆幸当初的选择。
返回列表