news 2026/5/3 14:38:25

基于树莓派的GitOps家庭实验室:K3s与Argo CD实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于树莓派的GitOps家庭实验室:K3s与Argo CD实战指南

1. 项目概述:一个树莓派上的GitOps家庭实验室

如果你和我一样,对Kubernetes和自动化运维着迷,同时又想在家里搭建一个低成本、高可用的实验环境,那么这个基于树莓派的GitOps家庭实验室项目,绝对值得你花时间研究。它不是一个简单的“一键部署”脚本合集,而是一个完整的、生产级理念的私有云基础设施蓝图。核心思路非常清晰:用声明式的代码(Git)来定义整个集群的状态,并通过Argo CD实现全自动的同步与部署,真正做到“基础设施即代码”。

简单来说,这个项目在单台或多台树莓派上部署了一个轻量级的K3s Kubernetes集群。所有应用的部署、配置和更新,都不再需要你手动敲kubectl apply,而是通过向Git仓库提交代码(合并到main分支)来触发。Argo CD会持续监控仓库变化,并自动将集群状态调整到与代码定义一致。这意味着你的整个家庭服务器环境——从网络插件、存储系统到监控告警——都具备了版本控制、审计追踪和自动化回滚的能力。无论你是想深入学习K8s和GitOps,还是希望搭建一个稳定可靠的个人媒体中心、智能家居中枢或开发测试平台,这个项目都提供了一个极佳的实践范本。

2. 核心架构与设计思路拆解

2.1 为什么选择K3s与单节点集群?

在资源受限的树莓派上运行完整的Kubernetes(K8s)是个挑战。K3s作为CNCF认证的轻量级K8s发行版,去掉了很多传统K8s中用于云环境的沉重组件(如旧的Docker支持、云驱动等),并将核心组件打包为一个不到100MB的二进制文件,内存占用极低。这对于树莓派这类ARM架构、内存通常只有4G或8G的设备来说,是近乎唯一的选择。

选择单节点集群而非多节点高可用集群,是基于家庭实验室场景的务实考量。多节点集群固然能提供更高的可用性,但也会带来额外的复杂度(如需要负载均衡器、更复杂的网络)和资源开销(每个节点都要运行一套系统Pod)。对于个人学习或非关键业务的家用服务,单节点集群在提供完整K8s体验的同时,极大地简化了运维。项目通过system-upgrade-controller应用来实现K3s自身的自动化升级,保证了基础平台的维护性。

2.2 GitOps:不仅仅是自动化部署

这个项目的灵魂是GitOps。很多人把GitOps简单理解为“用Git存YAML文件”,但这远远不够。真正的GitOps遵循几个核心原则:

  1. 声明式系统:整个系统的期望状态(所有K8s资源)都用YAML等声明式文件描述。
  2. 版本控制与不可变性:所有声明式文件存储在Git中,任何变更都通过提交(Commit)进行,历史可追溯。
  3. 自动调和:有一个自动化代理(这里是Argo CD)持续比较Git中定义的期望状态与集群中的实际状态,并自动将实际状态驱动至期望状态。
  4. 闭环反馈:代理会将调和结果(成功、失败、差异)反馈回Git或可视化界面。

本项目采用的App of Apps模式是Argo CD的最佳实践之一。你只需要在集群中部署一个“根应用”(root-application.yaml),这个应用指向一个包含其他应用定义的目录(apps/)。Argo CD会据此自动创建并管理所有子应用。这样做的好处是,你只需要管理一个入口点,就能控制整个应用生态的部署,实现了集群的“一键自举”。

2.3 技术栈选型的深层考量

