fix: align deployment manifests with available commands
This commit is contained in:
parent
c267f77eee
commit
155411ef23
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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", "--"]
|
||||||
|
|
||||||
|
|||||||
@ -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}
|
|
||||||
|
|
||||||
|
|||||||
@ -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}}
|
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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}}]
|
||||||
|
|
||||||
|
|||||||
@ -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]
|
||||||
|
|
||||||
|
|||||||
@ -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: 独占提取发生持续事务冲突
|
||||||
|
|
||||||
|
|||||||
@ -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`。示例中的
|
||||||
|
|||||||
@ -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 请求或完整数据库扫描。
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user