290 lines
7.2 KiB
Markdown
290 lines
7.2 KiB
Markdown
# 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:
|
||
|
||
```yaml
|
||
# 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:
|
||
|
||
```yaml
|
||
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 已部署
|
||
|
||
```bash
|
||
# 检查 Traefik 是否运行
|
||
kubectl get pods -n traefik
|
||
|
||
# 如果未部署,先部署 Traefik
|
||
kubectl apply -f k8s/xiongxiao.me/traefik/traefik-complete.yaml
|
||
```
|
||
|
||
### 2. 部署外部服务配置
|
||
|
||
```bash
|
||
# 应用外部服务配置
|
||
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
|
||
|
||
```bash
|
||
# 应用 IngressRoute 配置
|
||
kubectl apply -f k8s/xiongxiao.me/ingress/apps-ingressroute.yaml
|
||
|
||
# 验证 IngressRoute 创建成功
|
||
kubectl get ingressroute -n default
|
||
```
|
||
|
||
### 4. 验证路由配置
|
||
|
||
```bash
|
||
# 检查 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:
|
||
|
||
```yaml
|
||
apiVersion: traefik.io/v1alpha1
|
||
kind: Middleware
|
||
metadata:
|
||
name: large-upload
|
||
namespace: default
|
||
spec:
|
||
buffering:
|
||
maxRequestBodyBytes: 2147483648 # 2GB
|
||
```
|
||
|
||
## 特殊配置
|
||
|
||
### look-good.xiongxiao.me (静态网站)
|
||
|
||
这是一个静态网站服务,需要单独处理:
|
||
|
||
**方案 1**: 将静态文件打包到 Pod 中运行 Nginx
|
||
```bash
|
||
# 创建 ConfigMap 或使用 PV 挂载静态文件
|
||
# 运行 Nginx Pod
|
||
```
|
||
|
||
**方案 2**: 继续使用原 Nginx 服务器,通过 Service 映射
|
||
|
||
### home.mz.xiongxiao.me
|
||
|
||
这个服务指向外部域名 `xionmi.mz.zxj.im:8123`,需要特殊处理。
|
||
|
||
## 故障排查
|
||
|
||
### 服务无法访问
|
||
|
||
1. 检查 Service 和 Endpoints
|
||
```bash
|
||
kubectl get svc,endpoints -n default | grep <service-name>
|
||
```
|
||
|
||
2. 检查 IngressRoute
|
||
```bash
|
||
kubectl describe ingressroute <name> -n default
|
||
```
|
||
|
||
3. 检查 Traefik 日志
|
||
```bash
|
||
kubectl logs -n traefik -l app=traefik
|
||
```
|
||
|
||
### SSL 证书问题
|
||
|
||
1. 检查证书文件
|
||
```bash
|
||
kubectl exec -n traefik <traefik-pod> -- cat /acme/acme.json
|
||
```
|
||
|
||
2. 确认 Let's Encrypt 配置
|
||
```bash
|
||
kubectl describe deployment traefik -n traefik | grep acme
|
||
```
|
||
|
||
## 回滚到 Nginx
|
||
|
||
如果需要回滚:
|
||
|
||
1. 在 DNS 中将域名指回原 Nginx 服务器
|
||
2. 删除 K3s 配置:
|
||
```bash
|
||
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 收集日志
|
||
|
||
## 参考资料
|
||
|
||
- [Traefik 官方文档](https://doc.traefik.io/traefik/)
|
||
- [K3s 官方文档](https://docs.k3s.io/)
|
||
- [Kubernetes Services 文档](https://kubernetes.io/docs/concepts/services-networking/service/)
|