每个组件的选择都针对家庭环境做了优化:

  • 网络(Cilium + Tailscale):没有使用常见的Flannel或Calico,而是选择了基于eBPF的Cilium。eBPF能在内核层面高效处理网络策略和安全规则,性能更好、功能更强(如可视化、服务网格)。Tailscale则解决了家庭网络没有公网IP的核心痛点,它基于WireGuard协议,能轻松组建安全的点对点VPN网状网络,让你在外也能像在局域网内一样安全访问家中服务。更妙的是,其ACL(访问控制列表)策略也通过Git管理(policy.hujson),实现了网络安全的代码化。
  • 存储(Longhorn):树莓派通常使用SD卡或USB SSD,这些都不是为高并发IO设计的。Longhorn是一个轻量级、云原生的分布式块存储系统,它能在多个节点间复制数据提供冗余。即使在单节点上,Longhorn也能提供卷的动态配置、快照和备份功能。集成Backblaze B2进行异地备份,则为珍贵数据(如家庭照片、文档)加上了“保险锁”。
  • 监控(Grafana Cloud):没有自建Prometheus栈,而是选用Grafana Cloud的托管服务。这避免了在资源紧张的树莓派上运行资源消耗大户(如Prometheus、Loki、Tempo),将这些负担转移到云端,同时还能享受企业级的告警(Alerting)和值班(OnCall)功能。通过Terraform管理Grafana配置,使得监控策略也能代码化、版本化。
  • 密钥管理(Sealed Secrets):Git中不能存明文密码,这是铁律。Sealed Secrets通过非对称加密解决了这个问题。你可以在本地用集群的公钥加密密码,将加密后的密文存入Git。只有目标集群的控制器才能用私钥解密。这既满足了密钥安全,又不违背GitOps的“一切皆代码”原则。

3. 项目结构与核心组件详解

3.1 代码仓库结构:一切皆有序

清晰的项目结构是维护性的基础。这个仓库的结构体现了关注点分离的原则:

. ├── apps/ # GitOps的核心:所有应用定义 │ └── <app-name>/ # 例如:argo-cd, longhorn │ ├── application.yaml # Argo CD应用清单,定义同步源和目标 │ ├── secret.yaml # (可选)该应用所需的已加密密钥 │ └── resources/ # (可选)额外的Kustomize补丁或原生YAML ├── ansible/ # 底层节点配置(一次性的基础设施准备) │ ├── playbook.yml # 主剧本:初始化系统、安装K3s、基础配置 │ ├── inventory.yml # 目标主机(你的树莓派)清单 │ └── templates/ # 配置文件模板,如K3s服务单元 ├── terraform/ # 云服务配置(监控、告警) │ └── grafana/ # 定义Grafana Cloud的告警规则、联系点等 ├── policy.hujson # Tailscale网络访问策略文件 ├── scripts/ # 提高效率的辅助脚本 │ ├── seal-secrets.sh # 批量加密密钥脚本 │ ├── extract-secrets.sh # 从集群导出密钥(用于恢复或迁移) │ └── generate-apps-table.sh # 自动生成README中的应用表格 ├── secrets/ # .gitignore目录,存放所有明文密钥 └── root-application.yaml # GitOps引擎的启动器

关键解读

  • apps/目录是GitOps的“主战场”,这里的变动会直接触发集群更新。
  • ansible/terraform/分别对应“基础设施即代码”的不同层次:Ansible负责“裸机”或虚拟机层面的配置(Imperative,命令式),Terraform负责云服务API的配置(Declarative,声明式)。它们通常在集群建立初期或需要变更底层配置时使用。
  • secrets/目录不上传Git,是本地工作区。scripts/里的工具脚本则围绕密钥的加密解密,是安全流程的保障。

3.2 核心应用组件功能解析

