k3s 实战:用轻量级 Kubernetes 搭建边缘与开发集群

一、为什么需要 k3s:它和原生 Kubernetes 差在哪

标准 Kubernetes 发行版依赖 etcd、kube-apiserver、kube-scheduler、kube-controller-manager 等多个静态 Pod,再加上 kubelet、kube-proxy 与容器运行时,全套跑下来至少需要 2 核 2G,还要单独维护 etcd 的高可用与备份。对于边缘节点、IoT 网关、开发机上的本地集群,这种重量级架构既浪费资源又增加运维负担。k3s 由 Rancher(SUSE)开源,是 CNCF 毕业项目,它把控制面组件全部编译进单个二进制文件,体积控制在 100MB 以内,默认用 SQLite 存储集群状态,砍掉了云厂商 in-tree 驱动、遗留的 alpha 组件和大量非核心插件。所谓轻量级 Kubernetes,指的就是这种“一个二进制跑完整 K8s”的形态。

但轻量不等于阉割。k3s 完整兼容 Kubernetes API,你熟悉的 kubectl、Helm、Ingress、CRD、Operator 全部可用;它只是把组件打包得更紧凑,并把 Traefik Ingress、Service LB、本地存储等做成可插拔的“auto deploy”清单。这意味着同一套 YAML 既能推到生产 EKS,也能跑在树莓派上,学习成本和迁移成本几乎为零。

从资源账单看差距最直观:一个最小化的原生 K8s 控制面(含 etcd)空闲时就要吃掉 500MB~1GB 内存,而 k3s server 进程常驻仅约 50~100MB,agent 节点更是轻到可以在 512MB 内存的设备上稳定运行。对于按量计费的云主机、几十上百个边缘网点、以及只想在笔记本上起一套“像生产一样”的本地环境的人来说,这笔账很容易算清楚——省下的内存和 CPU,都能实打实地换成业务容器的容量。

维度原生 Kubernetesk3s(默认)k3s(嵌入式 etcd HA)
控制面形态多个静态 Pod单个二进制3 节点二进制 + 内置 etcd
集群存储etcdSQLite(可换 etcd/外部库)嵌入式 etcd
最低资源2C2G 起1C1G 可跑3×1C1G
部署复杂度高(kubeadm 多步)一行脚本一行脚本 + token
适用场景云上生产集群边缘/IoT/本地实验中小型生产/边缘

二、30 秒跑起单机节点

最快的体验方式是一台 1 核 1G 的机器(甚至树莓派)。k3s 官方安装脚本会自动检测架构、下载二进制、注册为 systemd 服务并启动。安装完成后,kubectl 被封装为 k3s kubectl,也可以软链出来单独使用。节点默认同时承担控制面与工作负载,适合本地实验。

# 1) 安装并启动单节点 server(同时是 master+worker)
curl -sfL https://get.k3s.io | sh -

# 2) 查看节点
sudo k3s kubectl get node

# 3) 取出 kubeconfig 供本地 kubectl 使用
sudo cat /etc/rancher/k3s/k3s.yaml

# 想独立使用 kubectl:
sudo ln -s $(which k3s) /usr/local/bin/kubectl 2>/dev/null || true

若只想要 agent 节点,用 K3S_URL 和 K3S_TOKEN 指向已有 server 即可,token 位于 server 的 /var/lib/rancher/k3s/server/node-token。把节点加进集群后,用 kubectl get node 应该能看到 ROLES 里出现 worker;如果需要把它也提升为可调度控制面,则在安装时去掉 –disable 并加入 etcd 节点列表。整套扩缩容不需要 kubeadm 那种多步“kubeadm init / join / token create”的心智负担,单行脚本即达目的。

调试时常用的几个命令:k3s check-config 校验节点环境,k3s etcd-snapshot 手动触发一次 etcd 快照(嵌入式 etcd 模式),systemctl status k3s 看服务状态,journalctl -u k3s 拉日志。不想要了也能干净卸载——/usr/local/bin/k3s-uninstall.sh(server)与 k3s-agent-uninstall.sh(agent)会把服务、二进制与数据目录一并清掉,不会在系统里留尾巴。

三、生产可用:高可用架构怎么选

单机 master 存在单点风险。k3s 提供两条 HA 路线:嵌入式 etcd(3 节点 server,自带 leader 选举,无需外部存储)和外部 datastore(server 无状态,状态放外部 MySQL/PostgreSQL/etcd)。嵌入式 etcd 最接近原生 K8s 体验、运维心智统一;外部 datastore 则把“有状态”彻底交给托管数据库,server 节点可随意扩缩、故障重启无数据顾虑。

