1. 环境准备与系统优化
在Ubuntu 20.04上部署k3s集群前,合理的系统配置是成功的基础。我曾在多个生产环境中验证过这套配置方案,能有效避免后续80%的常见问题。
1.1 硬件选型建议
k3s作为轻量级Kubernetes发行版,对硬件要求相对友好,但不同业务场景需要差异化配置:
- 开发测试环境:2核CPU/4GB内存/50GB存储即可运行基础功能
- 生产微服务集群:建议4核CPU/8GB内存起,每个节点配备独立NVMe SSD
- 高并发场景:需要根据业务压力测试结果扩展worker节点
重要提示:避免使用云厂商的超卖实例,特别是共享型实例。我曾在某云平台遇到因CPU争抢导致kubelet频繁超时的案例。
1.2 系统基础配置
执行以下命令完成基础环境准备:
# 更新软件源并升级系统 sudo apt update && sudo apt -y full-upgrade sudo apt install -y curl wget gnupg2 jq # 关闭swap(必须操作) sudo swapoff -a sudo sed -ri '/\sswap\s/s/^#?/#/' /etc/fstab # 设置时区同步 sudo timedatectl set-timezone Asia/Shanghai sudo apt install -y chrony sudo chronyc sources1.3 内核参数调优
创建/etc/sysctl.d/k8s.conf文件,写入以下内容:
net.ipv4.ip_forward = 1 net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 fs.inotify.max_user_watches = 524288 fs.file-max = 131072加载配置并验证:
sudo sysctl --system sysctl net.ipv4.ip_forward # 应返回12. k3s集群部署实战
k3s的安装虽然简单,但生产环境需要特别注意版本控制和组件配置。
2.1 主节点安装
推荐使用指定版本安装以避免版本漂移问题:
curl -sfL https://get.k3s.io | \ INSTALL_K3S_VERSION="v1.28.4+k3s1" \ INSTALL_K3S_EXEC="--disable traefik --disable servicelb --cluster-init" \ sh -关键参数说明:
--disable traefik:后续会安装更灵活的ingress-nginx--cluster-init:启用etcd高可用模式--resolv-conf:自定义DNS配置(如有特殊需求)
获取访问凭证:
sudo cat /etc/rancher/k3s/k3s.yaml > ~/.kube/config chmod 600 ~/.kube/config2.2 Worker节点加入
在主节点获取token:
sudo cat /var/lib/rancher/k3s/server/node-token在worker节点执行加入命令:
curl -sfL https://get.k3s.io | \ K3S_URL=https://<MASTER_IP>:6443 \ K3S_TOKEN=<NODE_TOKEN> \ INSTALL_K3S_VERSION="v1.28.4+k3s1" \ sh -验证节点状态:
kubectl get nodes -o wide kubectl get pods -A # 检查系统pod状态2.3 高可用方案(可选)
对于生产环境,建议部署3个master节点实现高可用:
# 后续master节点加入命令(首个master安装后执行) curl -sfL https://get.k3s.io | \ INSTALL_K3S_VERSION="v1.28.4+k3s1" \ K3S_TOKEN=<NODE_TOKEN> \ INSTALL_K3S_EXEC="server --server https://<MASTER_IP>:6443" \ sh -3. 网络与存储方案
3.1 Calico网络插件安装
k3s默认使用flannel,但Calico提供更强大的网络策略:
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml验证安装:
watch kubectl get pods -n calico-system配置网络策略示例(限制命名空间间访问):
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny namespace: microservices spec: podSelector: {} policyTypes: - Ingress3.2 Longhorn分布式存储
安装Longhorn提供持久化存储:
kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/v1.4.1/deploy/longhorn.yaml创建StorageClass:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: longhorn provisioner: driver.longhorn.io allowVolumeExpansion: true parameters: numberOfReplicas: "2" staleReplicaTimeout: "30"4. 微服务部署最佳实践
4.1 应用架构设计
典型的三层微服务架构:
- 接入层:ingress-nginx
- 服务层:Spring Cloud/Go微服务
- 数据层:MySQL/Redis集群
4.2 示例微服务部署
部署一个Spring Boot应用示例:
apiVersion: apps/v1 kind: Deployment metadata: name: product-service namespace: microservices spec: replicas: 3 selector: matchLabels: app: product-service template: metadata: labels: app: product-service spec: containers: - name: product-service image: registry.example.com/microservices/product-service:v1.2.0 ports: - containerPort: 8080 resources: requests: cpu: "500m" memory: "512Mi" limits: cpu: "1000m" memory: "1024Mi" livenessProbe: httpGet: path: /actuator/health port: 8080 initialDelaySeconds: 30 periodSeconds: 104.3 服务暴露与Ingress配置
安装ingress-nginx:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm install ingress-nginx ingress-nginx/ingress-nginx \ --namespace ingress-nginx \ --create-namespace \ --set controller.metrics.enabled=trueIngress配置示例:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: microservices-ingress namespace: microservices annotations: nginx.ingress.kubernetes.io/rewrite-target: /$1 spec: ingressClassName: nginx rules: - host: api.example.com http: paths: - path: /products/(.*) pathType: Prefix backend: service: name: product-service port: number: 80805. 运维与监控体系
5.1 日志收集方案
安装Loki日志系统:
helm repo add grafana https://grafana.github.io/helm-charts helm install loki grafana/loki-stack \ --namespace monitoring \ --create-namespace \ --set promtail.enabled=true配置应用日志标签:
spec: template: metadata: labels: app: product-service logging: "true"5.2 监控告警体系
部署Prometheus-Operator:
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm install prometheus prometheus-community/kube-prometheus-stack \ --namespace monitoring \ --create-namespace配置ServiceMonitor监控微服务:
apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: product-service-monitor namespace: microservices spec: selector: matchLabels: app: product-service endpoints: - port: http path: /actuator/prometheus6. 持续交付实践
6.1 GitOps工作流
安装Argo CD:
kubectl create namespace argocd kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml配置应用同步:
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: product-service namespace: argocd spec: project: default source: repoURL: https://git.example.com/microservices.git targetRevision: HEAD path: k8s/product-service destination: server: https://kubernetes.default.svc namespace: microservices syncPolicy: automated: prune: true selfHeal: true6.2 金丝雀发布策略
使用Flagger实现渐进式发布:
helm repo add flagger https://flagger.app helm install flagger flagger/flagger \ --namespace istio-system \ --create-namespace \ --set meshProvider=istio配置金丝雀发布:
apiVersion: flagger.app/v1beta1 kind: Canary metadata: name: product-service namespace: microservices spec: targetRef: apiVersion: apps/v1 kind: Deployment name: product-service service: port: 8080 analysis: interval: 1m threshold: 5 stepWeight: 10 metrics: - name: request-success-rate thresholdRange: min: 99 interval: 1m7. 性能调优经验
7.1 关键参数优化
k3s-server调优参数示例:
INSTALL_K3S_EXEC="--kubelet-arg=config=/etc/rancher/k3s/kubelet.config"kubelet配置文件示例(/etc/rancher/k3s/kubelet.config):
{ "apiVersion": "kubelet.config.k8s.io/v1beta1", "kind": "KubeletConfiguration", "maxPods": 150, "kubeAPIQPS": 50, "kubeAPIBurst": 100, "serializeImagePulls": false }7.2 节点资源预留
配置kubelet资源预留(/etc/rancher/k3s/config.yaml):
kubelet-arg: - "system-reserved=cpu=500m,memory=1Gi" - "kube-reserved=cpu=500m,memory=1Gi" - "eviction-hard=memory.available<500Mi,nodefs.available<10%"7.3 内核参数深度调优
对于高负载场景,建议调整以下参数:
# /etc/sysctl.d/10-kubelet.conf vm.swappiness = 0 vm.vfs_cache_pressure = 50 vm.dirty_ratio = 10 vm.dirty_background_ratio = 5 net.core.somaxconn = 32768 net.ipv4.tcp_max_syn_backlog = 80968. 故障排查指南
8.1 常见问题速查表
| 故障现象 | 排查命令 | 可能原因 |
|---|---|---|
| Pod卡在Pending状态 | kubectl describe pod <name> | 资源不足/调度约束 |
| 服务无法访问 | kubectl get endpoints | 标签选择器不匹配 |
| PVC无法绑定 | kubectl get storageclass | StorageClass未配置 |
| 节点NotReady | journalctl -u k3s -f | 网络插件故障 |
8.2 诊断工具集
安装k8s诊断工具包:
sudo apt install -y kubectl-trace ksniff kubectl krew install doctor关键诊断流程:
- 检查节点状态:
kubectl get nodes -o wide - 查看系统日志:
journalctl -u k3s -f - 检查网络连通性:
kubectl run test-$RANDOM --rm -it --image=alpine -- sh - 分析API延迟:
kubectl get --raw=/metrics | grep apiserver_request_duration
9. 安全加固措施
9.1 基础安全配置
启用PSP(Pod安全策略):
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' - 'persistentVolumeClaim' 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 EOF9.2 网络策略实践
隔离微服务命名空间:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-all namespace: microservices spec: podSelector: {} policyTypes: - Ingress - Egress允许特定服务访问:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-api-access namespace: microservices spec: podSelector: matchLabels: app: product-service ingress: - from: - podSelector: matchLabels: app: gateway-service ports: - protocol: TCP port: 808010. 成本优化策略
10.1 节点自动伸缩
安装cluster-autoscaler:
helm repo add autoscaler https://kubernetes.github.io/autoscaler helm install cluster-autoscaler autoscaler/cluster-autoscaler \ --namespace kube-system \ --set autoDiscovery.clusterName=<CLUSTER_NAME> \ --set aws.region=<REGION> \ --set extraArgs.balance-similar-node-groups=true10.2 资源分析与优化
使用kube-resource-report生成资源报告:
kubectl apply -f https://github.com/hjacobs/kube-resource-report/releases/latest/download/kubernetes.yaml优化建议:
- 设置合理的requests/limits
- 使用HPA自动扩缩容
- 合并低利用率服务
- 采用serverless架构处理突发流量
11. 版本升级方案
11.1 原地升级流程
主节点升级步骤:
# 备份关键数据 sudo cp -r /etc/rancher/k3s /etc/rancher/k3s.bak # 执行升级 curl -sfL https://get.k3s.io | \ INSTALL_K3S_VERSION="v1.28.5+k3s1" \ INSTALL_K3S_EXEC="--disable traefik --disable servicelb" \ sh -worker节点升级:
# 先drain节点 kubectl drain <node> --ignore-daemonsets # 执行升级 curl -sfL https://get.k3s.io | \ K3S_URL=https://<MASTER_IP>:6443 \ K3S_TOKEN=<NODE_TOKEN> \ INSTALL_K3S_VERSION="v1.28.5+k3s1" \ sh - # 恢复调度 kubectl uncordon <node>11.2 蓝绿升级策略
对于关键生产环境,建议:
- 部署新版本集群
- 逐步迁移流量
- 验证后下线旧集群
12. 扩展与集成
12.1 Service Mesh集成
安装Istio服务网格:
curl -L https://istio.io/downloadIstio | sh - cd istio-* ./bin/istioctl install --set profile=demo -y启用自动sidecar注入:
kubectl label namespace microservices istio-injection=enabled12.2 混合云部署
注册外部集群到Rancher:
curl -sfL https://get.rancher.io | sh - sudo rancherd server --cluster-init通过Rancher UI添加k3s集群,实现多集群管理。
13. 真实案例经验
在某电商项目中,我们使用k3s部署了包含200+微服务的集群,总结出以下经验:
Ingress性能瓶颈:当QPS超过5000时,需要调整nginx-ingress参数:
controller: config: worker-processes: "4" upstream-keepalive-connections: "200"数据库连接泄漏:使用linkerd可视化识别未关闭的连接
配置管理:将敏感信息移入SealedSecret,实现加密存储
突发流量处理:结合Keda实现基于Redis队列长度的自动伸缩
14. 未来演进方向
Wasm工作负载:实验性支持WasmEdge运行时
k3s server --container-runtime=wasmtimeeBPF网络加速:替换传统iptables规则
INSTALL_K3S_EXEC="--flannel-backend=ebpf"机密计算:集成Intel SGX/TDX技术保护敏感数据
15. 替代方案对比
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| k3s | 轻量简单 | 功能略少 | 边缘/中小集群 |
| k8s | 功能完整 | 部署复杂 | 大规模生产 |
| OpenShift | 企业级功能 | 商业授权 | 传统企业 |
| Nomad | 简单灵活 | 生态较弱 | 非容器负载 |
在实际项目中,我们通常根据团队技能栈和业务规模选择方案。对于大多数Java/Go微服务场景,k3s已经能够满足需求,且运维成本显著低于标准k8s。