feat: require production infrastructure evidence
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# 阿里云单机演示部署
|
||||
|
||||
该配置用于单机公网演示,不是生产验收配置。只向公网发布HTTP 80和HTTPS 443;PostgreSQL、Redis、MinIO、Keycloak内部端口以及API/Worker端口均不映射到宿主机。当前阿里云演示机使用Let's Encrypt短期IP证书,`certbot-ip-renew.timer`负责自动续期。单机备份覆盖PostgreSQL、Redis、MinIO对象和当前Keycloak数据目录,并执行数据库级隔离恢复校验;五分钟健康检查覆盖公网入口、OIDC、容器、备份、证书、定时任务和磁盘。跨故障域备份、真实告警接收器、真实RTC、模型、内容安全和云KMS仍按阶段8验收清单执行。
|
||||
该配置用于单机公网演示,不是生产验收配置。只向公网发布HTTP 80和HTTPS 443;PostgreSQL、Redis、MinIO、Keycloak内部端口以及API/Worker端口均不映射到宿主机。当前阿里云演示机使用Let's Encrypt短期IP证书,`certbot-ip-renew.timer`负责自动续期。单机备份覆盖PostgreSQL、Redis、MinIO对象和当前Keycloak数据目录,并执行数据库级隔离恢复校验;五分钟健康检查覆盖部署模式、公网入口、OIDC、容器、模拟服务、备份、外部告警、证书、定时任务和磁盘。跨故障域备份、真实告警接收器、真实RTC、模型、内容安全和云KMS仍按阶段8验收清单执行。
|
||||
|
||||
服务器至少需要Docker Engine 29与Compose 2.40。首次部署先生成权限为600的服务器专用配置:
|
||||
|
||||
@@ -54,7 +54,9 @@ sudo systemctl show platform-health-monitor.service -p Result -p ExecMainStatus
|
||||
python3 -m json.tool /var/lib/data-terminal-cloud-monitor/status.json
|
||||
```
|
||||
|
||||
监测任务每五分钟执行,正常状态为`healthy`。它还要求宿主机所有非回环TCP监听只能使用22、80和443,避免安全组误放行与错误容器端口映射叠加后暴露数据库或缓存。默认只记录结构化状态和systemd日志;在`/etc/data-terminal-cloud/monitor.env`配置`ALERT_WEBHOOK_URL`后,状态变化会发送带时间戳和HMAC-SHA256签名的JSON通知。完整检查项、签名规则、阈值和失败分支见[《单机云端健康监测与告警手册》](../../docs/server-health-monitoring.md)。
|
||||
监测任务每五分钟执行,正常状态为`healthy`。默认`HOST_DEPLOYMENT_PROFILE=demo`,要求两个模拟服务完整运行;切到`production`后则要求模拟服务全部停止。它还要求宿主机所有非回环TCP监听只能使用22、80和443,避免安全组误放行与错误容器端口映射叠加后暴露数据库或缓存。默认只记录结构化状态和systemd日志;在`/etc/data-terminal-cloud/monitor.env`配置`ALERT_WEBHOOK_URL`后,状态变化会发送带时间戳和HMAC-SHA256签名的JSON通知。完整检查项、签名规则、阈值和失败分支见[《单机云端健康监测与告警手册》](../../docs/server-health-monitoring.md)。
|
||||
|
||||
生产候选不能只修改部署模式。生产验收快照同时要求:`HOST_DEPLOYMENT_PROFILE=production`、OSS异地备份最近一次上传与回读验证成功、真实外部告警接收器已配置、`mock-provider`和`mock-alert-receiver`均不运行。任一条件缺失都会阻断生产基础设施门禁,但不会影响`LAB`或`STAGING`联调。
|
||||
|
||||
## OSS异地备份适配
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ alert_webhook_secret_file=${ALERT_WEBHOOK_SECRET_FILE:-/etc/data-terminal-cloud/
|
||||
platform_health_report_url=${PLATFORM_HEALTH_REPORT_URL:-}
|
||||
platform_health_report_secret_file=${PLATFORM_HEALTH_REPORT_SECRET_FILE:-/etc/data-terminal-cloud/platform-health-callback-secret}
|
||||
expected_public_tcp_ports=${EXPECTED_PUBLIC_TCP_PORTS:-22,80,443}
|
||||
deployment_profile=${HOST_DEPLOYMENT_PROFILE:-demo}
|
||||
if [[ -f "$offsite_config_file" ]]; then
|
||||
# shellcheck disable=SC1090
|
||||
source "$offsite_config_file"
|
||||
@@ -41,6 +42,10 @@ if [[ ! "$expected_public_tcp_ports" =~ ^[0-9]+(,[0-9]+)*$ ]]; then
|
||||
echo "EXPECTED_PUBLIC_TCP_PORTS must contain comma-separated integers" >&2
|
||||
exit 2
|
||||
fi
|
||||
if [[ "$deployment_profile" != demo && "$deployment_profile" != production ]]; then
|
||||
echo "HOST_DEPLOYMENT_PROFILE must be demo or production" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
compose=(docker compose -f "$project_root/compose.yaml" -f "$project_root/deploy/server/compose.override.yaml" --env-file "$project_root/deploy/server/.env")
|
||||
mkdir -p "$state_dir"
|
||||
@@ -73,6 +78,21 @@ record_check() {
|
||||
esac
|
||||
}
|
||||
|
||||
record_check deployment_profile healthy "$deployment_profile"
|
||||
if [[ -z "$alert_webhook_url" ]]; then
|
||||
if [[ "$deployment_profile" == production ]]; then
|
||||
record_check external_alert_receiver critical not_configured
|
||||
else
|
||||
record_check external_alert_receiver healthy not_configured
|
||||
fi
|
||||
elif [[ ! -r "$alert_webhook_secret_file" ]]; then
|
||||
record_check external_alert_receiver critical secret_missing
|
||||
elif (( $(tr -d '\r\n' <"$alert_webhook_secret_file" | wc -c) < 32 )); then
|
||||
record_check external_alert_receiver critical secret_invalid
|
||||
else
|
||||
record_check external_alert_receiver healthy configured
|
||||
fi
|
||||
|
||||
public_origin=$(sed -n 's/^PUBLIC_ORIGIN=//p' "$project_root/deploy/server/.env")
|
||||
if [[ "$public_origin" == https://* ]]; then
|
||||
record_check public_origin healthy "$public_origin"
|
||||
@@ -113,7 +133,10 @@ else
|
||||
record_check oidc_issuer critical request_failed
|
||||
fi
|
||||
|
||||
required_services=(postgres redis minio keycloak api callbacks worker web gateway mock-provider mock-alert-receiver)
|
||||
required_services=(postgres redis minio keycloak api callbacks worker web gateway)
|
||||
if [[ "$deployment_profile" == demo ]]; then
|
||||
required_services+=(mock-provider mock-alert-receiver)
|
||||
fi
|
||||
for service in "${required_services[@]}"; do
|
||||
container=$("${compose[@]}" ps -q "$service")
|
||||
if [[ -z "$container" ]]; then
|
||||
@@ -131,6 +154,25 @@ for service in "${required_services[@]}"; do
|
||||
fi
|
||||
done
|
||||
|
||||
mock_services_running=()
|
||||
for mock_service in mock-provider mock-alert-receiver; do
|
||||
mock_container=$("${compose[@]}" ps -q "$mock_service")
|
||||
if [[ -n "$mock_container" && $(docker inspect -f '{{.State.Status}}' "$mock_container") == running ]]; then
|
||||
mock_services_running+=("$mock_service")
|
||||
fi
|
||||
done
|
||||
if [[ "$deployment_profile" == production ]]; then
|
||||
if (( ${#mock_services_running[@]} > 0 )); then
|
||||
record_check mock_services critical unexpected_running
|
||||
else
|
||||
record_check mock_services healthy disabled
|
||||
fi
|
||||
elif (( ${#mock_services_running[@]} == 2 )); then
|
||||
record_check mock_services healthy enabled_for_demo
|
||||
else
|
||||
record_check mock_services critical incomplete_demo_stack
|
||||
fi
|
||||
|
||||
latest_backup=$(find "$backup_root" -maxdepth 1 -type f -name 'platform-*.tar.gz.enc' -printf '%T@ %p\n' 2>/dev/null | sort -nr | head -n1 | cut -d' ' -f2- || true)
|
||||
if [[ -z "$latest_backup" || ! -f "$latest_backup" ]]; then
|
||||
record_check backup_freshness critical missing
|
||||
@@ -168,7 +210,11 @@ except Exception: print("invalid|0|")' "$offsite_state_file")
|
||||
fi
|
||||
fi
|
||||
else
|
||||
record_check offsite_backup healthy not_required
|
||||
if [[ "$deployment_profile" == production ]]; then
|
||||
record_check offsite_backup critical not_required
|
||||
else
|
||||
record_check offsite_backup healthy not_required
|
||||
fi
|
||||
fi
|
||||
|
||||
backup_result=$(systemctl show platform-backup.service -p Result --value 2>/dev/null || true)
|
||||
|
||||
@@ -32,6 +32,7 @@ if [[ ! -e /etc/data-terminal-cloud/monitor.env ]]; then
|
||||
report_url="$public_origin/callbacks/v1/platform-health"
|
||||
fi
|
||||
cat >/etc/data-terminal-cloud/monitor.env <<EOF
|
||||
HOST_DEPLOYMENT_PROFILE=demo
|
||||
PLATFORM_HEALTH_REPORT_URL=$report_url
|
||||
PLATFORM_HEALTH_REPORT_SECRET_FILE=/etc/data-terminal-cloud/platform-health-callback-secret
|
||||
ALERT_WEBHOOK_URL=
|
||||
|
||||
Reference in New Issue
Block a user