让我们深入看看apps/目录下的几个关键应用,理解它们如何协同工作:

  1. argo-cd (v9.5.4):这是整个GitOps循环的控制中心。它被自己管理(Bootstrapping),即最初手动部署Argo CD后,其后续的配置和升级也通过Argo CD自身来完成。它持续监控Git仓库,并在UI上清晰展示每个应用的同步状态、健康状态和资源拓扑图。

  2. cilium (v1.19.3):作为CNI(容器网络接口)和网络策略执行者。安装后,它会接管K3s默认的Flannel(如果存在)。你需要关注其Hubble组件,它提供网络流量的可观测性,就像K8s网络的“监控摄像头”。

  3. longhorn (v1.11.1):为集群提供持久化存储。安装后,它会自动发现所有节点的可用磁盘(如挂载的SSD),并创建存储池。在UI中,你可以轻松创建PVC(持久卷声明),为数据库、文件服务等应用提供“硬盘”。重要配置:在树莓派上,务必在values.yaml中为Longhorn配置正确的defaultDataPath(例如指向一个外部USB SSD的挂载点),避免使用SD卡,否则会极大影响性能和寿命。

  4. tailscale (v1.96.5):这个Helm chart部署的是Tailscale官方Operator。它会为每个需要暴露到Tailscale VPN网络的服务创建相应的ProxyClassIngress资源。你的设备(手机、电脑)只要登录Tailscale账户,就能直接通过.ts.net域名或Tailscale IP访问家中的服务,无需公网IP和端口转发。

  5. sealed-secrets (v2.18.5):密钥安全的大门。部署后,控制器会生成加密密钥对。你需要使用附带的kubesealCLI工具,用这个公钥来加密你的明文密码,生成SealedSecret资源。只有在这个集群里,控制器才能解密它并生成对应的原生K8sSecret

4. 从零开始的完整实操部署指南

4.1 硬件与基础环境准备

硬件建议

  • 树莓派 4B 或 5:推荐4GB或8GB内存版本。4B足够运行核心组件,5的性能更充裕。
  • 存储强烈建议使用USB 3.0接口的SSD作为系统盘和存储盘,而非MicroSD卡。SD卡在频繁的读写下极易损坏,是家庭实验室数据丢失的头号杀手。一个256GB或512GB的SSD性价比很高。
  • 电源与散热:使用官方或足额(5V/3A)的电源,并配备有效的散热片或风扇,避免因过热降频。
  • 网络:通过有线网络连接路由器,保证稳定和速度。

系统准备

  1. 使用 Raspberry Pi Imager 工具,选择“Raspberry Pi OS Lite (64-bit)”镜像烧录到SSD中。Lite版本无桌面环境,资源占用更少。
  2. 在烧录时,Imager的高级设置(齿轮图标)中,预先启用SSH并设置你的用户名和密码,这样可以实现无头(无显示器)启动。
  3. 将SSD插入树莓派,上电启动。通过路由器管理界面或arp -a命令找到树莓派的IP地址。

4.2 使用Ansible完成节点初始化

Ansible剧本(ansible/playbook.yml)自动化了所有繁琐的系统配置步骤。在开始前,你需要修改ansible/inventory.yml文件,将your_raspberry_pi_ip替换为你树莓派的实际IP地址和正确的SSH用户名。

all: hosts: k3s-node: ansible_host: 192.168.1.100 # 你的树莓派IP ansible_user: pi # 你的用户名,通常是‘pi’ ansible_ssh_private_key_file: ~/.ssh/id_rsa # 建议使用SSH密钥登录

然后,在本地执行:

cd ansible ansible-playbook -i inventory.yml playbook.yml

这个剧本会执行以下关键操作:

  • 更新系统软件包。
  • 禁用交换分区(SWAP),因为Kubernetes对内存管理有严格要求,启用SWAP会影响其功能。
  • 配置Linux内核模块和系统参数(如net.bridge.bridge-nf-call-iptables),这是K8s网络正常工作所必需的。
  • 安装K3s。注意,剧本中可能通过curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC='--disable traefik' sh -这样的命令安装,并禁用自带的Ingress控制器Traefik(因为我们可能用其他方式,如Cilium的Ingress或单独的Ingress-NGINX)。
  • 将K3s的kubeconfig文件复制到本地,方便你用kubectl管理集群。

注意:首次运行Ansible剧本时,可能会因为SSH主机密钥验证而中断。你可以先手动SSH连接一次树莓派以接受密钥,或者使用ANSIBLE_HOST_KEY_CHECKING=False环境变量来运行playbook。

4.3 启动GitOps引擎:部署Argo CD根应用

