This commit is contained in:
2025-11-26 15:44:15 +08:00
parent 1cd698ed64
commit 2418891634
42 changed files with 3715 additions and 5 deletions

274
k8s/xiongxiao.me/README.md Normal file
View File

@@ -0,0 +1,274 @@
# Nginx 到 K3s Traefik 迁移总结
---
tags: kubernetes, k3s, traefik, nginx, migration, summary
description: Nginx 配置迁移到 K3s + Traefik 的完整总结和快速参考
title: 迁移总结和快速参考
createdAt: 2025-11-26
---
## 快速开始
### 一键部署
```bash
cd /Users/xion/kevisual/k8s-docs/k8s/xiongxiao.me
./deploy-apps.sh
```
### 测试服务
```bash
./test-services.sh
```
### 卸载
```bash
./undeploy-apps.sh
```
## 文件结构
```
k8s/xiongxiao.me/
├── services/
│ └── external-services.yaml # 外部服务定义 (18个服务)
├── ingress/
│ └── apps-ingressroute.yaml # Traefik 路由配置 (18个域名)
├── docs/
│ └── 07-nginx-migration.md # 详细迁移文档
├── deploy-apps.sh # 自动部署脚本
├── undeploy-apps.sh # 自动卸载脚本
└── test-services.sh # 服务测试脚本
```
## 迁移的服务 (18个)
| # | 域名 | 服务 | 端口 | 位置 |
|---|------|------|------|------|
| 1 | blinko.xiongxiao.me | 笔记 | 3111 | 10.0.32.6 |
| 2 | chat.xiongxiao.me | 聊天 | 3000 | 本地 |
| 3 | kevisual.xiongxiao.me | Kevisual | 3005 | 本地 |
| 4 | www.xiongxiao.me | 主站 | 3005 | 本地 |
| 5 | immich.xiongxiao.me | 图片 | 2283 | 本地 |
| 6 | cloud.xiongxiao.me | 云盘 | 5212 | 本地 |
| 7 | docmost.xiongxiao.me | 文档 | 3011 | 本地 |
| 8 | drawio.xiongxiao.me | 绘图 | 13000 | 本地 |
| 9 | minio.xiongxiao.me | 存储 | 9000 | 本地 |
| 10 | npm.xiongxiao.me | NPM | 30001 | 10.0.32.6 |
| 11 | gist.xiongxiao.me | 代码 | 6157 | 本地 |
| 12 | webdav.xiongxiao.me | WebDAV | 6060 | 本地 |
| 13 | esm.xiongxiao.me | CDN | 12000 | 本地 |
| 14 | umami.xiongxiao.me | 分析 | 4004 | 本地 |
| 15 | pwd.xiongxiao.me | 密码 | 8180 | 本地 |
| 16 | meilisearch.xiongxiao.me | 搜索 | 7700 | 本地 |
| 17 | memos.xiongxiao.me | Memos | 8181 | 10.0.32.6 |
| 18 | git.xiongxiao.me | Gitea | 3000 | 10.0.32.6 |
## 关键特性
### ✅ 自动 HTTPS
- 使用 Let's Encrypt 自动申请证书
- 自动续期,无需手动干预
- HTTP 自动重定向到 HTTPS
### ✅ WebSocket 支持
- 原生支持 WebSocket 连接
- 无需额外配置
### ✅ 灵活扩展
- 轻松添加新服务
- 支持多种后端类型
- 可配置中间件
## 常用命令
### 查看服务状态
```bash
# 查看所有外部服务
kubectl get svc -n default | grep external
# 查看 Endpoints
kubectl get endpoints -n default | grep external
# 查看 IngressRoute
kubectl get ingressroute -n default
```
### 查看日志
```bash
# Traefik 日志
kubectl logs -n traefik -l app=traefik -f
# 查看特定服务的 Endpoints
kubectl describe endpoints blinko-external -n default
```
### Traefik Dashboard
```bash
# 端口转发
kubectl port-forward svc/traefik 8080:8080 -n traefik
# 访问 http://localhost:8080/dashboard/
```
### 调试服务
```bash
# 测试单个服务
curl -k -v https://blinko.xiongxiao.me
# 查看 DNS 解析
nslookup blinko.xiongxiao.me
# 查看证书
openssl s_client -connect blinko.xiongxiao.me:443 -servername blinko.xiongxiao.me
```
## 添加新服务
### 1. 添加 Service 和 Endpoint
`services/external-services.yaml` 中添加:
```yaml
---
# 新服务
apiVersion: v1
kind: Service
metadata:
name: newapp-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 8080
targetPort: 8080
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: newapp-external
namespace: default
subsets:
- addresses:
- ip: 127.0.0.1 # 或实际 IP
ports:
- port: 8080
name: http
```
### 2. 添加 IngressRoute
`ingress/apps-ingressroute.yaml` 中添加:
```yaml
---
# 新应用 - newapp.xiongxiao.me
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: newapp-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`newapp.xiongxiao.me`)
kind: Rule
services:
- name: newapp-external
port: 8080
tls:
certResolver: letsencrypt
```
### 3. 应用配置
```bash
kubectl apply -f services/external-services.yaml
kubectl apply -f ingress/apps-ingressroute.yaml
```
## 故障排查清单
### 服务无法访问
- [ ] DNS 是否指向正确的 IP (Traefik NodePort 30443)
- [ ] Service 是否存在: `kubectl get svc -n default`
- [ ] Endpoints 是否有地址: `kubectl get endpoints -n default`
- [ ] IngressRoute 是否正确: `kubectl get ingressroute -n default`
- [ ] 后端服务是否运行
- [ ] 网络是否互通: `ping 10.0.32.6`
- [ ] Traefik 是否正常: `kubectl get pods -n traefik`
### SSL 证书问题
- [ ] 域名是否可以公网访问 (Let's Encrypt 验证)
- [ ] 端口 80 是否开放 (HTTP Challenge)
- [ ] ACME 存储是否正常: `kubectl get pvc -n traefik`
- [ ] 查看证书申请日志: `kubectl logs -n traefik -l app=traefik | grep acme`
### WebSocket 连接失败
- [ ] 检查后端服务是否支持 WebSocket
- [ ] 查看 Traefik 日志是否有错误
- [ ] 测试直接连接后端服务
## 性能优化
### 启用压缩
```yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: compress
namespace: default
spec:
compress: {}
```
### 限流
```yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: rate-limit
namespace: default
spec:
rateLimit:
average: 100
burst: 50
```
### 添加到 IngressRoute
```yaml
spec:
routes:
- match: Host(`example.xiongxiao.me`)
kind: Rule
middlewares:
- name: compress
- name: rate-limit
services:
- name: example-external
port: 8080
```
## 安全建议
1. **限制访问源**: 使用 IP 白名单中间件
2. **启用认证**: BasicAuth 或 OAuth 中间件
3. **定期更新**: 保持 Traefik 和 K3s 最新版本
4. **监控告警**: 集成 Prometheus 监控
5. **日志审计**: 保留访问日志
## 下一步
- [ ] 将服务逐步迁移到容器化部署
- [ ] 配置自动扩展 (HPA)
- [ ] 集成监控和告警
- [ ] 配置备份策略
- [ ] 文档化运维流程

View File

@@ -0,0 +1,19 @@
K1035ea36d4925cfd0a7f7938fb3eff1225e458c1aee4fb99bda40bb95f529913bf::server:03e3ef7d17dadc2471b0f2369248250d
# Agent 节点安装命令
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=https://light.xiongxiao.me:6443 K3S_TOKEN=K1035ea36d4925cfd0a7f7938fb3eff1225e458c1aee4fb99bda40bb95f529913bf::server:03e3ef7d17dadc2471b0f2369248250d sh -
会输出类似
[INFO] systemd: Enabling k3s-agent unit
Created symlink /etc/systemd/system/multi-user.target.wants/k3s-agent.service → /etc/systemd/system/k3s-agent.service.
[INFO] systemd: Starting k3s-agent
## 设置label
kubectl label nodes vm-32-6-ubuntu machine=library --overwrite
删除label
kubectl label nodes vm-32-6-ubuntu machine- --overwrite

View File

@@ -0,0 +1,78 @@
sudo vim /etc/rancher/k3s/registries.yaml
```yaml
mirrors:
docker.io:
endpoint:
- "https://docker.1ms.run"
- "https://docker.m.daocloud.io"
- "https://docker.1panel.live"
- "https://docker-0.unsee.tech"
- "https://dytt.online"
- "https://lispy.org"
- "https://docker.xiaogenban1993.com"
- "https://666860.xyz"
- "https://hub.rat.dev"
- "https://demo.52013120.xyz"
- "https://proxy.vvvv.ee"
- "https://registry.cyou"
- "http://hub-mirror.c.163.com"
# rancher 镜像加速
"rancher":
endpoint:
- "https://docker.1ms.run/rancher"
configs:
"docker.1ms.run":
tls:
insecure_skip_verify: true
```
```bash
# Master 节点重启 k3s
sudo systemctl restart k3s
# Worker 节点重启 k3s-agent
sudo systemctl restart k3s-agent
```
## container ctr
```bash
vim /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".registry]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors]
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
endpoint = [
"https://docker.1panel.live",
"https://docker.1ms.run",
"https://dytt.online",
"https://docker-0.unsee.tech",
"https://lispy.org",
"https://docker.xiaogenban1993.com",
"https://666860.xyz",
"https://hub.rat.dev",
"https://docker.m.daocloud.io",
"https://demo.52013120.xyz",
"https://proxy.vvvv.ee",
"https://registry.cyou"
]
sudo systemctl restart containerd
sudo ctr image pull docker.io/library/verdaccio:latest
# K3s 使用 k8s.io 命名空间
sudo ctr -n k8s.io images pull docker.m.daocloud.io/rancher/mirrored-pause:3.6
sudo ctr -n k8s.io images tag docker.m.daocloud.io/rancher/mirrored-pause:3.6 docker.io/rancher/mirrored-pause:3.6
sudo ctr -n k8s.io images delete docker.m.daocloud.io/rancher/mirrored-pause:3.6
# 查看镜像
sudo ctr -n k8s.io images ls | grep pause
```

91
k8s/xiongxiao.me/deploy-apps.sh Executable file
View File

@@ -0,0 +1,91 @@
#!/bin/bash
# Nginx 配置迁移到 K3s + Traefik 部署脚本
# tags: kubernetes, k3s, traefik, deployment, automation
# description: 自动部署外部服务和 IngressRoute 配置的脚本
# title: 自动部署脚本
# createdAt: 2025-11-26
set -e
echo "======================================"
echo "Nginx 配置迁移到 K3s + Traefik"
echo "======================================"
echo ""
# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# 检查 kubectl
if ! command -v kubectl &> /dev/null; then
echo -e "${RED}错误: kubectl 未安装${NC}"
exit 1
fi
# 检查 Traefik
echo -e "${YELLOW}步骤 1/4: 检查 Traefik 部署状态...${NC}"
if ! kubectl get namespace traefik &> /dev/null; then
echo -e "${YELLOW}Traefik namespace 不存在,正在创建...${NC}"
kubectl create namespace traefik
fi
if ! kubectl get deployment traefik -n traefik &> /dev/null; then
echo -e "${YELLOW}Traefik 未部署,正在部署...${NC}"
kubectl apply -f traefik/traefik-complete.yaml
echo -e "${GREEN}等待 Traefik Pod 就绪...${NC}"
kubectl wait --for=condition=ready pod -l app=traefik -n traefik --timeout=120s
else
echo -e "${GREEN}✓ Traefik 已部署${NC}"
fi
# 部署外部服务
echo ""
echo -e "${YELLOW}步骤 2/4: 部署外部服务配置...${NC}"
kubectl apply -f services/external-services.yaml
echo -e "${GREEN}✓ 外部服务配置已应用${NC}"
# 验证服务
echo ""
echo -e "${YELLOW}步骤 3/4: 验证服务创建...${NC}"
sleep 2
SERVICE_COUNT=$(kubectl get svc -n default | grep -c "external" || true)
ENDPOINT_COUNT=$(kubectl get endpoints -n default | grep -c "external" || true)
echo -e "${GREEN}✓ 创建了 ${SERVICE_COUNT} 个服务${NC}"
echo -e "${GREEN}✓ 创建了 ${ENDPOINT_COUNT} 个 Endpoints${NC}"
# 部署 IngressRoute
echo ""
echo -e "${YELLOW}步骤 4/4: 部署 IngressRoute 配置...${NC}"
kubectl apply -f ingress/apps-ingressroute.yaml
sleep 2
ROUTE_COUNT=$(kubectl get ingressroute -n default 2>/dev/null | grep -c "https" || true)
echo -e "${GREEN}✓ 创建了 ${ROUTE_COUNT} 个 IngressRoute${NC}"
# 显示结果
echo ""
echo -e "${GREEN}======================================"
echo "部署完成!"
echo "======================================${NC}"
echo ""
echo "已部署的服务:"
kubectl get svc -n default | grep external || echo "无"
echo ""
echo "已部署的 IngressRoute"
kubectl get ingressroute -n default || echo "无"
echo ""
echo -e "${YELLOW}提示:${NC}"
echo "1. 查看 Traefik Dashboard:"
echo " kubectl port-forward svc/traefik 8080:8080 -n traefik"
echo " 然后访问 http://localhost:8080/dashboard/"
echo ""
echo "2. 查看 Traefik 日志:"
echo " kubectl logs -n traefik -l app=traefik -f"
echo ""
echo "3. 测试服务访问:"
echo " curl -k https://blinko.xiongxiao.me"
echo ""
echo "4. 确保 DNS 已配置正确,将域名指向 Traefik 的 NodePort (30443)"
echo ""

View File

@@ -0,0 +1,63 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: verdaccio
namespace: default
labels:
machine: library
app: verdaccio
spec:
replicas: 1
selector:
matchLabels:
app: verdaccio
template:
metadata:
labels:
app: verdaccio
machine: library
spec:
# 指定调度到特定节点
nodeSelector:
machine: library
# 或者使用 nodeAffinity更灵活推荐用于生产
# affinity:
# nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# nodeSelectorTerms:
# - matchExpressions:
# - key: kubernetes.io/hostname
# operator: In
# values:
# - vm-32-6-ubuntu
containers:
- name: verdaccio
image: verdaccio/verdaccio:latest
ports:
- containerPort: 4873
volumeMounts:
- name: verdaccio-storage
mountPath: /verdaccio/storage
- name: verdaccio-config
mountPath: /verdaccio/conf
env:
- name: VERDACCIO_PORT
value: "4873"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
volumes:
- name: verdaccio-storage
hostPath:
path: /opt/docker/verdaccio/data/storage
type: DirectoryOrCreate
- name: verdaccio-config
hostPath:
path: /opt/docker/verdaccio/data/conf

View File

@@ -0,0 +1,47 @@
# 安装 master
```sh
## 1. 安装 k3s
curl -sfL https://get.k3s.io | sh -
sudo cat /var/lib/rancher/k3s/server/node-token
```
## 2. 安装 node
```sh
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn K3S_URL=https://myserver:6443 K3S_TOKEN=mynodetoken sh -
```
## 3. 删除
```sh
## master 节点上执行
sudo /usr/local/bin/k3s-uninstall.sh
## node 节点上执行
sudo /usr/local/bin/k3s-agent-uninstall.sh
```
## 4. 这是 role
```
kubectl label nodes <node-name> role=<value> --overwrite
```
## 部署
如何在某一个节点vm-32-6-ubuntu部署verdaccio
```sh
# services
kubectl apply -f verdaccio-deployment.yaml
# ip
kubectl apply -f verdaccio-services.yaml
# 查看pod
kubectl get pods -o wide
```

View File

@@ -0,0 +1,13 @@
# 本地管理
## 安装
```sh
brew install kubectl
```
## 查看配置
```sh
cat /etc/rancher/k3s/k3s.yaml
```

View File

@@ -0,0 +1,204 @@
---
title: Traefik Ingress Controller 部署与 RBAC 配置指南
description: 完整的 Kubernetes Traefik v2.10 部署教程,包含 RBAC 权限配置、ServiceAccount、ClusterRole、ClusterRoleBinding 设置,解决 ingresses.networking.k8s.io forbidden 权限问题,使用 NodePort 暴露服务
tags:
- kubernetes
- traefik
- ingress-controller
- rbac
- clusterrole
- clusterrolebinding
- serviceaccount
- deployment
- nodeport
- permissions
- networking
createdAt: 2025-11-26T04:30:00Z
---
# Traefik Ingress Controller 部署
本文档介绍如何使用 YAML 清单在 Kubernetes 集群中部署 Traefik Ingress Controller包含完整的 RBAC 权限配置。
## 部署步骤
### 1. 创建 Traefik 命名空间
```bash
kubectl create namespace traefik
```
### 2. 应用 Traefik CRDs
```bash
kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v2.10/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml
```
### 3. 配置 RBAC 权限(重要)
创建 `traefik-rbac.yaml` 文件,配置必要的权限:
```bash
kubectl apply -f /Users/xion/kevisual/k8s-docs/k8s/xiongxiao.me/traefik/traefik-rbac.yaml
```
RBAC 配置包含:
- **ServiceAccount**traefik 服务账户
- **ClusterRole**:定义访问 Kubernetes 资源的权限
- 读取 Services、Endpoints、Secrets
- 读取和监听 Ingresses、IngressClasses
- 更新 Ingress 状态
- 访问 Traefik CRDs
- **ClusterRoleBinding**:将 ClusterRole 绑定到 ServiceAccount
### 4. 部署 Traefik
使用 `traefik-deployment.yaml` 配置文件部署 Traefik
```bash
kubectl apply -f /Users/xion/kevisual/k8s-docs/k8s/xiongxiao.me/traefik/traefik-deployment.yaml
```
配置文件内容说明:
**Deployment**
- 使用 Traefik v2.10 镜像
- 引用前面创建的 ServiceAccount`traefik`
- 配置参数:
- `--api.insecure=true`:启用管理 API生产环境建议禁用
- `--providers.kubernetesingress=true`:启用 Kubernetes Ingress 支持
- `--entrypoints.web.address=:80`HTTP 入口点
- `--entrypoints.websecure.address=:443`HTTPS 入口点
- 暴露端口80、443、8080管理界面
**Service**
- 类型NodePort
- 端口映射:
- HTTP: 80 → NodePort 30080
- HTTPS: 443 → NodePort 30443
- Admin: 8080 → 集群内部访问
**IngressClass**
- 名称traefik
- Controllertraefik.io/ingress-controller
### 5. 验证部署
```bash
# 查看 RBAC 配置
kubectl get serviceaccount traefik -n traefik
kubectl get clusterrole traefik-ingress-controller
kubectl get clusterrolebinding traefik-ingress-controller
# 查看 Pod 状态
kubectl get pods -n traefik
# 查看 Service
kubectl get svc -n traefik
# 查看 IngressClass
kubectl get ingressclass
# 查看日志(确认没有权限错误)
kubectl logs -n traefik -l app=traefik
```
预期日志中不应出现类似错误:
```
Failed to watch *v1.Ingress: ingresses.networking.k8s.io is forbidden
```
## 访问方式
部署完成后Traefik 通过 NodePort 方式暴露服务:
- **HTTP 访问**`http://<任意Node-IP>:30080`
- **HTTPS 访问**`https://<任意Node-IP>:30443`
- **管理界面**:通过端口转发访问
```bash
# 访问 Traefik Dashboard
kubectl port-forward -n traefik svc/traefik 8080:8080
# 浏览器打开 http://localhost:8080/dashboard/
```
## 配置 Ingress
创建 Ingress 资源时,指定 `ingressClassName: traefik`
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: verdaccio-ingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
ingressClassName: traefik
rules:
- host: npm.xiongxiao.me
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: verdaccio-service
port:
number: 82
```
访问应用时需要使用 NodePort 端口,例如:`http://npm.xiongxiao.me:30080`
## 常见问题
### 1. 权限错误ingresses.networking.k8s.io is forbidden
**症状**Traefik 日志中出现权限错误
**解决**:确保已正确应用 `traefik-rbac.yaml` 配置,包含 ClusterRole 和 ClusterRoleBinding
### 2. 404 Page Not Found
**排查步骤**
```bash
# 检查 Ingress 是否被识别
kubectl describe ingress verdaccio-ingress
# 查看 Traefik 路由
kubectl port-forward -n traefik svc/traefik 8080:8080
# 访问 http://localhost:8080/dashboard/ 查看路由配置
# 确认 Service 正常
kubectl get svc verdaccio-service
kubectl get endpoints verdaccio-service
```
## 注意事项
1. **生产环境建议**
- 关闭 `--api.insecure=true`,使用安全的方式访问 Dashboard
- 使用 LoadBalancer 类型的 Service如果云环境支持
- 配置 TLS 证书和 HTTPS
- 限制 ServiceAccount 权限范围(使用 Role 而非 ClusterRole
2. **DNS 配置**
- 将域名解析到任意一个 Node 节点的 IP
- 确保防火墙开放 30080 和 30443 端口
3. **高可用性**
- 增加 Traefik 副本数(修改 `replicas`
- 使用 DaemonSet 在每个节点运行 Traefik
- 配置外部负载均衡器
4. **命名空间隔离**
- 当前配置使用 ClusterRole可以访问所有命名空间的 Ingress
- 如需限制访问范围,改用 Role 和 RoleBinding
##
wget http://verdaccio-service.default.svc.cluster.local:4873
wget http://10.43.17.172:4873

View File

@@ -0,0 +1,16 @@
# 使用 curl 镜像测试 DNS 解析
```bash
kubectl run curl-test --image=curlimages/curl --rm -it --restart=Never -n default -- curl -v http://verdaccio-service:4873
#进入容器后,可以使用 curl 命令测试 DNS 解析:
kubectl run -it --rm --image=curlimages/curl dns-test -- sh
```
## 创建 一个 curlimages/curl 测试 Pod
创建在 master访问的是 worker 几点的 verdaccio-service 服务run 完后自己删除
```bash
kubectl run curl-test --image=curlimages/curl --rm -it --restart=Never -- sh
```

View File

@@ -0,0 +1,292 @@
---
title: Traefik 配置主机服务指南
description: 通过 Traefik Ingress 将主机端口服务暴露到 Kubernetes 集群,实现域名访问
tags:
- Kubernetes
- Traefik
- Ingress
- 主机服务
- 端口转发
createdAt: 2025-11-26
---
# Traefik 配置主机服务指南
## 概述
本文档介绍如何通过 Traefik Ingress 将主机上的服务(例如 4000 端口)暴露到 Kubernetes 集群,并通过域名访问。
## 配置方案
### 方案一:使用 Service + Endpoints推荐
这种方式直接将主机 IP 和端口映射到 Kubernetes Service。
#### 1. 创建 Service 和 Endpoints
文件:`services/host-service-4000.yaml`
```yaml
---
# 主机服务端点配置
apiVersion: v1
kind: Service
metadata:
name: host-service-4000
namespace: default
spec:
ports:
- protocol: TCP
port: 4000
targetPort: 4000
clusterIP: None
---
apiVersion: v1
kind: Endpoints
metadata:
name: host-service-4000
namespace: default
subsets:
- addresses:
- ip: 192.168.65.254 # 主机 IP 地址
ports:
- port: 4000
```
**主机 IP 说明:**
- **Docker Desktop (Mac/Windows)**: `192.168.65.254``host.docker.internal`
- **Linux (Minikube)**: 使用 `minikube ssh "route -n | grep ^0.0.0.0 | awk '{ print \$2 }'"` 获取
- **自定义集群**: 使用实际的主机 IP 地址
#### 2. 创建 Ingress 规则
文件:`ingress/host-service-ingress.yaml`
```yaml
---
# 主机服务 Ingress 配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: host-service-ingress
namespace: default
spec:
ingressClassName: traefik
rules:
- host: zd.xiongxiao.me
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: host-service-4000
port:
number: 4000
```
#### 3. 部署配置
```bash
# 应用 Service 和 Endpoints
kubectl apply -f services/host-service-4000.yaml
# 应用 Ingress
kubectl apply -f ingress/host-service-ingress.yaml
```
#### 4. 验证配置
```bash
# 检查 Service
kubectl get svc host-service-4000
# 检查 Endpoints
kubectl get endpoints host-service-4000
# 检查 Ingress
kubectl get ingress host-service-ingress
# 查看 Ingress 详情
kubectl describe ingress host-service-ingress
```
#### 5. 配置 DNS
在你的 DNS 提供商或本地 hosts 文件中添加:
```
<traefik-ip> zd.xiongxiao.me
```
#### 6. 测试访问
```bash
# 通过域名访问
curl http://zd.xiongxiao.me
# 或在浏览器中访问
# http://zd.xiongxiao.me
```
### 方案二:使用 ExternalName Service
适用于可以通过主机名访问的情况。
```yaml
---
apiVersion: v1
kind: Service
metadata:
name: host-service-4000
namespace: default
spec:
type: ExternalName
externalName: host.docker.internal # 或使用实际主机名
ports:
- protocol: TCP
port: 4000
targetPort: 4000
```
**注意**: ExternalName 不支持指定端口,可能需要额外配置。
## 常见问题
### 1. 如何获取主机 IP
**Docker Desktop (Mac/Windows)**:
```bash
# 使用特殊域名
host.docker.internal
# 或使用固定 IP
192.168.65.254
```
**Linux/Minikube**:
```bash
# 方法一:从容器内查看
kubectl run -it --rm debug --image=alpine --restart=Never -- sh
/ # ip route | grep default
/ # exit
# 方法二Minikube 特定
minikube ssh "route -n | grep ^0.0.0.0 | awk '{ print \$2 }'"
```
### 2. 连接被拒绝
检查以下几点:
- 主机服务是否在 0.0.0.0:4000 监听(而不是 127.0.0.1:4000
- 防火墙是否允许访问
- 主机 IP 配置是否正确
**修改服务监听地址示例**:
```bash
# 错误 - 只监听本地
node server.js --host 127.0.0.1 --port 4000
# 正确 - 监听所有接口
node server.js --host 0.0.0.0 --port 4000
```
### 3. Ingress 无法路由
检查 Traefik 日志:
```bash
kubectl logs -n traefik -l app.kubernetes.io/name=traefik --tail=100
```
查看 Ingress 事件:
```bash
kubectl describe ingress host-service-ingress
```
## 配置多个主机服务
如果需要配置多个主机端口,只需复制配置并修改相应的值:
```yaml
---
# 第二个服务 - 5000 端口
apiVersion: v1
kind: Service
metadata:
name: host-service-5000
namespace: default
spec:
ports:
- protocol: TCP
port: 5000
targetPort: 5000
clusterIP: None
---
apiVersion: v1
kind: Endpoints
metadata:
name: host-service-5000
namespace: default
subsets:
- addresses:
- ip: 192.168.65.254
ports:
- port: 5000
---
# Ingress 配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: host-service-5000-ingress
namespace: default
spec:
ingressClassName: traefik
rules:
- host: another.xiongxiao.me
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: host-service-5000
port:
number: 5000
```
## HTTPS 配置
如果需要 HTTPS可以添加 TLS 配置:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: host-service-ingress
namespace: default
annotations:
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
ingressClassName: traefik
tls:
- hosts:
- zd.xiongxiao.me
secretName: zd-xiongxiao-me-tls
rules:
- host: zd.xiongxiao.me
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: host-service-4000
port:
number: 4000
```
## 参考资源
- [Traefik 官方文档](https://doc.traefik.io/traefik/routing/providers/kubernetes-ingress/)
- [Kubernetes Ingress 文档](https://kubernetes.io/docs/concepts/services-networking/ingress/)
- [Kubernetes Service 文档](https://kubernetes.io/docs/concepts/services-networking/service/)

View File

@@ -0,0 +1,18 @@
```bash
# 1. 安装 Helm如果未安装
curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# 2. 添加 Rancher Helm 仓库
helm repo add rancher-latest https://releases.rancher.com/server-charts/latest
# 3. 创建命名空间
kubectl create namespace cattle-system
# 4. 安装 Rancher使用自签名证书示例生产请用 Let's Encrypt
helm install rancher rancher-latest/rancher \
--namespace cattle-system \
--set hostname=rancher.xiongxiao.me \
--set ingress.tls.source=secret
```

View File

@@ -0,0 +1,176 @@
---
tags: traefik, ssl, https, let's encrypt, acme, ingress, kubernetes, 证书
description: Traefik 配置 Let's Encrypt 自动 SSL 证书的完整指南,解决浏览器显示不安全的问题
title: Traefik SSL 证书配置指南
createdAt: 2025-11-26
---
# Traefik SSL 证书配置指南
## 问题描述
Traefik 默认使用自签名证书,导致浏览器显示"不安全"警告。
## 解决方案
使用 Let's Encrypt 提供的免费 SSL 证书,通过 ACME 协议自动获取和续期。
## 配置步骤
### 1. 更新 Traefik 配置
已在 `traefik-complete.yaml` 中添加:
- **PersistentVolume/PVC**: 存储 ACME 证书数据
- **ACME 配置参数**:
- 证书解析器 `letsencrypt`
- HTTP Challenge 验证
- 自动 HTTP → HTTPS 重定向
### 2. 关键配置说明
```yaml
# Let's Encrypt 配置
- --certificatesresolvers.letsencrypt.acme.email=your-email@example.com # 修改为你的邮箱
- --certificatesresolvers.letsencrypt.acme.storage=/acme/acme.json
- --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web
```
### 3. 修改邮箱地址
**重要**: 在应用配置前,修改 `traefik-complete.yaml` 中的邮箱:
```bash
# 编辑文件,将 your-email@example.com 改为你的真实邮箱
vi k8s/xiongxiao.me/traefik/traefik-complete.yaml
```
### 4. 应用配置
```bash
# 创建存储目录(在 k8s master 节点上)
sudo mkdir -p /data/traefik-acme
sudo chmod 600 /data/traefik-acme
# 应用配置
kubectl apply -f k8s/xiongxiao.me/traefik/traefik-complete.yaml
# 检查 PV/PVC 状态
kubectl get pv,pvc -n traefik
# 检查 Traefik Pod 状态
kubectl get pods -n traefik
kubectl logs -f deployment/traefik -n traefik
```
### 5. Ingress 使用示例
创建带 SSL 的 Ingress 资源:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: default
annotations:
# 指定使用 letsencrypt 证书解析器
traefik.ingress.kubernetes.io/router.tls.certresolver: letsencrypt
spec:
ingressClassName: traefik
rules:
- host: example.xiongxiao.me
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: example-service
port:
number: 80
tls:
- hosts:
- example.xiongxiao.me
# Let's Encrypt 会自动生成证书,无需手动指定 secretName
```
## 验证 SSL 证书
### 检查证书状态
```bash
# 查看 Traefik 日志中的 ACME 证书获取过程
kubectl logs -f deployment/traefik -n traefik | grep -i acme
# 进入 Pod 检查证书文件
kubectl exec -it deployment/traefik -n traefik -- ls -la /acme/
kubectl exec -it deployment/traefik -n traefik -- cat /acme/acme.json
```
### 浏览器验证
1. 访问你的域名: `https://example.xiongxiao.me`
2. 点击浏览器地址栏的锁图标
3. 查看证书详情,应显示由 "Let's Encrypt" 签发
## 常见问题
### 1. 证书获取失败
**原因**:
- 域名未正确解析到 Traefik 的公网 IP
- 80 端口未开放(HTTP Challenge 需要)
- 邮箱地址无效
**解决**:
```bash
# 检查域名解析
nslookup example.xiongxiao.me
# 检查 Traefik Service 的 NodePort
kubectl get svc traefik -n traefik
# 确保防火墙开放 80 和 443 端口
```
### 2. 测试环境配置
如果需要测试,使用 Let's Encrypt Staging 环境(避免达到速率限制):
```yaml
# 在 traefik args 中添加:
- --certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
```
**注意**: Staging 证书不被浏览器信任,仅用于测试。
### 3. 证书续期
Let's Encrypt 证书有效期 90 天,Traefik 会自动在到期前 30 天续期。
### 4. 多域名支持
可以为不同的域名自动获取证书:
```yaml
tls:
- hosts:
- app1.xiongxiao.me
- app2.xiongxiao.me
```
## 生产环境检查清单
- [ ] 修改邮箱地址为真实邮箱
- [ ] 确认域名 DNS 解析正确
- [ ] 确认 NodePort 30080 (HTTP) 可访问
- [ ] 确认 NodePort 30443 (HTTPS) 可访问
- [ ] 移除或注释 staging 环境配置
- [ ] 备份 `/data/traefik-acme/acme.json` 文件
## 参考资料
- [Traefik 官方文档 - Let's Encrypt](https://doc.traefik.io/traefik/https/acme/)
- [Let's Encrypt 速率限制](https://letsencrypt.org/docs/rate-limits/)
- [ACME HTTP Challenge](https://letsencrypt.org/docs/challenge-types/#http-01-challenge)

View File

@@ -0,0 +1,289 @@
# 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/)

View File

@@ -0,0 +1,330 @@
---
# Traefik IngressRoute 配置 - 所有服务的路由规则
# tags: traefik, ingressroute, https, ssl, routing, nginx-migration
# description: 使用 Traefik IngressRoute CRD 配置所有服务的域名路由和 HTTPS
# title: Traefik IngressRoute 完整配置
# createdAt: 2025-11-26
---
# Blinko - blinko.xiongxiao.me
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: blinko-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`blinko.xiongxiao.me`)
kind: Rule
services:
- name: blinko-external
port: 3111
tls:
certResolver: letsencrypt
---
# Chat - chat.xiongxiao.me (支持 WebSocket)
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: chat-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`chat.xiongxiao.me`)
kind: Rule
services:
- name: chat-external
port: 3000
tls:
certResolver: letsencrypt
---
# Kevisual - kevisual.xiongxiao.me (支持 WebSocket)
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: kevisual-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`kevisual.xiongxiao.me`)
kind: Rule
services:
- name: kevisual-external
port: 3005
tls:
certResolver: letsencrypt
---
# WWW - www.xiongxiao.me (支持 WebSocket)
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: www-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`www.xiongxiao.me`)
kind: Rule
services:
- name: www-external
port: 3005
tls:
certResolver: letsencrypt
---
# Immich - immich.xiongxiao.me (支持 WebSocket)
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: immich-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`immich.xiongxiao.me`)
kind: Rule
services:
- name: immich-external
port: 2283
tls:
certResolver: letsencrypt
---
# Cloud - cloud.xiongxiao.me
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: cloud-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`cloud.xiongxiao.me`)
kind: Rule
services:
- name: cloud-external
port: 5212
tls:
certResolver: letsencrypt
---
# Docmost - docmost.xiongxiao.me (支持 WebSocket)
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: docmost-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`docmost.xiongxiao.me`)
kind: Rule
services:
- name: docmost-external
port: 3011
tls:
certResolver: letsencrypt
---
# Drawio - drawio.xiongxiao.me (支持 WebSocket)
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: drawio-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`drawio.xiongxiao.me`)
kind: Rule
services:
- name: drawio-external
port: 13000
tls:
certResolver: letsencrypt
---
# Minio - minio.xiongxiao.me (支持 WebSocket)
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: minio-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`minio.xiongxiao.me`)
kind: Rule
services:
- name: minio-external
port: 9000
tls:
certResolver: letsencrypt
---
# NPM - npm.xiongxiao.me
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: npm-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`npm.xiongxiao.me`)
kind: Rule
services:
- name: npm-external
port: 30001
tls:
certResolver: letsencrypt
---
# Gist - gist.xiongxiao.me (支持 WebSocket)
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: gist-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`gist.xiongxiao.me`)
kind: Rule
services:
- name: gist-external
port: 6157
tls:
certResolver: letsencrypt
---
# Webdav - webdav.xiongxiao.me (支持 WebSocket)
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: webdav-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`webdav.xiongxiao.me`)
kind: Rule
services:
- name: webdav-external
port: 6060
tls:
certResolver: letsencrypt
---
# ESM - esm.xiongxiao.me (支持 WebSocket)
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: esm-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`esm.xiongxiao.me`)
kind: Rule
services:
- name: esm-external
port: 12000
tls:
certResolver: letsencrypt
---
# Umami - umami.xiongxiao.me (支持 WebSocket)
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: umami-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`umami.xiongxiao.me`)
kind: Rule
services:
- name: umami-external
port: 4004
tls:
certResolver: letsencrypt
---
# PWD - pwd.xiongxiao.me
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: pwd-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`pwd.xiongxiao.me`)
kind: Rule
services:
- name: pwd-external
port: 8180
tls:
certResolver: letsencrypt
---
# Meilisearch - meilisearch.xiongxiao.me
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: meilisearch-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`meilisearch.xiongxiao.me`)
kind: Rule
services:
- name: meilisearch-external
port: 7700
tls:
certResolver: letsencrypt
---
# Memos - memos.xiongxiao.me
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: memos-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`memos.xiongxiao.me`)
kind: Rule
services:
- name: memos-external
port: 8181
tls:
certResolver: letsencrypt
---
# Gitea - git.xiongxiao.me
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: gitea-https
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`git.xiongxiao.me`)
kind: Rule
services:
- name: gitea-external
port: 3000
tls:
certResolver: letsencrypt