# 节点1(初始化嵌入式 etcd 集群)
curl -sfL https://get.k3s.io | sh -s - server \
  --cluster-init \
  --tls-san <VIP或域名> \
  --disable traefik   # 如不用内置 Ingress

# 节点2、3(加入已有集群)
curl -sfL https://get.k3s.io | sh -s - server \
  --server https://<节点1IP>:6443 \
  --token <NODE_TOKEN> \
  --tls-san <VIP或域名>

下面是用外部 MySQL 作为 datastore 的方式,适合已有高可用数据库、希望 server 完全无状态的团队:

# 外部 datastore:server 节点无状态
curl -sfL https://get.k3s.io | sh -s - server \
  --datastore-endpoint="mysql://k3s:pass@tcp(db.host:3306)/k3s" \
  --tls-san <VIP>
对比项嵌入式 etcd外部 datastore
运维心智统一 K8s 体系依赖外部 DB 团队
一致性强一致(Raft)取决于外部库
成本3 节点全角色可多 server 无固定存储
故障域etcd 与 K8s 同域存储与计算分离
备份方式etcd snapshot数据库备份

选型时要先想清楚“故障域”落在哪。嵌入式 etcd 的三个节点必须奇数、跨故障域部署(不同可用区或不同物理机),否则一旦多数派不可达,集群会整体拒绝写入。外部 datastore 把状态交给你已经信得过的数据库团队,k3s server 本身变成无状态、可随意重启的“计算组件”,扩容控制面节点时无需担心数据迁移——代价是你得自己保证那个外部库的可用性与备份策略。两种方案没有绝对优劣,只有是否契合团队已有的运维能力。

四、接入外部流量:Ingress 与反向代理

k3s 默认内置 Traefik 作为 Ingress Controller,安装后自动监听 80/443 并可配合 cert-manager 签发证书。如果你的架构里已经有一台 Nginx 在做反向代理(比如把站点 80 端口转发到内部服务),可以关掉内置 Traefik,让 Nginx 直接反代到 k3s 的 NodePort 或 Ingress Service,复用既有的 SSL 卸载与限流策略。延伸阅读:Nginx 反向代理实战、Caddy 实战。

# 安装时关闭内置 Traefik
curl -sfL https://get.k3s.io | sh -s - server --disable traefik

# Nginx 反代到 k3s Ingress Service(NodePort 30880)
location / {
  proxy_pass http://<k3s-node>:30880;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
}

如果你选择保留内置 Traefik,k3s 会在安装时自动部署它并监听 80/443;配合 cert-manager(或用 Traefik 自带的 ACME 的 DNS-01 / HTTP-01 挑战)即可自动为 Ingress 域名签发 Let’s Encrypt 证书,几乎零配置就能拿到 HTTPS。此外 k3s 还内置了 klipper-lb 这种轻量 ServiceLB,能在没有云厂商 LoadBalancer 的环境里,把 type=LoadBalancer 的 Service 通过节点端口暴露出来,省去额外装 MetalLB 的麻烦——对边缘和本地集群非常友好。

五、持久化存储:本地路径最快上手

边缘集群往往没有云盘,k3s 自带 Local Path Provisioner,能把每个节点的本地目录动态供给为 PVC,开箱即用,非常适合单机开发和小规模边缘。若需要跨节点共享或块存储,可再挂 Rook-Ceph、OpenEBS 等 CSI 驱动。下面申请一个 5G 的本地存储卷:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-pvc
spec:
  accessModes: [ReadWriteOnce]
  storageClassName: local-path
  resources:
    requests:
      storage: 5Gi

Local Path Provisioner 够用,但它把数据落在节点本地磁盘,Pod 一旦被调度到别的节点就找不到原来的卷——所以只适合“有状态但单机、可重建”的负载(如本地缓存、临时构建产物)。若你需要跨节点迁移 Pod 仍保留数据,或要块存储级别的可靠性,可以再挂 Redis 之外的 CSI 方案,比如 Longhorn:它把每个节点的空闲磁盘聚合成分布式块存储,支持卷快照、跨节点副本与备份到对象存储,是边缘集群里最接近“云盘体验”的开源选择,且对资源要求并不高。

六、接进 CI:用 GitHub Actions 部署到 k3s

