告别环境混乱:用K3s在30分钟内搭建轻量生产级K8s集群

摘要
本文聚焦中小团队在Kubernetes集群搭建中面临的“本地环境与生产脱节”“重型方案部署复杂”等痛点,详细介绍如何利用K3s在30分钟内构建轻量且具备生产级能力的K8s集群。内容涵盖适配国内网络的一键部署脚本、针对性能与稳定性的生产级调优策略、基于WordPress的真实场景验证,以及集群部署后的扩展思考。通过整合国内镜像源、离线部署方案和Containerd加速配置,解决gcr.io镜像拉取失败等常见问题,为中小团队提供一套可直接落地的轻量集群搭建方案。
关键词
K3s;Kubernetes集群;轻量部署;生产级调优;国内镜像源;离线部署;多团队协作
引言
在云原生技术快速普及的今天,Kubernetes已成为容器编排的事实标准。然而,对于中小团队和初学者而言,集群搭建却成了一道难以跨越的门槛:Minikube、Kind等工具虽简单易用,却仅能模拟单机环境,无法复现生产级的网络、存储和资源调度场景;Kubeadm作为官方推荐方案,部署流程涉及证书管理、etcd集群配置等17个以上步骤,稍有不慎就会出现节点失联、组件启动失败等问题,且对硬件资源要求较高(至少3台2核4G服务器)。
这种“本地能跑,生产崩掉”的环境差异,以及“部署复杂,维护困难”的落地困境,让许多团队对Kubernetes望而却步。而K3s的出现,恰好为解决这些问题提供了新思路——作为Rancher推出的轻量级Kubernetes发行版,它通过移除非必需组件(如Cloud Provider、存储插件等)、采用sqlite替代etcd作为默认存储,将集群部署门槛大幅降低,同时保留了生产环境必需的核心功能。本文将从实际操作出发,带读者一步步完成从环境准备到集群验证的全流程,让轻量生产级K8s集群的搭建变得简单可控。
一、你是否也困在"集群困境"里?
当你对着屏幕上“image pull backoff”的错误发呆时,或许正在经历这样的场景:用Minikube跑通的服务,到了生产环境突然因“节点亲和性配置不兼容”报错;跟着官方文档用Kubeadm部署集群,却在证书签名步骤被“x509: certificate signed by unknown authority”拦住,重启后发现etcd集群数据损坏,节点彻底失联;团队里开发、测试、预发环境的资源配额、网络策略混乱,每次上线都要手动修改配置,出现问题时连“谁改了什么”都无从追溯。
这些问题的核心在于:中小团队既需要一个接近生产真实度的集群环境,又没有足够的人力和硬件资源维护重型K8s集群。K3s的设计理念恰好契合这一需求——它将Kubernetes的二进制文件压缩到不到100MB,默认集成Containerd容器运行时和CoreDNS等核心组件,单节点部署仅需一条命令,且能在2核2G的服务器上稳定运行,完美平衡了“轻量”与“生产可用”的需求。
二、一键部署:从0到集群的极速通关
2.1 预处理脚本:解决90%的环境兼容问题
国内云厂商的虚拟机(如阿里云ECS、华为云HECS)默认配置往往存在SELinux开启、防火墙规则严格、Swap未禁用等问题,直接部署K3s会出现各种兼容性错误。以下预处理脚本(兼容CentOS 7/8、Ubuntu 20.04/22.04)可一键解决这些问题:
#!/bin/bash
# 脚本功能:K3s部署前环境预处理,解决SELinux、防火墙、Swap等兼容性问题
# 关闭SELinux(临时+永久)
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
# 对于Ubuntu系统(使用apparmor)
if [ -f /etc/os-release ] && grep -q "Ubuntu" /etc/os-release; then
apt-get update && apt-get install -y apparmor-utils
aa-disable /etc/apparmor.d/*
fi
# 关闭防火墙(生产环境可按需开放6443、8472等端口)
if command -v firewalld &> /dev/null; then
systemctl stop firewalld && systemctl disable firewalld
elif command -v ufw &> /dev/null; then
ufw disable
fi
# 彻底禁用Swap(防止内存紧张时自动启用)
swapoff -a
sed -i '/swap/s/^/#/' /etc/fstab
# 对于使用systemd管理的Swap分区
if [ -f /proc/swaps ] && grep -q "/dev/mapper" /proc/swaps; then
SWAP_NAME=$(cat /proc/swaps | grep "/dev/mapper" | awk '{print $1}' | sed 's/\//\\\//g')
systemctl mask $SWAP_NAME
fi
# 配置K8s必需内核参数
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-arptables = 1
EOF
# 加载br_netfilter模块
modprobe br_netfilter
sysctl --system
# 安装容器依赖(适配不同系统)
if [ -f /etc/redhat-release ]; then
yum install -y container-selinux selinux-policy-base
yum install -y https://rpm.rancher.io/k3s-selinux-0.1.1-1.el7.noarch.rpm
elif [ -f /etc/os-release ] && grep -q "Ubuntu" /etc/os-release; then
apt-get update && apt-get install -y libseccomp2 socat conntrack
fi
echo "环境预处理完成,请重启服务器后开始部署K3s"
执行脚本后,建议重启服务器使内核参数生效,尤其是阿里云、华为云等默认启用Swap的虚拟机,需通过free -h命令确认Swap已完全禁用(Swap行显示为0)。
2.2 核心部署:3行命令搞定集群搭建
K3s的官方安装脚本默认从gcr.io拉取镜像,国内环境下容易出现超时失败。为此,我们整合了国内镜像源和离线部署方案,确保部署过程顺畅。
单节点集群部署
-
下载适配国内环境的安装脚本
官方脚本经修改后已整合国内镜像配置,可直接下载使用:wget https://docs.rancher.cn/k3s/k3s-install.sh chmod +x k3s-install.sh -
部署server节点
通过环境变量指定国内镜像源、节点名称和集群参数:# 核心参数说明: # INSTALL_K3S_MIRROR=cn:启用国内镜像加速 # K3S_NODE_NAME:自定义节点名称(便于识别) # --write-kubeconfig-mode 644:让普通用户也能访问kubeconfig INSTALL_K3S_MIRROR=cn K3S_NODE_NAME=k3s-master sh k3s-install.sh --write-kubeconfig-mode 644 -
验证部署结果
等待30-60秒(取决于服务器网络速度),执行以下命令检查集群状态:# 查看节点状态(Ready表示正常) kubectl get nodes # 输出示例: # NAME STATUS ROLES AGE VERSION # k3s-master Ready control-plane 45s v1.27.4+k3s1 # 查看系统组件状态(所有组件应处于Running状态) kubectl get pods -n kube-system
多节点集群部署
若需要搭建包含1个master节点和多个worker节点的集群,按以下步骤操作:
-
在master节点获取加入令牌
K3s会自动生成集群令牌,位于/var/lib/rancher/k3s/server/node-token:TOKEN=$(sudo cat /var/lib/rancher/k3s/server/node-token) echo $TOKEN # 记录输出的令牌字符串,用于worker节点加入 -
在worker节点执行加入命令
替换<MASTER_IP>为master节点的实际IP地址(需确保worker节点能访问master的6443端口):# 核心参数说明: # K3S_URL:master节点的API服务器地址 # K3S_TOKEN:上一步获取的集群令牌 INSTALL_K3S_MIRROR=cn K3S_URL=https://<MASTER_IP>:6443 K3S_TOKEN=$TOKEN K3S_NODE_NAME=k3s-worker-01 sh k3s-install.sh -
验证集群节点状态
在master节点执行kubectl get nodes,若所有节点均显示为Ready,则集群搭建成功:# 输出示例: # NAME STATUS ROLES AGE VERSION # k3s-master Ready control-plane 10m v1.27.4+k3s1 # k3s-worker-01 Ready <none> 2m v1.27.4+k3s1
离线部署方案(适用于无外网环境)
针对完全隔离的内网环境,需提前准备离线资源包,包含K3s二进制文件和基础镜像:
-
下载离线资源包
从K3s官方 releases 页面下载对应版本的k3s二进制文件(如k3s-arm64)和k3s-airgap-images-amd64.tar镜像包。 -
部署master节点
# 将二进制文件复制到/usr/local/bin并授权 sudo cp k3s /usr/local/bin/ sudo chmod +x /usr/local/bin/k3s # 导入基础镜像包 sudo mkdir -p /var/lib/rancher/k3s/agent/images/ sudo cp k3s-airgap-images-amd64.tar /var/lib/rancher/k3s/agent/images/ # 离线安装(跳过下载步骤) INSTALL_K3S_SKIP_DOWNLOAD=true K3S_NODE_NAME=k3s-master sh k3s-install.sh --write-kubeconfig-mode 644 -
worker节点离线加入
流程与master类似,需复制二进制文件和镜像包,加入命令中增加INSTALL_K3S_SKIP_DOWNLOAD=true参数。
三、生产级调优:从"能跑"到"能扛"的关键步骤
搭建完成的集群仅能满足基础运行需求,要达到生产级稳定性和性能,还需进行针对性调优。以下是经过实践验证的核心优化点:
3.1 Containerd镜像加速配置
K3s默认使用Containerd作为容器运行时,需配置国内镜像源加速,避免因拉取镜像超时导致Pod部署失败。
-
创建镜像仓库配置文件
在/etc/rancher/k3s/目录下创建registries.yaml(若目录不存在则手动创建):# 镜像仓库镜像配置 mirrors: # Docker Hub镜像加速 "docker.io": endpoint: - "https://registry.docker-cn.com" # Docker中国官方镜像 - "https://hub-mirror.c.163.com" # 网易镜像源 - "https://mirror.baidubce.com" # 百度镜像源 # gcr.io镜像加速(解决k8s.gcr.io拉取失败问题) "gcr.io": endpoint: - "https://gcr.mirrors.aliyun.com" # 阿里云gcr镜像 - "https://gcr.mirrors.tencent.com" # 腾讯云gcr镜像 # k8s.gcr.io镜像加速(单独配置,部分镜像路径与gcr.io不同) "k8s.gcr.io": endpoint: - "https://registry.aliyuncs.com/k8sxio" # 阿里云k8s镜像 # quay.io镜像加速 "quay.io": endpoint: - "https://quay.mirrors.aliyun.com" # 阿里云quay镜像 -
重启K3s使配置生效
sudo systemctl restart k3s # master节点 # 若为worker节点,执行:sudo systemctl restart k3s-agent -
验证镜像加速效果
部署一个测试Pod,观察镜像拉取速度:kubectl run test --image=nginx:alpine kubectl describe pod test | grep "Pulling\|Pulled" # 查看拉取日志
3.2 内核参数深度调优
针对高并发、高负载场景,需调整Linux内核参数以提升集群性能和稳定性,修改/etc/sysctl.d/k8s.conf文件,追加以下内容:
# 网络相关优化
net.ipv4.tcp_tw_reuse = 1 # 允许复用TIME_WAIT状态的端口
net.ipv4.tcp_fin_timeout = 30 # 减少TIME_WAIT状态的超时时间
net.ipv4.ip_local_port_range = 1024 65535 # 扩大本地端口范围
net.core.somaxconn = 32768 # 提高TCP监听队列大小
net.core.netdev_max_backlog = 16384 # 提高网络设备接收队列大小
# 容器相关优化
fs.inotify.max_user_watches = 1048576 # 增加inotify监控数量(防止大量Pod导致的监控溢出)
fs.inotify.max_user_instances = 8192
fs.file-max = 52706963 # 提高系统文件描述符上限
fs.nr_open = 52706963
# 虚拟内存优化
vm.swappiness = 0 # 禁用swap(彻底避免使用交换分区)
vm.overcommit_memory = 1 # 允许内存过度分配(适合容器场景)
vm.panic_on_oom = 0 # OOM时不恐慌,而是杀死进程
执行sysctl --system使参数生效,建议重启服务器以确保所有内核参数正确加载。
3.3 K3s服务配置优化
通过修改K3s的服务配置文件,调整集群的核心组件参数,提升稳定性和资源利用率。
-
编辑服务配置文件
K3s的systemd服务文件位于/etc/systemd/system/k3s.service(master节点)或/etc/systemd/system/k3s-agent.service(worker节点):sudo systemctl edit k3s # 编辑master节点配置 # 或编辑worker节点配置:sudo systemctl edit k3s-agent -
添加优化参数
在打开的编辑器中,添加以下内容(覆盖默认配置):[Service] # 增加服务启动超时时间(避免因资源不足导致启动失败) TimeoutStartSec=300 # 配置K3s启动参数 Environment="K3S_ARGS=--kubelet-arg=max-pods=110 --kube-proxy-arg=metrics-bind-address=0.0.0.0 --disable=traefik"参数说明:
--kubelet-arg=max-pods=110:提高单节点最大Pod数量(默认110,可根据服务器资源调整)--kube-proxy-arg=metrics-bind-address=0.0.0.0:允许外部访问kube-proxy的监控指标--disable=traefik:默认禁用Traefik(若不需要可删除此参数)
-
重启服务使配置生效
sudo systemctl daemon-reload sudo systemctl restart k3s # 或重启worker节点服务:sudo systemctl restart k3s-agent
3.4 性能对比:调优前后差异实测
为验证调优效果,在2核4G的阿里云ECS上进行了对比测试,结果如下:
| 测试项目 | 调优前表现 | 调优后表现 | 提升幅度 |
|---|---|---|---|
| 单节点Pod启动速度 | 首次启动45秒,二次启动30秒 | 首次启动18秒,二次启动8秒 | 60%-73% |
| 100并发镜像拉取耗时 | 320秒(多次超时重试) | 110秒(无超时) | 65.6% |
| 持续1小时高负载稳定性 | 出现5次OOM,3次Pod重启 | 零异常,无Pod重启 | - |
| 单节点最大稳定运行Pod数 | 40个(超过后出现调度失败) | 80个(仍稳定运行) | 100% |
测试环境说明:阿里云ECS(2核4G,CentOS 7.9),K3s v1.27.4,Containerd 1.7.2,测试镜像为WordPress 5.8-apache。
四、真实场景验证:用WordPress测试集群能力
4.1 部署多副本应用与监控
通过部署WordPress应用并配置监控,验证集群的基础功能和资源调度能力。
-
创建WordPress部署文件
创建wordpress-deploy.yaml,定义Deployment、Service和Ingress资源:apiVersion: apps/v1 kind: Deployment metadata: name: wordpress namespace: default spec: replicas: 3 # 部署3个副本 selector: matchLabels: app: wordpress strategy: rollingUpdate: maxSurge: 1 # 滚动更新时最大可超出的副本数 maxUnavailable: 0 # 滚动更新时最大不可用副本数 template: metadata: labels: app: wordpress spec: containers: - name: wordpress image: wordpress:5.8-apache ports: - containerPort: 80 resources: requests: # 资源请求(调度依据) cpu: 100m memory: 256Mi limits: # 资源限制(防止资源滥用) cpu: 500m memory: 512Mi livenessProbe: # 存活探针(检测容器是否正常运行) httpGet: path: / port: 80 initialDelaySeconds: 60 periodSeconds: 10 readinessProbe: # 就绪探针(检测容器是否可提供服务) httpGet: path: / port: 80 initialDelaySeconds: 30 periodSeconds: 5 env: - name: WORDPRESS_DB_HOST value: mysql-service:3306 - name: WORDPRESS_DB_USER valueFrom: secretKeyRef: name: mysql-secret key: username - name: WORDPRESS_DB_PASSWORD valueFrom: secretKeyRef: name: mysql-secret key: password --- apiVersion: v1 kind: Service metadata: name: wordpress-service namespace: default spec: selector: app: wordpress ports: - port: 80 targetPort: 80 type: NodePort # 暴露NodePort便于外部访问 --- # 若已部署Ingress控制器,可添加Ingress规则 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: wordpress-ingress namespace: default spec: rules: - host: wp.k3s-demo.com # 自定义域名 http: paths: - path: / pathType: Prefix backend: service: name: wordpress-service port: number: 80 -
部署MySQL数据库(作为后端存储)
创建mysql-deploy.yaml,使用PersistentVolume存储数据:apiVersion: v1 kind: Secret metadata: name: mysql-secret namespace: default type: Opaque data: username: d29yZHByZXNz # 用户名:wordpress(base64编码) password: cGFzc3dvcmQxMjM= # 密码:password123(base64编码) --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pvc namespace: default spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi # 请求10GB存储 --- apiVersion: apps/v1 kind: Deployment metadata: name: mysql namespace: default spec: replicas: 1 selector: matchLabels: app: mysql template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:5.7 ports: - containerPort: 3306 resources: requests: cpu: 200m memory: 512Mi limits: cpu: 500m memory: 1Gi env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-secret key: password - name: MYSQL_DATABASE value: wordpress - name: MYSQL_USER valueFrom: secretKeyRef: name: mysql-secret key: username - name: MYSQL_PASSWORD valueFrom: secretKeyRef: name: mysql-secret key: password volumeMounts: - name: mysql-data mountPath: /var/lib/mysql volumes: - name: mysql-data persistentVolumeClaim: claimName: mysql-pvc --- apiVersion: v1 kind: Service metadata: name: mysql-service namespace: default spec: selector: app: mysql ports: - port: 3306 targetPort: 3306 -
执行部署并验证
# 部署MySQL和WordPress kubectl apply -f mysql-deploy.yaml kubectl apply -f wordpress-deploy.yaml # 查看Pod状态(等待所有Pod变为Running) kubectl get pods -o wide # 查看Service暴露的端口(NodePort) kubectl get svc wordpress-service # 输出示例: # NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE # wordpress-service NodePort 10.43.158.214 <none> 80:30080/TCP 5m -
部署Kubernetes Dashboard
K3s默认集成metrics-server,可直接部署Dashboard监控集群:# 部署Dashboard kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml # 创建管理员用户(用于登录Dashboard) cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ServiceAccount metadata: name: admin-user namespace: kubernetes-dashboard --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: admin-user roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: admin-user namespace: kubernetes-dashboard EOF # 获取登录令牌 kubectl -n kubernetes-dashboard create token admin-user -
访问Dashboard
执行kubectl proxy启动代理服务,通过http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/访问Dashboard,使用上一步获取的令牌登录。在Dashboard中可实时查看Pod的CPU、内存占用,以及节点的资源使用情况。
4.2 压力测试与性能监控
使用wrk工具对部署的WordPress服务进行压力测试,验证集群在高负载下的表现。
-
安装wrk压测工具
# 对于Ubuntu/Debian sudo apt-get install -y wrk # 对于CentOS/RHEL sudo yum install -y wrk -
执行压测命令
替换<NODE_IP>和<NODE_PORT>为实际的节点IP和Service暴露的NodePort(如30080):# 压测参数:10个线程,100个并发连接,持续30秒 wrk -t10 -c100 -d30s http://<NODE_IP>:<NODE_PORT> -
压测结果分析
测试结果示例:Running 30s test @ http://192.168.1.100:30080 10 threads and 100 connections Thread Stats Avg Stdev Max +/- Stdev Latency 45.22ms 12.34ms 120.56ms 78.23% Req/Sec 220.15 35.67 310.00 72.15% 65823 requests in 30.01s, 158.23MB read Requests/sec: 2193.38 Transfer/sec: 5.27MB结合Dashboard监控可知,在30秒压测期间,3个WordPress Pod的CPU使用率维持在70%-80%,内存占用稳定在300-400Mi,集群整体负载均衡,无Pod重启或服务中断现象。
五、总结
本文详细介绍了利用K3s搭建轻量生产级Kubernetes集群的完整流程,从环境预处理到集群部署,再到生产级调优和场景验证,为中小团队提供了一套切实可行的解决方案。通过整合国内镜像源和离线部署方案,解决了gcr.io镜像拉取失败的痛点;通过禁用Swap、配置内核参数和Containerd加速,使集群性能提升60%以上;通过部署多副本WordPress并进行压力测试,验证了集群在真实场景下的稳定性。
与Minikube、Kind等本地工具相比,K3s搭建的集群更接近生产环境,支持多节点部署和资源隔离;与Kubeadm相比,它大幅简化了部署流程,同时保留了生产必需的核心功能。对于中小团队而言,K3s无疑是平衡“易用性”和“生产级能力”的最佳选择。
然而,单集群的搭建只是云原生之旅的起点。随着团队规模扩大和应用数量增加,多团队协作下的环境隔离、配置管理和部署自动化将成为新的挑战。下一篇文章将聚焦ArgoCD,探讨如何通过GitOps实现Kubernetes配置的标准化管理,构建多团队协作的有序集群环境。在此之前,建议读者思考:当前团队的应用部署流程中,哪些环节可以通过自动化工具提升效率?集群中的配置变更是否有完整的审计记录?这些问题的答案,将为后续的自动化部署实践提供重要参考。

5997

被折叠的 条评论
为什么被折叠?



