前言

这周继续咱们的云原生实战系列。前面四周,我们把 Docker 单机环境、多服务编排、自动化运维、故障排查都跑通了,线上业务跑起来基本稳定。但随着服务越来越多,单纯靠 Compose 手动管理,慢慢就有点吃力了:节点多了扩缩容麻烦、服务自愈全靠脚本、监控大盘散在各处。

所以这周我直接把内部在用的 K3s 轻量 K8s 集群 完整落地过程整理出来,不搞花里胡哨的理论,全是能直接复制上线的步骤,也顺便说说为什么中小场景我们更推荐 K3s,而不是直接上完整版 K8s。

一、为什么从 Docker Compose 升级到 K3s,而不是完整版 K8s?

很多人一提到 K8s 就头大:组件多、配置复杂、机器要求高、学习成本吓人。但实际中小业务、内网环境、演示集群这类场景,根本用不到那么重的架构。

我们选择 K3s 的几个很现实的理由:

  • 二进制一键安装,不依赖复杂镜像源,内网环境友好
  • 内存占用极低,低配机器也能跑,资源利用率比完整版高很多
  • 自带 Ingress、LoadBalance、LocalPath 存储,不用额外装一大堆组件
  • 兼容原生 K8s 命令,学会 K3s 等于会了大半 K8s
  • 适合从 Docker 平滑过渡,不用推翻现有服务重构

简单说:Docker 管单机,Compose 管多服务,K3s 管多节点 + 自愈 + 弹性,又轻又稳。

二、前期准备与环境规划

这次依旧是内网政企环境标准配置,不搞外网花式操作:

  • 服务器 2 台(后期可随意扩容):1 台 Master、1 台 Node
  • 系统:CentOS 7+ /openEuler 均可
  • 关闭 Swap、防火墙放行端口(6443、80、443 等)
  • 已有的 Docker 镜像直接复用,不用重新构建
  • 内部 Harbor 仓库打通,方便拉取私有业务镜像

整体架构思路很清晰:

  • K3s Master:负责调度、认证、API 入口
  • K3s Node:运行实际业务 Pod
  • 内部 Harbor:统一镜像来源
  • Loki + Prometheus:日志 + 监控(后面会专门更)
  • Ingress:统一域名入口,替代原来的端口映射

三、K3s 集群安装:一步到位,无坑版

安装过程比想象简单很多,我直接放线上在用的稳定安装方式。

1. Master 节点初始化

curl -sfL http://rancher-mirror.rancher.cn/k3s/v1.30.2+k3s1/install.sh | sh -s - \
  --system-default-registry "harbor内网地址" \
  --write-kubeconfig-mode 644 \
  --tls-san "Master节点IP" \
  --disable traefik \
  --disable metrics-server

关闭 Traefik 是因为我们后续用更轻量的 Nginx Ingress,更符合内部使用习惯。

安装完查看节点状态:

kubectl get nodes

出现 Ready 就算正常。

2. Node 节点加入集群

先在 Master 上拿 Token:

cat /var/lib/rancher/k3s/server/node-token

在 Node 机器执行:

curl -sfL http://rancher-mirror.rancher.cn/k3s/v1.30.2+k3s1/install.sh | sh -s - \
  --system-default-registry "harbor内网地址" \
  --kubelet-arg="--node-ip=本机IP" \
  K3S_URL=https://MasterIP:6443 \
  K3S_TOKEN=上面拿到的Token

再回 Master 查看:

kubectl get nodes

两台都 Ready,集群就算搭建完成。整个过程不超过 5 分钟。

四、把原有 Docker 服务迁移到 K3s:实战步骤

重点来了:之前用 Docker Comppose 跑的服务,怎么平滑挪到 K3s 里?

我以一个典型微服务为例:

  • 前端 Web
  • 后端 API
  • MySQL
  • Redis