把 k3s 当 staging 集群时,最常见的方式是让 GitHub Actions 在合并后通过 kubectl 应用清单。把 kubeconfig 或仅含 deploy 权限的 ServiceAccount token 存为仓库 secret,CI 里 kubectl apply 即可。关于流水线编排可参考 GitHub Actions 实战,镜像构建则通常用 Docker。

name: deploy
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: deploy to k3s
        env:
          KUBECONFIG: ${{ secrets.K3S_KUBECONFIG }}
        run: |
          kubectl apply -f k8s/
          kubectl rollout status deploy/app

上面的写法是“push 式”CI:合并代码后由 Actions 主动 apply。如果你更想要“pull 式”的 GitOps,可以把清单推到 Git 仓库,再由 Argo CD 或 Flux 持续比对集群实际状态与 Git 声明状态、自动纠偏——这对 k3s 边缘集群尤其合适,因为边缘节点网络不稳,GitOps 的“始终向声明态收敛”能兜住偶发的手工漂移。无论哪种,核心都是把 kubeconfig 或最小权限 ServiceAccount 的 token 妥善放进 secret,并且遵循“只给 deploy 权限、不给 cluster-admin”的least-privilege 原则。

七、可观测性:把节点指标接进 Prometheus

k3s 自带 metrics-server,kubectl top 立即可用;若要告警与长期存储,可部署 kube-prometheus-stack。集群节点的 CPU、内存、网络指标能直接喂给你的 Prometheus,与既有监控体系打通。详见 Prometheus 监控实战、eBPF 内核观测、Cilium 网络安全。

# 轻量:仅装 metrics-server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/
  releases/latest/download/components.yaml

# 完整监控栈:kube-prometheus-stack
helm repo add prometheus-community \
  https://prometheus-community.github.io/helm-charts
helm install mon prometheus-community/kube-prometheus-stack \
  -n mon --create-namespace

装好 kube-prometheus-stack 后,Grafana 里已自带 Kubernetes 集群、节点、Pod 的常用面板,Alertmanager 也预置了一批针对节点 NotReady、CPU/ 内存压力、PVC 空间耗尽的告警规则,基本开箱即用。把 Alertmanager 的 webhook 接到你的钉钉或飞书机器人,就能在边缘节点掉线、磁盘将满时第一时间收到通知。需要更深度的内核指标(如网络重传、系统调用延迟),再叠加 eBPF 内核观测 采集即可,二者互不冲突。

八、生产落地检查清单

检查项建议做法
TLS用 cert-manager 或外层 Nginx 统一卸载,禁止明文 80 暴露 API
etcd/DB 备份嵌入式 etcd 定期 snapshot;外部库走数据库备份
资源限制所有工作负载设 requests/limits,避免单 Pod 拖垮节点
网络策略用 Cilium 或 NetworkPolicy 缩小 Pod 间可达范围
镜像来源仅允许私有仓库/受信基线,启用准入校验
监控告警部署 kube-prometheus-stack,配置节点与组件健康告警
升级策略先升级一个 server 观察,再滚动其余,保留回滚快照
Token 管理NODE_TOKEN / kubeconfig 走 secret 管理,定期轮换

k3s 用“一个二进制”把 Kubernetes 的重量级运维大幅压缩,却不牺牲 API 兼容性与生态。无论你是要给边缘设备铺一套轻量编排,还是在笔记本上跑贴近生产的本地集群,它都是当前最省心的选择。先把单机跑顺,再按流量与可用性需求逐步上 HA,你会发现 K8s 原来也可以很轻。

上一篇 CrewAI 实战:用角色扮演多智能体协作完成复杂任务
下一篇 Neo4j 实战:用图数据库建模关系与 Cypher 查询
最新评论
Docker 网络模式详解:bridge/host 生产选型 - FSData
Docker 网络模式详解:bridge/host 生产选型 - FSData
8月20日
[…] 注意最后那条:把端口绑定到 127.0.0.1,再由宿主机上的 Nginx 反代进来,比直接 -p 80:80 暴露安全得多,也方便统一做
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
8月20日
[…] Pinia 的工程化用法,可以参考我们之前的实战文章 《Vue3 组合式 API + Pinia:状态管理从入门到实战》,那里覆盖了 Sto
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
8月19日
[…] 状态,点一下就能起停容器,配合我们讲过的 Docker Compose 编排 […]
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
8月19日
[…] 缓存三大坑的本质都是”缓存失效导致请求穿透到数据库”。记住口诀:穿透用布隆、击穿用锁、雪崩用错峰。配合合理的过期策略
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
8月19日
[…] Docker 镜像部署。结合我们之前写的 Docker Compose 一键编排实战,可以在 CI […]