节点准备就绪后,K3s集群已经在运行。现在,我们需要将GitOps的“大脑”——Argo CD部署上去,并让它开始管理自己和其他应用。

  1. 验证集群连接

    # 通常kubeconfig在 /etc/rancher/k3s/k3s.yaml,需要复制到本地并设置权限 mkdir -p ~/.kube sudo cat /etc/rancher/k3s/k3s.yaml | sed 's/127.0.0.1/<你的树莓派IP>/g' > ~/.kube/config chmod 600 ~/.kube/config kubectl get nodes # 应看到你的树莓派节点状态为 Ready
  2. 部署根应用

    # 在项目根目录执行 kubectl apply -f root-application.yaml

    这个root-application.yaml文件定义了一个Argo CDApplication资源,其spec.source.repoURL指向了这个Git仓库,targetRevision指向HEAD(或某个分支),path指向apps/目录。Argo CD控制器会读取这个文件,并开始创建和管理apps/目录下定义的所有子应用。

  3. 访问Argo CD UI: 部署后,需要暴露Argo CD的服务。通常可以通过端口转发快速访问:

    kubectl port-forward svc/argocd-server -n argocd 8080:443

    然后浏览器访问https://localhost:8080。默认用户名是admin,初始密码可以通过以下命令获取:

    kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo

    在UI中,你应该能看到一个名为root-application的应用,以及它下面自动创建的所有子应用(如cilium,longhorn等)。它们的状态会从OutOfSync逐渐变为SyncedHealthy

4.4 密钥管理实战:使用Sealed Secrets

假设我们要为一个数据库应用添加密码,步骤如下:

  1. 创建明文Secret文件(本地,不提交): 在secrets/目录下创建my-db-secret.yaml

    apiVersion: v1 kind: Secret metadata: name: my-db-auth namespace: my-app type: Opaque data: username: YWRtaW4= # echo -n 'admin' | base64 password: cGFzc3dvcmQxMjM= # echo -n 'password123' | base64
  2. 使用kubeseal加密: 首先,确保sealed-secrets应用已部署且控制器正在运行。

    # 从集群获取公钥并加密 kubeseal --format=yaml --cert=<(kubectl get secret -n kube-system -l sealedsecrets.bitnami.com/sealed-secrets-key -o jsonpath='{.data.tls\.crt}' | base64 --decode) < secrets/my-db-secret.yaml > apps/my-app/secret.yaml

    更常见的做法是使用离线公钥文件或控制器名称。项目提供的scripts/seal-secrets.sh脚本很可能封装了这个流程。执行它,会自动处理secrets/目录下所有文件。

  3. 提交加密后的文件: 现在,apps/my-app/secret.yaml文件的内容是加密的,可以安全地提交到Git仓库。Argo CD同步这个应用时,sealed-secrets-controller会监听到这个SealedSecret资源,将其解密,并在my-app命名空间下创建出名为my-db-auth的原始Secret供应用使用。

5. 网络与存储:家庭环境下的特殊配置

5.1 打通内外网:Tailscale与Cilium的集成

这是项目中最精妙的部分之一,实现了安全的远程访问。

  1. Tailscale配置:在apps/tailscale/目录下的values.yaml或相关配置中,你需要填入从Tailscale官网获取的oauth客户端ID和密钥,以便Operator能代表你的集群进行认证。同时,policy.hujson文件定义了精细的访问控制,例如:“允许家庭网络标签的设备访问所有服务,而开发标签的设备只能访问特定测试服务”。

  2. Cilium网络策略:Cilium提供了基于eBPF的L3/L4层网络策略。你可以编写CiliumNetworkPolicy资源,定义Pod之间的通信规则。例如,禁止监控命名空间以外的Pod访问数据库的3306端口。GitOps使得这些安全策略的变更也和业务应用一样,经过代码评审和自动化部署。

  3. 访问服务:当tailscale应用部署成功后,你可以为你的服务创建Ingress资源,并指定ingressClassName: tailscale。Tailscale Operator会自动为该服务在Tailscale网络中创建一个唯一的.ts.net子域。你在任何安装了Tailscale客户端的设备上,都能直接通过这个域名访问服务,无需配置公网IP或防火墙规则。

