实现完整的自动化运维方案,包括自动启动、健康检查和数据备份。 ## 新增功能 ### 1. OrbStack 自动启动 - macOS 登录时自动启动 OrbStack - 等待 Kubernetes 集群就绪 - 检查关键服务状态 - 配置文件:scripts/auto-start-orbstack.sh - LaunchAgent:scripts/com.orbstack.auto-start.plist ### 2. 定时健康检查 - 每 15 分钟自动检查集群状态 - 检查所有关键 Pod、Service、Ingress - 自动重启异常的 Deployment/StatefulSet - 详细日志记录 - 脚本:scripts/health-check.sh ### 3. 定时数据备份 - 每天凌晨 2:00 自动备份 - 备份内容: - PostgreSQL 所有数据库 - Redis RDB 快照 - Kubernetes 配置(Ingress, ConfigMap, Secret, PVC) - Helm Values 文件 - 自动压缩和清理(保留 7 天) - 脚本:scripts/auto-backup.sh ### 4. 一键配置脚本 - scripts/setup-automation.sh - 自动配置所有 LaunchAgent 和 crontab - 测试所有脚本运行状态 - 显示配置摘要 ## 文档 - 新增详细文档:docs/automation-guide.md - 包含使用说明、故障排查、高级配置 - 更新 README.md 添加自动化部分 ## 使用方法 ```bash # 一键配置所有自动化功能 ./scripts/setup-automation.sh # 手动运行各个脚本 ./scripts/health-check.sh # 健康检查 ./scripts/auto-backup.sh # 立即备份 ``` ## 日志位置 - OrbStack 自动启动:~/.orbstack-auto-start.log - 健康检查:~/.k8s-health-check.log - 数据备份:~/k8s-backups/backup.log 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
OrbStack Kubernetes 基础设施
这是一套完整的 Kubernetes 基础设施方案,运行在 OrbStack 自带的 k8s 上,为所有业务线(健康平台、股票推荐、学习助手、AI 服务等)提供统一的基础层。
整体架构
分层设计
┌─────────────────────────────────────────────────────────────┐
│ L0: 宿主机层(Mac Studio) │
│ - Gitea(代码仓库) │
│ - Gitea Runner(CI/CD) │
│ - Harbor(镜像仓库 + Docker Hub Proxy) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ L1: Kubernetes 核心层(infra namespace) │
│ - ingress-nginx(统一入口,监听 30080 端口) │
│ - StorageClass(持久化存储) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ L2: 数据服务层(data namespace) │
│ - PostgreSQL(主力数据库) │
│ - Redis(缓存 + Session + 队列) │
│ - MySQL(可选,仅在有依赖时安装) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ L3: 可观测性层(observability namespace) │
│ - Prometheus + Grafana(监控 + 可视化) │
│ - Loki + Promtail(日志采集 + 查询) │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 业务应用层 │
│ - 健康平台(health namespace) │
│ - 股票推荐(stock namespace) │
│ - 学习助手(learn namespace) │
│ - AI 服务(ai namespace) │
└─────────────────────────────────────────────────────────────┘
流量路径
外网请求
↓
Contabo Nginx(反向代理)
↓
WireGuard VPN(10.7.0.0/24)
↓
Mac Studio:30080(ingress-nginx)
↓
各业务 Service(根据域名路由)
快速开始
前置要求
- OrbStack:已安装并启动 OrbStack,Kubernetes 功能已开启
- Helm:版本 >= 3.0
- kubectl:已配置好 OrbStack k8s 的 context
检查环境
# 检查 kubectl 连接
kubectl cluster-info
# 检查 Helm
helm version
# 确认当前 context 是 OrbStack
kubectl config current-context
一键部署
# 进入项目目录
cd orbstack-k8s-infra
# 运行初始化脚本(不安装 MySQL)
./init-orbstack-k8s-infra.sh
# 如果需要 MySQL,添加 --enable-mysql 参数
./init-orbstack-k8s-infra.sh --enable-mysql
脚本会自动:
- 创建所需的 namespace(infra, data, observability)
- 添加并更新 Helm 仓库
- 按顺序部署所有组件
- 验证部署状态
- 打印访问信息
部署时间
首次部署大约需要 10-15 分钟,主要时间花在:
- 下载 Helm charts
- 拉取容器镜像
- 等待 Pod 就绪
🤖 配置全自动运行(可选)
一键配置所有自动化功能:
./scripts/setup-automation.sh
这将配置:
- ✅ OrbStack 登录时自动启动
- ✅ 每 15 分钟健康检查和自动修复
- ✅ 每天凌晨 2:00 自动备份数据
📚 详细说明请参考:自动化运维指南
登录信息汇总
⚠️ 安全提示:以下为开发环境的默认密码,生产环境务必修改!
PostgreSQL
| 项目 | 值 |
|---|---|
| 服务地址(集群内) | postgres-postgresql.data.svc.cluster.local:5432 |
| 服务地址(端口转发) | localhost:5432 |
| 管理员用户 | postgres |
| 管理员密码 | admin123 |
| 应用用户 | appuser |
| 应用密码 | appuser123 |
| 预置数据库 | health_db, stock_db, learn_db, ai_db |
连接示例:
# 集群内连接
postgresql://appuser:[email protected]:5432/health_db
# 端口转发后连接
kubectl port-forward -n data svc/postgres-postgresql 5432:5432
psql -h localhost -U appuser -d health_db
# 密码: appuser123
Redis
| 项目 | 值 |
|---|---|
| 服务地址(集群内) | redis-master.data.svc.cluster.local:6379 |
| 服务地址(端口转发) | localhost:6379 |
| 密码 | redis123 |
| DB 0 | 健康平台 (health) |
| DB 1 | 股票推荐 (stock) |
| DB 2 | 学习助手 (learn) |
| DB 3 | AI 服务 (ai) |
| DB 4-15 | 预留 |
连接示例:
# 集群内连接
redis://:[email protected]:6379/0
# 端口转发后连接
kubectl port-forward -n data svc/redis-master 6379:6379
redis-cli -h localhost -a redis123
# 选择数据库: SELECT 0
MySQL(可选)
| 项目 | 值 |
|---|---|
| 服务地址(集群内) | mysql.data.svc.cluster.local:3306 |
| 服务地址(端口转发) | localhost:3306 |
| Root 密码 | root123 |
| 应用用户 | appuser |
| 应用密码 | appuser123 |
| 默认数据库 | appdb |
连接示例:
# 集群内连接
mysql://appuser:[email protected]:3306/appdb
# 端口转发后连接
kubectl port-forward -n data svc/mysql 3306:3306
mysql -h localhost -u appuser -p
# 密码: appuser123
监控服务(统一域名访问)
🌐 统一访问入口: https://monitor.omniverseai.net
| 服务 | 路径 | 说明 |
|---|---|---|
| Grafana | / 或 /grafana |
监控仪表板(默认) |
| Prometheus | /prometheus |
指标查询和浏览 |
| Alertmanager | /alertmanager |
告警管理 |
访问方式 1:域名访问(推荐)
# Grafana(默认路径会自动重定向到 /grafana)
https://monitor.omniverseai.net/
https://monitor.omniverseai.net/grafana
# Prometheus
https://monitor.omniverseai.net/prometheus
# Alertmanager
https://monitor.omniverseai.net/alertmanager
访问方式 2:端口转发
# Grafana
kubectl port-forward -n observability svc/monitoring-grafana 3000:80
# 浏览器访问: http://localhost:3000
# Prometheus
kubectl port-forward -n observability svc/monitoring-kube-prometheus-prometheus 9090:9090
# 浏览器访问: http://localhost:9090
# Alertmanager
kubectl port-forward -n observability svc/monitoring-kube-prometheus-alertmanager 9093:9093
# 浏览器访问: http://localhost:9093
登录信息(Grafana):
- 用户名:
admin - 密码:
admin123
预置数据源:
- Prometheus(默认):
http://monitoring-kube-prometheus-prometheus.observability.svc.cluster.local:9090 - Loki:
http://loki.observability.svc.cluster.local:3100
快速测试路由:
# 运行测试脚本
./scripts/test-monitoring-routes.sh
📝 详细的路由配置说明请参考:docs/monitoring-ingress-setup.md
Loki(日志查询)
| 项目 | 值 |
|---|---|
| 服务地址(集群内) | loki.observability.svc.cluster.local:3100 |
| 查询界面 | 通过 Grafana → Explore → 选择 Loki 数据源 |
查询示例:
# 在 Grafana Explore 中使用 LogQL 查询:
# 查看所有 data namespace 的日志
{namespace="data"}
# 查看 PostgreSQL 日志
{namespace="data", pod=~"postgres-.*"}
# 查看包含错误的日志
{namespace="data"} |= "error"
# 按时间范围查询
{namespace="data"} | json | level="error"
Harbor(镜像仓库,L0 层宿主机)
| 项目 | 值 |
|---|---|
| Web UI | https://harbor.omniverseai.net |
| 用户名 | 根据 Harbor 部署配置 |
| 密码 | 根据 Harbor 部署配置 |
| Docker 登录 | docker login harbor.omniverseai.net |
Gitea(代码仓库,L0 层宿主机)
| 项目 | 值 |
|---|---|
| Web UI | https://gitea.omniverseai.net |
| 用户名 | 根据 Gitea 配置 |
| 密码 | 根据 Gitea 配置 |
快速访问命令
# 一键打开所有端口转发
cat > /tmp/port-forward-all.sh << 'EOF'
#!/bin/bash
kubectl port-forward -n data svc/postgres-postgresql 5432:5432 &
kubectl port-forward -n data svc/redis-master 6379:6379 &
kubectl port-forward -n observability svc/monitoring-grafana 3000:80 &
kubectl port-forward -n observability svc/monitoring-kube-prometheus-prometheus 9090:9090 &
kubectl port-forward -n observability svc/monitoring-kube-prometheus-alertmanager 9093:9093 &
echo "所有端口转发已启动!"
echo "PostgreSQL: localhost:5432 (appuser/appuser123)"
echo "Redis: localhost:6379 (密码: redis123)"
echo "Grafana: http://localhost:3000 (admin/admin123)"
echo "Prometheus: http://localhost:9090"
echo "AlertManager: http://localhost:9093"
echo ""
echo "按 Ctrl+C 停止所有端口转发"
wait
EOF
chmod +x /tmp/port-forward-all.sh
/tmp/port-forward-all.sh
组件说明
L1: 核心层
ingress-nginx
- 作用:统一的 HTTP/HTTPS 入口,负责路由流量到各业务服务
- 监听端口:30080(HTTP)、30443(HTTPS)
- 配置文件:
values/ingress-nginx-values.yaml - 关键特性:
- 使用 hostNetwork 模式,直接监听宿主机端口
- 支持大文件上传(100MB)
- 自动暴露 metrics 给 Prometheus
验证:
# 检查服务状态
kubectl get pods -n infra
# 测试本地访问(应返回 404)
curl http://127.0.0.1:30080
# 从 Contabo 测试(需先配置 WireGuard)
curl http://10.7.0.2:30080
L2: 数据服务层
PostgreSQL
- 作用:统一的关系型数据库,支持多业务
- 配置文件:
values/postgres-values.yaml - 连接信息:
- 主机:
postgres-postgresql.data.svc.cluster.local - 端口:
5432 - 管理员用户:
postgres/admin123 - 应用用户:
appuser/appuser123
- 主机:
预置数据库:
health_db:健康平台stock_db:股票推荐learn_db:学习助手ai_db:AI 服务
连接示例:
# 从集群内连接
kubectl run -it --rm psql --image=postgres:15 --restart=Never -- \
psql -h postgres-postgresql.data.svc.cluster.local \
-U appuser -d health_db
# 端口转发到本地
kubectl port-forward -n data svc/postgres-postgresql 5432:5432
# 使用本地工具连接
psql -h localhost -U appuser -d health_db
Redis
- 作用:统一的缓存、Session 存储、简单队列
- 配置文件:
values/redis-values.yaml - 连接信息:
- 主机:
redis-master.data.svc.cluster.local - 端口:
6379 - 密码:
redis123
- 主机:
DB 分配:
- DB 0:健康平台
- DB 1:股票推荐
- DB 2:学习助手
- DB 3:AI 服务
- DB 4-15:预留
连接示例:
# 从集群内连接
kubectl run -it --rm redis-cli --image=redis:7 --restart=Never -- \
redis-cli -h redis-master.data.svc.cluster.local -a redis123
# 端口转发到本地
kubectl port-forward -n data svc/redis-master 6379:6379
# 使用本地 redis-cli 连接
redis-cli -h localhost -a redis123
MySQL(可选)
- 作用:仅在有历史项目或三方依赖时安装
- 配置文件:
values/mysql-values.yaml - 连接信息:
- 主机:
mysql.data.svc.cluster.local - 端口:
3306 - 用户:
appuser/appuser123
- 主机:
L3: 可观测性层
Prometheus + Grafana
- 作用:监控所有 k8s 资源和业务指标
- 配置文件:
values/kube-prometheus-stack-values.yaml
Grafana 访问:
# 方式 1:域名访问(需配置 DNS 和 Ingress)
# https://monitor.omniverseai.net
# 方式 2:端口转发
kubectl port-forward -n observability svc/monitoring-grafana 3000:80
# 访问 http://localhost:3000
# 用户名:admin
# 密码:admin123
预置 Dashboard:
- Kubernetes Cluster Overview(ID: 7249)
- Node Exporter(ID: 1860)
- Ingress Nginx(ID: 9614)
Loki + Promtail
- 作用:采集和查询所有 Pod 日志
- 配置文件:
values/loki-values.yaml - 访问:通过 Grafana 的 Explore 功能
查询日志示例:
# 在 Grafana 中切换到 Loki 数据源,使用 LogQL 查询:
# 查看某个 namespace 的日志
{namespace="data"}
# 查看某个 Pod 的日志
{namespace="data", pod="postgres-postgresql-0"}
# 查看包含错误的日志
{namespace="data"} |= "error"
# 查看特定容器的日志
{namespace="data", container="postgresql"}
业务应用接入
1. 创建业务 Namespace
# 以健康平台为例
kubectl create namespace health
2. 部署应用
使用 Helm 或直接 apply YAML:
# health-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: health-api
namespace: health
spec:
replicas: 2
selector:
matchLabels:
app: health-api
template:
metadata:
labels:
app: health-api
spec:
containers:
- name: api
image: harbor.omniverseai.net/health/api:latest
env:
- name: DATABASE_URL
value: postgresql://appuser:[email protected]:5432/health_db
- name: REDIS_URL
value: redis://:[email protected]:6379/0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: health-api
namespace: health
spec:
selector:
app: health-api
ports:
- port: 80
targetPort: 8080
3. 配置 Ingress
# health-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: health-ingress
namespace: health
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod" # 如有 cert-manager
spec:
ingressClassName: nginx
rules:
- host: health.omniverseai.net
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: health-api
port:
number: 80
tls:
- hosts:
- health.omniverseai.net
secretName: health-tls
4. 在 Contabo 配置反向代理
在 Contabo 的 Nginx 配置中添加:
# /etc/nginx/sites-available/health.omniverseai.net
server {
listen 80;
server_name health.omniverseai.net;
location / {
proxy_pass http://10.7.0.2:30080;
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;
}
}
运维操作
查看资源状态
# 查看所有 Pod
kubectl get pods -A
# 查看所有 Service
kubectl get svc -A
# 查看所有 Ingress
kubectl get ingress -A
# 查看存储
kubectl get pvc -A
查看日志
# 查看 Pod 日志
kubectl logs -n data postgres-postgresql-0
# 实时查看日志
kubectl logs -n data postgres-postgresql-0 -f
# 查看前一个容器的日志(容器崩溃时)
kubectl logs -n data postgres-postgresql-0 --previous
备份和恢复
PostgreSQL 备份
# 备份单个数据库
kubectl exec -n data postgres-postgresql-0 -- \
pg_dump -U appuser health_db > health_db_backup.sql
# 备份所有数据库
kubectl exec -n data postgres-postgresql-0 -- \
pg_dumpall -U postgres > all_databases_backup.sql
Redis 备份
# 手动触发持久化
kubectl exec -n data redis-master-0 -- redis-cli -a redis123 BGSAVE
# 复制 RDB 文件
kubectl cp data/redis-master-0:/data/dump.rdb ./redis_backup.rdb
更新配置
修改 values/*.yaml 文件后,重新部署:
# 更新 ingress-nginx
helm upgrade ingress-nginx ingress-nginx/ingress-nginx \
-n infra \
-f values/ingress-nginx-values.yaml
# 更新 Postgres
helm upgrade postgres bitnami/postgresql \
-n data \
-f values/postgres-values.yaml
扩缩容
# 扩容 Deployment
kubectl scale deployment -n health health-api --replicas=5
# 查看 HPA(如已配置)
kubectl get hpa -n health
故障排查
ingress-nginx 无法访问
# 检查 Pod 状态
kubectl get pods -n infra
# 查看日志
kubectl logs -n infra -l app.kubernetes.io/name=ingress-nginx
# 检查端口监听
ss -tlnp | grep 30080
# 测试内部访问
kubectl run -it --rm curl --image=curlimages/curl --restart=Never -- \
curl http://ingress-nginx-controller.infra.svc.cluster.local
数据库连接失败
# 检查 Pod 状态
kubectl get pods -n data
# 查看详细信息
kubectl describe pod -n data postgres-postgresql-0
# 检查 Service
kubectl get svc -n data
# 测试 DNS 解析
kubectl run -it --rm busybox --image=busybox --restart=Never -- \
nslookup postgres-postgresql.data.svc.cluster.local
Prometheus/Grafana 无法访问
# 检查 Pod 状态
kubectl get pods -n observability
# 查看 Grafana 日志
kubectl logs -n observability -l app.kubernetes.io/name=grafana
# 重置 Grafana 密码
kubectl exec -n observability -it \
$(kubectl get pod -n observability -l app.kubernetes.io/name=grafana -o name) -- \
grafana-cli admin reset-admin-password newpassword
重新初始化
如果需要完全重置:
方式 1:删除 Helm Releases
# 删除所有组件
helm uninstall loki -n observability
helm uninstall monitoring -n observability
helm uninstall mysql -n data # 如已安装
helm uninstall redis -n data
helm uninstall postgres -n data
helm uninstall ingress-nginx -n infra
# 删除 PVC(会删除数据!)
kubectl delete pvc -n data --all
kubectl delete pvc -n observability --all
# 删除 namespace
kubectl delete namespace infra data observability
# 重新运行初始化脚本
./init-orbstack-k8s-infra.sh
方式 2:重置 OrbStack k8s
在 OrbStack UI 中:
- 停止 Kubernetes
- 选择 Reset / Recreate Cluster
- 重新启动 Kubernetes
- 运行初始化脚本
./init-orbstack-k8s-infra.sh
扩展功能
添加 cert-manager(自动 TLS 证书)
# 安装 cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
# 创建 Let's Encrypt Issuer
kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: [email protected]
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
EOF
添加本地路径存储(如需)
# 安装 local-path-provisioner
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.24/deploy/local-path-storage.yaml
# 设为默认 StorageClass
kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
安全建议
生产环境务必修改以下默认密码:
- PostgreSQL:
postgres-values.yaml中的postgresPassword和password - Redis:
redis-values.yaml中的password - MySQL:
mysql-values.yaml中的rootPassword和password - Grafana:
kube-prometheus-stack-values.yaml中的adminPassword
建议使用 Kubernetes Secret 管理密码:
# 创建 Secret
kubectl create secret generic postgres-secret \
-n data \
--from-literal=postgres-password='strong-password-here' \
--from-literal=password='strong-password-here'
# 在 values.yaml 中引用
# existingSecret: postgres-secret
资源需求
最小配置
- CPU:4 核
- 内存:8 GB
- 存储:100 GB
推荐配置(Mac Studio 已满足)
- CPU:8+ 核
- 内存:16+ GB
- 存储:500 GB SSD
文件结构
orbstack-k8s-infra/
├── README.md # 本文档
├── init-orbstack-k8s-infra.sh # 一键初始化脚本
├── values/ # Helm values 配置
│ ├── ingress-nginx-values.yaml
│ ├── postgres-values.yaml
│ ├── redis-values.yaml
│ ├── mysql-values.yaml
│ ├── kube-prometheus-stack-values.yaml
│ └── loki-values.yaml
├── scripts/ # 辅助脚本(预留)
└── docs/ # 文档目录(预留)
常见问题
Q: 为什么选择 OrbStack 而不是 k3s?
A: OrbStack 自带的 k8s 对 Mac 集成度更好,资源占用更少,且已经满足开发环境需求。k3s 可以作为备选方案。
Q: 能否在生产环境使用这套方案?
A: 不建议。这套方案是为开发/测试环境设计的单节点部署。生产环境建议使用:
- 多节点 k8s 集群(3+ master,多 worker)
- 托管 k8s 服务(如 EKS、GKE、AKS)
- 数据库使用云服务或专业 DBA 管理
Q: 如何备份整个集群?
A: 可以使用 Velero 进行集群级别的备份:
# 安装 Velero
brew install velero
# 配置备份到本地或云存储
velero install --provider aws --bucket my-backup-bucket ...
Q: 如何监控资源使用?
A: 通过 Grafana Dashboard:
- 访问 Grafana(http://localhost:3000)
- 导入 Dashboard ID: 7249(Kubernetes Cluster)
- 查看 CPU、内存、存储、网络使用情况
参考链接
- OrbStack 官方文档
- ingress-nginx 文档
- Bitnami PostgreSQL Chart
- Bitnami Redis Chart
- kube-prometheus-stack
- Loki Stack Chart
贡献
欢迎提交 Issue 和 Pull Request!
许可证
MIT License
作者:Bruno Gao 更新时间:2025-01-22