1. 项目概述从“玩具”到“生产力”的蜕变几年前当我第一次在GitHub上看到“khuedoan/homelab”这个项目时我的第一反应是这又是一个技术爱好者的“炫技”仓库。但随着我深入翻阅其超过6千颗星的代码和详尽的文档我意识到这远不止是一个简单的配置清单。它是一套完整的、生产级别的个人家庭实验室蓝图其设计理念、技术选型和自动化程度足以让许多中小型企业的IT基础设施汗颜。“Homelab”中文常译为“家庭实验室”其核心概念是利用个人拥有的硬件如旧电脑、迷你主机、NAS甚至树莓派和软件搭建一个私有的、可控的IT环境。你可以用它来跑自己的网站、搭建媒体库、做自动化备份、学习容器化技术甚至模拟一个微服务架构的生产环境。而khuedoan的这套方案将这个概念推向了极致。它不仅仅是在一台机器上装几个服务而是构建了一个高可用、可扩展、完全声明式配置的私有云平台。所有服务通过代码Infrastructure as Code, IaC定义一键部署并且具备从硬件故障中自愈的能力。这套方案最适合两类人一是渴望系统性学习现代云原生和运维技术的开发者或运维工程师它提供了一个绝佳的、零成本的沙盒环境二是对数据隐私和自主控制权有极高要求的极客用户它让你彻底摆脱对公有云服务商的依赖将数字生活的核心牢牢掌握在自己手中。接下来我将带你深入拆解这个宏伟工程的每一个细节。2. 核心架构与设计哲学解析2.1 为什么选择“不可变基础设施”与GitOpskhuedoan的homelab最核心的设计哲学是“不可变基础设施”和“GitOps”。这听起来很抽象我举个生活中的例子传统的服务器管理就像打理一个花园你直接登录到服务器花园里手动安装软件种花、修改配置修剪、打补丁浇水施肥。时间一长这台服务器就变成了一个充满“手工痕迹”的“雪花服务器”独一无二且难以复制一旦出问题排查和恢复极其困难。而khuedoan的方案是把服务器当成乐高积木。你首先用代码比如Terraform或Ansible精确地定义每一块“积木”应该长什么样操作系统、内核参数、基础软件。部署时不是去修改现有的服务器而是直接根据代码“烧录”出一块全新的、完全符合定义的“积木”虚拟机或容器替换掉旧的。这就是“不可变”——基础设施一旦创建就不再修改只替换。所有对环境的修改都体现在代码的版本变更中。GitOps则是将这套代码的管理流程标准化你的基础设施代码库就是唯一的“事实来源”。任何变更都必须通过向代码库提交Pull Request来完成经过审核合并后自动化工具如Argo CD会监听到代码变化并自动将变更同步到实际环境中。这意味着你的整个数据中心的状态都可以通过git log命令来追溯和回滚。这种模式带来了几个颠覆性优势一致性在任何地方本地、云端都能一键复现完全相同的环境彻底告别“在我机器上是好的”这类问题。可审计性所有变更都有清晰的代码提交记录、作者和原因安全性和合规性极大提升。灾难恢复硬件损毁直接在新机器上执行部署代码几个小时就能从零重建整个生产环境。2.2 硬件选型与网络拓扑设计考量原项目作者使用了Intel NUC迷你主机作为计算节点搭配Synology NAS作为集中存储。这是一个非常经典且平衡的搭配。NUC功耗低、性能足够、体积小巧适合作为多个节点组成集群。NAS则提供了大容量、可靠且易于管理的网络存储用于存放虚拟机磁盘、容器镜像以及所有应用数据。注意硬件选择没有定式。你可以用任何x86_64架构的机器甚至多台旧笔记本。核心原则是至少要有两台或以上节点以实现高可用并且它们之间需要千兆或更快的网络互联。如果预算有限树莓派集群也是一个有趣的起点但需要注意ARM架构可能带来的软件兼容性问题。网络层面该项目采用了典型的“三层网络”隔离管理网络用于节点间通信如Kubernetes控制平面、SSH管理。通常是一个独立的VLAN或物理网络。业务网络承载实际应用流量如你部署的网站、Nextcloud等服务对外的访问。存储网络专用于计算节点与NAS存储之间的高速数据交换如iSCSI或NFS流量。有条件的话这层网络最好用万兆光缆或电口隔离避免IO成为瓶颈。这种隔离不仅提升了安全性业务流量故障不会影响管理也优化了性能存储流量独占带宽。在家庭环境中你可能只有一台多网口路由器或一个支持VLAN的智能交换机通过划分不同的VLAN即可实现类似的逻辑隔离。2.3 技术栈全景图从裸机到服务整个技术栈可以自底向上分为四层基础设施层物理硬件NUC、NAS、交换机、底层操作系统通常是精简的Linux发行版如Ubuntu Server。编排与虚拟化层这是核心中的核心。项目使用Proxmox VE作为裸机管理程序。Proxmox是一款开源的、集虚拟化KVM、容器LXC和软件定义存储/网络于一体的超融合平台。它在物理机上创建出多台虚拟机VM这些虚拟机将作为Kubernetes集群的节点。容器编排层在Proxmox创建的虚拟机上部署Kubernetes集群。项目选用k3s这是一个经CNCF认证的、轻量级的Kubernetes发行版相比原版K8s它去掉了很多非核心组件安装更快资源占用更少特别适合边缘和资源受限环境。应用定义与交付层使用Ansible自动化所有节点的初始配置和K3s安装。然后使用FluxCD或Argo CDGitOps工具来管理部署在K3s集群上的所有应用。所有应用的Kubernetes配置文件YAML都存放在Git仓库中由GitOps工具自动同步到集群。最终用户通过浏览器访问的每一个服务如Bitwarden密码管理器、Nextcloud网盘都是一个运行在K3s集群中的Pod其生命周期完全由代码控制。3. 核心组件深度拆解与实操要点3.1 Proxmox VE稳定高效的虚拟化基石Proxmox VE的安装相对简单从官网下载ISO镜像制作启动U盘即可。安装过程中关键决策点是磁盘配置和网络配置。磁盘配置如果你的节点有多个硬盘比如一块小容量SSD和一块大容量HDD一个最佳实践是SSD安装Proxmox系统并创建“local-lvm”存储池用于存放虚拟机的操作系统磁盘。这能保证VM启动和系统IO的速度。HDD/NAS创建指向NAS的存储如NFS或CIFS共享或者将HDD直通给Proxmox作为“local”存储用于存放虚拟机的大型数据盘、ISO镜像和容器模板。网络配置建议在安装时就配置好Linux Bridge网桥而不是简单的NAT。将物理网卡如eno1绑定到一个名为vmbr0的网桥上并为此网桥配置一个管理IP地址。这样后续创建的虚拟机就可以连接到vmbr0与物理网络处于同一层级如同直接插在交换机上一样性能最好且配置简单。实操心得在Proxmox中创建虚拟机时强烈建议使用“Cloud-Init”镜像。Cloud-Init是一种行业标准用于在虚拟机首次启动时自动注入主机名、SSH密钥、网络配置等信息。你可以先下载一个通用的Cloud镜像如Ubuntu Cloud Image然后基于它创建模板。以后所有新虚拟机都从这个模板克隆并借助Cloud-Init实现个性化这比手动安装操作系统并配置要高效无数倍。3.2 K3s on Proxmox轻量级K8s集群部署在Proxmox中创建好作为K3s节点的虚拟机后通常至少需要3台以实现高可用控制平面就可以通过Ansible来批量安装和配置K3s了。Ansible剧本的核心任务基础准备在所有节点上安装必要的软件包如curlvim、配置SSH互信、关闭交换分区Kubernetes要求、设置正确的防火墙规则开放6443、8472等K3s端口。安装K3s Server在第一个节点上执行K3s的服务器安装命令。关键参数包括curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC--cluster-init --tls-san 你的负载均衡器IP或域名 sh ---cluster-init会使用内嵌的etcd作为数据库并启用集群模式。--tls-san非常重要它将在TLS证书中添加额外的Subject Alternative Name让你后续可以通过一个固定的IP或域名访问Kubernetes API这对于高可用部署至关重要。获取Join Token安装完成后从第一个Server节点上获取节点加入令牌位于/var/lib/rancher/k3s/server/node-token。加入其他Server节点在其他Server节点上使用相同的安装脚本但指定第一个节点的URL和令牌将它们加入为额外的控制平面节点。加入Worker节点在只作为工作负载运行的节点上使用Worker模式的加入命令。高可用架构这样部署后你就拥有了一个多Master的K3s集群。为了对外提供统一的API入口你还需要一个负载均衡器。在homelab环境中最简单的方案是在集群外部比如你的家庭路由器或一台单独的虚拟机部署一个HAProxy或Nginx将流量轮询转发到所有K3s Server节点的6443端口。更云原生的做法是在集群内部部署一个如MetalLB这样的负载均衡器配合kube-vip项目可以实现虚拟IP在多个节点间的漂移提供真正的高可用API服务。3.3 GitOps实战用FluxCD接管你的集群集群就绪后真正的魔法开始了——用GitOps工具接管。这里以FluxCD v2为例。引导Bootstrap你只需要在本地开发机执行一条命令就可以让FluxCD在集群中“自举”安装。flux bootstrap github \ --owner你的GitHub用户名 \ --repository你的homelab配置仓库 \ --branchmain \ --path./clusters/production \ # 配置文件在仓库中的路径 --personal这条命令会在你的GitHub仓库中创建一个新的分支如果需要。在仓库中生成FluxCD所需的清单文件如kustomization.yaml。在你的K3s集群中安装FluxCD的所有控制器。配置这些控制器去监视你指定的Git仓库路径。仓库结构一个良好的GitOps仓库结构通常如下你的-homelab-仓库/ ├── clusters/ │ └── production/ # 对应生产环境集群 │ ├── flux-system/ # Flux自身的配置由bootstrap生成 │ └── kustomization.yaml # 入口文件引用下面的基础配置 ├── infrastructure/ # 基础组件如ingress, monitoring │ ├── ingress-nginx/ │ ├── cert-manager/ │ └── kustomization.yaml └── apps/ # 业务应用 ├── networking/ ├── monitoring/ ├── media/ # 媒体应用如Jellyfin └── kustomization.yamlclusters/production/kustomization.yaml文件会通过resources:字段引用infrastructure和apps目录。这样当你在apps/media/下为Jellyfin添加一个Kustomize配置后只需将其路径添加到apps/kustomization.yaml的resources列表中提交代码FluxCD就会自动在集群中部署或更新Jellyfin。核心概念FluxCD定义了几个关键CRD自定义资源GitRepository定义从哪里哪个Git仓库、哪个分支同步清单文件。Kustomization定义如何同步。它指向一个GitRepository中的路径并应用Kustomize进行渲染然后将结果应用到集群。 这种声明式的方式使得你的集群状态与Git仓库状态始终保持一致。4. 关键服务部署与配置详解4.1 入口网关与SSL证书自动化ingress-nginx cert-manager在Kubernetes中外部流量需要通过Ingress资源进入集群。ingress-nginx是一个高性能的Ingress控制器它监听Ingress对象的变化并动态配置Nginx来路由流量。部署ingress-nginx后你需要为其配置一个负载均衡器服务Service of type LoadBalancer。在公有云上这会自动创建一个云负载均衡器。在家庭实验室你需要MetalLB来提供这个功能。MetalLB会从你配置的IP地址池中分配一个IP给ingress-nginx服务这个IP就是你的homelab所有服务的统一入口IP。接下来是HTTPS。手动为每个服务申请和更新SSL证书是噩梦。cert-manager是Kubernetes上的证书管理大师它可以自动从Let‘s Encrypt申请和续订免费的SSL证书。配置流程部署cert-manager。创建ClusterIssuer这是一个集群范围的证书颁发者配置。你需要配置ACMELet‘s Encrypt使用的协议挑战方式。对于家庭网络通常使用DNS01挑战验证你对域名的DNS解析权比HTTP01挑战验证你的Web服务器更可靠因为它不要求你的服务80/443端口能被公网直接访问。apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: your-emailexample.com privateKeySecretRef: name: letsencrypt-prod solvers: - dns01: cloudflare: # 假设你使用Cloudflare管理DNS email: cloudflare-emailexample.com apiTokenSecretRef: name: cloudflare-api-token key: api-token selector: {}你需要提前在Kubernetes中创建一个Secret存放你的DNS服务商如Cloudflare的API令牌。为Ingress自动签发证书在创建Ingress资源时添加特定的注解annotationcert-manager就会自动为其创建Certificate资源并完成整个申请、验证和安装流程。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-app annotations: cert-manager.io/cluster-issuer: letsencrypt-prod # 指定使用哪个Issuer spec: tls: - hosts: - app.yourdomain.com secretName: my-app-tls-secret # 证书会存储在这个Secret里 rules: - host: app.yourdomain.com http: paths: - path: / pathType: Prefix backend: service: name: my-app-service port: number: 80从此你只需要关心Ingress规则HTTPS证书的繁琐工作全部自动化。4.2 持久化存储方案Longhorn vs. NAS直连容器本身是无状态的但我们的应用如数据库、网盘需要持久化数据。在Kubernetes中这通过PersistentVolumePV和PersistentVolumeClaimPVC来实现。khuedoan的方案中提到了两种主要方式NAS直接提供存储在Proxmox层面将NAS的共享目录如NFS挂载给K3s虚拟机。然后在K3s集群中创建对应的NFS StorageClass。当应用声明需要存储时Kubernetes会动态地在你的NAS上创建目录并挂载。这种方式简单直接性能取决于网络并且NAS本身通常提供了RAID、快照等数据保护功能。Longhorn分布式块存储这是一个云原生的、轻量级的分布式块存储系统。它在K3s集群的每个节点上运行一个DaemonSet将各个节点上的本地硬盘聚合起来形成一个虚拟的、可复制的高可用存储池。当应用申请存储时Longhorn会在多个节点间同步数据副本通常为3副本即使一个节点宕机数据也不会丢失并且Pod可以漂移到其他有数据副本的节点上继续运行。如何选择追求极致简单和性能如果你的NAS性能强劲万兆网络SSD缓存且不要求存储随Pod在节点间迁移直接使用NFS/CIFS StorageClass是最佳选择。管理界面就在NAS上非常直观。追求云原生高可用和弹性如果你的节点有本地SSD且希望存储能像Pod一样在集群内自由调度和迁移Longhorn是更好的选择。它提供了漂亮的Web UI可以方便地管理卷、快照和备份。但请注意它会消耗额外的节点资源CPU、内存、网络带宽用于数据同步。实操心得对于核心有状态服务如数据库PostgreSQL我倾向于使用Longhorn因为它能提供真正的Kubernetes原生高可用体验。对于媒体库、下载目录等大型、冷数据我使用NFS直接挂载管理方便且不占用计算节点宝贵的本地存储。4.3 监控与日志体系搭建Prometheus Grafana Loki“可观测性”是生产系统的生命线。khuedoan的homelab集成了完整的监控栈。监控指标Prometheus GrafanaPrometheus负责抓取和存储时间序列指标。它通过ServiceMonitor或PodMonitor这些CRD资源自动发现Kubernetes中需要监控的服务并定期拉取它们的/metrics端点数据。Grafana负责数据可视化。它从Prometheus查询数据绘制成丰富的仪表盘。社区有大量现成的Kubernetes、Node Exporter、应用如Nginx, PostgreSQL仪表盘模板导入即可使用。日志聚合Loki PromtailLoki受Prometheus启发的日志聚合系统它不索引日志内容只索引标签如Pod名、命名空间因此非常轻量和高效。它使用与Prometheus相同的标签体系使得关联指标和日志变得异常简单。Promtail运行在每个节点上的代理负责收集节点和容器日志添加标签如Pod信息并推送到Loki。部署与配置关键点使用Helm Chart部署这套监控栈是最方便的方式。确保为Prometheus和Loki配置好持久化存储PVC否则重启数据就丢了。配置prometheus-node-exporterDaemonSet用于收集每个节点的硬件和操作系统指标CPU、内存、磁盘、网络。配置kube-state-metrics它将Kubernetes API对象如Deployment、Pod的状态转换为Prometheus指标让你能在Grafana中监控“我有多少个Pod在运行”、“Deployment的副本数是否达标”。在Grafana中配置数据源时Prometheus的地址通常是http://prometheus-operated.monitoring.svc.cluster.local:9090Loki的地址是http://loki-gateway.monitoring.svc.cluster.local具体取决于你的Release命名和命名空间。完成这些后你就能在一个统一的Grafana界面里看到集群资源使用率、服务请求量、错误日志真正做到对homelab的“了如指掌”。5. 高级主题与运维实践5.1 备份与灾难恢复策略再高可用的系统没有备份也是空中楼阁。对于homelab我们需要分层备份基础设施即代码IaC备份你的整个homelab定义都在Git仓库里这本身就是最重要的备份。确保仓库推送到远程GitHub、GitLab、Gitea并定期每天提交变更。Kubernetes资源备份使用Velero工具。它可以备份整个集群的资源和持久卷需要配合卷插件。你可以配置定时任务将备份上传到对象存储如MinIO 也可以部署在homelab内或云服务如Backblaze B2。备份命令示例velero backup create homelab-daily --include-namespaces default,media,monitoring恢复命令示例velero restore create --from-backup homelab-daily应用数据备份这是最关键的。对于数据库如PostgreSQL应使用其原生工具如pg_dump进行逻辑备份并配合cronjob定期执行将dump文件存放到NAS或对象存储。对于文件类应用如Nextcloud除了卷快照还应定期用rsync进行文件级同步到另一个位置。物理设备配置备份不要忘记你的路由器、交换机的配置。有些设备支持导出配置文件定期保存这些文件到Git仓库或NAS。灾难恢复演练至少每季度模拟一次“最坏情况”如主节点硬盘完全损坏。流程应该是1) 用Proxmox镜像重装系统2) 用Ansible剧本重新配置节点3) 引导新的K3s集群4) 使用FluxCD从Git仓库同步所有应用5) 从Velero恢复持久化数据。记录整个恢复过程和时间不断优化。5.2 安全加固要点家庭实验室虽然在内网但安全同样重要尤其是当你通过DDNS将服务暴露到公网时。网络层面防火墙在路由器或每个节点上启用防火墙。只开放必要的端口如K3s API的6443 HTTP/HTTPS的80/443 SSH的22。对于SSH强烈建议禁用密码登录仅使用密钥认证并更改默认端口。网络策略在Kubernetes中启用并配置NetworkPolicy网络策略。默认情况下Kubernetes集群内所有Pod是互通的。使用NetworkPolicy可以实现“零信任”网络例如只允许前端Pod访问后端API Pod的特定端口数据库Pod不接受任何来自非白名单Pod的流量。Cilium或Calico这类CNI插件提供了强大的网络策略能力。Kubernetes层面RBAC遵循最小权限原则。不要给ServiceAccount过宽的权限。为FluxCD、监控组件等创建特定角色的ServiceAccount。Pod安全策略/PSA使用Pod Security AdmissionPSA来限制Pod的权限。例如禁止容器以root身份运行禁止挂载主机敏感目录。Secret管理永远不要在Git仓库中明文存储密码、API密钥。使用SealedSecretsBitnami Labs或SOPSMozilla等工具加密Secret再将加密后的文件存入Git。FluxCD可以在同步时自动解密。应用层面定期更新使用RenovateBot或Dependabot等工具自动为你的Git仓库创建依赖项如容器镜像版本更新PR。及时合并保持应用和基础镜像的漏洞修复。漏洞扫描在CI/CD流水线如GitHub Actions或集群内集成Trivy等镜像漏洞扫描工具在部署前发现潜在风险。5.3 成本优化与能效管理7x24小时运行多个节点电费不容小觑。硬件能效选择低功耗的硬件是根本。Intel NUC、AMD Ryzen APU迷你主机都是好选择。避免使用老旧的高功耗台式机。动态资源调度Kubernetes本身可以根据节点资源使用情况调度Pod。你可以更进一步使用Kube-green或Descheduler这样的工具。例如在夜间设定一个“睡眠期”让非关键应用如开发环境、CI工具的副本数缩容到0白天再恢复。或者定期重新平衡Pod让节点负载更均匀。服务自动启停对于非必须持续运行的服务可以写一个简单的CronJob在特定时间如工作日上班时间通过kubectl scale命令来扩容Deployment下班后再缩容。存储休眠如果你的NAS支持可以设置硬盘在不活动一段时间后休眠。对于Longhorn如果数据副本分布在多个节点可以考虑在夜间将某些非关键卷的副本数从3降为2减少磁盘IO和网络同步开销。6. 常见问题与排查技巧实录即使按照蓝图部署过程中也难免遇到问题。以下是我在搭建和维护过程中遇到的典型问题及解决方法。6.1 节点无法加入K3s集群现象在Worker节点执行加入命令后长时间卡住或报错“Failed to connect to ...”。排查步骤检查网络连通性在Worker节点上pingMaster节点的IP再telnet Master-IP 6443检查API Server端口是否开放。检查防火墙这是最常见的原因。确保Master节点的6443端口和8472端口Flannel VXLAN默认端口对Worker节点开放。在Ubuntu上可以使用sudo ufw status检查。检查Token和URL确认Join Token正确且K3S_URL指向了正确的Master节点IP和端口。如果是高可用集群应指向负载均衡器的VIP。查看日志在Worker节点上运行sudo journalctl -u k3s-agent -f查看代理日志通常会有更详细的错误信息。6.2 Pod一直处于Pending状态现象kubectl get pods显示某个Pod卡在Pending。排查步骤查看Pod详情kubectl describe pod pod-name。在Events部分通常会直接告诉你原因例如Insufficient cpu/memory节点资源不足。需要检查节点资源分配或为Pod设置更合理的requests和limits。0/3 nodes are available: 3 node(s) didn‘t match Pod‘s node affinity/selector节点选择器或亲和性规则不匹配。persistentvolumeclaim xxx not foundPVC不存在或未被绑定。检查PVC状态kubectl get pvc。如果PVC是Pending可能是StorageClass配置错误或者后端存储如NFS服务器无法访问。检查节点调度kubectl get nodes查看节点是否都是Ready状态。如果有NotReady的节点Pod自然不会调度上去。6.3 通过Ingress无法访问服务现象配置了Ingress域名解析也正确但访问时超时或返回502错误。排查步骤像侦探一样层层推进检查Ingress控制器kubectl get pods -n ingress-nginx确认ingress-nginx的Pod在运行。检查Ingress资源kubectl get ingress确认你的Ingress资源已存在。kubectl describe ingress name查看Events和Rules是否正确配置。检查ServiceIngress背后指向一个Service。kubectl get svc service-name确认Service存在并且有正确的端口映射。kubectl describe svc service-name查看Endpoints列表是否为空。如果Endpoints为空说明没有Pod匹配这个Service的selector。检查Pod确认Service selector匹配的Pod是Running且Ready状态READY列为1/1或2/2。kubectl logs pod-name查看应用日志确认应用本身在监听正确的端口且没有报错。检查网络策略如果集群启用了NetworkPolicy确认是否有策略阻断了Ingress控制器Pod到后端应用Pod的流量。从集群内部测试在集群内临时运行一个busyboxPod用curl直接从Pod内部访问Service的ClusterIP可以绕过Ingress快速定位问题是Ingress层还是Service/Pod层。kubectl run -it --rm debug --imagebusybox --restartNever -- sh # 进入容器后 curl http://service-cluster-ip:port6.4 Longhorn卷挂载失败现象Pod因为waiting for volume to attach/mount而卡住。排查步骤查看卷状态在Longhorn UI中查看该卷的状态。如果是Detached尝试手动附加Attach到Pod所在节点。检查节点条件Longhorn要求节点满足一定条件如已安装open-iscsi、内核模块加载。在Longhorn UI的Node页面检查问题节点是否所有条件都显示为True。查看实例管理器日志在Longhorn UI中进入该卷的详情页查看Engine和Replica的日志。常见的错误包括磁盘空间不足、网络通信故障导致副本同步失败。重启相关Pod有时重启Longhorn的实例管理器Podlonghorn-managerDaemonSet可以解决临时性问题。搭建和维护这样一个复杂的homelab系统本身就是一场持续的学习和探险。它迫使你去理解从硬件、网络、虚拟化到容器编排、GitOps、可观测性的完整栈。每一次故障排查都是对系统理解的一次深化。我最深的体会是文档和自动化是你的最佳盟友。将每一个步骤、每一个配置都代码化、文档化不仅是为了可重复更是为了在深夜被报警叫醒时能快速找到恢复的路径。这个homelab已经不再是一个玩具它是我个人数字世界坚实、可靠且完全自主的基石。