资讯动态

基于GitOps与IaC的全栈家庭实验室架构设计与实践

发布时间:2026/8/20 7:32:50 来源:尧图企业网站定制
1. 从零到一我的全栈家庭实验室架构演进之路几年前我还在为家里几台旧电脑和树莓派上零零散散的服务发愁。Jellyfin媒体服务器、Gitea代码仓库、Nextcloud网盘每个都运行在不同的机器上配置混乱备份困难更新更是噩梦。直到我接触到了“家庭实验室”这个概念才意识到家中的IT基础设施完全可以像云服务商的数据中心一样用现代DevOps的理念来管理和运维。今天我想分享的就是基于Khue Doan的Homelab项目为蓝本结合我个人超过一年的实践与深度定制构建的一套完整、自动化、可扩展的家庭云平台。这不仅仅是一个技术栈的堆砌更是一套关于如何将“基础设施即代码”和“GitOps”哲学落地到个人环境中的系统工程实践。这套系统能为你做什么简单来说它把你的家庭网络变成一个高度自动化的私有云。从按下物理服务器的电源键开始到所有服务如媒体库、代码托管、CI/CD、监控告警完全就绪整个过程无需手动干预。你可以像管理代码一样管理你的整个服务器集群配置变更通过Git提交系统自动同步和应用应用更新通过PR审核后自动部署甚至操作系统和Kubernetes集群的升级也能实现滚动更新最大程度保证服务可用性。无论你是想深入学习Kubernetes和云原生技术还是单纯希望拥有一个稳定、可控、功能强大的自托管环境这个架构都能提供一个绝佳的起点和框架。2. 核心设计哲学为什么选择GitOps与IaC在深入技术细节之前理解背后的“为什么”至关重要。家庭实验室的维护最怕的就是变成“宠物”而不是“牲畜”。所谓“宠物”是指你需要精心呵护、手动配置、出了问题得单独处理的服务器而“牲畜”则是可以批量创建、销毁、由自动化工具统一管理的资源。我们的目标就是将所有服务器和应用都变成“牲畜”。2.1 基础设施即代码让一切可重复、可版本控制Infrastructure as Code的核心思想是用定义文件代码来描述和配置你的基础设施服务器、网络、存储等。在Khue的架构中这主要体现在两个层面物理服务器自动化配置通过Ansible Playbook定义。从操作系统的基础配置主机名、网络、用户、SSH密钥、系统服务的安装与配置如Docker、Kubelet到安全策略的实施防火墙规则、SELinux全部由代码描述。这意味着重装一台机器或者新增一个节点你只需要运行对应的Ansible剧本半小时内就能得到一个状态完全已知、符合标准的服务器。Kubernetes集群与应用声明通过Kustomize和Helm Chart定义。整个Kubernetes集群的组件CNI、Ingress Controller、存储类以及跑在上面的所有应用Gitea、Jellyfin、Prometheus其期望状态都以YAML文件的形式存储在Git仓库中。实操心得IaC最大的好处不是初次部署而是灾难恢复和一致性保证。我曾经因为误操作导致一台主节点系统崩溃。在传统模式下我可能需要花一晚上回忆各种配置。而在IaC模式下我只需要找一台备用机器重新PXE启动运行Ansible然后集群的GitOps工具ArgoCD会自动把所有的应用拉起来。整个过程从硬件到应用完全自动化让我能安心睡觉。2.2 GitOps以Git为单一可信源GitOps是IaC在应用交付层面的具体实践模式。它将Git仓库作为声明期望状态的唯一来源并有一个自动化控制器这里是ArgoCD持续比对Kubernetes集群中的实际状态与Git中声明的期望状态一旦发现偏差就自动进行同步。在这个家庭实验室中GitOps工作流是这样的配置即代码所有Kubernetes的YAML清单、Helm values文件都存放在一个专门的GitOps仓库中通常由Gitea托管。变更即提交当你需要更新一个应用的镜像版本或者修改某个配置参数时你不再是去服务器上敲kubectl edit而是在本地修改对应的YAML文件然后提交一个Pull Request。审核与合并PR会触发CI流水线Woodpecker CI进行简单的语法验证或测试。通过人工或自动审核后代码被合并到主分支。自动同步ArgoCD监控着这个Git仓库的主分支。一旦检测到新的提交它会在几秒到几分钟内自动将变更应用到Kubernetes集群中使集群状态与代码声明保持一致。这个闭环带来了几个革命性的优势可审计所有变更都有Git记录、可回滚一键回退到任意历史提交、一致性杜绝了手动操作导致的配置漂移。你的家庭服务从此拥有了企业级应用的发布流程。3. 硬件选型与网络架构务实与性价比的平衡Khue的原方案使用了4台NEC SFF小型主机i5-6600T, 16GB RAM。这是一个非常务实的选择。家庭实验室不必追求最新的硬件稳定、低功耗、性价比高是关键。3.1 我的硬件配置演进我最初采用了两台英特尔NUCi5-8259U, 32GB RAM作为主节点搭配一台旧笔记本i7-6700HQ, 16GB RAM作为工作节点。后来为了获得更好的存储扩展性和HA能力我升级为三台迷你主机AMD Ryzen 5 5600U, 64GB RAM的配置。这里有几个选型建议CPU选择支持虚拟化Intel VT-x / AMD-V和直通VT-d / AMD-Vi的型号为未来可能玩虚拟机或GPU直通留有余地。核心数比单核高频更重要因为Kubernetes的很多组件是并发的。内存这是最容易成为瓶颈的资源。Kubernetes系统组件、监控日志栈Prometheus, Loki、以及用户应用都会消耗大量内存。个人建议每个节点起步16GB规划32GB或以上会更从容。我的每个节点64GB让我可以轻松运行内存数据库如Redis和多个Java应用。存储强烈建议使用SSD作为系统盘和应用盘。机械硬盘可以作为冷数据或媒体库的存储通过Ceph RBD或Longhorn提供块存储给Kubernetes。我采用了一个NVMe SSD系统盘etcd数据加一个SATA SSD应用数据加多个大容量HDD媒体存储的混合方案。网络一个可靠的千兆交换机是必须的。如果计划运行Ceph这类分布式存储或者有内部高速传输需求如视频剪辑素材库可以考虑2.5G或10G网络。我使用了一个8口千兆管理型交换机便于划分VLAN和监控流量。3.2 网络规划与安全隔离家庭网络环境相对简单但良好的规划能提升安全性和可管理性。VLAN划分我在交换机上创建了几个VLAN管理VLAN仅供服务器管理口、IPMI/iDRAC接口、交换机本身使用。严格限制访问来源。Kubernetes节点VLAN所有工作节点和主节点的业务网口在此VLAN内保证Pod网络通信的低延迟和隔离。服务VLAN承载从Ingress暴露出来的家庭服务如Jellyfin, Homepage。家庭主网络可以访问此VLAN。IoT设备VLAN隔离智能家居设备防止它们窥探主网络。防火墙策略在作为家庭网关的路由器或软路由上设置严格的规则。例如仅允许从服务VLAN到特定Pod端口的访问禁止节点VLAN直接访问互联网出口流量需经过网关审查。内部服务发现与DNS使用CoreDNS作为Kubernetes集群内部的DNS服务器并配置stubDomains将家庭内部域名如home.lab的解析指向运行在集群内的AdGuard Home或Pi-hole实例。这样在家庭网络中的任何设备都可以通过jellyfin.home.lab这样的域名访问服务。注意事项分布式存储如Ceph对网络延迟和丢包非常敏感。务必确保节点间的网络质量。如果使用多台交换机避免复杂的跨交换机链路聚合简单的Trunk链路可能更稳定。我曾因为一个交换机的STP配置问题导致Ceph OSD不断失联排查了很久。4. 自动化基石PXE引导与Ansible配置管理这是整个自动化流水线的起点目标是实现裸机“一键加入集群”。4.1 构建全自动PXE引导环境PXEPreboot Execution Environment允许计算机通过网络启动而不是从本地硬盘。我们需要搭建几个服务DHCP服务器为待安装的机器分配IP地址并告知其TFTP服务器的地址和引导文件名。我使用dnsmasq因为它轻量且能同时提供DHCP、TFTP和DNS服务。关键配置是告诉客户端去TFTP服务器获取grubx64.efiUEFI模式或pxelinux.0BIOS模式。TFTP服务器存放引导加载程序GRUB、内核vmlinuz和初始内存磁盘initrd.img。这些文件可以从Fedora Server的ISO镜像中提取。HTTP服务器存放完整的操作系统安装源Fedora Server的软件包仓库以及我们的Kickstart文件。Kickstart是Red Hat系Linux的自动安装应答文件它定义了分区方案、软件包选择、用户密码、后安装脚本等一切。Khue项目的精髓在于它用一个Docker容器封装了上述所有服务dnsmasq nginx并通过一个简单的docker run命令启动。这个容器是临时的只在安装阶段需要。Kickstart文件的核心是后安装脚本它会从指定的URL下载并执行一个Ansible Playbook完成后续所有配置。4.2 Ansible状态定义与配置漂移修正Ansible在这个架构中扮演着“配置状态管理器”的角色。它的任务不仅仅是初次安装更重要的是确保系统状态始终符合定义修正任何手动修改造成的“漂移”。我的Ansible Playbook主要包含以下角色基础配置设置主机名、配置静态IP或DHCP、配置DNS、更新系统、安装基础工具vim, git, curl等。安全加固配置SSH密钥登录、禁用密码登录、设置防火墙规则firewalld或nftables、配置fail2ban。容器运行时安装并配置containerd或Docker。我选择containerd因为它更轻量是Kubernetes默认的运行时。Kubernetes节点准备关闭swap、加载内核模块br_netfilter,overlay、配置sysctl参数、安装kubeadm,kubelet,kubectl。K3s特定配置由于Khue项目使用K3s角色会安装K3s但关键点在于将其安装为“未启动”状态。真正的集群初始化将由后续的Kubernetes GitOps流程来控制这保证了集群配置也由代码管理。踩坑记录Ansible的apt模块在Ubuntu/Debian上更新缓存时可能有并发问题。建议在Playbook开头显式地使用ansible.builtin.command: apt update并加上retries和delay参数。另外对于系统服务如docker, k3s的启动状态管理务必使用ansible.builtin.systemd模块并设置enabled: yes和state: started确保重启后生效。5. Kubernetes集群搭建选择K3s及其深度调优为什么是K3s而不是原生K8s或KubeadmK3s是一个经过CNCF认证的、轻量级的Kubernetes发行版它将所有控制平面组件打包成一个不到100MB的二进制文件默认使用sqlite3作为存储后端极大地简化了部署和运维。对于资源有限且不需要极高可用性的家庭环境它是完美选择。5.1 K3s集群初始化与高可用考量单服务器部署K3s非常简单curl -sfL https://get.k3s.io | sh -。但对于生产级家庭实验室我们需要考虑一定的可用性。K3s支持多种高可用模式我采用了一种折中方案嵌入式etcd高可用启动第一个节点时使用--cluster-init标志这会启用内置的etcd。后续节点加入时使用--server https://第一个节点的IP:6443 --token token并同样指定--cluster-init实际上后续节点会自动组成etcd集群。这样就形成了一个多主节点的HA控制平面。# 第一个主节点 curl -sfL https://get.k3s.io | K3S_TOKENmy-secret-token sh -s - server --cluster-init # 第二个主节点 curl -sfL https://get.k3s.io | K3S_TOKENmy-secret-token sh -s - server --server https://node1-ip:6443 --cluster-init负载均衡多个API Server需要一个负载均衡器。在家庭环境一个简单的方案是使用klipper-lbK3s自带或MetalLB在Layer2模式下提供一个虚拟IP。更简单的方式是在客户端kubectl, ArgoCD等的kubeconfig中配置多个server地址让客户端去重试。我选择了后者因为家庭环境中断电概率低且配置简单。5.2 关键组件替换与优化K3s默认使用Flannel作为CNITraefik作为Ingress Controller以及自带的service load balancer。为了获得更强大的功能和更好的性能我替换了其中一些组件这与Khue的方案一致CNIFlannel - CiliumCilium基于eBPF提供了远超传统CNI的能力包括基于身份的网络策略、可观测性Hubble、集群级负载均衡等。安装Cilium后需要禁用K3s自带的Flannel和Kube-Proxy因为Cilium可以替代它们。# 在K3s启动参数中禁用自带组件 --flannel-backendnone --disable-kube-proxy --disable-network-policy # 然后通过Helm安装Cilium helm install cilium cilium/cilium --namespace kube-system --set kubeProxyReplacementstrict ...Ingress ControllerTraefik - NGINX Ingress Controller个人更喜欢NGINX的配置语义和生态。替换后需要更新IngressClass和相关的Annotations。存储K3s自带一个本地路径存储类local-path。对于有状态应用我们需要更强大的方案。我部署了Rook Ceph它提供了块存储RBD、文件系统CephFS和对象存储S3兼容接口。Ceph的配置非常复杂关键点在于为每个节点准备独立的裸设备磁盘或分区作为OSD并确保网络低延迟。实操心得Ceph对内存要求不低每个OSD进程可能消耗几个GB。在资源有限的家庭集群中可以考虑更轻量的方案如Longhorn。Longhorn是云原生的分布式块存储部署简单支持快照、备份和跨节点复制。我曾在早期使用Longhorn它的Web界面非常友好对于初学者更友好。但如果你需要同时提供文件存储和对象存储Ceph是更全面的选择。6. GitOps引擎ArgoCD的部署与应用管理ArgoCD是整个GitOps流程的大脑。它被部署在Kubernetes集群内部持续监控着我们的GitOps仓库。6.1 部署与配置ArgoCD通常通过Helm Chart部署ArgoCD。关键配置在于如何让它“自举”——即ArgoCD如何管理自己的配置这里我们采用“App of Apps”模式。根应用Root Application我们首先手动创建一个ArgoCD应用这个应用指向一个包含所有其他应用定义的Kustomize目录或Helm Chart。这个根应用通常定义在argocd命名空间下的一个Application资源中可以通过kubectl apply手动创建或者更“GitOps”一点在初始化的Ansible脚本中创建。应用集ApplicationSet这是更高级的模式。ApplicationSet控制器可以根据Git仓库中的目录结构、文件内容等动态生成ArgoCDApplication资源。例如你可以定义一个规则“为apps/目录下的每一个子目录生成一个ArgoCD应用”。这样当你新增一个应用时只需要在apps/下新建一个目录并提交ArgoCD就会自动创建对应的应用对象无需手动修改任何YAML清单。Khue的项目就大量使用了ApplicationSet。我的配置中根应用指向一个包含以下内容的Kustomize overlay基础设施层Cilium, NGINX Ingress, Cert-manager, ExternalDNS, Rook Ceph等集群必需组件。运维层监控栈Prometheus, Grafana, Loki, Alertmanager日志收集备份工具Velero。应用层所有业务应用如Gitea, Jellyfin, Nextcloud, Homepage等。6.2 同步策略与自动更新ArgoCD支持多种同步策略手动同步安全但失去了自动化的意义。自动同步检测到Git仓库状态落后时自动同步。对于生产环境这可能过于激进。自动同步与修剪在自动同步的基础上还会删除Git中已不存在的资源。使用此选项需极其谨慎误删目录可能导致服务被删除。我采用的是一种混合策略对于基础设施层和运维层使用自动同步。因为这些是集群的基石需要快速响应配置变更且变更相对可控。对于应用层使用手动同步但结合自动更新工具。我使用Renovate机器人它会监控我应用的Helm Chart版本和容器镜像版本并自动创建Pull Request。我审查PR后合并ArgoCD检测到Git变更我会在Grafana或ArgoCD的UI上手动点击“同步”。这既保证了变更的可控性又减轻了手动检查更新的负担。避坑指南ArgoCD在同步Helm Chart时如果Chart的values.yaml使用了{{ .Values.someKey }}这样的模板语法而你的覆盖值文件里没有定义someKey同步可能会失败。建议在ArgoCD的Application资源中明确设置helm.parameters来覆盖这些值而不是完全依赖外部的values.yaml文件。另外对于有状态应用如数据库务必配置syncPolicy中的preserveResourcesOnDeletion: true防止ArgoCD在删除应用时误删PVC持久卷声明导致数据丢失。7. 关键服务栈详解监控、日志、存储与安全一个健壮的家庭实验室离不开可观测性、持久化存储和安全管理。7.1 监控告警体系Prometheus Grafana Alertmanager数据采集使用prometheus-operator现更名为kube-prometheus-stack一键部署Prometheus、相关Exporter以及Alertmanager。它会自动发现集群中的Service和Pod并配置抓取任务。对于物理节点需要在节点上部署node-exporterDaemonSet。数据可视化Grafana连接到Prometheus作为数据源。我导入了一些社区仪表板如“Kubernetes Cluster Monitoring”、“Node Exporter Full”并自定义了针对家庭实验室特定应用如Jellyfin转码状态、硬盘SMART信息的仪表板。告警管理Alertmanager负责接收Prometheus的告警并进行分组、抑制、静音并通过不同的接收器发送通知。我配置了以下接收器ntfy一个轻量的HTTP推送服务。Alertmanager通过Webhook将告警发送到自托管的ntfy服务器ntfy再推送到我的手机App。这是实时性最高的方式。电子邮件用于非紧急的、摘要性的告警。Slack/Matrix用于团队协作虽然家庭实验室通常就一个人。关键的告警规则包括节点NotReady、Pod持续重启、内存/磁盘使用率超过80%、服务端点不可达、证书即将过期等。7.2 日志聚合Loki Grafana传统ELK栈Elasticsearch, Logstash, Kibana资源消耗大。Grafana Loki是一个为日志而生的聚合系统设计理念是“只索引元数据不索引日志内容”因此非常轻量。收集使用Promtail作为日志收集代理以DaemonSet形式运行在每个节点上收集节点和容器日志并附加Pod标签后推送给Loki。存储Loki可以使用本地存储、S3兼容对象存储如MinIO或云服务。我使用Ceph RGW提供的S3接口作为Loki的后端存储成本低廉。查询在Grafana中添加Loki数据源就可以使用LogQL查询语言像查询指标一样查询日志。结合Pod标签可以快速定位某个特定服务的错误日志。7.3 持久化存储Rook Ceph实战部署Ceph是家庭实验室中最具挑战性的环节之一。以下是我的步骤和要点准备裸设备为每个Kubernetes节点准备至少一块独立的硬盘或SSD不要分区直接用整块盘。通过lsblk确认设备路径如/dev/sdb。部署Rook Operator这是管理Ceph集群的Kubernetes Operator。创建CephCluster在YAML中定义存储节点、设备筛选规则、网络配置等。关键参数apiVersion: ceph.rook.io/v1 kind: CephCluster metadata: name: rook-ceph namespace: rook-ceph spec: dataDirHostPath: /var/lib/rook # 主机路径存放配置 cephVersion: image: quay.io/ceph/ceph:v17.2.6 # 使用稳定版本 storage: storageClassDeviceSets: - name: set1 count: 3 # OSD数量至少3个用于数据冗余 portable: false # 设备不跨节点移动 tuneDeviceClass: true encrypted: false # 家庭环境可关闭加密提升性能 volumeClaimTemplates: - metadata: name: data spec: resources: requests: storage: 1Ti # 每个OSD申请的大小实际使用整块盘 storageClassName: local-path # 临时使用本地存储类创建PVC实际OSD会直接使用裸设备 volumeMode: Block accessModes: - ReadWriteOnce network: provider: host # 对于性能敏感场景使用host网络 healthCheck: daemonHealth: mon: interval: 45s osd: interval: 60s创建存储类Ceph集群就绪后Rook Operator会自动创建rook-ceph-blockRBD和rook-cephfsCephFS存储类。应用就可以通过PVC申请持久化存储了。血泪教训Ceph对时钟同步要求极高。务必确保所有节点的时间同步使用chrony或systemd-timesyncd偏差最好在毫秒级以内否则可能导致OSD进程崩溃。我曾因为一台旧主机CMOS电池老化导致时钟漂移引发整个Ceph集群状态异常。7.4 安全与访问控制单点登录与网络策略单点登录使用Dex或Keycloak作为OIDC提供商集成Gitea、Grafana、ArgoCD等服务。用户只需登录一次即可访问所有授权应用。我选择了相对轻量的Dex它支持多种后端LDAP, Git, 静态用户等。我将它与Kanidm一个现代的身份管理平台结合统一管理用户和组。网络策略使用Cilium的CiliumNetworkPolicy实施零信任网络。默认拒绝所有Pod间的通信然后按需开放。例如只允许监控命名空间的Pod抓取应用命名空间的Pod的指标只允许前端Pod访问后端Pod的特定端口。这极大地缩小了攻击面。证书管理使用cert-manager自动从Let‘s Encrypt申请和续期TLS证书。配置一个ClusterIssuer然后为每个Ingress资源添加注解cert-manager就会自动创建Certificate资源并配置TLS Secret。8. 持续集成与交付内部CI/CD流水线有了GitOps管理应用部署我们还需要一个CI系统来构建容器镜像、运行测试。8.1 为什么选择Woodpecker CI相比Jenkins或GitLab CIWoodpecker CI的设计更简单、更云原生。它本身就是一个轻量的容器通过Webhook驱动配置文件.woodpecker.yml直接放在代码仓库根目录概念清晰。部署Woodpecker非常简单一个Helm Chart即可。它需要连接一个Gitea实例作为代码仓库和认证源。当代码推送到Gitea时Gitea会发送Webhook给Woodpecker触发流水线。8.2 一个完整的应用CI/CD流水线示例以部署一个简单的Go Web应用为例代码仓库代码托管在自建的Gitea上。Woodpecker流水线定义(.woodpecker.yml)pipeline: build: image: golang:1.20 commands: - go build -o myapp ./cmd/server - docker build -t $CI_REGISTRY/$CI_REPO_OWNER/$CI_REPO_NAME:$CI_COMMIT_SHA . - docker push $CI_REGISTRY/$CI_REPO_OWNER/$CI_REPO_NAME:$CI_COMMIT_SHA update-manifest: image: alpine/helm:latest commands: # 使用helm upgrade --dry-run生成新的YAML并更新GitOps仓库中的values.yaml - apk add git - git clone https://$GITEA_USER:$GITEA_TOKENgitea.home.lab/my-homelab/gitops-repo.git - cd gitops-repo/apps/myapp - sed -i s|tag:.*|tag: \$CI_COMMIT_SHA\| values.yaml - git config user.email cihome.lab - git config user.name Woodpecker CI - git commit -am Update myapp image to $CI_COMMIT_SHA - git pushGitOps仓库gitops-repo中有一个apps/myapp目录里面包含一个Kustomization文件或Helm values文件定义了该应用的部署配置。流程开发者提交代码 - Woodpecker触发流水线 - 构建Go二进制文件 - 构建Docker镜像 - 推送镜像到私有仓库Zot - 自动更新GitOps仓库中该应用的镜像标签 - ArgoCD检测到Git变更 - 自动同步将新版本的应用部署到Kubernetes集群。这样就实现了一个完整的、从代码提交到服务上线的自动化流水线。所有环节都在家庭实验室内部完成安全且高效。9. 对外暴露服务安全与便利的权衡家庭宽带通常没有固定公网IP且80/443端口可能被运营商封锁。如何安全地从外部访问家庭服务Cloudflare Tunnel这是Khue项目推荐也是我采用的首选方案。cloudflared作为一个轻量级守护进程运行在集群内与Cloudflare的边缘网络建立出站连接隧道。你不需要在路由器上设置任何端口转发也不需要公网IP。流量路径是用户 - Cloudflare全球网络 - 隧道 - 你的家庭服务。Cloudflare还提供了免费的SSL证书、WAF防护和访问策略Zero Trust安全性很高。配置好后你的服务可以通过your-service.your-domain.com这样的自定义域名访问。Tailscale/WireGuard VPN对于需要直接访问集群内部网络如SSH到节点、访问数据库管理端口的场景一个Mesh VPN是更好的选择。Tailscale基于WireGuard配置极其简单几乎零配置就能让所有设备处于一个安全的虚拟网络中。我使用Tailscale来管理服务器间的通信以及让我个人的笔记本电脑和手机能直接访问集群内网。端口转发备选如果拥有公网IP且运营商未封锁端口可以在路由器上设置端口转发将443端口指向运行Ingress Controller的节点。务必配合动态DNS服务如Cloudflare API来更新域名解析。同时必须在Ingress层面配置严格的访问认证如OAuth2 Proxy和WAF规则如ModSecurity因为你的服务将直接暴露在互联网上。安全警告绝对不要将管理界面如ArgoCD, Grafana, 数据库直接暴露到公网即使有密码保护。务必通过Cloudflare Tunnel的Access策略或VPN来访问。我曾见过太多因为暴露了未打补丁的Web界面而被入侵的案例。10. 日常运维、备份与问题排查实录系统搭建完成后日常运维才是真正的开始。10.1 自动化备份策略备份必须遵循“3-2-1”原则至少3份副本用2种不同介质存储其中1份在异地。集群状态备份使用Velero。它可以备份整个Kubernetes集群的资源YAML和持久卷的数据需要与存储提供商集成。我配置Velero每天凌晨3点对prod命名空间进行备份并将备份文件上传到另一个Ceph集群的S3存储桶中模拟异地。关键数据备份对于数据库如PostgreSQL for Gitea除了Velero的卷备份我还配置了定期的pg_dump逻辑备份并通过rclone同步到加密的云存储如Backblaze B2。GitOps仓库备份Gitea本身有备份功能定期将仓库打包并上传到远程存储。这是你的“基础设施代码”的最终保障。10.2 常见问题与排查命令家庭实验室出问题时按以下顺序排查节点状态kubectl get nodes -o wide kubectl describe node node-name # 查看节点事件和资源压力Pod状态kubectl get pods -A --watch kubectl describe pod -n namespace pod-name # 查看Pod事件经常能直接定位问题如镜像拉取失败、资源不足 kubectl logs -n namespace pod-name [-c container] # 查看应用日志网络问题使用Cilium提供的cilium connectivity test在命名空间内进行Pod间连通性测试。使用hubble observe实时观察网络流量。存储问题检查PVC/PV状态。kubectl get pvc -A kubectl get pv kubectl describe pvc -n namespace pvc-name对于Ceph进入rook-ceph命名空间的工具Pod进行检查kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash ceph status ceph osd status ceph dfIngress访问问题检查Ingress资源、Service和对应的Endpoint。kubectl get ingress -A kubectl describe ingress -n namespace ingress-name kubectl get svc -n namespace service-name kubectl get endpoints -n namespace service-name10.3 升级与维护系统升级使用Ansible Playbook批量对节点执行dnf update或apt upgrade并重启。通过设置Pod Disruption Budget和优雅终止可以做到滚动重启节点而不中断服务。Kubernetes升级对于K3s升级相对简单。在主节点上执行k3s-upgrade.sh脚本或使用系统包管理器升级k3s二进制文件然后逐个节点进行。务必先查看官方升级说明特别是涉及etcd或CNI的版本变更。应用升级交给GitOps和Renovate。养成定期审查和合并依赖更新PR的习惯。构建和维护这样一个家庭实验室是一个持续学习和精进的过程。它不仅仅是一堆服务的集合更是你对现代软件部署、运维、监控、安全理念的实践场。从最初的几个Pod到如今几十个微服务协同工作每一次故障排查、每一次架构优化都让我对云原生的理解更加深刻。最让我满意的不是它提供了多少服务而是当任何一台物理服务器突然宕机时我能从容不迫因为我知道整个系统具有弹性能够自我修复或至少提供清晰的恢复路径。这种对自家数字环境的完全掌控感和信心是任何公有云服务都无法给予的。如果你也心动了不妨就从一台旧电脑和一个K3s集群开始吧。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价