一、为什么需要 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,都能实打实地换成业务容器的容量。
| 维度 | 原生 Kubernetes | k3s(默认) | k3s(嵌入式 etcd HA) |
|---|---|---|---|
| 控制面形态 | 多个静态 Pod | 单个二进制 | 3 节点二进制 + 内置 etcd |
| 集群存储 | etcd | SQLite(可换 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: 5GiLocal 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 原来也可以很轻。




