fix: align deployment manifests with available commands
Some checks are pending
ci / proto (push) Waiting to run
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
ci / race (push) Waiting to run
ci / integration (push) Waiting to run

This commit is contained in:
youfak 2026-07-31 16:56:38 +08:00
parent c267f77eee
commit 155411ef23
12 changed files with 52 additions and 76 deletions

View File

@ -2,6 +2,8 @@ package deploy
import ( import (
"os" "os"
"path/filepath"
"regexp"
"slices" "slices"
"strings" "strings"
"testing" "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 { func loadComposeDocument(t *testing.T) composeDocument {
t.Helper() t.Helper()
return loadComposeFile(t, "docker-compose.yml") return loadComposeFile(t, "docker-compose.yml")
@ -172,3 +208,11 @@ func commandFlag(command []string, name string) (string, bool) {
} }
return "", false 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)
}
}

View File

@ -65,23 +65,6 @@ services:
retries: 12 retries: 12
start_period: 15s 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: haproxy:
image: haproxy:3.2-alpine image: haproxy:3.2-alpine
restart: unless-stopped restart: unless-stopped

View File

@ -11,11 +11,7 @@ ARG TARGETARCH=amd64
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
go build -trimpath -ldflags="-s -w" -o /out/proxy-gateway ./cmd/proxy-gateway && \ go build -trimpath -ldflags="-s -w" -o /out/proxy-gateway ./cmd/proxy-gateway && \
CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \ CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
go build -trimpath -ldflags="-s -w" -o /out/proxy-controller ./cmd/proxy-controller && \ 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
FROM debian:bookworm-slim FROM debian:bookworm-slim
@ -27,4 +23,3 @@ RUN apt-get update && \
COPY --from=build /out/ /usr/local/bin/ COPY --from=build /out/ /usr/local/bin/
USER 10001:10001 USER 10001:10001
ENTRYPOINT ["/usr/bin/tini", "--"] ENTRYPOINT ["/usr/bin/tini", "--"]

View File

@ -24,24 +24,3 @@ spec:
resource: resource:
name: memory name: memory
target: {type: Utilization, averageUtilization: 65} 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}

View File

@ -11,11 +11,3 @@ metadata: {name: proxy-controller, namespace: proxy-pool}
spec: spec:
minAvailable: 2 minAvailable: 2
selector: {matchLabels: {app.kubernetes.io/name: proxy-controller}} 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}}

View File

@ -6,7 +6,6 @@ resources:
- configmap.yaml - configmap.yaml
- gateway.yaml - gateway.yaml
- controller.yaml - controller.yaml
- checker.yaml
- availability.yaml - availability.yaml
- autoscaling.yaml - autoscaling.yaml
- networkpolicy.yaml - networkpolicy.yaml
@ -14,4 +13,3 @@ images:
- name: REGISTRY/proxy-pool - name: REGISTRY/proxy-pool
newName: REGISTRY/proxy-pool newName: REGISTRY/proxy-pool
newTag: VERSION newTag: VERSION

View File

@ -34,8 +34,7 @@ kind: NetworkPolicy
metadata: {name: control-plane-traffic, namespace: proxy-pool} metadata: {name: control-plane-traffic, namespace: proxy-pool}
spec: spec:
podSelector: podSelector:
matchExpressions: matchLabels: {app.kubernetes.io/name: proxy-controller}
- {key: app.kubernetes.io/name, operator: In, values: [proxy-controller, proxy-checker]}
policyTypes: [Ingress, Egress] policyTypes: [Ingress, Egress]
ingress: ingress:
- from: - from:
@ -49,4 +48,3 @@ spec:
ports: [{port: 53, protocol: UDP}, {port: 53, protocol: TCP}] ports: [{port: 53, protocol: UDP}, {port: 53, protocol: TCP}]
# Provider、健康目标及外部托管 PostgreSQL/Redis 的精确网段应在环境 Overlay 收紧。 # Provider、健康目标及外部托管 PostgreSQL/Redis 的精确网段应在环境 Overlay 收紧。
- to: [{ipBlock: {cidr: 0.0.0.0/0}}] - to: [{ipBlock: {cidr: 0.0.0.0/0}}]