5.2 Longhorn在树莓派上的存储优化

树莓派的ARM架构和可能的USB存储介质,需要一些额外优化。

  • 数据路径:如前所述,在Longhorn的Helm配置中,设置persistence.defaultDataPath到一个高性能的外部存储挂载点,例如/mnt/usb-ssd/longhorn
  • 副本数:在单节点集群中,Longhorn卷的副本数(numberOfReplicas)只能设置为1。因为多副本需要分布在不同节点上。这意味着存储不具备节点级高可用。因此,定期通过Backblaze B2进行快照和备份至关重要。
  • 备份配置:在Longhorn UI中配置备份目标为Backblaze B2。你需要提供B2的Access KeySecret Key以及Bucket名称。配置完成后,可以为重要卷创建定期的备份计划,例如每天凌晨进行一次增量备份。

6. 监控、告警与日常运维

6.1 利用Grafana Cloud实现零负担监控

自建监控栈(Prometheus, Grafana, Alertmanager, Loki)非常消耗内存和CPU。Grafana Cloud的免费额度对于家庭实验室通常足够。

  1. Terraform配置terraform/grafana/目录下的代码定义了你的监控即代码。你需要先登录Grafana Cloud,创建一个服务账户并生成API密钥。然后,在本地配置Terraform的backend(可选)和变量(如grafana_cloud_url,grafana_cloud_api_key)。

  2. 应用监控:项目中的k8s-monitoring应用(通常基于prometheus-community/kube-prometheus-stack的简化版)负责采集集群指标。但它的Prometheus被配置为“远程写入”模式,将数据推送到Grafana Cloud的Prometheus端点,本地不存储历史数据,大大减轻了负担。

  3. 告警管理:告警规则定义在apps/alerting-rules/中。当规则被触发时,Grafana Cloud的Alertmanager会根据terraform/中定义的联系点(Contact Points,如邮件、Slack、钉钉)和通知策略(Notification Policies)将告警信息发送给你。你甚至可以通过Terraform配置OnCall排班,实现告警的升级。

6.2 日常GitOps工作流与问题排查

标准工作流

  1. 开发/修改:在本地克隆的仓库中,修改apps/下某个应用的配置(如升级镜像版本、修改Helm values)。
  2. 测试:(可选)可以使用kubectl kustomizehelm template命令预览生成的YAML。
  3. 提交git add,git commit -m "feat: upgrade nginx to v1.25"
  4. 推送与合并git push到特性分支,创建Pull Request,经过Review后合并到main分支。
  5. 自动同步:GitHub Webhook通知Argo CD,Argo CD自动开始同步过程。你可以在UI中实时观察同步状态。

常见问题与排查

问题现象可能原因排查步骤
Argo CD应用状态为OutOfSyncGit中的配置与集群实际状态不一致。1. 点击应用,查看“差异”(Diff),确认是哪些字段不同。
2. 检查是否有人手动修改过集群资源(kubectl edit),这违背了GitOps原则。
Argo CD应用状态为DegradedHealthy但服务不可用应用Pod启动失败或就绪探针失败。1. 在Argo CD UI中点击资源,查看事件(Events)。
2. 使用kubectl logs -f <pod-name>查看Pod日志。
3. 使用kubectl describe pod <pod-name>查看详细状态和错误信息(如镜像拉取失败、配置错误)。
同步失败,报错“manifest generation error”Helm/Kustomize渲染出错。1. 检查application.yamlsourcetargetRevision(分支/标签)是否存在。
2. 检查Helmvalues.yaml或Kustomizekustomization.yaml的语法是否正确。
3. 查看Argo CD应用的详细日志。
Tailscale无法访问服务ACL策略限制或域名未生效。1. 检查tailscale status确认设备已登录且在线。
2. 在Tailscale Admin控制台检查policy.hujson是否已生效。
3. 检查集群中对应服务的Ingress资源是否已正确创建且状态正常。
Longhorn卷挂载失败节点存储路径权限问题或磁盘空间不足。1. 登录节点,检查defaultDataPath目录是否存在且权限正确(通常应为longhorn:longhorn)。
2. 在Longhorn UI中检查卷和节点的状态。
3. 使用df -h检查磁盘空间。

