diff --git a/deploy/compose_test.go b/deploy/compose_test.go index 9c8be29..d692d15 100644 --- a/deploy/compose_test.go +++ b/deploy/compose_test.go @@ -2,6 +2,8 @@ package deploy import ( "os" + "path/filepath" + "regexp" "slices" "strings" "testing" @@ -131,6 +133,40 @@ func TestLocalGatewaysDoNotDependOnControlPlaneStorage(t *testing.T) { } } +func TestDeploymentEntrypointsExistInSource(t *testing.T) { + dockerfile, err := os.ReadFile("docker/Dockerfile") + if err != nil { + t.Fatalf("read docker/Dockerfile: %v", err) + } + entrypoints := regexp.MustCompile(`\./cmd/(proxy-[a-z0-9-]+)`).FindAllStringSubmatch(string(dockerfile), -1) + if len(entrypoints) == 0 { + t.Fatal("docker/Dockerfile has no proxy command build target") + } + for _, entrypoint := range entrypoints { + assertCommandDirectory(t, entrypoint[1]) + } + + document := loadComposeDocument(t) + for name, service := range document.Services { + if len(service.Command) == 0 || !strings.HasPrefix(service.Command[0], "proxy-") { + continue + } + if _, err := os.Stat(filepath.Join("..", "cmd", service.Command[0])); err != nil { + t.Errorf("compose service %s command %q has no source entrypoint: %v", name, service.Command[0], err) + } + } +} + +func TestKubernetesBaseExcludesUnimplementedProcessManifests(t *testing.T) { + payload, err := os.ReadFile("kubernetes/base/kustomization.yaml") + if err != nil { + t.Fatalf("read kustomization.yaml: %v", err) + } + if strings.Contains(string(payload), "checker.yaml") { + t.Fatal("kubernetes base includes checker.yaml before proxy-checker exists") + } +} + func loadComposeDocument(t *testing.T) composeDocument { t.Helper() return loadComposeFile(t, "docker-compose.yml") @@ -172,3 +208,11 @@ func commandFlag(command []string, name string) (string, bool) { } return "", false } + +func assertCommandDirectory(t *testing.T, command string) { + t.Helper() + info, err := os.Stat(filepath.Join("..", "cmd", command)) + if err != nil || !info.IsDir() { + t.Errorf("build command %q has no source directory", command) + } +} diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index efcc839..93179b6 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -65,23 +65,6 @@ services: retries: 12 start_period: 15s - checker: - <<: *app - command: ["proxy-checker"] - depends_on: - postgres: - condition: service_healthy - redis: - condition: service_healthy - expose: ["9090"] - healthcheck: - test: ["CMD", "curl", "--fail", "--silent", "http://127.0.0.1:9090/readyz"] - interval: 10s - timeout: 2s - retries: 12 - start_period: 15s - - haproxy: image: haproxy:3.2-alpine restart: unless-stopped diff --git a/deploy/docker/Dockerfile b/deploy/docker/Dockerfile index 3837f30..31b389d 100644 --- a/deploy/docker/Dockerfile +++ b/deploy/docker/Dockerfile @@ -11,11 +11,7 @@ ARG TARGETARCH=amd64 RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ go build -trimpath -ldflags="-s -w" -o /out/proxy-gateway ./cmd/proxy-gateway && \ CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ - go build -trimpath -ldflags="-s -w" -o /out/proxy-controller ./cmd/proxy-controller && \ - CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ - go build -trimpath -ldflags="-s -w" -o /out/proxy-checker ./cmd/proxy-checker && \ - CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ - go build -trimpath -ldflags="-s -w" -o /out/proxy-loadgen ./cmd/proxy-loadgen + go build -trimpath -ldflags="-s -w" -o /out/proxy-controller ./cmd/proxy-controller FROM debian:bookworm-slim @@ -27,4 +23,3 @@ RUN apt-get update && \ COPY --from=build /out/ /usr/local/bin/ USER 10001:10001 ENTRYPOINT ["/usr/bin/tini", "--"] - diff --git a/deploy/kubernetes/base/autoscaling.yaml b/deploy/kubernetes/base/autoscaling.yaml index 760c6f5..9c57d3b 100644 --- a/deploy/kubernetes/base/autoscaling.yaml +++ b/deploy/kubernetes/base/autoscaling.yaml @@ -24,24 +24,3 @@ spec: resource: name: memory target: {type: Utilization, averageUtilization: 65} ---- -apiVersion: autoscaling/v2 -kind: HorizontalPodAutoscaler -metadata: {name: proxy-checker, namespace: proxy-pool} -spec: - scaleTargetRef: {apiVersion: apps/v1, kind: Deployment, name: proxy-checker} - minReplicas: 3 - maxReplicas: 30 - behavior: - scaleUp: - stabilizationWindowSeconds: 0 - policies: [{type: Percent, value: 100, periodSeconds: 30}] - scaleDown: - stabilizationWindowSeconds: 300 - policies: [{type: Percent, value: 20, periodSeconds: 60}] - metrics: - - type: Resource - resource: - name: cpu - target: {type: Utilization, averageUtilization: 60} - diff --git a/deploy/kubernetes/base/availability.yaml b/deploy/kubernetes/base/availability.yaml index 7f71f40..ae6b8bb 100644 --- a/deploy/kubernetes/base/availability.yaml +++ b/deploy/kubernetes/base/availability.yaml @@ -11,11 +11,3 @@ metadata: {name: proxy-controller, namespace: proxy-pool} spec: minAvailable: 2 selector: {matchLabels: {app.kubernetes.io/name: proxy-controller}} ---- -apiVersion: policy/v1 -kind: PodDisruptionBudget -metadata: {name: proxy-checker, namespace: proxy-pool} -spec: - minAvailable: 2 - selector: {matchLabels: {app.kubernetes.io/name: proxy-checker}} - diff --git a/deploy/kubernetes/base/kustomization.yaml b/deploy/kubernetes/base/kustomization.yaml index a26498e..a8b542c 100644 --- a/deploy/kubernetes/base/kustomization.yaml +++ b/deploy/kubernetes/base/kustomization.yaml @@ -6,7 +6,6 @@ resources: - configmap.yaml - gateway.yaml - controller.yaml - - checker.yaml - availability.yaml - autoscaling.yaml - networkpolicy.yaml @@ -14,4 +13,3 @@ images: - name: REGISTRY/proxy-pool newName: REGISTRY/proxy-pool newTag: VERSION - diff --git a/deploy/kubernetes/base/networkpolicy.yaml b/deploy/kubernetes/base/networkpolicy.yaml index 67f3627..4ce96db 100644 --- a/deploy/kubernetes/base/networkpolicy.yaml +++ b/deploy/kubernetes/base/networkpolicy.yaml @@ -34,8 +34,7 @@ kind: NetworkPolicy metadata: {name: control-plane-traffic, namespace: proxy-pool} spec: podSelector: - matchExpressions: - - {key: app.kubernetes.io/name, operator: In, values: [proxy-controller, proxy-checker]} + matchLabels: {app.kubernetes.io/name: proxy-controller} policyTypes: [Ingress, Egress] ingress: - from: @@ -49,4 +48,3 @@ spec: ports: [{port: 53, protocol: UDP}, {port: 53, protocol: TCP}] # Provider、健康目标及外部托管 PostgreSQL/Redis 的精确网段应在环境 Overlay 收紧。 - to: [{ipBlock: {cidr: 0.0.0.0/0}}] - diff --git a/deploy/prometheus/prometheus.yml b/deploy/prometheus/prometheus.yml index 325e204..e979350 100644 --- a/deploy/prometheus/prometheus.yml +++ b/deploy/prometheus/prometheus.yml @@ -14,11 +14,7 @@ scrape_configs: - job_name: proxy-controller static_configs: - targets: [controller:9090] - - job_name: proxy-checker - static_configs: - - targets: [checker:9090] - job_name: haproxy metrics_path: /metrics static_configs: - targets: [haproxy:8404] - diff --git a/deploy/prometheus/rules/proxy-pool.yml b/deploy/prometheus/rules/proxy-pool.yml index c68ead8..3727d6a 100644 --- a/deploy/prometheus/rules/proxy-pool.yml +++ b/deploy/prometheus/rules/proxy-pool.yml @@ -31,13 +31,6 @@ groups: severity: warning annotations: summary: Provider Fetch 错误持续发生 - - alert: ProxyPoolCheckerBacklog - expr: proxy_pool_checker_queue_depth > 10000 - for: 5m - labels: - severity: warning - annotations: - summary: Checker 队列积压 - alert: ProxyPoolExtractionConflict expr: sum(rate(proxy_pool_extraction_total{result="conflict"}[5m])) > 0 for: 5m @@ -45,4 +38,3 @@ groups: severity: warning annotations: summary: 独占提取发生持续事务冲突 - diff --git a/docs/configuration/reference.md b/docs/configuration/reference.md index eb4e2d2..d00031c 100644 --- a/docs/configuration/reference.md +++ b/docs/configuration/reference.md @@ -22,7 +22,7 @@ go run ./cmd/proxy-controller -config CONFIG_FILE PostgreSQL 管理面迁移、Redis 活动池、Distribution/Admin 独立监听与优雅停机; Controller Metrics 独立监听、`/livez`、`/readyz` 和基础 Prometheus 运行时指标; Provider 自动补池、分布式配额、动态重载和 Admin 低基数统计已装配。Gateway 进程、 -Worker 控制面会话和 Snapshot 就绪探针已装配;Checker、带凭据 Proxy 分发与代表性 +Worker 控制面会话、Snapshot 凭据分发和 Snapshot 就绪探针已装配;Checker 与代表性 负载验证仍在后续实施范围。 所有时间值使用 Go duration,例如 `500ms`、`30s`、`5m`。示例中的 diff --git a/docs/operations/runbook.md b/docs/operations/runbook.md index 4c85028..635bb26 100644 --- a/docs/operations/runbook.md +++ b/docs/operations/runbook.md @@ -20,8 +20,8 @@ `cmd/proxy-controller` 已完成配置单次加载、PostgreSQL 迁移、Redis 活动池、 Distribution/Admin/Metrics 独立监听和有界停机装配。Provider 自动补池、分布式 -配额、动态重载和 Admin 低基数统计已装配;完整 Gateway/Checker/Loadgen 与 Worker -控制面仍属于 `implementation-plan.md` 后续任务。 +配额、动态重载和 Admin 低基数统计已装配;Checker/Loadgen 与完整 mTLS 环境 Overlay +仍属于 `implementation-plan.md` 后续任务。 因此 Compose/Kubernetes 资产当前仍用于评审网络、资源、探针和依赖关系,不能 视为完整可运行拓扑。 @@ -105,7 +105,6 @@ kubectl apply -f deploy/kubernetes/base/namespace.yaml kubectl -n proxy-pool apply -f ENVIRONMENT_SECRET.yaml kubectl apply -k deploy/kubernetes/base kubectl -n proxy-pool rollout status deployment/proxy-controller --timeout=5m -kubectl -n proxy-pool rollout status deployment/proxy-checker --timeout=5m kubectl -n proxy-pool rollout status deployment/proxy-gateway --timeout=10m ``` @@ -120,7 +119,6 @@ kubectl -n proxy-pool rollout status deployment/proxy-gateway --timeout=10m - 同一 Controller 同时启用 Distribution 与 Admin 时,Pod `/readyz` 以 Redis 活动池为服务流量门槛;PostgreSQL 故障由 Admin 接口独立返回不可用,不把仍可 完成的 Extract 从 Service 摘除。Admin-only 进程才同时检查 PostgreSQL 与 Redis。 -- Checker 在任务消费与结果上报通道可用时 Ready。 - `/metrics`:独立于业务入口,NetworkPolicy 仅允许监控命名空间访问。 探针不得执行 Provider 请求或完整数据库扫描。 diff --git a/docs/requirements/completion-audit.md b/docs/requirements/completion-audit.md index 60c1d9f..2da6c4b 100644 --- a/docs/requirements/completion-audit.md +++ b/docs/requirements/completion-audit.md @@ -85,7 +85,8 @@ Mermaid blocks 35 Windows 环境为 `CGO_ENABLED=0` 且没有 C 编译器,`go test -race` 在本机未执行; CI 已配置 Linux race job。PostgreSQL 18 和 Redis 8.2 的隔离 Adapter fixture -已经运行;完整 Controller/Gateway/Checker Docker/Kubernetes 拓扑仍只有静态验证。 +已经运行;当前 Docker 镜像和激活的 Compose/Kubernetes 清单只包含已实现的 +Controller/Gateway 入口,完整 mTLS 运行时拓扑仍只有静态验证。 ## 3. 后续实现范围 @@ -94,7 +95,7 @@ CI 已配置 Linux race job。PostgreSQL 18 和 Redis 8.2 的隔离 Adapter fixt 1. `cmd/proxy-checker/loadgen` 进程装配;`proxy-controller` 已完成 Admin/Distribution/Metrics 与 PostgreSQL/Redis 启动装配,`proxy-gateway` 已完成 HTTP/Metrics 与控制面 Session 装配,但 Provider 和业务指标链未闭环。 -2. Gateway 的带凭据 Proxy 分发、生产连接池调优与代表性流量压测。 +2. Gateway 的生产连接池调优与代表性流量压测。 3. Provider 分布式 singleflight/Leader、长期凭据回收和累计额度执行器。 4. Controller 的 PostgreSQL 连接池、迁移和 pgx Adapter 启动装配已完成; 公用 bootstrap 已通过 PostgreSQL 18 + Redis 8.2 双存储集成,Controller