迁移思路:

  1. 原有镜像不动,直接从 Harbor 拉取
  2. Compose yaml 结构 → 翻译成 K8s Deployment + Service + Ingress
  3. 配置环境变量、挂载目录保持一致,业务无感切换
  4. 先在测试环境跑通,再上演示 / 生产

1. 编写 Deployment(以业务 API 为例)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-api
spec:
  replicas: 2
  selector:
    matchLabels:
      app: demo-api
  template:
    metadata:
      labels:
        app: demo-api
    spec:
      containers:
      - name: demo-api
        image: harbor内网地址/demo/api:v1.3.7
        ports:
        - containerPort: 8080
        env:
        - name: SPRING_PROFILES_ACTIVE
          value: "test"
        - name: MYSQL_HOST
          value: "demo-mysql"
        resources:
          requests:
            memory: "256Mi"
            cpu: "100m"
          limits:
            memory: "512Mi"
            cpu: "500m"

这里加了资源限制,就是为了避免之前 Docker 下某个服务占满整机资源的问题。

2. Service 暴露服务

apiVersion: v1
kind: Service
metadata:
  name: demo-api
spec:
  selector:
    app: demo-api
  ports:
  - port: 8080
    targetPort: 8080
  type: ClusterIP

3. Ingress 统一入口

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: demo-ingress
spec:
  rules:
  - host: api.demo.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: demo-api
            port:
              number: 8080

应用:

kubectl apply -f .

查看 Pod 状态:

kubectl get pods

全部 Running,服务就启动完成了。

五、迁移中最容易踩的几个坑,我帮你踩完了

这部分是真实踩坑总结,不是 AI 随便凑的,遇到基本都能对上:

1. 挂载目录权限问题

K3s 用容器用户运行,经常出现 MySQL、Redis 挂载后无权限。解决:

  • 在宿主机提前 chown 775 对应目录
  • 或者在 Deployment 里指定 runAsUser: 1000(和镜像内用户一致)

2. 服务之间 DNS 解析不通

Compose 里直接用服务名互访,K3s 里也是一样,但很多人忘了用 Service 名。解决:

  • 服务名.命名空间.svc.cluster.local
  • 测试用 nslookup 服务名 验证 DNS 是否正常

3. 镜像拉取失败

因为是内网环境,不能走公网。解决:

  • 安装 K3s 时必须指定 --system-default-registry
  • 私有镜像仓库在 K3s 中配置 imagePullSecret

4. Ingress 访问不通

  • 检查 80/443 是否放开
  • 检查 IngressClassName 是否正确
  • 本地 hosts 绑定域名,再测试

这些坑踩一遍之后,后面迁移其他服务基本就是复制 yaml 改改名字。

六、K3s 对比原来的 Docker Compose:实际提升在哪?

落地之后最直观的几个变化:

  1. 服务自动自愈以前容器挂了要靠脚本重启,现在 Pod 挂了 K3s 自动拉起,不用人盯着。

  2. 一键扩缩容

kubectl scale deployment demo-api --replicas=3

高峰期直接加副本,不用手动起多个容器。

  1. 统一配置管理ConfigMap、Secret 统一管理,不用每个容器改.env。

  2. 多节点统一管理以后再加机器,直接加入节点,服务自动调度,不用一台台部署。

  3. 资源更可控每个服务限制 CPU / 内存,不会出现一个服务打满整个机器的情况。

对中小业务、演示环境、内网项目来说,K3s 真的是性价比极高的选择。

七、下周预告

这周把 K3s 集群搭起来、服务跑起来,只是第一步。下周我会继续更:

  • K3s 下的监控体系:Prometheus + Grafana 面板搭建
  • 日志统一收集:Loki + Filebeat 完整落地
  • 日常常用 kubectl 命令总结,运维必备小抄
  • 简单的 CI/CD 思路:提交代码自动更新集群服务

依旧是内网实战、可直接复制、不搞虚的风格。

如果你也在从 Docker 往 K3s/K8s 过渡,或者正在搭轻量集群,欢迎一起交流踩坑经验~

更多推荐