实操心得

  • 养成“只通过Git操作”的习惯:一旦GitOps流程跑通,坚决避免使用kubectl edit/apply直接修改集群资源。任何变更都必须通过提交代码来进行。这是掌握GitOps思想的关键。
  • 善用Argo CD的自动同步策略:对于非核心应用,可以在application.yaml中设置syncPolicy.automated,让Argo CD在检测到差异时自动同步。但对于核心组件(如Argo CD自身、CNI、存储),建议设置为手动同步(或至少开启prune: false),给自己一个审查和回滚的机会。
  • 备份不仅仅是数据:定期备份你的Git仓库。你的整个集群状态都在里面。可以考虑将仓库定时备份到私有Gitea实例或另一个Git托管平台。对于Sealed Secrets,务必安全备份控制器的私钥(kubectl get secret -n kube-system -l sealedsecrets.bitnami.com/sealed-secrets-key -o yaml > sealed-secrets-key-backup.yaml),否则加密的密钥将无法恢复。

7. 进阶扩展与个性化定制

基础平台搭建完成后,你可以在此基础上部署任何你需要的应用。例如,通过Helm chart部署bitnami/wordpress来搭建个人博客,部署jellyfin/jellyfin打造家庭影音库,或者部署vaultwarden/server搭建密码管理器。

部署新应用的通用流程

  1. apps/目录下创建新文件夹,如apps/my-wordpress/
  2. 创建application.yaml,定义从哪个Helm仓库拉取Chart,以及覆盖的values。
    apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: my-wordpress namespace: argocd spec: project: default source: repoURL: https://charts.bitnami.com/bitnami chart: wordpress targetRevision: 18.0.0 helm: valueFiles: - values.yaml destination: server: https://kubernetes.default.svc namespace: wordpress syncPolicy: automated: prune: true selfHeal: true
  3. 创建values.yaml,配置WordPress的参数,如数据库密码(通过引用SealedSecret)、持久化存储大小、Ingress主机名等。
  4. 如果需要密码,在secrets/下创建明文secret,运行seal-secrets.sh脚本生成加密文件。
  5. 提交代码,等待Argo CD自动同步。

这个项目为你提供了一个坚如磐石的、现代化的家庭IT基础设施底座。它不仅仅是一套可运行的配置,更是一套关于如何以软件工程的方式管理基础设施的完整方法论。随着你的不断实践和定制,它会逐渐演化成完全贴合你个人需求的数字家园中枢。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/3 14:28:42

在OpenWrt路由器上部署AI智能体:MicroPython+Shell实现自动化运维

1. 项目概述&#xff1a;在路由器上部署一个AI大脑 如果你和我一样&#xff0c;家里或办公室有一台刷了OpenWrt系统的路由器&#xff0c;除了让它默默无闻地转发数据包&#xff0c;偶尔还想让它干点更“聪明”的活儿&#xff0c;比如定时检查网络状态、自动下载文件、甚至根据…

作者头像 李华
网站建设 2026/5/3 14:27:36

ERP系统是什么意思?企业资源计划系统的功能与选型指南

ERP系统是什么意思&#xff1f;ERP&#xff08;Enterprise Resource Planning&#xff09;即企业资源计划系统&#xff0c;是用于管理企业核心业务资源的软件工具。ERP系统通过整合财务、采购、生产、销售、库存等核心环节&#xff0c;帮助企业实现资源的统一规划和高效调配。相…

作者头像 李华
网站建设 2026/5/3 14:24:46

Book118文档下载器:Java实现的免费PDF文档获取终极方案

Book118文档下载器&#xff1a;Java实现的免费PDF文档获取终极方案 【免费下载链接】book118-downloader 基于java的book118文档下载器 项目地址: https://gitcode.com/gh_mirrors/bo/book118-downloader 还在为Book118网站的文档付费限制而烦恼吗&#xff1f;Book118文…

作者头像 李华