View File

@ -14,11 +14,7 @@ scrape_configs:
- job_name: proxy-controller - job_name: proxy-controller
static_configs: static_configs:
- targets: [controller:9090] - targets: [controller:9090]
- job_name: proxy-checker
static_configs:
- targets: [checker:9090]
- job_name: haproxy - job_name: haproxy
metrics_path: /metrics metrics_path: /metrics
static_configs: static_configs:
- targets: [haproxy:8404] - targets: [haproxy:8404]

View File

@ -31,13 +31,6 @@ groups:
severity: warning severity: warning
annotations: annotations:
summary: Provider Fetch 错误持续发生 summary: Provider Fetch 错误持续发生
- alert: ProxyPoolCheckerBacklog
expr: proxy_pool_checker_queue_depth > 10000
for: 5m
labels:
severity: warning
annotations:
summary: Checker 队列积压
- alert: ProxyPoolExtractionConflict - alert: ProxyPoolExtractionConflict
expr: sum(rate(proxy_pool_extraction_total{result="conflict"}[5m])) > 0 expr: sum(rate(proxy_pool_extraction_total{result="conflict"}[5m])) > 0
for: 5m for: 5m
@ -45,4 +38,3 @@ groups:
severity: warning severity: warning
annotations: annotations:
summary: 独占提取发生持续事务冲突 summary: 独占提取发生持续事务冲突

View File

@ -22,7 +22,7 @@ go run ./cmd/proxy-controller -config CONFIG_FILE
PostgreSQL 管理面迁移、Redis 活动池、Distribution/Admin 独立监听与优雅停机; PostgreSQL 管理面迁移、Redis 活动池、Distribution/Admin 独立监听与优雅停机;
Controller Metrics 独立监听、`/livez`、`/readyz` 和基础 Prometheus 运行时指标; Controller Metrics 独立监听、`/livez`、`/readyz` 和基础 Prometheus 运行时指标;
Provider 自动补池、分布式配额、动态重载和 Admin 低基数统计已装配。Gateway 进程、 Provider 自动补池、分布式配额、动态重载和 Admin 低基数统计已装配。Gateway 进程、
Worker 控制面会话和 Snapshot 就绪探针已装配Checker、带凭据 Proxy 分发与代表性 Worker 控制面会话、Snapshot 凭据分发和 Snapshot 就绪探针已装配Checker 与代表性
负载验证仍在后续实施范围。 负载验证仍在后续实施范围。
所有时间值使用 Go duration例如 `500ms`、`30s`、`5m`。示例中的 所有时间值使用 Go duration例如 `500ms`、`30s`、`5m`。示例中的

View File

