chore: update ci and k8s configs

This commit is contained in:
root
2025-12-17 11:18:26 +01:00
parent e3bcb3797c
commit 2fe3f70bc6
16 changed files with 838 additions and 30 deletions
+302
View File
@@ -0,0 +1,302 @@
# 本地 Docker Registry + GitHub Actions Self-Hosted Runner 完整配置指南
本文档记录了如何配置本地 Docker Registry 并与 K3s 中的 GitHub Actions Self-Hosted Runner 集成。
## 架构概览
```
GitHub Push → Self-Hosted Runner (K3s Pod)
↓
Docker Build (DinD)
↓
Push to 173.212.254.252:5000
↓
Deploy to K3s (ljwx-health namespace)
```
## 关键组件
### 1. 本地 Docker Registry
**部署位置**: 宿主机
**地址**: `173.212.254.252:5000`
**Web UI**: `http://localhost:8888`
**凭据**: `admin/admin123`
**配置文件**:
- `harbor/docker-compose.yml` - Registry 服务定义
- `harbor/setup.sh` - 部署脚本
**启动**:
```bash
cd /root/codes/ljwx-health/harbor
./setup.sh
```
**验证**:
```bash
curl -u admin:admin123 http://localhost:5000/v2/_catalog
docker login 173.212.254.252:5000 -u admin -p admin123
```
### 2. GitHub Actions Runner (K3s)
**Namespace**: `github-runner`
**类型**: RunnerDeployment (summerwind/actions-runner-controller)
**组织**: `BrunoGaoSZ`
**副本数**: 1
**关键配置**:
- **Docker-in-Docker (DinD)**: 每个 runner pod 包含两个容器 (`runner` + `docker`)
- **Docker Daemon 配置**: 通过 ConfigMap 持久化
- **资源限制**: 2 CPU, 4Gi Memory
### 3. 配置持久化
#### ConfigMap: docker-daemon-config
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: docker-daemon-config
namespace: github-runner
data:
daemon.json: |
{
"insecure-registries": ["173.212.254.252:5000", "localhost:5000"]
}
```
**作用**:
- 允许 Runner 的 DinD 容器访问 HTTP Registry(无 TLS)
- 配置会自动挂载到每个新 runner pod
- Pod 重建后配置依然生效
#### RunnerDeployment 配置
```yaml
apiVersion: actions.summerwind.dev/v1alpha1
kind: RunnerDeployment
metadata:
name: brunogao-runner
namespace: github-runner
spec:
replicas: 1
template:
spec:
dockerEnabled: true
organization: BrunoGaoSZ
labels: ["k3s", "self-hosted", "linux", "x64"]
# 挂载 Docker daemon 配置到 DinD 容器
dockerVolumeMounts:
- mountPath: /etc/docker/daemon.json
name: docker-daemon-config
subPath: daemon.json
volumes:
- name: docker-daemon-config
configMap:
name: docker-daemon-config
```
## 配置步骤总结
### 步骤 1: 部署本地 Registry
```bash
cd /root/codes/ljwx-health/harbor
./setup.sh
```
### 步骤 2: 配置宿主机 Docker
```bash
# 允许不安全的 Registry
cat > /etc/docker/daemon.json <<EOF
{
"insecure-registries": ["173.212.254.252:5000", "localhost:5000"]
}
EOF
systemctl restart docker
```
### 步骤 3: 配置 K3s
```bash
# 配置 K3s Registry
mkdir -p /etc/rancher/k3s
cat > /etc/rancher/k3s/registries.yaml <<EOF
mirrors:
"173.212.254.252:5000":
endpoint:
- "http://173.212.254.252:5000"
configs:
"173.212.254.252:5000":
auth:
username: admin
password: admin123
tls:
insecure_skip_verify: true
EOF
systemctl restart k3s
```
### 步骤 4: 创建 Docker Daemon ConfigMap
```bash
kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: docker-daemon-config
namespace: github-runner
data:
daemon.json: |
{
"insecure-registries": ["173.212.254.252:5000", "localhost:5000"]
}
EOF
```
### 步骤 5: 更新 RunnerDeployment
```bash
kubectl apply -f /tmp/runner-deployment-updated.yaml
```
### 步骤 6: 验证配置
```bash
# 等待新 runner pod 启动
kubectl get pods -n github-runner -w
# 验证 Docker daemon 配置
NEW_POD=$(kubectl get pods -n github-runner -o name | grep runner | tail -1 | sed 's|pod/||')
kubectl exec -n github-runner $NEW_POD -c docker -- cat /etc/docker/daemon.json
# 测试登录
kubectl exec -n github-runner $NEW_POD -c runner -- \
sh -c 'echo "admin123" | docker login 173.212.254.252:5000 -u admin --password-stdin'
```
## 故障排查
### 问题 1: Pod 无法访问 localhost:5000
**原因**: 在 Pod 内部,localhost 指向 Pod 自己,而不是宿主机。
**解决**: 使用宿主机 IP 地址 `173.212.254.252:5000`
### 问题 2: HTTPS 错误
```
Error: http: server gave HTTP response to HTTPS client
```
**原因**: Docker 默认尝试使用 HTTPS 连接 Registry。
**解决**: 配置 `insecure-registries` 允许 HTTP。
### 问题 3: Runner Pod 重建后配置丢失
**原因**: DinD 容器的配置未持久化。
**解决**:
1. 创建 ConfigMap 包含 daemon.json
2. 在 RunnerDeployment 中使用 `dockerVolumeMounts` 挂载配置
3. 每次 pod 重建时自动应用配置
### 问题 4: 认证失败
```
Error: unauthorized: authentication required
```
**解决**:
```bash
# 在 K3s 中创建镜像拉取密钥
kubectl create secret docker-registry harbor-secret \
--docker-server=173.212.254.252:5000 \
--docker-username=admin \
--docker-password=admin123 \
--namespace=ljwx-health
```
## 监控和维护
### 查看 Registry 镜像
```bash
# 命令行
curl -u admin:admin123 http://173.212.254.252:5000/v2/_catalog
# Web UI
open http://localhost:8888
# 使用脚本
./check-registry.sh
```
### 查看 Runner 状态
```bash
# Runner Deployment
kubectl get runnerdeployment -n github-runner
# Runner Pods
kubectl get pods -n github-runner
# Runner 日志
kubectl logs -n github-runner -l app.kubernetes.io/component=runner -c runner --tail=50 -f
```
### 实时监控 CI/CD
```bash
./watch-cicd.sh
```
## 文件清单
| 文件路径 | 说明 |
|---------|------|
| `harbor/docker-compose.yml` | Registry 服务定义 |
| `harbor/setup.sh` | Registry 部署脚本 |
| `.env.local-registry` | Registry 配置变量 |
| `.github/workflows/build-and-push.yml` | CI/CD workflow |
| `/etc/docker/daemon.json` | 宿主机 Docker 配置 |
| `/etc/rancher/k3s/registries.yaml` | K3s Registry 配置 |
| `docker-daemon-config` ConfigMap | Runner DinD 配置 |
| `brunogao-runner` RunnerDeployment | Runner 部署配置 |
## 安全注意事项
### 生产环境建议
1. **使用 TLS**: 配置 HTTPS Registry
2. **强密码**: 更改默认的 admin/admin123
3. **网络隔离**: 限制 Registry 访问范围
4. **定期备份**: Registry 数据目录 `harbor/data/registry`
### 当前配置(开发环境)
- ⚠️ HTTP Registry(无加密)
- ⚠️ 默认密码
- ✅ 基本认证
- ✅ 配置持久化
## 参考资料
- [Docker Registry Documentation](https://docs.docker.com/registry/)
- [Actions Runner Controller](https://github.com/actions/actions-runner-controller)
- [K3s Private Registry Configuration](https://docs.k3s.io/installation/private-registry)
---
**最后更新**: 2025-12-16
**维护者**: Claude Code with BrunoGaoSZ
@@ -0,0 +1,118 @@
name: Build -> Push Harbor -> Update Deploy Repo
on:
push:
branches: [ "main" ]
workflow_dispatch:
concurrency:
group: ljwx-health-dev
cancel-in-progress: false
jobs:
build_push_and_bump_deploy:
# ✅ 推荐:用 EU 节点 self-hosted runner(能稳定 push 到 HTTP Harbor)
runs-on: [self-hosted, linux, x64]
# 如你临时要用 GitHub-hosted(不推荐在 HTTP Harbor 场景):
# runs-on: ubuntu-latest
env:
IMAGE: harbor.eu.lingjingwanxiang.cn:8080/ljwx/ljwx-health
DEPLOY_REPO: BrunoGaoSZ/ljwx-deploy
DEPLOY_BRANCH: main
DEPLOY_FILE: apps/nginx/overlays/dev/kustomization.yaml
steps:
- name: Checkout app repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Compute tag (dev-${sha7})
id: meta
shell: bash
run: |
set -euo pipefail
SHA7="${GITHUB_SHA:0:7}"
TAG="dev-${SHA7}"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "Computed tag: ${TAG}"
# ---- Build & Push to Harbor ----
- name: Docker login to Harbor
shell: bash
run: |
set -euo pipefail
echo "${{ secrets.HARBOR_PASSWORD }}" | docker login harbor.eu.lingjingwanxiang.cn:8080 \
-u "${{ secrets.HARBOR_USERNAME }}" --password-stdin
- name: Build & push image
shell: bash
run: |
set -euo pipefail
# 这里假设你仓库根目录有 Dockerfile
docker build -t "${IMAGE}:${{ steps.meta.outputs.tag }}" .
docker push "${IMAGE}:${{ steps.meta.outputs.tag }}"
# ---- Update deploy repo ----
- name: Checkout deploy repo
uses: actions/checkout@v4
with:
repository: ${{ env.DEPLOY_REPO }}
token: ${{ secrets.DEPLOY_REPO_TOKEN }}
path: deploy
ref: ${{ env.DEPLOY_BRANCH }}
fetch-depth: 0
- name: Update newTag in deploy repo
shell: bash
run: |
set -euo pipefail
cd deploy
FILE="${DEPLOY_FILE}"
TAG="${{ steps.meta.outputs.tag }}"
if [[ ! -f "${FILE}" ]]; then
echo "[FATAL] Deploy file not found: ${FILE}"
exit 1
fi
echo "Updating ${FILE} -> newTag: ${TAG}"
# 只替换 images: 块里 newTag 行(尽量不误伤)
# 兼容 "newTag: xxx" 前面可能有空格
perl -0777 -i -pe "s/(\\bnewTag:\\s*).*/\$1${TAG}/m" "${FILE}"
git status --porcelain
if [[ -z "$(git status --porcelain)" ]]; then
echo "No change detected, skip commit."
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add "${FILE}"
git commit -m "deploy(dev): bump ljwx-health to ${TAG}"
- name: Push deploy repo (rebase + retry)
shell: bash
run: |
set -euo pipefail
cd deploy
for i in 1 2 3; do
echo "Push attempt ${i}..."
git pull --rebase origin "${DEPLOY_BRANCH}" || true
if git push origin "HEAD:${DEPLOY_BRANCH}"; then
echo "Pushed successfully."
exit 0
fi
sleep 2
done
echo "[FATAL] failed to push after retries"
exit 1
+45
View File
@@ -0,0 +1,45 @@
#!/bin/bash
echo "========================================="
echo "📦 本地 Registry 镜像检查"
echo "========================================="
echo ""
echo "🔍 Registry 容器状态:"
docker ps | grep -E "NAME|registry" | grep -v grep
echo ""
echo "📋 Registry 中的所有仓库:"
curl -s -u admin:admin123 http://localhost:5000/v2/_catalog | jq '.'
echo ""
echo "🏷️ ljwx-health 项目的镜像:"
REPOS=$(curl -s -u admin:admin123 http://localhost:5000/v2/_catalog | jq -r '.repositories[]' 2>/dev/null)
if [ -z "$REPOS" ]; then
echo "暂无镜像(CI/CD 构建中...)"
else
for repo in $REPOS; do
if [[ $repo == ljwx-health/* ]]; then
echo ""
echo "📦 $repo:"
TAGS=$(curl -s -u admin:admin123 "http://localhost:5000/v2/$repo/tags/list" | jq -r '.tags[]?' 2>/dev/null)
if [ -z "$TAGS" ]; then
echo " └─ 暂无标签"
else
for tag in $TAGS; do
echo " └─ $tag"
done
fi
fi
done
fi
echo ""
echo "========================================="
echo "💡 实用命令"
echo "========================================="
echo "访问 Web UI: http://localhost:8888"
echo "重新运行检查: ./check-registry.sh"
echo "查看 K3s 部署: ./monitor-deployment.sh"
echo ""
+1 -1
View File
@@ -1,2 +1,2 @@
admin:$2y$05$DtBHPQ2Xl6BaiRU.W5BZ0uv1Ilcq64LW5oWH4e2jgk/nMQe6ou3GC
admin:$2y$05$d3UA3lnupxLKfSoVhqHoG.QQriPbPTkdrCKJbVxmxvtXXCGDhwcaW
+7 -7
View File
@@ -2,9 +2,9 @@ apiVersion: v1
kind: ConfigMap
metadata:
name: ljwx-config
namespace: ljwx-system
namespace: ljwx-health
data:
redis.host: "redis-service.ljwx-system.svc.cluster.local"
redis.host: "redis-service.ljwx-health.svc.cluster.local"
redis.port: "6379"
app.log.level: "INFO"
app.debug: "false"
@@ -14,10 +14,10 @@ apiVersion: v1
kind: Secret
metadata:
name: ljwx-db-secret
namespace: ljwx-system
namespace: ljwx-health
type: Opaque
data:
host: bXlzcWwtc2VydmljZS5sand4LXN5c3RlbS5zdmMuY2x1c3Rlci5sb2NhbA== # mysql-service.ljwx-system.svc.cluster.local
username: bGp3eA== # ljwx
password: bGp3eDEyMw== # ljwx123
database: bGp3eA== # ljwx
host: bXlzcWwtc2VydmljZS5sand4LWhlYWx0aC5zdmMuY2x1c3Rlci5sb2NhbA== # mysql-service.ljwx-health.svc.cluster.local
username: cm9vdA== # root
password: MTIzNDU2 # 123456
database: dGVzdA== # test
+10 -9
View File
@@ -2,7 +2,7 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: ljwx-bigscreen
namespace: ljwx-system
namespace: ljwx-health
labels:
app: ljwx-bigscreen
env: prod
@@ -41,7 +41,7 @@ spec:
topologyKey: kubernetes.io/hostname
containers:
- name: ljwx-bigscreen
image: ${REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG}
image: 173.212.254.252:5000/ljwx-health/ljwx-bigscreen:latest
ports:
- containerPort: 5001
name: http
@@ -63,6 +63,10 @@ spec:
secretKeyRef:
name: ljwx-db-secret
key: password
- name: MYSQL_DATABASE
value: "test"
- name: APP_PORT
value: "5001"
- name: REDIS_HOST
valueFrom:
configMapKeyRef:
@@ -80,24 +84,21 @@ spec:
memory: "1Gi"
cpu: "1000m"
livenessProbe:
httpGet:
path: /api/health
tcpSocket:
port: 5001
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /api/ready
tcpSocket:
port: 5001
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 5
failureThreshold: 3
startupProbe: # 启动探针,给应用更多启动时间
httpGet:
path: /api/health
tcpSocket:
port: 5001
initialDelaySeconds: 30
periodSeconds: 10
@@ -108,7 +109,7 @@ apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: ljwx-bigscreen-hpa
namespace: ljwx-system
namespace: ljwx-health
spec:
scaleTargetRef:
apiVersion: apps/v1
+1 -1
View File
@@ -2,7 +2,7 @@ apiVersion: v1
kind: Service
metadata:
name: ljwx-bigscreen-service
namespace: ljwx-system
namespace: ljwx-health
labels:
app: ljwx-bigscreen
env: prod
+5 -1
View File
@@ -7,7 +7,7 @@ metadata:
app: ljwx-boot
data:
# 数据库配置
database.url: "jdbc:mysql://mysql-service.ljwx-health.svc.cluster.local:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false"
database.url: "jdbc:mysql://mysql-service.ljwx-health.svc.cluster.local:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true"
database.driver: "com.mysql.cj.jdbc.Driver"
# Redis配置
@@ -30,6 +30,7 @@ data:
name: ljwx-boot
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
hikari:
minimum-idle: 10
@@ -39,6 +40,9 @@ data:
max-lifetime: 1800000
redis:
# Redis Service DNS 名称(K8s 集群内部)
host: redis-service.ljwx-health.svc.cluster.local
port: 6379
database: 1
timeout: 10000
lettuce:
+27 -11
View File
@@ -80,18 +80,18 @@ spec:
name: ljwx-boot-secret
key: database.password
# Redis配置
# Redis配置 - 直接指定值,覆盖配置文件
- name: SPRING_DATA_REDIS_HOST
value: "redis-service.ljwx-health.svc.cluster.local"
- name: SPRING_DATA_REDIS_PORT
value: "6379"
- name: SPRING_REDIS_HOST
valueFrom:
configMapKeyRef:
name: ljwx-boot-config
key: redis.host
value: "redis-service.ljwx-health.svc.cluster.local"
- name: SPRING_REDIS_PORT
valueFrom:
configMapKeyRef:
name: ljwx-boot-config
key: redis.port
value: "6379"
- name: SPRING_REDIS_PASSWORD
valueFrom:
@@ -102,9 +102,25 @@ spec:
- name: SPRING_REDIS_DATABASE
value: "1"
# Redis URL 连接配置(application-common.yml 使用)
- name: REDIS_HOST
value: "redis-service.ljwx-health.svc.cluster.local"
- name: REDIS_PORT
value: "6379"
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: ljwx-boot-secret
key: redis.password
- name: REDIS_DB
value: "1"
# JVM参数
- name: JAVA_OPTS
value: "-Xms1g -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof"
value: "-Xms1g -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof -Dspring.data.redis.host=redis-service.ljwx-health.svc.cluster.local -Dspring.data.redis.port=6379 -Dspring.redis.host=redis-service.ljwx-health.svc.cluster.local -Dspring.redis.port=6379"
# 资源限制
resources:
@@ -147,7 +163,7 @@ spec:
# 挂载卷
volumeMounts:
- name: logs
mountPath: /app/logs
mountPath: /app/ljwx-boot-logs
- name: config
mountPath: /app/config
readOnly: true
+97
View File
@@ -0,0 +1,97 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
namespace: ljwx-health
labels:
app: mysql
component: database
spec:
replicas: 1
selector:
matchLabels:
app: mysql
strategy:
type: Recreate # MySQL 使用 Recreate 策略,避免多实例同时访问数据
template:
metadata:
labels:
app: mysql
spec:
imagePullSecrets:
- name: harbor-secret
containers:
- name: mysql
image: 173.212.254.252:5000/ljwx-health/ljwx-mysql:latest
imagePullPolicy: Always
ports:
- name: mysql
containerPort: 3306
protocol: TCP
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: ljwx-boot-secret
key: database.password
- name: MYSQL_DATABASE
value: "test"
- name: TZ
value: "Asia/Shanghai"
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "2000m"
memory: "2Gi"
livenessProbe:
exec:
command:
- mysqladmin
- ping
- -h
- localhost
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
exec:
command:
- mysqladmin
- ping
- -h
- localhost
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
- name: mysql-config
mountPath: /etc/mysql/conf.d
readOnly: true
volumes:
- name: mysql-data
persistentVolumeClaim:
claimName: mysql-pvc
- name: mysql-config
configMap:
name: mysql-config
---
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
namespace: ljwx-health
data:
custom.cnf: |
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
default-time-zone='+08:00'
max_connections=200
innodb_buffer_pool_size=1G
innodb_log_file_size=256M
+14
View File
@@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
namespace: ljwx-health
labels:
app: mysql
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
storageClassName: local-path # k3s 默认使用 local-path
+17
View File
@@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
name: mysql-service
namespace: ljwx-health
labels:
app: mysql
component: database
spec:
type: ClusterIP
selector:
app: mysql
ports:
- name: mysql
port: 3306
targetPort: 3306
protocol: TCP
+109
View File
@@ -0,0 +1,109 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: ljwx-health
labels:
app: redis
component: cache
spec:
replicas: 1
selector:
matchLabels:
app: redis
strategy:
type: Recreate # Redis 使用 Recreate 策略
template:
metadata:
labels:
app: redis
spec:
imagePullSecrets:
- name: harbor-secret
containers:
- name: redis
image: 173.212.254.252:5000/ljwx-health/ljwx-redis:latest
imagePullPolicy: Always
ports:
- name: redis
containerPort: 6379
protocol: TCP
env:
- name: TZ
value: "Asia/Shanghai"
command:
- redis-server
- /usr/local/etc/redis/redis.conf
- --requirepass
- $(REDIS_PASSWORD)
env:
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: ljwx-boot-secret
key: redis.password
resources:
requests:
cpu: "200m"
memory: "512Mi"
limits:
cpu: "1000m"
memory: "1Gi"
livenessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
volumeMounts:
- name: redis-data
mountPath: /data
- name: redis-config
mountPath: /usr/local/etc/redis
readOnly: true
volumes:
- name: redis-data
persistentVolumeClaim:
claimName: redis-pvc
- name: redis-config
configMap:
name: redis-config
---
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-config
namespace: ljwx-health
data:
redis.conf: |
bind 0.0.0.0
port 6379
protected-mode yes
timeout 0
tcp-keepalive 300
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data
maxmemory 512mb
maxmemory-policy allkeys-lru
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
+14
View File
@@ -0,0 +1,14 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis-pvc
namespace: ljwx-health
labels:
app: redis
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: local-path # k3s 默认使用 local-path
+17
View File
@@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
name: redis-service
namespace: ljwx-health
labels:
app: redis
component: cache
spec:
type: ClusterIP
selector:
app: redis
ports:
- name: redis
port: 6379
targetPort: 6379
protocol: TCP
Executable
+54
View File
@@ -0,0 +1,54 @@
#!/bin/bash
echo "========================================="
echo "🔍 实时监控 CI/CD 执行 (每 10 秒刷新)"
echo "========================================="
echo "按 Ctrl+C 停止监控"
echo ""
sleep 2
while true; do
clear
echo "========================================="
echo "🚀 CI/CD 执行状态监控"
echo "========================================="
date "+%Y-%m-%d %H:%M:%S"
echo ""
echo "📦 GitHub Actions Runner:"
kubectl get pods -n github-runner -o wide | grep -E "NAME|runner"
echo ""
echo "🔨 当前正在执行的任务:"
RUNNER_POD=$(kubectl get pods -n github-runner -o name | grep runner | head -1 | cut -d'/' -f2)
if [ -n "$RUNNER_POD" ]; then
kubectl logs -n github-runner "$RUNNER_POD" -c runner --tail=5 2>&1 | grep -E "Running job|Finished|Starting" || echo " 等待任务分配..."
else
echo " 无 runner pod 运行"
fi
echo ""
echo "🐳 Registry 镜像数量:"
REPO_COUNT=$(curl -s -u admin:admin123 http://localhost:5000/v2/_catalog 2>/dev/null | jq -r '.repositories | length' 2>/dev/null || echo "0")
echo " 已推送镜像仓库数: $REPO_COUNT"
if [ "$REPO_COUNT" -gt 0 ]; then
echo ""
echo "📋 Registry 中的镜像:"
curl -s -u admin:admin123 http://localhost:5000/v2/_catalog 2>/dev/null | jq -r '.repositories[]' | while read repo; do
TAGS=$(curl -s -u admin:admin123 "http://localhost:5000/v2/$repo/tags/list" 2>/dev/null | jq -r '.tags[]?' | head -3 | tr '\n' ', ' | sed 's/,$//')
echo " └─ $repo: $TAGS"
done
fi
echo ""
echo "📊 K3s 部署状态 (ljwx-health namespace):"
kubectl get deployments -n ljwx-health 2>/dev/null | grep -E "NAME|ljwx" || echo " 部署尚未更新"
echo ""
echo "========================================="
echo "⏰ 每 10 秒自动刷新 | 按 Ctrl+C 退出"
echo "========================================="
sleep 10
done