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

290 lines
7.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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/)