@ -20,8 +20,8 @@
`cmd/proxy-controller` 已完成配置单次加载、PostgreSQL 迁移、Redis 活动池、 `cmd/proxy-controller` 已完成配置单次加载、PostgreSQL 迁移、Redis 活动池、
Distribution/Admin/Metrics 独立监听和有界停机装配。Provider 自动补池、分布式 Distribution/Admin/Metrics 独立监听和有界停机装配。Provider 自动补池、分布式
配额、动态重载和 Admin 低基数统计已装配;完整 Gateway/Checker/Loadgen 与 Worker 配额、动态重载和 Admin 低基数统计已装配;Checker/Loadgen 与完整 mTLS 环境 Overlay
控制面仍属于 `implementation-plan.md` 后续任务。 仍属于 `implementation-plan.md` 后续任务。
因此 Compose/Kubernetes 资产当前仍用于评审网络、资源、探针和依赖关系,不能 因此 Compose/Kubernetes 资产当前仍用于评审网络、资源、探针和依赖关系,不能
视为完整可运行拓扑。 视为完整可运行拓扑。
@ -105,7 +105,6 @@ kubectl apply -f deploy/kubernetes/base/namespace.yaml
kubectl -n proxy-pool apply -f ENVIRONMENT_SECRET.yaml kubectl -n proxy-pool apply -f ENVIRONMENT_SECRET.yaml
kubectl apply -k deploy/kubernetes/base 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-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 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 - 同一 Controller 同时启用 Distribution 与 Admin 时Pod `/readyz` 以 Redis
活动池为服务流量门槛PostgreSQL 故障由 Admin 接口独立返回不可用,不把仍可 活动池为服务流量门槛PostgreSQL 故障由 Admin 接口独立返回不可用,不把仍可
完成的 Extract 从 Service 摘除。Admin-only 进程才同时检查 PostgreSQL 与 Redis。 完成的 Extract 从 Service 摘除。Admin-only 进程才同时检查 PostgreSQL 与 Redis。
- Checker 在任务消费与结果上报通道可用时 Ready。
- `/metrics`独立于业务入口NetworkPolicy 仅允许监控命名空间访问。 - `/metrics`独立于业务入口NetworkPolicy 仅允许监控命名空间访问。
探针不得执行 Provider 请求或完整数据库扫描。 探针不得执行 Provider 请求或完整数据库扫描。

View File

@ -85,7 +85,8 @@ Mermaid blocks 35
Windows 环境为 `CGO_ENABLED=0` 且没有 C 编译器,`go test -race` 在本机未执行; Windows 环境为 `CGO_ENABLED=0` 且没有 C 编译器,`go test -race` 在本机未执行;
CI 已配置 Linux race job。PostgreSQL 18 和 Redis 8.2 的隔离 Adapter fixture CI 已配置 Linux race job。PostgreSQL 18 和 Redis 8.2 的隔离 Adapter fixture
已经运行;完整 Controller/Gateway/Checker Docker/Kubernetes 拓扑仍只有静态验证。 已经运行;当前 Docker 镜像和激活的 Compose/Kubernetes 清单只包含已实现的
Controller/Gateway 入口,完整 mTLS 运行时拓扑仍只有静态验证。
## 3. 后续实现范围 ## 3. 后续实现范围
@ -94,7 +95,7 @@ CI 已配置 Linux race job。PostgreSQL 18 和 Redis 8.2 的隔离 Adapter fixt
1. `cmd/proxy-checker/loadgen` 进程装配;`proxy-controller` 已完成 1. `cmd/proxy-checker/loadgen` 进程装配;`proxy-controller` 已完成
Admin/Distribution/Metrics 与 PostgreSQL/Redis 启动装配,`proxy-gateway` 已完成 Admin/Distribution/Metrics 与 PostgreSQL/Redis 启动装配,`proxy-gateway` 已完成
HTTP/Metrics 与控制面 Session 装配,但 Provider 和业务指标链未闭环。 HTTP/Metrics 与控制面 Session 装配,但 Provider 和业务指标链未闭环。
2. Gateway 的带凭据 Proxy 分发、生产连接池调优与代表性流量压测。 2. Gateway 的生产连接池调优与代表性流量压测。
3. Provider 分布式 singleflight/Leader、长期凭据回收和累计额度执行器。 3. Provider 分布式 singleflight/Leader、长期凭据回收和累计额度执行器。
4. Controller 的 PostgreSQL 连接池、迁移和 pgx Adapter 启动装配已完成; 4. Controller 的 PostgreSQL 连接池、迁移和 pgx Adapter 启动装配已完成;
公用 bootstrap 已通过 PostgreSQL 18 + Redis 8.2 双存储集成Controller 公用 bootstrap 已通过 PostgreSQL 18 + Redis 8.2 双存储集成Controller