From 2418891634c2c88154888e37775a5560a096ca19 Mon Sep 17 00:00:00 2001 From: abearxiong Date: Wed, 26 Nov 2025 15:44:15 +0800 Subject: [PATCH] temp --- k8s/xiongxiao.me/README.md | 274 ++++++++++ k8s/xiongxiao.me/config/master-token.md | 19 + k8s/xiongxiao.me/config/registry.md | 78 +++ k8s/xiongxiao.me/deploy-apps.sh | 91 ++++ .../deployment/verdaccio-deployment.yaml | 63 +++ k8s/xiongxiao.me/docs/00-master.md | 47 ++ k8s/xiongxiao.me/docs/01-local-m.md | 13 + k8s/xiongxiao.me/docs/02-traefik.md | 204 ++++++++ k8s/xiongxiao.me/docs/03-dns.md | 16 + k8s/xiongxiao.me/docs/04-host-service.md | 292 +++++++++++ k8s/xiongxiao.me/docs/05-rancher.md | 18 + k8s/xiongxiao.me/docs/06-traefik-ssl.md | 176 +++++++ k8s/xiongxiao.me/docs/07-nginx-migration.md | 289 +++++++++++ .../ingress/apps-ingressroute.yaml | 330 ++++++++++++ k8s/xiongxiao.me/ingress/rancher-ingress.yaml | 26 + .../ingress/verdaccio-ingress.yaml | 20 + .../services/external-services.yaml | 474 ++++++++++++++++++ .../services/verdaccio-services.yaml | 13 + k8s/xiongxiao.me/test-services.sh | 88 ++++ k8s/xiongxiao.me/todos/nginx/blinko.conf | 35 ++ k8s/xiongxiao.me/todos/nginx/chat.conf | 50 ++ k8s/xiongxiao.me/todos/nginx/cloud.conf | 34 ++ k8s/xiongxiao.me/todos/nginx/docmost.conf | 45 ++ k8s/xiongxiao.me/todos/nginx/drawio.conf | 48 ++ k8s/xiongxiao.me/todos/nginx/esm.conf | 47 ++ k8s/xiongxiao.me/todos/nginx/gist.conf | 48 ++ k8s/xiongxiao.me/todos/nginx/git.xx.conf | 39 ++ k8s/xiongxiao.me/todos/nginx/home.mz.conf | 50 ++ k8s/xiongxiao.me/todos/nginx/immich.conf | 48 ++ k8s/xiongxiao.me/todos/nginx/kevisual.conf | 85 ++++ k8s/xiongxiao.me/todos/nginx/look-good.conf | 42 ++ k8s/xiongxiao.me/todos/nginx/meilisearch.conf | 34 ++ k8s/xiongxiao.me/todos/nginx/memos.conf | 43 ++ k8s/xiongxiao.me/todos/nginx/minio.conf | 49 ++ k8s/xiongxiao.me/todos/nginx/npm.conf | 35 ++ k8s/xiongxiao.me/todos/nginx/pwd.conf | 44 ++ k8s/xiongxiao.me/todos/nginx/unami.conf | 47 ++ k8s/xiongxiao.me/todos/nginx/webdav.conf | 50 ++ .../todos/nginx/www.xiongxiao.me.conf | 42 ++ .../traefik/traefik-complete.yaml | 194 +++++++ k8s/xiongxiao.me/undeploy-apps.sh | 70 +++ package.json | 10 +- 42 files changed, 3715 insertions(+), 5 deletions(-) create mode 100644 k8s/xiongxiao.me/README.md create mode 100644 k8s/xiongxiao.me/config/master-token.md create mode 100644 k8s/xiongxiao.me/config/registry.md create mode 100755 k8s/xiongxiao.me/deploy-apps.sh create mode 100644 k8s/xiongxiao.me/deployment/verdaccio-deployment.yaml create mode 100644 k8s/xiongxiao.me/docs/00-master.md create mode 100644 k8s/xiongxiao.me/docs/01-local-m.md create mode 100644 k8s/xiongxiao.me/docs/02-traefik.md create mode 100644 k8s/xiongxiao.me/docs/03-dns.md create mode 100644 k8s/xiongxiao.me/docs/04-host-service.md create mode 100644 k8s/xiongxiao.me/docs/05-rancher.md create mode 100644 k8s/xiongxiao.me/docs/06-traefik-ssl.md create mode 100644 k8s/xiongxiao.me/docs/07-nginx-migration.md create mode 100644 k8s/xiongxiao.me/ingress/apps-ingressroute.yaml create mode 100644 k8s/xiongxiao.me/ingress/rancher-ingress.yaml create mode 100644 k8s/xiongxiao.me/ingress/verdaccio-ingress.yaml create mode 100644 k8s/xiongxiao.me/services/external-services.yaml create mode 100644 k8s/xiongxiao.me/services/verdaccio-services.yaml create mode 100755 k8s/xiongxiao.me/test-services.sh create mode 100644 k8s/xiongxiao.me/todos/nginx/blinko.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/chat.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/cloud.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/docmost.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/drawio.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/esm.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/gist.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/git.xx.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/home.mz.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/immich.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/kevisual.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/look-good.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/meilisearch.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/memos.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/minio.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/npm.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/pwd.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/unami.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/webdav.conf create mode 100644 k8s/xiongxiao.me/todos/nginx/www.xiongxiao.me.conf create mode 100644 k8s/xiongxiao.me/traefik/traefik-complete.yaml create mode 100755 k8s/xiongxiao.me/undeploy-apps.sh diff --git a/k8s/xiongxiao.me/README.md b/k8s/xiongxiao.me/README.md new file mode 100644 index 0000000..aa33b0f --- /dev/null +++ b/k8s/xiongxiao.me/README.md @@ -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) +- [ ] 集成监控和告警 +- [ ] 配置备份策略 +- [ ] 文档化运维流程 diff --git a/k8s/xiongxiao.me/config/master-token.md b/k8s/xiongxiao.me/config/master-token.md new file mode 100644 index 0000000..a1f42b3 --- /dev/null +++ b/k8s/xiongxiao.me/config/master-token.md @@ -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 \ No newline at end of file diff --git a/k8s/xiongxiao.me/config/registry.md b/k8s/xiongxiao.me/config/registry.md new file mode 100644 index 0000000..ca9c25a --- /dev/null +++ b/k8s/xiongxiao.me/config/registry.md @@ -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 +``` \ No newline at end of file diff --git a/k8s/xiongxiao.me/deploy-apps.sh b/k8s/xiongxiao.me/deploy-apps.sh new file mode 100755 index 0000000..345978d --- /dev/null +++ b/k8s/xiongxiao.me/deploy-apps.sh @@ -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 "" diff --git a/k8s/xiongxiao.me/deployment/verdaccio-deployment.yaml b/k8s/xiongxiao.me/deployment/verdaccio-deployment.yaml new file mode 100644 index 0000000..2c5e467 --- /dev/null +++ b/k8s/xiongxiao.me/deployment/verdaccio-deployment.yaml @@ -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 \ No newline at end of file diff --git a/k8s/xiongxiao.me/docs/00-master.md b/k8s/xiongxiao.me/docs/00-master.md new file mode 100644 index 0000000..5272afc --- /dev/null +++ b/k8s/xiongxiao.me/docs/00-master.md @@ -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 role= --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 +``` \ No newline at end of file diff --git a/k8s/xiongxiao.me/docs/01-local-m.md b/k8s/xiongxiao.me/docs/01-local-m.md new file mode 100644 index 0000000..5aa61fa --- /dev/null +++ b/k8s/xiongxiao.me/docs/01-local-m.md @@ -0,0 +1,13 @@ +# 本地管理 + +## 安装 + +```sh +brew install kubectl +``` + +## 查看配置 + +```sh +cat /etc/rancher/k3s/k3s.yaml +``` \ No newline at end of file diff --git a/k8s/xiongxiao.me/docs/02-traefik.md b/k8s/xiongxiao.me/docs/02-traefik.md new file mode 100644 index 0000000..1d7622f --- /dev/null +++ b/k8s/xiongxiao.me/docs/02-traefik.md @@ -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 +- Controller:traefik.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 \ No newline at end of file diff --git a/k8s/xiongxiao.me/docs/03-dns.md b/k8s/xiongxiao.me/docs/03-dns.md new file mode 100644 index 0000000..be08d24 --- /dev/null +++ b/k8s/xiongxiao.me/docs/03-dns.md @@ -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 +``` \ No newline at end of file diff --git a/k8s/xiongxiao.me/docs/04-host-service.md b/k8s/xiongxiao.me/docs/04-host-service.md new file mode 100644 index 0000000..78c9358 --- /dev/null +++ b/k8s/xiongxiao.me/docs/04-host-service.md @@ -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 文件中添加: + +``` + 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/) diff --git a/k8s/xiongxiao.me/docs/05-rancher.md b/k8s/xiongxiao.me/docs/05-rancher.md new file mode 100644 index 0000000..eacd7b3 --- /dev/null +++ b/k8s/xiongxiao.me/docs/05-rancher.md @@ -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 + +``` \ No newline at end of file diff --git a/k8s/xiongxiao.me/docs/06-traefik-ssl.md b/k8s/xiongxiao.me/docs/06-traefik-ssl.md new file mode 100644 index 0000000..69bb407 --- /dev/null +++ b/k8s/xiongxiao.me/docs/06-traefik-ssl.md @@ -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) diff --git a/k8s/xiongxiao.me/docs/07-nginx-migration.md b/k8s/xiongxiao.me/docs/07-nginx-migration.md new file mode 100644 index 0000000..c0bf075 --- /dev/null +++ b/k8s/xiongxiao.me/docs/07-nginx-migration.md @@ -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 +``` + +2. 检查 IngressRoute +```bash +kubectl describe ingressroute -n default +``` + +3. 检查 Traefik 日志 +```bash +kubectl logs -n traefik -l app=traefik +``` + +### SSL 证书问题 + +1. 检查证书文件 +```bash +kubectl exec -n traefik -- 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/) diff --git a/k8s/xiongxiao.me/ingress/apps-ingressroute.yaml b/k8s/xiongxiao.me/ingress/apps-ingressroute.yaml new file mode 100644 index 0000000..814ad41 --- /dev/null +++ b/k8s/xiongxiao.me/ingress/apps-ingressroute.yaml @@ -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 diff --git a/k8s/xiongxiao.me/ingress/rancher-ingress.yaml b/k8s/xiongxiao.me/ingress/rancher-ingress.yaml new file mode 100644 index 0000000..00e40a2 --- /dev/null +++ b/k8s/xiongxiao.me/ingress/rancher-ingress.yaml @@ -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 diff --git a/k8s/xiongxiao.me/ingress/verdaccio-ingress.yaml b/k8s/xiongxiao.me/ingress/verdaccio-ingress.yaml new file mode 100644 index 0000000..be56cef --- /dev/null +++ b/k8s/xiongxiao.me/ingress/verdaccio-ingress.yaml @@ -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 \ No newline at end of file diff --git a/k8s/xiongxiao.me/services/external-services.yaml b/k8s/xiongxiao.me/services/external-services.yaml new file mode 100644 index 0000000..b919c17 --- /dev/null +++ b/k8s/xiongxiao.me/services/external-services.yaml @@ -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 diff --git a/k8s/xiongxiao.me/services/verdaccio-services.yaml b/k8s/xiongxiao.me/services/verdaccio-services.yaml new file mode 100644 index 0000000..5bb84ce --- /dev/null +++ b/k8s/xiongxiao.me/services/verdaccio-services.yaml @@ -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 \ No newline at end of file diff --git a/k8s/xiongxiao.me/test-services.sh b/k8s/xiongxiao.me/test-services.sh new file mode 100755 index 0000000..bd2ffe7 --- /dev/null +++ b/k8s/xiongxiao.me/test-services.sh @@ -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 diff --git a/k8s/xiongxiao.me/todos/nginx/blinko.conf b/k8s/xiongxiao.me/todos/nginx/blinko.conf new file mode 100644 index 0000000..74bb5de --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/blinko.conf @@ -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 + + +} diff --git a/k8s/xiongxiao.me/todos/nginx/chat.conf b/k8s/xiongxiao.me/todos/nginx/chat.conf new file mode 100644 index 0000000..82f4faa --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/chat.conf @@ -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 + + +} \ No newline at end of file diff --git a/k8s/xiongxiao.me/todos/nginx/cloud.conf b/k8s/xiongxiao.me/todos/nginx/cloud.conf new file mode 100644 index 0000000..29b1964 --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/cloud.conf @@ -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 + + +} \ No newline at end of file diff --git a/k8s/xiongxiao.me/todos/nginx/docmost.conf b/k8s/xiongxiao.me/todos/nginx/docmost.conf new file mode 100644 index 0000000..5e440eb --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/docmost.conf @@ -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 + + +} \ No newline at end of file diff --git a/k8s/xiongxiao.me/todos/nginx/drawio.conf b/k8s/xiongxiao.me/todos/nginx/drawio.conf new file mode 100644 index 0000000..31c54d8 --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/drawio.conf @@ -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 + + +} \ No newline at end of file diff --git a/k8s/xiongxiao.me/todos/nginx/esm.conf b/k8s/xiongxiao.me/todos/nginx/esm.conf new file mode 100644 index 0000000..2b372ec --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/esm.conf @@ -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 +} + diff --git a/k8s/xiongxiao.me/todos/nginx/gist.conf b/k8s/xiongxiao.me/todos/nginx/gist.conf new file mode 100644 index 0000000..9cb7a7a --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/gist.conf @@ -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 + + +} \ No newline at end of file diff --git a/k8s/xiongxiao.me/todos/nginx/git.xx.conf b/k8s/xiongxiao.me/todos/nginx/git.xx.conf new file mode 100644 index 0000000..cafe604 --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/git.xx.conf @@ -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 + + +} diff --git a/k8s/xiongxiao.me/todos/nginx/home.mz.conf b/k8s/xiongxiao.me/todos/nginx/home.mz.conf new file mode 100644 index 0000000..bb0feab --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/home.mz.conf @@ -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; +} diff --git a/k8s/xiongxiao.me/todos/nginx/immich.conf b/k8s/xiongxiao.me/todos/nginx/immich.conf new file mode 100644 index 0000000..f380e54 --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/immich.conf @@ -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 + + +} \ No newline at end of file diff --git a/k8s/xiongxiao.me/todos/nginx/kevisual.conf b/k8s/xiongxiao.me/todos/nginx/kevisual.conf new file mode 100644 index 0000000..456b5df --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/kevisual.conf @@ -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 + + +} diff --git a/k8s/xiongxiao.me/todos/nginx/look-good.conf b/k8s/xiongxiao.me/todos/nginx/look-good.conf new file mode 100644 index 0000000..56e85c0 --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/look-good.conf @@ -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 + + +} diff --git a/k8s/xiongxiao.me/todos/nginx/meilisearch.conf b/k8s/xiongxiao.me/todos/nginx/meilisearch.conf new file mode 100644 index 0000000..975cbdf --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/meilisearch.conf @@ -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 + + +} \ No newline at end of file diff --git a/k8s/xiongxiao.me/todos/nginx/memos.conf b/k8s/xiongxiao.me/todos/nginx/memos.conf new file mode 100644 index 0000000..f1a6b77 --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/memos.conf @@ -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 + +} diff --git a/k8s/xiongxiao.me/todos/nginx/minio.conf b/k8s/xiongxiao.me/todos/nginx/minio.conf new file mode 100644 index 0000000..25a2894 --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/minio.conf @@ -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 + + +} diff --git a/k8s/xiongxiao.me/todos/nginx/npm.conf b/k8s/xiongxiao.me/todos/nginx/npm.conf new file mode 100644 index 0000000..ab4487e --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/npm.conf @@ -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 + + +} diff --git a/k8s/xiongxiao.me/todos/nginx/pwd.conf b/k8s/xiongxiao.me/todos/nginx/pwd.conf new file mode 100644 index 0000000..057b13a --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/pwd.conf @@ -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 +} + diff --git a/k8s/xiongxiao.me/todos/nginx/unami.conf b/k8s/xiongxiao.me/todos/nginx/unami.conf new file mode 100644 index 0000000..6560313 --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/unami.conf @@ -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 + + +} diff --git a/k8s/xiongxiao.me/todos/nginx/webdav.conf b/k8s/xiongxiao.me/todos/nginx/webdav.conf new file mode 100644 index 0000000..b34ee59 --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/webdav.conf @@ -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 + + +} \ No newline at end of file diff --git a/k8s/xiongxiao.me/todos/nginx/www.xiongxiao.me.conf b/k8s/xiongxiao.me/todos/nginx/www.xiongxiao.me.conf new file mode 100644 index 0000000..bab803a --- /dev/null +++ b/k8s/xiongxiao.me/todos/nginx/www.xiongxiao.me.conf @@ -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 + + +} diff --git a/k8s/xiongxiao.me/traefik/traefik-complete.yaml b/k8s/xiongxiao.me/traefik/traefik-complete.yaml new file mode 100644 index 0000000..31bf74c --- /dev/null +++ b/k8s/xiongxiao.me/traefik/traefik-complete.yaml @@ -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 \ No newline at end of file diff --git a/k8s/xiongxiao.me/undeploy-apps.sh b/k8s/xiongxiao.me/undeploy-apps.sh new file mode 100755 index 0000000..720d3a2 --- /dev/null +++ b/k8s/xiongxiao.me/undeploy-apps.sh @@ -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 "" diff --git a/package.json b/package.json index 37397b9..f571969 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,17 @@ { - "name": "@kevisual/astro-simplate-template", + "name": "@kevisual/k8s", "version": "0.0.2", "description": "", "main": "index.js", - "basename": "/root/astro-simplate-template-docs", + "basename": "/root/k8s-docs", "scripts": { "dev": "astro dev", "build": "astro build", "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:build": "slidev build slides/index.md --base /root/astro-simplate-template-slide/", - "slide:pub": "envision deploy ./slides/dist -k astro-simplate-template-slide -v 0.0.2 -u", + "slide:build": "slidev build slides/index.md --base /root/k8s-slide/", + "slide:pub": "envision deploy ./slides/dist -k k8s-slide -v 0.0.2 -u", "ui": "pnpm dlx shadcn@latest add " }, "keywords": [],