feat(deploy): autoscale apihost and keep sessions on one pod
apihost HPA: min 2 / max 6, CPU 65% as the primary signal, memory 80% as
the guard against L1 growth; scale-up reacts fast (20s window, +100% or
+4 pods per 30s, selectPolicy Max) while scale-down waits 300s and removes
one pod per minute, so a burst does not oscillate the fleet. max 6 is
1.5 CPU of requests, well inside the pool.
Ingress cookie affinity (GD-AFFINITY, HttpOnly, SameSite=Lax, Secure,
non-persistent) with value-strategy incremental: the cookie carries the
backend identity rather than a position in the balanced tree, so adding or
removing a replica under load does not reshuffle every existing session.
What this buys is L1 locality - cache.l1_capacity is per process - not
correctness: sessions, PoW and 2FA challenges live in Redis via
session.set, and the WS hub is in the im process, so a request landing on
another pod only pays an L2/origin read.
The annotations sit on the one gitdata.ai Ingress, which also carries
/ws/v1 (im) and *.git (githost): browsers do not store cookies from a WS
handshake response and git's HTTP client does not either, so the pinning
effectively applies to the apihost backend.
Verified live: HPA reports 2%/65% and 31%/80% from metrics-server, and
forcing the Deployment to 1 was corrected back to 2 within 6s
("Current number of replicas below Spec.MinReplicas"); responses now carry
Set-Cookie: GD-AFFINITY=...; Secure; HttpOnly; SameSite=Lax.
ZhenYi committed
Modified deploy/values/prod.yaml deploy/values/prod.yaml +41 −0 View deploy/values/prod.yaml
@@ -74,6 +74,47 @@
7474 enabled: true
7575 className: nginx
7676 host: gitdata.ai
77 annotations:
78 # 会话亲和:apihost 的 oxocache 带进程内 L1(cache.l1_capacity / l1_ttl_secs),
79 # 同一会话固定落在同一个 pod 才吃得到热缓存;跨 pod 迁移只是退回 L2/回源,
80 # 不影响正确性——会话、PoW、2FA challenge 都在 Redis 里(session.set),
81 # WS 集线器在 im 进程内,与 apihost 无关。
82 # 值策略用 incremental:cookie 存的是后端身份,HPA 增删副本时
83 # 已登录用户不会被整体重排(balanced 存的是索引,拓扑一变就错位)。
84 nginx.ingress.kubernetes.io/affinity: "cookie"
85 nginx.ingress.kubernetes.io/session-cookie-name: "GD-AFFINITY"
86 nginx.ingress.kubernetes.io/session-cookie-value-strategy: "incremental"
87 nginx.ingress.kubernetes.io/session-cookie-http-only: "true"
88 nginx.ingress.kubernetes.io/session-cookie-samesite: "Lax"
89 nginx.ingress.kubernetes.io/session-cookie-persistent: "false"
90 # 该注解作用于整张 Ingress:/ws/v1 的握手响应浏览器不会存 cookie(WS 无 cookie jar),
91 # git smart HTTP 客户端也不保存 cookie,因此实际只对 "/" -> apihost 生效。
92 # apihost 自动扩缩:CPU 是主指标,内存负责兜住 L1 缓存膨胀(limit 1Gi / request 256Mi)
93 # min 2 与 PDB minAvailable 1 相容;max 6 = 1.5 核请求量,节点池足够。
94apihost:
95 autoscaling:
96 enabled: true
97 minReplicas: 2
98 maxReplicas: 6
99 targetCPUUtilizationPercentage: 65
100 targetMemoryUtilizationPercentage: 80
101 behavior:
102 scaleUp:
103 stabilizationWindowSeconds: 20
104 policies:
105 - type: Percent
106 value: 100
107 periodSeconds: 30
108 - type: Pods
109 value: 4
110 periodSeconds: 30
111 selectPolicy: Max
112 scaleDown:
113 stabilizationWindowSeconds: 300
114 policies:
115 - type: Pods
116 value: 1
117 periodSeconds: 60
77118 tls:
78119 enabled: true
79120 secretName: ""