当我一月份开始在Grafana工作时,我已经习惯了与私有云和内部基础设施打交道,所以我在这里作为Grafana Mimir客户团队的高级软件工程师,几乎所有的东西对我来说都是新的。我对Golang、Docker、Kubernetes、gRPC、公共云服务等都很陌生。
Kubernetes尤其具有挑战性。在我从事Grafana Mimir和Grafana Enterprise Metrics的工作中,我以两种极端的方式体验k8s。对于本地开发,我把所有东西都放在Docker或k3d中。我可以打破或调试任何我想要的东西,这对代码开发来说是很好的,但我没有得到与 "真正 "集群一起工作的感觉。
在另一个极端,我与我们的云计算集群一起工作,这些集群非常真实,性能相当好。然而,我们的目标是满足我们的SLO,而不是破坏东西,所以我与这些集群的互动往往是在精心策划的新版本和变化的推出。
我需要的是一个中间地带,以加快我的Kubernetes能力:一个物理的多节点集群,我可以在一个小但非微不足道的规模上运行东西,并反复打破东西。
进入我的家庭实验室集群,又称 "蜂巢"。
Homelab的配置
这就是 "蜂巢":

之所以这样命名,是因为Beelink微型电脑和我儿子帮我建造的定制乐高架。我认为蜂巢也是描述Kubernetes集群的一个合适的比喻。一阵阵活动,每个微服务(蜜蜂)都在执行其指定的角色,每个pod(蜂巢单元)都被隔离,有其需要的资源,整个过程都是无形的协调和高效率的。
硬件配置
我最初打算建立一个基于树莓派的集群;然而,目前RPi几乎不可能采购到,除非你愿意支付明显高于零售价的价格。相反,我购买了4台Beelink微型PC,作为Kubernetes节点使用。每个单元大致相当于一个Raspberry Pi 4。
我对Beelink不熟悉,所以上面的表格是一个方便的指南,可以将规格与著名的Raspberry Pi 4B进行比较。最后,我很高兴我最终选择了Beelink的单元,原因如下:
- 价格高于8GB Raspberry Pi 4B的零售价,但在当今供应紧张的市场上,与RPi转售商的现行价格相似或更低。
- 我对CPU的性能很满意。在启用涡轮增压后,Beelink的频率高出53%。同样重要的是,Beelink的L1和L2缓存更大。这些缓存的命中性能对微服务的整体CPU性能至关重要。
- 与前一点相关,通过使用x86_64微架构,工作负载可以通过SSE、AVX等利用矢量操作。我们使用的许多软件都是为了使用这些针对x86_64 CPU的SIMD优化而编译的。现代基于ARM的CPU有一个名为Neon的SIMD单元,但代码必须经过编译才能使用。像crc32这样的操作在RPC和基于存储的工作负载中无处不在,它们被矢量指令大大加快了速度。
- Beelink配备了一块固态硬盘,又少了一样东西要买。
- Beelink配备了机箱、风扇等。我唯一需要建造的东西是乐高 "机架"。
我的家庭实验室基础设施的另一个关键部分是我去年建造的TrueNAS服务器。除了有70TB的存储空间(42TB可用),它还为Grafana Mimir提供了S3存储,为Kubernetes卷提供了NFS存储,为Nexus私有Docker注册中心提供了虚拟机,并为Pi-Hole(DNS)和Traefik(反向代理)提供了虚拟机。下面是我的家庭实验室配置图。
安装Kubernetes
作为Kubernetes的新手,我首先加入了Grafana实验室的#homelab Slack群,并向同事们提问。Ed Welch给了我很多好建议。事实上,我是在开会时看到他的5个节点的RPi集群在后台,才有了建立homelab集群的想法。他建议我使用k3s发行版,这是为资源有限的节点所优化的。
在确定了k3s之后,我看了很多YouTube视频。就像那句老话,"量两次,切一次",但对于YouTube教程来说,是 "看三次,部署两次",因为你第一次肯定会弄错。特别是有两个频道对我帮助很大。
我在Beelink节点上安装了一个Ubuntu服务器。然后,我使用了下面视频中描述的基于Ansible的方法,安装了一个完全配置好的k3s HA集群,包括kube-vip和MetalLB等额外的好东西。
kube-vip和MetalLB都解决了我在早期尝试手动建立k3s时遇到的问题,即用一个IP来代表前端的集群,在控制平面之间进行负载平衡,并通过LoadBalancer类型为服务分配一个IP池,以便它们可以从集群外部访问。
在这一点上,我有一个功能齐全的集群,所以我尝试着通过Helm图表添加MySQL和MongoDB。实际上,我开始使用MySQL部署,通过使用我之前写的OpenWeatherMap API从Go程序中填充天气和空气质量数据。
这就是集群在进入Prometheus和Mimir安装之前的样子。
安装普罗米修斯
我决定通过Helm来安装Prometheus操作器。就像k3s的安装一样,Prometheus的安装也是经过了几次尝试和重启才得到我想要的一切。我最终按照这个视频中的步骤进行了安装。
我对默认图表值所做的唯一改动是设置远程写入配置,因为我知道我接下来会安装Grafana Mimir。

远程写入配置包含:

