1. 项目概述:当Web应用遇上轻量级K3s集群
去年接手某智慧园区项目时,我面临一个典型困境:需要部署20+微服务支撑园区管理系统,但服务器资源只有5台2核4G的NUC迷你主机。传统K8s方案光是控制平面就要吃掉1/3资源,直到发现Rancher开源的K3s——这个专为边缘计算设计的轻量级Kubernetes发行版,最终用单台NUC就承载了整个控制平面,剩余节点全部用于运行业务负载。
K3s本质上是个经过极致优化的Kubernetes发行版,通过以下设计实现轻量化:
- 将etcd替换为内置的SQLite(也支持外部etcd集群)
- 容器运行时默认使用containerd而非Docker
- 控制平面组件合并为单个二进制进程
- 默认使用轻量级Flannel作为CNI插件
这种架构使得K8s的学习成本和资源消耗大幅降低,特别适合:
- 中小型Web服务集群
- 边缘计算场景(如物联网网关)
- 混合云环境下的节点管理
- 开发测试环境快速搭建
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 集群规划与节点准备
2.1 硬件资源配置策略
在物理机部署场景下,建议采用以下配置方案:
| 节点类型 | CPU核心 | 内存 | 磁盘 | 数量 | 网络要求 |
|---|---|---|---|---|---|
| Server节点 | 2核+ | 4GB+ | SSD 50GB | 奇数台 | 1Gbps稳定内网 |
| Agent节点 | 1核+ | 2GB+ | HDD 30GB | 按需 | 100Mbps以上 |
关键经验:生产环境务必保证Server节点分布在不同的物理机上。我曾因将3个Server节点部署在同一台物理机导致电源故障时集群脑裂。
2.2 操作系统优化要点
在所有节点执行以下预处理(以CentOS 7为例):
bash复制# 关闭Swap避免性能问题
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab
# 加载内核模块
cat <<EOF | sudo tee /etc/modules-load.d/k3s.conf
br_netfilter
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
EOF
# 设置内核参数
cat <<EOF | sudo tee /etc/sysctl.d/k3s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
3. 集群部署实战流程
3.1 控制平面安装(Server节点)
使用国内镜像源加速安装:
bash复制curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | \
INSTALL_K3S_MIRROR=cn \
INSTALL_K3S_EXEC="--cluster-init --tls-san your_domain.com" \
sh -
关键参数说明:
--cluster-init:启用内置数据存储(默认SQLite)--tls-san:为API Server添加额外SAN认证--docker:如需使用Docker而非containerd
获取join token(保存到安全位置):
bash复制sudo cat /var/lib/rancher/k3s/server/node-token
3.2 工作节点接入(Agent节点)
bash复制curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | \
K3S_URL=https://<server_ip>:6443 \
K3S_TOKEN=<join_token> \
sh -
3.3 网络方案选型对比
| 方案 | 性能 | 复杂度 | 适用场景 | 配置示例 |
|---|---|---|---|---|
| Flannel | ★★★ | ★★ | 中小规模集群 | --flannel-backend=host-gw |
| Calico | ★★★★ | ★★★ | 需要网络策略 | --flannel-backend=none + 单独部署 |
| Cilium | ★★★★★ | ★★★★ | 高性能网络观测 | 需禁用K3s默认CNI |
踩坑记录:某次使用Calico时因MTU不匹配导致网络性能下降50%,通过
ip link show对比节点MTU值后,添加--mtu=1440参数解决。
4. Web应用部署实践
4.1 典型部署架构示例
yaml复制apiVersion: apps/v1
kind: Deployment
metadata:
name: web-frontend
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.25-alpine
ports:
- containerPort: 80
resources:
limits:
cpu: "500m"
memory: "512Mi"
---
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
4.2 流量入口方案对比
| 方案 | 所需资源 | 功能特性 | 适用场景 |
|---|---|---|---|
| K3s内置ServiceLB | 低 | 基础四层负载 | 开发测试环境 |
| Traefik (默认安装) | 中 | 七层路由、Let's Encrypt证书 | 中小型生产环境 |
| Nginx Ingress | 中 | 成熟稳定、功能丰富 | 已有Nginx运维经验 |
| MetalLB | 高 | 裸金属环境LoadBalancer | 本地数据中心 |
启用Traefik仪表板(需提前创建ingressroute CRD):
bash复制kubectl apply -f - <<EOF
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard
namespace: kube-system
spec:
entryPoints:
- web
routes:
- match: Host(`traefik.local`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))
kind: Rule
services:
- name: api@internal
kind: TraefikService
EOF
5. 运维监控体系搭建
5.1 基础监控方案
启用K3s内置指标收集:
bash复制curl -sfL https://get.k3s.io | \
INSTALL_K3S_EXEC="--kubelet-arg=address=0.0.0.0 --kubelet-arg=anonymous-auth=true" \
sh -
部署Prometheus-Stack:
bash复制helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus prometheus-community/kube-prometheus-stack \
--set grafana.adminPassword=yourpassword \
--set prometheus.prometheusSpec.serviceMonitorSelectorNilUsesHelmValues=false
5.2 日志收集方案对比
| 组件组合 | 存储需求 | 查询性能 | 部署复杂度 |
|---|---|---|---|
| Loki + Promtail | 低 | 中 | ★★ |
| EFK (Elasticsearch + Fluentd + Kibana) | 高 | 高 | ★★★★ |
| Vector + ClickHouse | 中 | 极高 | ★★★ |
快速部署Loki栈:
bash复制helm install loki grafana/loki-stack \
--set promtail.enabled=true \
--set grafana.enabled=true
6. 常见故障排查指南
6.1 节点NotReady状态处理流程
-
检查基础网络连通性:
bash复制
ping <control_plane_ip> nc -zv <control_plane_ip> 6443 -
查看kubelet日志:
bash复制
journalctl -u k3s-agent -xe --no-pager -
常见证书问题修复:
bash复制rm -f /etc/rancher/k3s/k3s.yaml systemctl restart k3s-agent
6.2 Pod启动失败排查步骤
bash复制# 查看Pod事件
kubectl describe pod <pod-name>
# 查看容器日志
kubectl logs <pod-name> -c <container-name>
# 进入故障容器诊断
kubectl exec -it <pod-name> -- sh
7. 性能调优实战技巧
7.1 关键参数调整
在/etc/rancher/k3s/config.yaml中添加:
yaml复制kubelet-arg:
- "max-pods=100"
- "image-gc-high-threshold=85"
- "image-gc-low-threshold=80"
kube-controller-manager-arg:
- "node-monitor-grace-period=20s"
- "pod-eviction-timeout=30s"
7.2 内核参数优化
bash复制# 增加连接跟踪表大小
echo 262144 > /sys/module/nf_conntrack/parameters/hashsize
# 调整TCP缓冲区
cat <<EOF >> /etc/sysctl.conf
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
EOF
8. 安全加固方案
8.1 基础安全措施
-
启用PSP(Pod安全策略):
bash复制kubectl apply -f - <<EOF apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: restricted spec: privileged: false allowPrivilegeEscalation: false requiredDropCapabilities: - ALL volumes: - 'configMap' - 'emptyDir' - 'projected' - 'secret' - 'downwardAPI' hostNetwork: false hostIPC: false hostPID: false runAsUser: rule: 'MustRunAsNonRoot' seLinux: rule: 'RunAsAny' supplementalGroups: rule: 'MustRunAs' ranges: - min: 1 max: 65535 fsGroup: rule: 'MustRunAs' ranges: - min: 1 max: 65535 EOF -
定期轮换证书:
bash复制
k3s certificate rotate
8.2 网络策略示例
yaml复制apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-allow-only-ingress
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
role: ingress-controller
ports:
- protocol: TCP
port: 80
9. 升级与备份策略
9.1 滚动升级方案
bash复制# 单个Server节点升级
sudo k3s-upgrade.sh --channel v1.28
# 集群整体升级流程
1. 升级首个Server节点
2. 逐个升级其他Server节点
3. 批量升级Agent节点(可设置最大不可用比例)
9.2 备份恢复方案
使用etcdsnap工具备份:
bash复制sudo k3s etcd-snapshot save \
--name pre-upgrade-backup \
--dir /opt/k3s-backups
灾难恢复步骤:
bash复制sudo k3s server \
--cluster-init \
--cluster-reset \
--etcd-snapshot-skip-compress \
--etcd-snapshot-dir /opt/k3s-backups
