K3s集群搭建与配置实战:轻量级Kubernetes从部署到高可用

发布时间:2026/10/21 13:47:47
K3s集群搭建与配置实战:轻量级Kubernetes从部署到高可用 这两年凡是遇到资源紧张的部署场景我几乎第一反应就是K3s。K3s集群搭建及配置这件事说简单真的可以五分钟出一条命令跑起来说复杂也能让你折腾一整天还不明白节点为什么一直NotReady。我在不同机器上反复搭过很多次从单机测试到多节点生产过程中踩过的坑、优化过的参数、实际用下来的感受整理成这篇分享。内容主要覆盖为什么选K3s而不是标准Kubernetes、节点规划和环境准备、单Server安装、Agent节点接入、高可用配置、部署应用时的组合拳以及运行三个月后总结的排障经验。不管你是刚接触容器编排的新手还是想在边缘设备、小内存服务器上把集群跑起来的老手这篇都能帮你少走弯路。1. 为什么轻量环境反而更需要K3s搭过一次就回不去的理由1.1 K3s到底解决了什么问题标准Kubernetes集群部署起来有多痛苦搭过的人都懂。kubeadm拉一堆镜像、初始化控制面、配置网络插件、处理证书流程长、内存占用高在一台2G内存或4G内存的VPS上跑起来光是系统组件就能把资源吃去一大半。而K3s把几乎所有控制面组件打包成单个二进制文件内置了容器运行时、kubectl、网络插件、负载均衡器安装包体积只有几十MB装完以后单Server节点空闲内存占用通常在几百MB以内。它并不是Kubernetes的简化缩水版而是针对资源受限场景做了工程化裁剪API兼容性基本保持完整日常用到的Deployment、Service、Ingress、ConfigMap这些标准对象都能正常操作。我最初接触K3s是因为一台用来跑定时任务的4G内存小主机原来的方案是直接跑几个Docker容器后来发现定时任务变多、配置管理越来越乱想着要不要上Kubernetes可是标准Kubernetes光控制面就要占2G左右内存小主机根本扛不住。换成K3s之后同样的机器还能再跑两三个生产级应用这就是它的核心价值。1.2 它和标准Kubernetes的差别在哪里很多人第一次听到K3s的时候会问它是不是把Kubernetes的功能砍掉了很多实际上主要差别集中在几个工程层面。存储层默认使用本地SQLite替代etcd单Server节点下不需要额外维护数据库调度器、控制器、API Server这些组件被集成进同一个进程而不是一堆独立容器运行时默认使用containerd配置好之后就能无缝操作。网络方面默认自带Flannel服务暴露方面自带ServiceLBIngress方面默认集成Traefik等于开箱即用。对比一下常见轻量Kubernetes方案会更直观方案安装复杂度单节点内存占用控制面重量典型场景标准Kubernetes高需自行处理网络与证书2G以上重组件多为独立容器大规模生产集群K3s低一条命令完成300M-800M轻单二进制进程边缘计算、开发测试、小主机其他轻量发行版中部分需要额外配置网络视方案而定中开发环境、单机演示如果你的核心诉求是把一个可用的Kubernetes环境快速跑起来并且不在乎一点点组件整合带来的架构差异那K3s是非常合适的选项。1.3 什么时候不建议用K3s工具选型最重要的是知道边界。K3s默认使用SQLite作为存储后端这对单Server节点的场景完全够用但如果你要搭一个真正的高可用控制面就需要切换外部数据库或嵌入式etcd模式配置复杂度会上升。另一个容易踩的坑是很多第三方Kubernetes工具会直接访问/etc/kubernetes目录或者特定的证书路径K3s把相关路径都放在了/etc/rancher/k3s下面这类工具需要额外适配。如果你需要深度定制容器运行时、特殊网络插件或者对控制面组件版本有极其严格的要求标准Kubernetes或者按需自行组装会更合适。我一般判断标准很简单要不要在高可用控制面上花大力气有没有多团队多租户的隔离要求。都没有优先K3s都有再考虑标准Kubernetes。2. 开工前的节点规划与系统准备哪些检查能帮你少踩一半坑2.1 节点角色怎么划分K3s节点主要分两种Server节点和Agent节点。Server节点运行完整的Kubernetes控制面组件同时默认也可以调度普通工作负载Agent节点更像传统Kubernetes里的Worker节点只运行kubelet和容器运行时。这样的设计比标准Kubernetes更灵活因为单台Server节点也能既管又干对于资源不多的小集群很友好。我在规划节点时一般遵循一个原则控制面尽量和业务负载弱耦合。如果手里只有一台机器不用纠结它就同时承担Server和Worker职责如果有三台机器我会让两台Server负责控制面和高可用剩下的机器作为Agent跑业务负载。生产环境千万别把业务容器直接放在重要的控制面节点上除非资源实在紧张至少也要给Server节点打上污点防止业务Pod被调度上去。2.2 系统层面的检查清单这部分看起来基础但很多搭建失败的问题都出在系统准备不完整。以下是我每次装机前固定检查的几个项目关闭或合理配置Swap。Kubernetes对Swap的处理逻辑比较保守虽然新版默认允许一定程度的Swap使用但为了避免内存驱逐和性能抖动我在Server节点上直接把Swap关闭Agent节点也尽量关掉。确保主机名唯一。三个节点如果都叫localhost加入集群后节点名称会冲突尤其是Agent节点加入时经常出现一个节点踢掉另一个节点的情况。同步时间。证书验证严重依赖系统时间时间偏移超过五分钟kubectl访问可能直接报证书错误。网络连通性。多数情况集群内网是私网地址节点之间要能互相访问尤其是TCP 6443端口和UDP 8472端口。下面这个表是我经常参考的端口清单端口协议用途6443TCPKubernetes API Server8472UDPFlannel VXLAN网络10250TCPkubelet指标采集2379TCP外部etcd/数据库场景30000-32767TCPNodePort服务端口如果你的服务器开了防火墙建议先把这些端口放行而不是等到加入节点失败才开始排查。我在第一次搭建时就因为防火墙没放行UDP 8472导致Agent节点虽然成功加入但Pod之间网络始终不通排查了很久才发现是VXLAN流量被丢弃。2.3 版本选择和下载注意事项安装K3s有一个很容易犯的错误直接装latest然后在几个月后升级时出现兼容性问题。我现在习惯装固定版本比如安装时指定INSTALL_K3S_VERSION参数系统管理和升级节奏都可控。还有一个经常被忽略的点安装脚本是否需要指定镜像加速参数取决于你的网络环境。K3s安装脚本内置了一个常用的镜像加速选项设好之后镜像拉取速度和安装脚本下载都稳定很多。下载安装包时如果反复超时不要一味重试先看DNS解析是否正常再看有没有必要走代理或镜像通道。把安装脚本下载到本地再执行比每次现场从远程拉更可控。3. 单Server集群安装从下载到kubectl可用的完整过程3.1 一条命令安装到底做了什么K3s的安装非常简单一条命令就能完成Server节点的安装curl -sfL https://get.k3s.io | sh -跑完以后系统会自动下载二进制、生成配置目录、创建systemd服务并且自动启动集群。刚执行完命令头一分钟别急着查节点状态K3s会先拉镜像、初始化网络插件通常需要几十秒到几分钟不等。我看到很多新手在这一步就开始怀疑集群挂了其实多等一会儿就行。如果需要在国内网络环境下安装官方安装脚本支持指定镜像加速参数curl -sfL https://get.k3s.io | INSTALL_K3S_MIRRORcn sh -这个参数会把镜像拉取通道切到国内节点很多场景下安装速度和后续拉镜像速度都会明显变快。安装完成后第一件确认的事情是服务状态systemctl status k3s然后查看节点和Pod状态k3s kubectl get nodes k3s kubectl get pods -A这里有个细节默认安装完kubectl的配置文件在/etc/rancher/k3s/k3s.yaml用k3s kubectl命令时不需要额外配置。如果想使用独立的kubectl客户端可以把这份配置拷贝到本机的kube配置目录mkdir -p ~/.kube sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config sudo chown $(id -u):$(id -g) ~/.kube/config拷贝后注意文件中server地址指向的是127.0.0.1还是实际IP。默认指向127.0.0.1在服务器本机操作没问题如果要从其他机器管理集群需要把server字段改成Server节点的实际IP或域名并且在安装时配置tls-san参数否则证书校验会失败。3.2 我最常用的几个安装参数一条命令直接装虽然快但生产环境还是建议写配置。K3s支持/etc/rancher/k3s/config.yaml配置文件下面是我一套比较精简的Server节点配置write-kubeconfig-mode: 0644 tls-san: - k3s.example.internal disable: - traefik node-name: server-01 node-label: - rolecontrol其中disable掉traefik是我个人的习惯不是因为Traefik不好而是有小内存主机时默认的Traefik加上ServiceLB会额外占用资源和端口。如果你本来就打算用Ingress暴露服务那可以保留。其他常用参数还有--write-kubeconfig-mode设置kubeconfig文件权限方便多用户读取。--node-name指定节点名称避免主机名产生歧义。--node-label给节点打标签之后可以按标签调度。--private-registry如果使用内部镜像仓库需要配置私库认证信息否则拉取私有镜像时会失败。3.3 单节点跑通后的性能观察装完单节点之后可以先观察一下资源占用确认机器的剩余资源是否满足预期。我实测在空闲状态下2G内存的机器跑一个K3s Server节点整个K3s相关进程加起来大概占用500M左右内存CPU几乎可以忽略。这跟标准Kubernetes控制面全套动辄超过2G内存的情况相比确实轻量很多。看到这个数据你就可以放手规划剩余资源的业务负载了。4. 把Agent节点接进来从单点变成真正集群的关键动作4.1 拿到Token再谈集群单Server节点严格来说还不算“集群”只是有一个控制面加一个可调度节点。真正的多节点集群需要把Agent节点接入进来。接入的前提是拿到Server节点的Token这个Token保存在:cat /var/lib/rancher/k3s/server/node-tokenToken内容是一长串随机字符串本质上是Agent加入集群时的身份凭证。拿到Token之后在Agent节点执行:curl -sfL https://get.k3s.io | K3S_URLhttps://server-node-ip:6443 K3S_TOKENmy-node-token sh -安装完成后查看节点状态k3s kubectl get nodes正常情况下新Agent节点几十秒内会进入Ready状态。如果一直NotReady优先排查Agent节点的网络到Server节点的6443/TCP是否通以及主机名是否和已有节点冲突。4.2 Agent节点的配置管理和Server节点一样Agent节点也支持配置文件。一个典型的Agent配置server: https://server-node-ip:6443 token: my-node-token node-name: agent-01 node-label: - roleworker配置文件路径同样是/etc/rancher/k3s/config.yaml安装脚本执行时会自动读取。用配置文件的好处是升级重装时不会丢参数尤其是需要固定节点名、标签的场合。如果没有配置node-nameAgent节点会默认使用系统主机名一旦主机名在不同节点间重复集群里就会出现同名节点互相挤兑的问题。4.3 节点角色与调度策略的补充在标准Kubernetes里Worker节点天然不具备控制面组件但在K3s里Server节点默认也是可以调度业务Pod的。如果不想让业务负载跑上控制面节点可以给Server节点加污点。比如安装Server节点时加上--node-taint node-role.kubernetes.io/control-planetrue:NoSchedule这样普通Pod就不会调度到Server节点只有能够容忍该污点的Pod才能上去。对于Agent节点集群我还习惯给不同Agent打上不同标签比如GPU节点、大存储节点然后在Deployment的nodeSelector里指定目标标签实现精细调度。这是K3s多节点集群从“能跑”走向“好用”非常关键的一步。5. 高可用配置外部数据库、固定Token与多Server架构5.1 单Server节点的数据库瓶颈在哪里默认安装的K3s使用SQLite做数据存储数据文件放在/var/lib/rancher/k3s/server/db目录。SQLite对单Server节点是完全够用的但一旦Server节点宕机整个控制面就不可用了因为SQLite不支持多个Server节点并发访问。很多人想当然地启动第二个Server节点指望它自动接替控制面结果发现新节点一直处于启动失败状态原因就是SQLite文件被占用或数据版本不匹配。如果集群对控制面高可用有要求第一步就是把数据后端从SQLite换掉。K3s支持的外部数据库包括MySQL、PostgreSQL、MariaDB也可以切换到嵌入式etcd。我自己最常用的切换方式是外部PostgreSQL逻辑清晰、备份简单。5.2 外部数据库模式的配置过程假设已经有一个PostgreSQL实例先创建数据库和账号CREATE DATABASE k3sdb; CREATE USER k3suser WITH PASSWORD strongpassword; GRANT ALL PRIVILEGES ON DATABASE k3sdb TO k3suser;然后在Server节点配置文件中加入datastore-endpoint: postgres://k3suser:strongpasswordpostgres-host:5432/k3sdb token: my-fixed-token tls-san: - k3s.example.internal关键一点从SQLite切换到外部数据库不是改一下配置文件那么简单。对于已存在的集群直接用新的datastore-endpoint启动K3s并不会自动导入旧数据。我一般建议三个Server节点从一开始就统一用外部数据库搭建避免后期迁移数据带来的麻烦。如果必须迁移可以提前备份现有资源清单重建集群后再用kubectl apply重新创建。这里还有一个容易踩的坑非常不建议直接把原来用SQLite的server目录完整拷贝到新服务器去恢复因为证书和节点身份信息是绑定的拷贝不当会导致旧节点证书过期问题。5.3 固定Token为什么重要多Server架构下有一个细节经常被忽略token不是一成不变的。如果服务器重启后某Agent拿着旧Token来连接发现控制面换了一批Token就可能会出现一系列异常。解决方法是安装配置时通过token参数指定一个固定字符串curl -sfL https://get.k3s.io | sh -s - --token my-fixed-token所有Server和Agent节点都用同一个固定Token之后无论控制面怎么重启、Server增加或减少Agent都能正常找到并连接控制面。这个习惯我从一开始就坚持之后再也没遇到过节点批量掉线的问题。5.4 多个Server节点之间的负载均衡怎么接控制面有多个Server节点之后Agent不能直接写死单台Server的IP否则这台挂了Agent也没法注册。常见做法是在前面放一个四层负载均衡把6443端口的流量分发到所有Server节点。Agent的K3S_URL就指向这个负载均衡地址。负载均衡器可以是云厂商的LB也可以是自建的四层转发方案重点是保证6443端口可达且会话保持时间合理。我在三台Server节点的场景里会把其中一台节点同时作为负载均衡的入口通过系统服务和iptables规则转发到另外两台Server这个方案对节点数少的集群够用省去额外维护一台专用LB的成本。配置完成之后停掉其中一台Server实测kubectl命令依然正常响应这才是高可用控制面该有的样子。6. 部署第一个真实应用Ingress、存储与服务暴露的组合拳6.1 最小部署先验证调度链路集群搭好以后光看节点Ready还不够要真实部署一个应用验证整个调度链路。下面这个例子我几乎每次搭建完都会跑一遍apiVersion: apps/v1 kind: Deployment metadata: name: echo-server spec: replicas: 2 selector: matchLabels: app: echo-server template: metadata: labels: app: echo-server spec: containers: - name: echo-server image: registry.cn-hangzhou.aliyuncs.com/google_containers/echoserver:1.10 ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: echo-server spec: selector: app: echo-server ports: - port: 80 targetPort: 8080保存为echo-server.yaml后执行kubectl apply -f echo-server.yaml kubectl get pods -o wide kubectl get svc通过kubectl get pods -o wide能看到两个副本是否被调度到不同的节点这一步能验证节点间网络和调度是否正常。如果两个副本都堆在同一个节点先别急着调整调度策略看看是不是另一个节点有污点或者资源不足。6.2 服务暴露方式选哪种K3s默认的服务暴露方式有三种可选NodePort、ServiceLB和Ingress。NodePort最直接但生产环境不建议对外暴露高位端口ServiceLB是K3s内置的负载均衡器能在没有云LB的情况下给Service分配外部IPIngress则通过域名和路径路由适合HTTP服务对外发布。刚装好的K3s默认带有Traefik Ingress Controller如果你安装时没有disable它就可以直接创建Ingress资源通过域名访问服务。比如下面这个apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: echo-server spec: rules: - host: echo.example.internal http: paths: - path: / pathType: Prefix backend: service: name: echo-server port: number: 80记得把域名解析到集群任意节点的80端口Traefik默认监听宿主的80和443端口。如果你安装时禁用了Traefik又想用Ingress就需要自己装一个小型Ingress控制器。我个人在轻量集群上的选择是保留Traefik它的配置灵活度和资源占用都在可接受范围内禁掉它反而少了很多便利。6.3 存储怎么解决本地存储还是外置存储有状态应用绕不开存储。K3s默认自带了local-path Provisioner能自动在节点本地目录创建持久卷。默认存储类名称是local-path使用方法很简单PVC里直接指定存储类即可。本地存储适合日志、临时数据、测试环境但需要注意的是数据绑定了具体节点节点挂了数据可能就丢了。对于需要跨节点共享数据的场景建议接外置存储。最朴素的做法是节点上挂载NFS然后通过Kubernetes的NFS驱动创建PV也可以先装一个块存储方案再部署CSI插件。轻量集群上我一般优先NFS因为它够通用、维护简单唯一的缺点是性能和单点问题但绝大多数内部业务对这个要求并不高。6.4 资源限制在轻量集群上的重要性在标准Kubernetes集群上不写资源requests可能是懒惰但在K3s这种资源有限的环境里不写资源requests会直接导致节点过载。我见过最典型的情况是一台4G机器上的多个Pod都不写内存限制结果一个容器内存泄漏把整台机器打爆节点进入MemoryPressure所有Pod都被驱逐集群进入雪崩状态。所以我的习惯是所有Deployment都预算好requests和limits即使不确定具体数值也会给一个保守估计。比如下面这样resources: requests: memory: 64Mi cpu: 50m limits: memory: 128Mi cpu: 100m不要觉得给低一点显得小气在轻量集群上保护整机稳定比让单个应用跑满更重要。7. 运行三个月后总结的配置心得与排障笔记7.1 证书类问题怎么处理K3s证书机制是自签名的Root CA自动签发生成日常运行中碰到的绝大多数证书问题有两个来源一是系统时间漂移二是Server节点重启后证书陈旧。前者通过配置NTP同步即可解决后者典型现象是kubectl突然报出x509证书过期之类的错误。遇到这类问题先别急着重建集群尝试重启一下K3s服务systemctl restart k3sK3s服务启动时会自动重新生成或轮转部分过期证书配置很多证书问题在重启之后会自行恢复。这里要提醒一点不要去手动改证书有效期参数也不要随便换CA改不好会让Agent节点全部失联排错成本极高。7.2 节点NotReady的第一排查思路节点NotReady是最常见的异常。先看kubelet日志journalctl -u k3s -f再看系统资源是否耗尽。很多时候节点NotReady不是因为网络不通而是节点磁盘满了。K3s默认镜像数据和容器数据都存放在/var/lib/rancher/k3s/agent/containerd目录下长时间不清理镜像这个目录会越滚越大。我通常定期做一次镜像清理把不再使用的镜像删掉给节点留出充足空间。如果是多节点场景下某一个Agent节点一直NotReady重点检查该节点和Server节点之间的UDP 8472端口是否可以互通。这个端口是Flannel的VXLAN通道不通的话节点虽然加入集群但Pod之间无法通信节点状态也会异常。可以临时关闭防火墙或用策略放行然后重启Agent节点的K3s服务一般能恢复。7.3 升级和备份怎么做K3s升级最简单的方式是重新执行安装脚本脚本会检测到已安装版本并升级到目标版本也可以直接下载新版二进制替换旧的k3s文件然后重启systemd服务。无论哪种方式升级前先备份数据。备份的重点是/var/lib/rancher/k3s/server/db目录和/etc/rancher/k3s目录。如果使用SQLite直接打包db目录就能达到备份目的如果使用外部数据库则直接用数据库自己的备份机制。另一种方式是用kubectl导出资源清单把Deployment、Service、ConfigMap、Secret等都导出保存这种做法在灾难恢复时最直观。我在三个月运维中的经验是定期备份数据库目录一个月至少一次配置文件变更前先复制一份原文件升级前先看Release变更记录再决定是否执行。这套习惯让几次看似危急的问题都变成了小插曲。7.4 一个小技巧小机器上尽量做减法如果你也是把小主机当作K3s主力机器一定要学会做减法。默认安装的K3s会启用Traefik和ServiceLB如果暂时用不上安装时直接设参数禁掉能明显降低内存占用。K3s还默认安装了一些系统组件对于内部实验环境把用不到的Ingress控制器停掉资源占用又能再降一档。另一个减法是控制镜像数量。不要看到镜像就想拉K3s节点本身维护的数据少一分故障概率就少一分。运行一段时间后用crictl工具查看当前节点上到底有哪些容器和镜像心里有个底比等到磁盘满了再处理要舒服得多。我最后再分享一个体会K3s集群搭建及配置这件事最大的收益不是省了多少内存而是让你在资源有限的条件下依然能用完整Kubernetes的思维方式管理应用。这套集群我已经连续跑了大半年中间经历过节点重启、磁盘告警、证书异常每一次排障都让后面的运维更顺手。如果你也打算在轻量环境里上KubernetesK3s值得成为第一个尝试方案。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询