使用kube-prometheus-stackHelm图表来部署Prometheus有两个好处。
- 它预先配置了一些输出器和仪表盘,旨在监控Kubernetes和节点。它带有一个Grafana pod,可以随时查看所有的仪表盘。我最后用这个pod来做我的Mimir和个人仪表板。
- 很容易添加额外的出口商,并通过ServiceMonitor配置让他们的指标被Prometheus刮走。在上面的链接中,有一个 "第二部分 "的视频,介绍了为MongoDB设置的过程。我能够按照这个教程,然后用同样的过程将MySQL指标添加到Prometheus中。Mimir Helm图表也使用ServiceMonitor来向Prometheus提供指标。
一旦运营商和额外的出口商被安装,我验证了我可以通过端口转发连接到Prometheus和Grafana pods并执行一些查询。最后,是Grafana Mimir的时候了。
安装Grafana Mimir
安装Mimir Helm图是一个简单的双线程:
❯ helm repo add grafana
https://grafana.github.io/helm-charts
❯ helm install mimir grafana/mimir-distributed -f mimir.yaml
然而,有一些配置细节需要在值文件中覆盖,这将是针对你的集群的。在我的案例中,这些是需要配置的地方:
- 普罗米修斯的ServiceMonitor
- 对象存储
- 功能和组件数量
服务监测器
让我们从ServiceMonitor开始,因为它是最直接的。下面是数值文件中的相关部分:
serviceMonitor:
enabled: true
namespace: default
namespaceSelector:
matchNames:
- default
labels:
release: kube-prometheus-stack
这里的关键部分是标签release: kube-prometheus-stack ,这是让Prometheus操作员发现要搜刮哪些出口商的服务。这一部分可能有点不同,取决于Prometheus的部署方式。
安装完毕后,我通过Prometheus界面验证了Mimir指标是否被刮取。然后我按照Grafana Mimir文档中的说明,建立Mimir仪表盘。这产生了一组JSON文件,我可以将其导入由Prometheus操作员创建的Grafana pod中。
对象存储
存储配置可以通过复制和粘贴值文件中mimir->config部分的完整多行字符串来改变,然后根据需要进行修改。有三个部分需要配置,对应于使用对象存储的三个组件:alertmanager_storage,blocks_storage, 和ruler_storage。每个部分的过程都是一样的,但我将展示 ruler_storage 章节,因为它很短。
下面是默认的节段的样子:
{{- if .Values.minio.enabled }}
ruler_storage:
backend: s3
s3:
endpoint: {{ .Release.Name }}-minio.{{ .Release.Namespace }}.svc:9000
bucket_name: {{ include "mimir.minioBucketPrefix" . }}-ruler
access_key_id: {{ .Values.minio.accessKey }}
secret_access_key: {{ .Values.minio.secretKey }}
insecure: true
{{- end }}
这里是为我的TrueNAS服务器上的S3桶定制后的样子:
ruler_storage
backend: s3
s3:
endpoint: 192.168.4.200:29000
bucket_name: mimir-ruler
access_key_id: mimir
secret_access_key: NOT_MY_ACTUAL_SECRET_KEY
insecure: true
正如你所看到的,我删除了Go模板,并使用了我在TrueNAS服务器上配置的端点、桶名和S3凭证。我配置了三个独立的桶,分别命名为mimir-alert、mimir-ruler和mimir-tsdb。
在安装了Helm图表并等待一段时间后,我可以看到数据开始从我的对象存储网络界面中显示出来。
功能和组件计数
我试验了启用memcached和摄入者的数量。前者可以在数值文件的memcached、memcached-queries和memcached-metadata部分单独启用/禁用。最后,我的节点对memcached很不满意。每个节点只有8GB的内存,根本没有足够的空间。我肯定也不需要memcached,因为我将在系统上投入低负荷水平。
组件数量对我来说确实有点神秘,因为我只在笔记本电脑或企业级集群上使用过Mimir。在Helm图表库中,有一些针对各种规模的集群的漂亮模板。为了简单起见,我采用了默认值,到目前为止效果不错,尽管对我的小集群来说有点矫枉过正。
最后,我终于把Grafana Mimir在蜂巢上启动并运行了。
踢皮球
在查看了Mimir的仪表盘并看着对象存储开始填充后,我决定创建一个整体状态仪表盘。仪表盘(如下)显示了Grafana Mimir的整体硬件利用率指标、温度和组件数量以及其他基本信息。
除了让我快速了解集群和Mimir的健康状况,将仪表盘放在一边,每30秒刷新一次,也给Mimir带来了一些查询负载。(BTW,忽略活动系列的数字,我的查询是不正确的。)
在写这篇文章时,我已经拆掉了旧的配置,我正在试验一个稍微不同的Prometheus + Grafana Mimir设置。从内存使用情况可以看出,有一个不平衡,beehive3既有Prometheus的操作者,也有一个摄取者,我不喜欢这样。这就是拥有这样一个家庭实验室集群的好处,我可以随心所欲地把它拆掉再建起来,而且每次都能学到新东西。
总结
从头开始建立一个Kubernetes集群并安装Grafana Mimir,让我对我们最新的开源产品和它的价值有了更深的了解。在操作上,它给了我一个基于集群规模的性能预期的良好基线。当我看到我们的云计算集群时,我对数据如何在组件中流动有了更深入的了解,对一切的扩展性有了更多的尊重。