Files
k8s-docs/k8s/xiongxiao.me/docs/07-nginx-migration.md
2025-11-26 15:44:15 +08:00

7.2 KiB
Raw Permalink Blame History

Nginx 配置迁移到 K3s + Traefik 指南


tags: kubernetes, k3s, traefik, nginx-migration, ingress, services description: 将 Nginx 反向代理配置迁移到 K3s Kubernetes 集群,使用 Traefik 作为 Ingress Controller title: Nginx 到 K3s Traefik 迁移指南 createdAt: 2025-11-26

概述

本指南说明如何将原有的 Nginx 反向代理配置迁移到 K3s Kubernetes 集群,使用 Traefik 作为 Ingress Controller。

架构说明

原架构Nginx

  • Nginx 直接反向代理到各个应用服务
  • 使用 Let's Encrypt 证书
  • 手动配置每个域名的 SSL

新架构K3s + Traefik

  • Traefik 作为统一的 Ingress Controller
  • 自动申请和续期 Let's Encrypt 证书
  • 使用 Kubernetes Service 和 Endpoints 映射外部服务
  • 使用 IngressRoute CRD 配置路由规则

配置文件说明

1. 外部服务配置 (services/external-services.yaml)

为每个外部运行的应用创建 Kubernetes Service 和 Endpoints

# Service 定义服务接口
apiVersion: v1
kind: Service
metadata:
  name: blinko-external
  namespace: default
spec:
  type: ClusterIP
  ports:
  - port: 3111
    targetPort: 3111
    protocol: TCP
    name: http

# Endpoints 指向实际的 IP 地址
apiVersion: v1
kind: Endpoints
metadata:
  name: blinko-external
  namespace: default
subsets:
- addresses:
  - ip: 10.0.32.6  # 实际服务运行的 IP
  ports:
  - port: 3111
    name: http

2. Traefik IngressRoute 配置 (ingress/apps-ingressroute.yaml)

为每个服务配置域名路由和 HTTPS

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: blinko-https
  namespace: default
spec:
  entryPoints:
    - websecure  # HTTPS 入口
  routes:
    - match: Host(`blinko.xiongxiao.me`)
      kind: Rule
      services:
        - name: blinko-external
          port: 3111
  tls:
    certResolver: letsencrypt  # 自动申请 SSL 证书

服务列表

已迁移的服务包括:

域名 服务名称 端口 IP 地址 说明
blinko.xiongxiao.me blinko-external 3111 10.0.32.6 Blinko 笔记
chat.xiongxiao.me chat-external 3000 127.0.0.1 聊天服务
kevisual.xiongxiao.me kevisual-external 3005 127.0.0.1 Kevisual
www.xiongxiao.me www-external 3005 127.0.0.1 主网站
immich.xiongxiao.me immich-external 2283 127.0.0.1 图片管理
cloud.xiongxiao.me cloud-external 5212 127.0.0.1 云盘
docmost.xiongxiao.me docmost-external 3011 127.0.0.1 文档协作
drawio.xiongxiao.me drawio-external 13000 127.0.0.1 绘图工具
minio.xiongxiao.me minio-external 9000 127.0.0.1 对象存储
npm.xiongxiao.me npm-external 30001 10.0.32.6 NPM 私有仓库
gist.xiongxiao.me gist-external 6157 127.0.0.1 代码片段
webdav.xiongxiao.me webdav-external 6060 127.0.0.1 WebDAV
esm.xiongxiao.me esm-external 12000 127.0.0.1 ESM CDN
umami.xiongxiao.me umami-external 4004 127.0.0.1 网站分析
pwd.xiongxiao.me pwd-external 8180 127.0.0.1 密码管理
meilisearch.xiongxiao.me meilisearch-external 7700 127.0.0.1 搜索引擎
memos.xiongxiao.me memos-external 8181 10.0.32.6 Memos
git.xiongxiao.me gitea-external 3000 10.0.32.6 Gitea

部署步骤

1. 确保 Traefik 已部署

# 检查 Traefik 是否运行
kubectl get pods -n traefik

# 如果未部署,先部署 Traefik
kubectl apply -f k8s/xiongxiao.me/traefik/traefik-complete.yaml