View File

@@ -0,0 +1,26 @@
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rancher
namespace: cattle-system
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
ingressClassName: traefik
rules:
- host: rancher.xiongxiao.me
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: rancher
port:
number: 80
tls:
- hosts:
- rancher.xiongxiao.me
secretName: tls-rancher-ingress

View File

@@ -0,0 +1,20 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: verdaccio-ingress
namespace: default
spec:
ingressClassName: traefik
rules:
- host: npm.xiongxiao.me
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: verdaccio-service
port:
number: 4873
# curl http://verdaccio-service:4873
# wget http://verdaccio-service:4873

View File

@@ -0,0 +1,474 @@
---
# 外部服务配置 - Services with Endpoints
# tags: kubernetes, services, external-services, nginx-migration, endpoints
# description: 将外部运行的服务映射为 Kubernetes Services供 Traefik IngressRoute 使用
# title: 外部服务 Kubernetes Service 配置
# createdAt: 2025-11-26
---
# Blinko 服务 (端口 3111, IP: 10.0.32.6)
apiVersion: v1
kind: Service
metadata:
name: blinko-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 3111
targetPort: 3111
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: blinko-external
namespace: default
subsets:
- addresses:
- ip: 10.0.32.6
ports:
- port: 3111
name: http
---
# Chat 服务 (端口 3000, 本地)
apiVersion: v1
kind: Service
metadata:
name: chat-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 3000
targetPort: 3000
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: chat-external
namespace: default
subsets:
- addresses:
- ip: 121.4.112.18
ports:
- port: 3000
name: http
---
# Kevisual 服务 (端口 3005, 本地)
apiVersion: v1
kind: Service
metadata:
name: kevisual-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 3005
targetPort: 3005
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: kevisual-external
namespace: default
subsets:
- addresses:
- ip: 121.4.112.18
ports:
- port: 3005
name: http
---
# WWW 服务 (端口 3005, 本地) - 与 kevisual 相同
apiVersion: v1
kind: Service
metadata:
name: www-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 3005
targetPort: 3005
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: www-external
namespace: default
subsets:
- addresses:
- ip: 121.4.112.18
ports:
- port: 3005
name: http
---
# Immich 服务 (端口 2283, 本地)
apiVersion: v1
kind: Service
metadata:
name: immich-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 2283
targetPort: 2283
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: immich-external
namespace: default
subsets:
- addresses:
- ip: 121.4.112.18
ports:
- port: 2283
name: http
---
# Cloud 服务 (端口 5212, 本地)
apiVersion: v1
kind: Service
metadata:
name: cloud-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 5212
targetPort: 5212
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: cloud-external
namespace: default
subsets:
- addresses:
- ip: 121.4.112.18
ports:
- port: 5212
name: http
---
# Docmost 服务 (端口 3011, 本地)
apiVersion: v1
kind: Service
metadata:
name: docmost-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 3011
targetPort: 3011
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: docmost-external
namespace: default
subsets:
- addresses:
- ip: 121.4.112.18
ports:
- port: 3011
name: http
---
# Drawio 服务 (端口 13000, 本地)
apiVersion: v1
kind: Service
metadata:
name: drawio-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 13000
targetPort: 13000
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: drawio-external
namespace: default
subsets:
- addresses:
- ip: 121.4.112.18
ports:
- port: 13000
name: http
---
# Minio 服务 (端口 9000, 本地)
apiVersion: v1
kind: Service
metadata:
name: minio-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 9000
targetPort: 9000
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: minio-external
namespace: default
subsets:
- addresses:
- ip: 121.4.112.18
ports:
- port: 9000
name: http
---
# NPM (Verdaccio) 服务 (端口 30001, IP: 10.0.32.6)
apiVersion: v1
kind: Service
metadata:
name: npm-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 30001
targetPort: 30001
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: npm-external
namespace: default
subsets:
- addresses:
- ip: 10.0.32.6
ports:
- port: 30001
name: http
---
# Gist 服务 (端口 6157, 本地)
apiVersion: v1
kind: Service
metadata:
name: gist-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 6157
targetPort: 6157
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: gist-external
namespace: default
subsets:
- addresses:
- ip: 121.4.112.18
ports:
- port: 6157
name: http
---
# Webdav 服务 (端口 6060, 本地)
apiVersion: v1
kind: Service
metadata:
name: webdav-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 6060
targetPort: 6060
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: webdav-external
namespace: default
subsets:
- addresses:
- ip: 121.4.112.18
ports:
- port: 6060
name: http
---
# ESM 服务 (端口 12000, 本地)
apiVersion: v1
kind: Service
metadata:
name: esm-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 12000
targetPort: 12000
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: esm-external
namespace: default
subsets:
- addresses:
- ip: 121.4.112.18
ports:
- port: 12000
name: http
---
# Umami 服务 (端口 4004, 本地)
apiVersion: v1
kind: Service
metadata:
name: umami-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 4004
targetPort: 4004
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: umami-external
namespace: default
subsets:
- addresses:
- ip: 121.4.112.18
ports:
- port: 4004
name: http
---
# PWD 服务 (端口 8180, 本地)
apiVersion: v1
kind: Service
metadata:
name: pwd-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 8180
targetPort: 8180
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: pwd-external
namespace: default
subsets:
- addresses:
- ip: 121.4.112.18
ports:
- port: 8180
name: http
---
# Meilisearch 服务 (端口 7700, 本地)
apiVersion: v1
kind: Service
metadata:
name: meilisearch-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 7700
targetPort: 7700
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: meilisearch-external
namespace: default
subsets:
- addresses:
- ip: 121.4.112.18
ports:
- port: 7700
name: http
---
# Memos 服务 (端口 8181, IP: 10.0.32.6)
apiVersion: v1
kind: Service
metadata:
name: memos-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 8181
targetPort: 8181
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: memos-external
namespace: default
subsets:
- addresses:
- ip: 10.0.32.6
ports:
- port: 8181
name: http
---
# Gitea 服务 (端口 3000, IP: 10.0.32.6)
apiVersion: v1
kind: Service
metadata:
name: gitea-external
namespace: default
spec:
type: ClusterIP
ports:
- port: 3000
targetPort: 3000
protocol: TCP
name: http
---
apiVersion: v1
kind: Endpoints
metadata:
name: gitea-external
namespace: default
subsets:
- addresses:
- ip: 10.0.32.6
ports:
- port: 3000
name: http

