- 添加 Gitea Actions 工作流 (.gitea/workflows/) - cicd.yml: 完整 CICD 流程(构建、测试、推送、部署) - test.yml: 快速测试工作流 - 配置 Kubernetes 部署清单 (k8s/) - namespace.yaml: 创建 claude-stock namespace - configmap.yaml: 应用配置和 Ollama 连接配置 - deployment.yaml: 后端和前端部署(支持 Node IP 连接 Ollama) - service.yaml: 服务定义、RBAC 和网络策略 - ollama-bridge.yaml: 四种 K8s 与宿主 Ollama 通信方案 - secrets.sh: 自动创建 K8s Secrets - 部署脚本和工具 - deploy-to-k8s.sh: 一键 K8s 部署脚本 - verify-cicd.sh: CICD 环境验证脚本 - 文档 - CICD_DEPLOYMENT_GUIDE.md: 完整部署指南(中文) - QUICK_START.md: 5 分钟快速启动指南(中文) 关键功能: ✅ Gitea Runners(Docker + K8s) ✅ Harbor 镜像仓库集成 ✅ 自动化测试和安全扫描 ✅ K8s 滚动更新和健康检查 ✅ Ollama 集成(使用 Node IP 解决通信问题) ✅ 完整的部署后验证 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
226 lines
5.5 KiB
YAML
226 lines
5.5 KiB
YAML
# ========== Ollama 桥接配置 ==========
|
||
# 此配置解决 Kubernetes Pod 与宿主 Ollama 的通信问题
|
||
#
|
||
# 问题:
|
||
# - Pod 内无法直接访问 localhost:11434(宿主 Ollama)
|
||
# - 需要使用 Node IP 而不是 localhost
|
||
#
|
||
# 解决方案:
|
||
# 1. 使用 ExternalName Service 映射宿主地址
|
||
# 2. 或在 Pod 中动态获取 Node IP
|
||
# 3. 使用 hostNetwork 允许访问宿主网络(不推荐)
|
||
|
||
---
|
||
# 方案1:ExternalName Service(推荐)
|
||
# 此方案允许 Pod 通过 DNS 名称访问宿主 Ollama
|
||
apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
name: ollama-host
|
||
namespace: claude-stock
|
||
spec:
|
||
type: ExternalName
|
||
# 这个需要替换为实际的宿主 IP
|
||
# 或使用特殊的 kubernetes 内部 IP
|
||
externalName: "host.docker.internal"
|
||
ports:
|
||
- name: ollama
|
||
port: 11434
|
||
protocol: TCP
|
||
|
||
---
|
||
# 方案2:Endpoint + Service(适合动态宿主 IP)
|
||
# 手动创建 Endpoint 指向宿主 IP
|
||
apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
name: ollama-endpoint
|
||
namespace: claude-stock
|
||
labels:
|
||
app: ollama-bridge
|
||
spec:
|
||
ports:
|
||
- name: ollama
|
||
port: 11434
|
||
protocol: TCP
|
||
targetPort: 11434
|
||
# 不设置 selector,使用外部 endpoint
|
||
clusterIP: None # Headless service
|
||
|
||
---
|
||
apiVersion: v1
|
||
kind: Endpoints
|
||
metadata:
|
||
name: ollama-endpoint
|
||
namespace: claude-stock
|
||
subsets:
|
||
# 注意:这个 IP 需要替换为实际的宿主节点 IP
|
||
- addresses:
|
||
- ip: "127.0.0.1" # 如果 K8s 运行在宿主上
|
||
ports:
|
||
- name: ollama
|
||
port: 11434
|
||
|
||
---
|
||
# 方案3:宿主 Ollama 的 ConfigMap
|
||
# 存储 Ollama 连接信息
|
||
apiVersion: v1
|
||
kind: ConfigMap
|
||
metadata:
|
||
name: ollama-host-config
|
||
namespace: claude-stock
|
||
data:
|
||
OLLAMA_HOST_METHOD: "node-ip" # node-ip, external-name, 或 localhost
|
||
OLLAMA_PORT: "11434"
|
||
|
||
# 获取宿主 IP 的脚本
|
||
get-ollama-host.sh: |
|
||
#!/bin/bash
|
||
set -e
|
||
|
||
# 方法1:使用 status.hostIP(最可靠)
|
||
if [ ! -z "$KUBERNETES_HOST_IP" ]; then
|
||
echo "$KUBERNETES_HOST_IP"
|
||
exit 0
|
||
fi
|
||
|
||
# 方法2:从环境变量获取(由 init 容器设置)
|
||
if [ ! -z "$NODE_IP" ]; then
|
||
echo "$NODE_IP"
|
||
exit 0
|
||
fi
|
||
|
||
# 方法3:从 DNS 解析
|
||
HOST_IP=$(nslookup kubernetes.default | grep "^Address:" | tail -n1 | awk '{print $2}')
|
||
if [ ! -z "$HOST_IP" ]; then
|
||
echo "$HOST_IP"
|
||
exit 0
|
||
fi
|
||
|
||
# 方法4:使用默认网关(Linux)
|
||
HOST_IP=$(ip route | grep default | awk '{print $3}' | head -n1)
|
||
if [ ! -z "$HOST_IP" ]; then
|
||
echo "$HOST_IP"
|
||
exit 0
|
||
fi
|
||
|
||
# 最后的备选方案
|
||
echo "127.0.0.1"
|
||
|
||
# 健康检查脚本
|
||
check-ollama.sh: |
|
||
#!/bin/bash
|
||
|
||
# 获取宿主 IP
|
||
OLLAMA_HOST=$(sh /config/get-ollama-host.sh)
|
||
OLLAMA_PORT=${OLLAMA_PORT:-11434}
|
||
|
||
echo "检查 Ollama 服务于: $OLLAMA_HOST:$OLLAMA_PORT"
|
||
|
||
# 尝试连接
|
||
curl -f -s "http://${OLLAMA_HOST}:${OLLAMA_PORT}/api/tags" > /dev/null 2>&1
|
||
|
||
if [ $? -eq 0 ]; then
|
||
echo "✅ Ollama 服务正常"
|
||
exit 0
|
||
else
|
||
echo "❌ 无法连接到 Ollama"
|
||
exit 1
|
||
fi
|
||
|
||
---
|
||
# 方案4:使用 DaemonSet 在每个节点上运行代理(最复杂但最灵活)
|
||
# 如果需要跨节点访问宿主服务,可以部署一个代理 DaemonSet
|
||
|
||
apiVersion: apps/v1
|
||
kind: DaemonSet
|
||
metadata:
|
||
name: ollama-proxy
|
||
namespace: claude-stock
|
||
labels:
|
||
app: ollama-proxy
|
||
spec:
|
||
selector:
|
||
matchLabels:
|
||
app: ollama-proxy
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: ollama-proxy
|
||
spec:
|
||
# 重要:使用 hostNetwork 允许访问宿主网络
|
||
hostNetwork: true
|
||
hostPID: true
|
||
|
||
containers:
|
||
- name: proxy
|
||
image: socat:latest
|
||
command:
|
||
- socat
|
||
- "-d"
|
||
- "-d"
|
||
- "TCP-LISTEN:11434,reuseaddr,fork"
|
||
- "TCP:127.0.0.1:11434"
|
||
ports:
|
||
- containerPort: 11434
|
||
hostPort: 11434
|
||
protocol: TCP
|
||
|
||
resources:
|
||
requests:
|
||
cpu: "50m"
|
||
memory: "50Mi"
|
||
limits:
|
||
cpu: "100m"
|
||
memory: "100Mi"
|
||
|
||
securityContext:
|
||
privileged: true
|
||
capabilities:
|
||
add:
|
||
- NET_ADMIN
|
||
- SYS_ADMIN
|
||
|
||
# 容错配置
|
||
tolerations:
|
||
- key: "node-role.kubernetes.io/master"
|
||
operator: "Exists"
|
||
effect: "NoSchedule"
|
||
- key: "node-role.kubernetes.io/control-plane"
|
||
operator: "Exists"
|
||
effect: "NoSchedule"
|
||
|
||
---
|
||
# 方案5:KubeVirt 虚拟机网络(如果使用 KubeVirt)
|
||
# 用于 MicroK8s 或其他轻量级 K8s 环境
|
||
apiVersion: v1
|
||
kind: ConfigMap
|
||
metadata:
|
||
name: ollama-microk8s-config
|
||
namespace: claude-stock
|
||
data:
|
||
microk8s-notes.txt: |
|
||
## MicroK8s 中访问宿主 Ollama 的方法:
|
||
|
||
### 方法1:使用 host.docker.internal
|
||
- 在 Pod 中设置:OLLAMA_BASE_URL=http://host.docker.internal:11434
|
||
- 需要 MicroK8s 支持此特殊 DNS 名称
|
||
|
||
### 方法2:直接使用宿主 IP
|
||
- 获取宿主 IP:hostname -I
|
||
- 设置:OLLAMA_BASE_URL=http://<HOSTIP>:11434
|
||
|
||
### 方法3:使用节点 IP
|
||
- 通过 status.hostIP 获取:kubectl get node -o wide
|
||
- Pod 中可通过环境变量访问:status.hostIP
|
||
|
||
### 方法4:修改 Ollama 监听配置
|
||
- 在宿主上设置:OLLAMA_HOST=0.0.0.0:11434
|
||
- 这样容器网络可以直接访问
|
||
|
||
### 检查连接:
|
||
```bash
|
||
kubectl exec -it <pod-name> -n claude-stock -- bash
|
||
curl -v http://<host-ip>:11434/api/tags
|
||
```
|