2. 部署外部服务配置

# 应用外部服务配置
kubectl apply -f k8s/xiongxiao.me/services/external-services.yaml

# 验证服务创建成功
kubectl get svc -n default | grep external
kubectl get endpoints -n default | grep external

3. 部署 IngressRoute

# 应用 IngressRoute 配置
kubectl apply -f k8s/xiongxiao.me/ingress/apps-ingressroute.yaml

# 验证 IngressRoute 创建成功
kubectl get ingressroute -n default

4. 验证路由配置

# 检查 Traefik Dashboard
kubectl port-forward svc/traefik 8080:8080 -n traefik
# 访问 http://localhost:8080/dashboard/

# 测试域名解析
curl -k https://blinko.xiongxiao.me

注意事项

IP 地址说明

  • 127.0.0.1 - 指向 Kubernetes 主节点本地运行的服务
  • 10.0.32.6 - 指向局域网中其他机器运行的服务

重要: 如果服务是在 Pod 外部运行的:

  • 本地服务需要确保端口可以从 Pod 内访问
  • 远程服务需要确保网络互通

WebSocket 支持

Traefik 默认支持 WebSocket以下服务需要 WebSocket

  • chat.xiongxiao.me
  • kevisual.xiongxiao.me
  • www.xiongxiao.me
  • immich.xiongxiao.me
  • docmost.xiongxiao.me
  • drawio.xiongxiao.me
  • minio.xiongxiao.me
  • gist.xiongxiao.me
  • webdav.xiongxiao.me
  • esm.xiongxiao.me
  • umami.xiongxiao.me

SSL 证书

  • Traefik 自动使用 Let's Encrypt 申请证书
  • 证书存储在 /data/traefik-acme/acme.json
  • 自动续期,无需手动操作

大文件上传

部分服务配置了大文件上传支持(原 Nginx 的 client_max_body_size

  • blinko: 1024m
  • chat: 200m
  • kevisual: 200m
  • immich: 1024m
  • cloud: 1024m
  • docmost: 1024m
  • drawio: 1024m
  • minio: 200m
  • npm: 24m
  • gist: 1024m
  • webdav: 2024m
  • esm: 2048m
  • umami: 1024m
  • git: 2048m

如需在 Traefik 中配置,可添加 Middleware

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: large-upload
  namespace: default
spec:
  buffering:
    maxRequestBodyBytes: 2147483648  # 2GB

特殊配置

look-good.xiongxiao.me (静态网站)

这是一个静态网站服务,需要单独处理:

方案 1: 将静态文件打包到 Pod 中运行 Nginx

# 创建 ConfigMap 或使用 PV 挂载静态文件
# 运行 Nginx Pod

方案 2: 继续使用原 Nginx 服务器,通过 Service 映射

home.mz.xiongxiao.me

这个服务指向外部域名 xionmi.mz.zxj.im:8123,需要特殊处理。

故障排查

服务无法访问

  1. 检查 Service 和 Endpoints
kubectl get svc,endpoints -n default | grep <service-name>
  1. 检查 IngressRoute
kubectl describe ingressroute <name> -n default
  1. 检查 Traefik 日志
kubectl logs -n traefik -l app=traefik

SSL 证书问题

  1. 检查证书文件
kubectl exec -n traefik <traefik-pod> -- cat /acme/acme.json
  1. 确认 Let's Encrypt 配置
kubectl describe deployment traefik -n traefik | grep acme

回滚到 Nginx

如果需要回滚:

  1. 在 DNS 中将域名指回原 Nginx 服务器
  2. 删除 K3s 配置:
kubectl delete -f k8s/xiongxiao.me/ingress/apps-ingressroute.yaml
kubectl delete -f k8s/xiongxiao.me/services/external-services.yaml

后续优化

  1. 容器化服务: 逐步将外部服务容器化并部署到 K3s
  2. 服务网格: 考虑使用 Istio 或 Linkerd
  3. 监控告警: 集成 Prometheus + Grafana
  4. 自动扩展: 配置 HPA (Horizontal Pod Autoscaler)
  5. 日志聚合: 使用 ELK 或 Loki 收集日志

参考资料