View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: Service
metadata:
name: verdaccio-service
spec:
selector:
machine: library
ports:
- protocol: TCP
port: 4873
targetPort: 4873
nodePort: 30001 # 可选,指定端口范围 30000-32767
type: NodePort

View File

@@ -0,0 +1,88 @@
#!/bin/bash
# 服务连通性测试脚本
# tags: kubernetes, k3s, traefik, testing, health-check
# description: 测试所有已部署服务的连通性和健康状态
# title: 服务测试脚本
# createdAt: 2025-11-26
# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
echo "======================================"
echo "服务连通性测试"
echo "======================================"
echo ""
# 定义所有服务
declare -a SERVICES=(
"blinko.xiongxiao.me"
"chat.xiongxiao.me"
"kevisual.xiongxiao.me"
"www.xiongxiao.me"
"immich.xiongxiao.me"
"cloud.xiongxiao.me"
"docmost.xiongxiao.me"
"drawio.xiongxiao.me"
"minio.xiongxiao.me"
"npm.xiongxiao.me"
"gist.xiongxiao.me"
"webdav.xiongxiao.me"
"esm.xiongxiao.me"
"umami.xiongxiao.me"
"pwd.xiongxiao.me"
"meilisearch.xiongxiao.me"
"memos.xiongxiao.me"
"git.xiongxiao.me"
)
# 统计
TOTAL=${#SERVICES[@]}
SUCCESS=0
FAILED=0
echo "测试 ${TOTAL} 个服务..."
echo ""
# 测试每个服务
for service in "${SERVICES[@]}"; do
printf "%-35s ... " "$service"
# 使用 curl 测试,允许不安全的 SSL (因为是自签名)
# 设置 5 秒超时
if curl -k -s -o /dev/null -w "%{http_code}" --max-time 5 "https://${service}" | grep -qE "^(200|301|302|401|403)$"; then
echo -e "${GREEN}✓ OK${NC}"
((SUCCESS++))
else
echo -e "${RED}✗ FAILED${NC}"
((FAILED++))
fi
done
# 显示结果
echo ""
echo "======================================"
echo "测试结果"
echo "======================================"
echo -e "总计: ${TOTAL}"
echo -e "${GREEN}成功: ${SUCCESS}${NC}"
echo -e "${RED}失败: ${FAILED}${NC}"
echo ""
if [ $FAILED -eq 0 ]; then
echo -e "${GREEN}所有服务测试通过!${NC}"
exit 0
else
echo -e "${YELLOW}部分服务测试失败,请检查:${NC}"
echo "1. Service 和 Endpoints 配置是否正确"
echo "2. 后端服务是否正常运行"
echo "3. 网络连接是否正常"
echo "4. DNS 解析是否正确"
echo ""
echo "查看详细日志:"
echo " kubectl logs -n traefik -l app=traefik"
exit 1
fi

View File

@@ -0,0 +1,35 @@
server {
server_name blinko.xiongxiao.me;
client_max_body_size 1024m;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_pass http://localhost:3111/;
proxy_pass http://10.0.32.6:3111/;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/blinko.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/blinko.xiongxiao.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = blinko.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name blinko.xiongxiao.me;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,50 @@
map $http_upgrade $connection_upgrade {
default keep-alive; #默认为keep-alive 可以支持 一般http请求
'websocket' upgrade; #如果为websocket 则为 upgrade 可升级的。
}
server {
server_name chat.xiongxiao.me;
client_max_body_size 200m;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_read_timeout 86400; # 可选的长时间保持 WebSocket 连接
proxy_pass http://localhost:3000/;
}
listen 443 ssl; # managed by Certbot
listen [::]:443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/chat.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/chat.xiongxiao.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = chat.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name chat.xiongxiao.me;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,34 @@
server {
server_name cloud.xiongxiao.me;
client_max_body_size 1024m;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:5212/;
}
listen 443 ssl; # managed by Certbot
listen [::]:443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/cloud.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/cloud.xiongxiao.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = cloud.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name cloud.xiongxiao.me;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,45 @@
map $http_upgrade $connection_upgrade {
default keep-alive; #默认为keep-alive 可以支持 一般http请求
'websocket' upgrade; #如果为websocket 则为 upgrade 可升级的。
}
server {
server_name docmost.xiongxiao.me;
client_max_body_size 1024m;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_read_timeout 86400; # 可选的长时间保持 WebSocket 连接
proxy_pass http://localhost:3011/;
}
listen 443 ssl; # managed by Certbot
listen [::]:443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/docmost.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/docmost.xiongxiao.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}server {
if ($host = docmost.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name docmost.xiongxiao.me;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,48 @@
map $http_upgrade $connection_upgrade {
default keep-alive; #默认为keep-alive 可以支持 一般http请求
'websocket' upgrade; #如果为websocket 则为 upgrade 可升级的。
}
server {
server_name drawio.xiongxiao.me;
client_max_body_size 1024m;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_read_timeout 86400; # 可选的长时间保持 WebSocket 连接
proxy_pass http://localhost:13000/;
}
listen 443 ssl; # managed by Certbot
listen [::]:443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/drawio.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/drawio.xiongxiao.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = drawio.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name drawio.xiongxiao.me;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,47 @@
map $http_upgrade $connection_upgrade {
default keep-alive; #默认为keep-alive 可以支持 一般http请求
'websocket' upgrade; #如果为websocket 则为 upgrade 可升级的。
}
server {
listen 80;
listen [::]:80;
server_name esm.xiongxiao.me;
client_max_body_size 1200m;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_read_timeout 86400; # 可选的长时间保持 WebSocket 连接
proxy_pass http://localhost:12000;
}
}
server {
server_name esm.xiongxiao.me;
location / {
# root /root/web;
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:12000;
}
client_max_body_size 2048M;
listen 443 ssl; # managed by Certbot
listen [::]:443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/esm.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/esm.xiongxiao.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

View File

@@ -0,0 +1,48 @@
map $http_upgrade $connection_upgrade {
default keep-alive; #默认为keep-alive 可以支持 一般http请求
'websocket' upgrade; #如果为websocket 则为 upgrade 可升级的。
}
server {
server_name gist.xiongxiao.me;
client_max_body_size 1024m;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_read_timeout 86400; # 可选的长时间保持 WebSocket 连接
proxy_pass http://localhost:6157/;
}
listen 443 ssl; # managed by Certbot
listen [::]:443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/gist.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/gist.xiongxiao.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = gist.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name gist.xiongxiao.me;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,39 @@
server {
#填写绑定证书的域名
server_name git.xiongxiao.me;
#把http的域名请求转成https
#rewrite ^(.*)$ https://${server_name}$1 permanent;
# return 301 https://$host$request_uri;
location / {
# root /root/web;
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_pass http://10.0.0.10:3000/;
proxy_pass http://10.0.32.6:3000/;
}
client_max_body_size 2048M;
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/git.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/git.xiongxiao.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = git.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name git.xiongxiao.me;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,50 @@
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on; # ✅ 启用 HTTP/2
server_name home.mz.xiongxiao.me;
client_max_body_size 240m;
# SSL 配置
ssl_certificate /etc/letsencrypt/live/home.mz.xiongxiao.me/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/home.mz.xiongxiao.me/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# 提升 WebSocket 支持
proxy_http_version 1.1;
location ~* \.(gif|png|jpg|css|js|woff|woff2)$ {
proxy_pass http://xionmi.mz.zxj.im:8123;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
expires 12h;
add_header Cache-Control "public";
}
location / {
proxy_pass http://xionmi.mz.zxj.im:8123/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
add_header X-Cache $upstream_cache_status;
add_header Cache-Control no-cache;
}
}
server {
listen 80;
listen [::]:80;
server_name home.mz.xiongxiao.me;
return 301 https://$host$request_uri;
}

View File

@@ -0,0 +1,48 @@
map $http_upgrade $connection_upgrade {
default keep-alive; #默认为keep-alive 可以支持 一般http请求
'websocket' upgrade; #如果为websocket 则为 upgrade 可升级的。
}
server {
server_name immich.xiongxiao.me;
client_max_body_size 1024m;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_read_timeout 86400; # 可选的长时间保持 WebSocket 连接
proxy_pass http://localhost:2283/;
}
listen 443 ssl; # managed by Certbot
listen [::]:443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/immich.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/immich.xiongxiao.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = immich.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name immich.xiongxiao.me;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,85 @@
map $http_upgrade $connection_upgrade {
default keep-alive; #默认为keep-alive 可以支持 一般http请求
'websocket' upgrade; #如果为websocket 则为 upgrade 可升级的。
}
server {
server_name kevisual.xiongxiao.me;
#add_header Access-Control-Allow-Origin *;
#add_header Access-Control-Allow-Credentials true;
#add_header Access-Control-Allow-Methods GET,POST;
client_max_body_size 200m;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_read_timeout 86400; # 可选的长时间保持 WebSocket 连接
proxy_pass http://localhost:3005/;
}
location /api/proxy {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
proxy_http_version 1.1;
proxy_read_timeout 86400; # 可选的长时间保持 WebSocket 连接
proxy_pass http://localhost:3005/api/proxy;
}
location /api {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
proxy_http_version 1.1;
proxy_read_timeout 86400; # 可选的长时间保持 WebSocket 连接
proxy_pass http://localhost:4005/api;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/kevisual.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/kevisual.xiongxiao.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = kevisual.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name kevisual.xiongxiao.me;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,42 @@
server {
server_name look-good.xiongxiao.me;
client_max_body_size 1024m;
root /var/www/book/look-good;
index index.html index.htm;
# 更安全的访问控制
location / {
try_files $uri $uri.html $uri/ =404;
}
# 隐藏 .git 等敏感文件
location ~ /\.(git|svn|hg) {
deny all;
}
# 日志路径可自定义
access_log /var/log/nginx/look-good.access.log;
error_log /var/log/nginx/look-good.error.log;
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/look-good.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/look-good.xiongxiao.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = look-good.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name look-good.xiongxiao.me;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,34 @@
server {
server_name meilisearch.xiongxiao.me;
client_max_body_size 1024m;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:7700/;
}
listen 443 ssl; # managed by Certbot
listen [::]:443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/meilisearch.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/meilisearch.xiongxiao.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = meilisearch.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name meilisearch.xiongxiao.me;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,43 @@
server {
if ($host = memos.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
#填写绑定证书的域名
server_name memos.xiongxiao.me memos.zxj.im;
#把http的域名请求转成https
rewrite ^(.*)$ https://${server_name}$1 permanent;
# return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
#填写绑定证书的域名
server_name memos.xiongxiao.me;
#网站主页路径。此路径仅供参考,具体请您按照实际目录操作。
# root /root/web;
index index.html index.htm;
#证书文件名称
#ssl_certificate /etc/nginx/conf/short.xiongxiao.me_bundle.crt;
#私钥文件名称
#ssl_certificate_key /etc/nginx/conf/short.xiongxiao.me.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
# root /root/web;
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://10.0.32.6:8181/;
}
ssl_certificate /etc/letsencrypt/live/memos.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/memos.xiongxiao.me/privkey.pem; # managed by Certbot
}

View File

@@ -0,0 +1,49 @@
map $http_upgrade $connection_upgrade {
default keep-alive; #默认为keep-alive 可以支持 一般http请求
'websocket' upgrade; #如果为websocket 则为 upgrade 可升级的。
}
server {
server_name minio.xiongxiao.me;
client_max_body_size 200m;
location / {
proxy_pass http://127.0.0.1:9000/;
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_read_timeout 86400; # 可选的长时间保持 WebSocket 连接
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/minio.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/minio.xiongxiao.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = minio.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name minio.xiongxiao.me;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,35 @@
server {
server_name npm.xiongxiao.me;
client_max_body_size 24m;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#proxy_pass http://10.0.0.10:4873/;
proxy_pass http://10.0.32.6:30001/;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/npm.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/npm.xiongxiao.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = npm.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name npm.xiongxiao.me;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,44 @@
server {
if ($host = pwd.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
#填写绑定证书的域名
server_name pwd.xiongxiao.me;
#把http的域名请求转成https
rewrite ^(.*)$ https://${server_name}$1 permanent;
# return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
#填写绑定证书的域名
server_name pwd.xiongxiao.me;
#网站主页路径。此路径仅供参考,具体请您按照实际目录操作。
# root /root/web;
index index.html index.htm;
#证书文件名称
#ssl_certificate /etc/nginx/conf/short.xiongxiao.me_bundle.crt;
#私钥文件名称
#ssl_certificate_key /etc/nginx/conf/short.xiongxiao.me.key;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
# root /root/web;
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8180/;
}
ssl_certificate /etc/letsencrypt/live/pwd.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/pwd.xiongxiao.me/privkey.pem; # managed by Certbot
}

View File

@@ -0,0 +1,47 @@
map $http_upgrade $connection_upgrade {
default keep-alive; #默认为keep-alive 可以支持 一般http请求
'websocket' upgrade; #如果为websocket 则为 upgrade 可升级的。
}
server {
server_name umami.xiongxiao.me;
index index.html;
client_max_body_size 1024m;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_read_timeout 86400; # 可选的长时间保持 WebSocket 连接
proxy_pass http://localhost:4004;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/umami.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/umami.xiongxiao.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = umami.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name umami.xiongxiao.me;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,50 @@
map $http_upgrade $connection_upgrade {
default keep-alive; #默认为keep-alive 可以支持 一般http请求
'websocket' upgrade; #如果为websocket 则为 upgrade 可升级的。
}
server {
server_name webdav.xiongxiao.me;
client_max_body_size 2024m;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_read_timeout 86400; # 可选的长时间保持 WebSocket 连接
proxy_pass http://localhost:6060;
}
listen [::]:443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/webdav.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/webdav.xiongxiao.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = webdav.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name webdav.xiongxiao.me;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,42 @@
server {
server_name www.xiongxiao.me;
index index.html index.htm index.nginx-debian.html;
client_max_body_size 24m;
location / {
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_http_version 1.1;
proxy_read_timeout 86400; # 可选的长时间保持 WebSocket 连接
proxy_pass http://localhost:3005/;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/www.xiongxiao.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/www.xiongxiao.me/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.xiongxiao.me) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name www.xiongxiao.me;
return 404; # managed by Certbot
}

View File

@@ -0,0 +1,194 @@
---
# Traefik 完整部署配置
# 包含 RBAC、Deployment、Service、IngressClass 和 Let's Encrypt SSL
# tags: traefik, ingress, ssl, https, let's encrypt, acme, kubernetes
# description: Traefik 反向代理完整配置,包含自动 SSL 证书支持(Let's Encrypt)
# title: Traefik 完整部署配置 - 含 SSL 证书
# createdAt: 2025-11-26
---
# PersistentVolume 用于存储 ACME 证书数据
apiVersion: v1
kind: PersistentVolume
metadata:
name: traefik-acme-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /data/traefik-acme
storageClassName: local-storage
---
# PersistentVolumeClaim 用于申请证书存储空间
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: traefik-acme-pvc
namespace: traefik
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-storage
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik
namespace: traefik
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: traefik-ingress-controller
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
- nodes
verbs:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- traefik.containo.us
- traefik.io
resources:
- ingressroutes
- ingressroutetcps
- ingressrouteudps
- middlewares
- middlewaretcps
- tlsoptions
- tlsstores
- traefikservices
- serverstransports
- serverstransporttcps
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: traefik-ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
name: traefik
namespace: traefik
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: traefik
namespace: traefik
labels:
app: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
hostNetwork: true
serviceAccountName: traefik
containers:
- name: traefik
image: traefik:v3.2
args:
- --api.insecure=true
- --providers.kubernetesingress
- --providers.kubernetescrd
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
# HTTP 自动重定向到 HTTPS
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
# Let's Encrypt 配置
- --certificatesresolvers.letsencrypt.acme.email=root@xiongxiao.me
- --certificatesresolvers.letsencrypt.acme.storage=/acme/acme.json
- --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web
# 使用 Let's Encrypt 生产环境(如果测试,使用 caserver)
# - --certificatesresolvers.letsencrypt.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
- --log.level=DEBUG
ports:
- name: web
containerPort: 80
- name: websecure
containerPort: 443
- name: admin
containerPort: 8080
volumeMounts:
- name: acme-storage
mountPath: /acme
volumes:
- name: acme-storage
persistentVolumeClaim:
claimName: traefik-acme-pvc
---
apiVersion: v1
kind: Service
metadata:
name: traefik
namespace: traefik
spec:
type: ClusterIP
selector:
app: traefik
ports:
- name: web
port: 80
targetPort: 80
- name: websecure
port: 443
targetPort: 443
- name: admin
port: 8080
targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: traefik
spec:
controller: traefik.io/ingress-controller

View File

@@ -0,0 +1,70 @@
#!/bin/bash
# Nginx 配置迁移卸载脚本
# tags: kubernetes, k3s, traefik, cleanup, uninstall
# description: 卸载所有已部署的外部服务和 IngressRoute 配置
# title: 卸载脚本
# createdAt: 2025-11-26
set -e
echo "======================================"
echo "卸载 K3s 外部服务配置"
echo "======================================"
echo ""
# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# 确认卸载
read -p "确认要卸载所有外部服务和 IngressRoute 配置吗?(y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${YELLOW}取消卸载${NC}"
exit 0
fi
# 删除 IngressRoute
echo ""
echo -e "${YELLOW}步骤 1/2: 删除 IngressRoute...${NC}"
if kubectl get ingressroute -n default &> /dev/null; then
kubectl delete -f k8s/xiongxiao.me/ingress/apps-ingressroute.yaml || true
echo -e "${GREEN}✓ IngressRoute 已删除${NC}"
else
echo -e "${YELLOW}无 IngressRoute 需要删除${NC}"
fi
# 删除外部服务
echo ""
echo -e "${YELLOW}步骤 2/2: 删除外部服务和 Endpoints...${NC}"
if kubectl get svc -n default | grep -q external; then
kubectl delete -f k8s/xiongxiao.me/services/external-services.yaml || true
echo -e "${GREEN}✓ 外部服务已删除${NC}"
else
echo -e "${YELLOW}无外部服务需要删除${NC}"
fi
# 验证清理
echo ""
echo -e "${YELLOW}验证清理结果...${NC}"
REMAINING_SVC=$(kubectl get svc -n default | grep -c "external" || true)
REMAINING_ROUTES=$(kubectl get ingressroute -n default 2>/dev/null | grep -c "https" || true)
if [ "$REMAINING_SVC" -eq 0 ] && [ "$REMAINING_ROUTES" -eq 0 ]; then
echo -e "${GREEN}✓ 所有配置已清理完成${NC}"
else
echo -e "${RED}警告: 仍有 ${REMAINING_SVC} 个服务和 ${REMAINING_ROUTES} 个路由${NC}"
fi
echo ""
echo -e "${GREEN}======================================"
echo "卸载完成!"
echo "======================================${NC}"
echo ""
echo -e "${YELLOW}注意: Traefik 本身未被删除${NC}"
echo "如需删除 Traefik请运行"
echo " kubectl delete -f k8s/xiongxiao.me/traefik/traefik-complete.yaml"
echo ""

View File

@@ -1,17 +1,17 @@
{ {
"name": "@kevisual/astro-simplate-template", "name": "@kevisual/k8s",
"version": "0.0.2", "version": "0.0.2",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"basename": "/root/astro-simplate-template-docs", "basename": "/root/k8s-docs",
"scripts": { "scripts": {
"dev": "astro dev", "dev": "astro dev",
"build": "astro build", "build": "astro build",
"preview": "astro preview", "preview": "astro preview",
"pub": "envision deploy ./dist -k astro-simplate-template-docs -v 0.0.2 -u", "pub": "envision deploy ./dist -k k8s-docs -v 0.0.2 -u",
"slide:dev": "slidev --open slides/index.md", "slide:dev": "slidev --open slides/index.md",
"slide:build": "slidev build slides/index.md --base /root/astro-simplate-template-slide/", "slide:build": "slidev build slides/index.md --base /root/k8s-slide/",
"slide:pub": "envision deploy ./slides/dist -k astro-simplate-template-slide -v 0.0.2 -u", "slide:pub": "envision deploy ./slides/dist -k k8s-slide -v 0.0.2 -u",
"ui": "pnpm dlx shadcn@latest add " "ui": "pnpm dlx shadcn@latest add "
}, },
"keywords": [], "keywords": [],