Files
easyai-ai-gateway/deploy/kubernetes/production/application.yaml
T
wangbo bc44af751e fix(worker): 为容量扩展预留数据库连接
原因:单实例执行容量提升到 24 后,Worker 的 24 条数据库连接会被执行任务全部占用,导致心跳、选主、健康检查和并发租约续期超时。

影响:生产 Worker 连接池提高到 32,在 24 个执行槽之外保留 8 条控制连接;PostgreSQL max_connections=200,两实例与 API 的理论连接总量仍在安全范围内。

验证:kubectl kustomize deploy/kubernetes/production、git diff --check 通过;线上两地 Worker 按 32 条连接滚动后连续 3 分钟 Ready、0 重启、0 数据库控制错误、0 租约丢失。
2026-07-30 16:17:16 +08:00

846 lines
22 KiB
YAML

apiVersion: apps/v1
kind: Deployment
metadata:
name: easyai-api-ningbo
labels:
app.kubernetes.io/name: easyai-api
app.kubernetes.io/component: api
app.kubernetes.io/part-of: easyai-ai-gateway
spec:
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app.kubernetes.io/name: easyai-api
easyai.io/site: ningbo
template:
metadata:
labels:
app.kubernetes.io/name: easyai-api
app.kubernetes.io/component: api
app.kubernetes.io/part-of: easyai-ai-gateway
easyai.io/site: ningbo
spec:
serviceAccountName: easyai-ai-gateway
terminationGracePeriodSeconds: 90
nodeSelector:
easyai.io/site: ningbo
easyai.io/workload: "true"
securityContext:
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
fsGroup: 10001
fsGroupChangePolicy: OnRootMismatch
seccompProfile:
type: RuntimeDefault
containers:
- name: api
image: easyai-api
imagePullPolicy: IfNotPresent
envFrom:
- configMapRef:
name: easyai-ai-gateway-config
- secretRef:
name: easyai-ai-gateway-runtime
env:
- name: AI_GATEWAY_PROCESS_ROLE
value: api
- name: AI_GATEWAY_ASYNC_QUEUE_WORKER_ENABLED
value: "false"
- name: AI_GATEWAY_DATABASE_MAX_CONNS
value: "16"
- name: AI_GATEWAY_MEDIA_REQUEST_CONCURRENCY
value: "16"
- name: AI_GATEWAY_MEDIA_MATERIALIZATION_CONCURRENCY
value: "8"
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_UID
valueFrom:
fieldRef:
fieldPath: metadata.uid
- name: EASYAI_SITE
value: ningbo
ports:
- name: http
containerPort: 8088
startupProbe:
httpGet:
path: /api/v1/healthz
port: http
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 120
readinessProbe:
httpGet:
path: /api/v1/readyz
port: http
initialDelaySeconds: 3
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 6
livenessProbe:
httpGet:
path: /api/v1/healthz
port: http
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 6
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 10"]
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: "2"
memory: 2Gi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
readOnlyRootFilesystem: true
volumeMounts:
- name: application-data
mountPath: /app/data
- name: temporary-files
mountPath: /tmp
volumes:
- name: application-data
emptyDir:
sizeLimit: 5Gi
- name: temporary-files
emptyDir:
sizeLimit: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: easyai-api-hongkong
labels:
app.kubernetes.io/name: easyai-api
app.kubernetes.io/component: api
app.kubernetes.io/part-of: easyai-ai-gateway
spec:
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app.kubernetes.io/name: easyai-api
easyai.io/site: hongkong
template:
metadata:
labels:
app.kubernetes.io/name: easyai-api
app.kubernetes.io/component: api
app.kubernetes.io/part-of: easyai-ai-gateway
easyai.io/site: hongkong
spec:
serviceAccountName: easyai-ai-gateway
terminationGracePeriodSeconds: 90
nodeSelector:
easyai.io/site: hongkong
easyai.io/workload: "true"
securityContext:
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
fsGroup: 10001
fsGroupChangePolicy: OnRootMismatch
seccompProfile:
type: RuntimeDefault
containers:
- name: api
image: easyai-api
imagePullPolicy: IfNotPresent
envFrom:
- configMapRef:
name: easyai-ai-gateway-config
- secretRef:
name: easyai-ai-gateway-runtime
env:
- name: AI_GATEWAY_PROCESS_ROLE
value: api
- name: AI_GATEWAY_ASYNC_QUEUE_WORKER_ENABLED
value: "false"
- name: AI_GATEWAY_DATABASE_MAX_CONNS
value: "16"
- name: AI_GATEWAY_MEDIA_REQUEST_CONCURRENCY
value: "16"
- name: AI_GATEWAY_MEDIA_MATERIALIZATION_CONCURRENCY
value: "8"
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_UID
valueFrom:
fieldRef:
fieldPath: metadata.uid
- name: EASYAI_SITE
value: hongkong
ports:
- name: http
containerPort: 8088
startupProbe:
httpGet:
path: /api/v1/healthz
port: http
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 120
readinessProbe:
httpGet:
path: /api/v1/readyz
port: http
initialDelaySeconds: 3
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 6
livenessProbe:
httpGet:
path: /api/v1/healthz
port: http
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 6
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 10"]
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: "2"
memory: 2Gi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
readOnlyRootFilesystem: true
volumeMounts:
- name: application-data
mountPath: /app/data
- name: temporary-files
mountPath: /tmp
volumes:
- name: application-data
emptyDir:
sizeLimit: 5Gi
- name: temporary-files
emptyDir:
sizeLimit: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: easyai-worker-ningbo
labels:
app.kubernetes.io/name: easyai-worker
app.kubernetes.io/component: worker
app.kubernetes.io/part-of: easyai-ai-gateway
spec:
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app.kubernetes.io/name: easyai-worker
easyai.io/site: ningbo
template:
metadata:
labels:
app.kubernetes.io/name: easyai-worker
app.kubernetes.io/component: worker
app.kubernetes.io/part-of: easyai-ai-gateway
easyai.io/site: ningbo
spec:
serviceAccountName: easyai-ai-gateway
terminationGracePeriodSeconds: 90
nodeSelector:
easyai.io/site: ningbo
easyai.io/workload: "true"
securityContext:
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
fsGroup: 10001
fsGroupChangePolicy: OnRootMismatch
seccompProfile:
type: RuntimeDefault
containers:
- name: worker
image: easyai-api
imagePullPolicy: IfNotPresent
envFrom:
- configMapRef:
name: easyai-ai-gateway-config
- secretRef:
name: easyai-ai-gateway-runtime
env:
- name: AI_GATEWAY_PROCESS_ROLE
value: worker
- name: AI_GATEWAY_ASYNC_QUEUE_WORKER_ENABLED
value: "true"
- name: AI_GATEWAY_DATABASE_MAX_CONNS
value: "32"
- name: AI_GATEWAY_ASYNC_WORKER_INSTANCE_HARD_LIMIT
value: "24"
- name: AI_GATEWAY_MEDIA_MATERIALIZATION_CONCURRENCY
value: "24"
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_UID
valueFrom:
fieldRef:
fieldPath: metadata.uid
- name: EASYAI_SITE
value: ningbo
ports:
- name: health
containerPort: 8088
startupProbe:
httpGet:
path: /healthz
port: health
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 120
readinessProbe:
httpGet:
path: /readyz
port: health
initialDelaySeconds: 3
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 6
livenessProbe:
httpGet:
path: /healthz
port: health
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 6
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 10"]
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: "2"
memory: 2Gi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
readOnlyRootFilesystem: true
volumeMounts:
- name: application-data
mountPath: /app/data
- name: temporary-files
mountPath: /tmp
volumes:
- name: application-data
emptyDir:
sizeLimit: 5Gi
- name: temporary-files
emptyDir:
sizeLimit: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: easyai-worker-hongkong
labels:
app.kubernetes.io/name: easyai-worker
app.kubernetes.io/component: worker
app.kubernetes.io/part-of: easyai-ai-gateway
spec:
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app.kubernetes.io/name: easyai-worker
easyai.io/site: hongkong
template:
metadata:
labels:
app.kubernetes.io/name: easyai-worker
app.kubernetes.io/component: worker
app.kubernetes.io/part-of: easyai-ai-gateway
easyai.io/site: hongkong
spec:
serviceAccountName: easyai-ai-gateway
terminationGracePeriodSeconds: 90
nodeSelector:
easyai.io/site: hongkong
easyai.io/workload: "true"
securityContext:
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
fsGroup: 10001
fsGroupChangePolicy: OnRootMismatch
seccompProfile:
type: RuntimeDefault
containers:
- name: worker
image: easyai-api
imagePullPolicy: IfNotPresent
envFrom:
- configMapRef:
name: easyai-ai-gateway-config
- secretRef:
name: easyai-ai-gateway-runtime
env:
- name: AI_GATEWAY_PROCESS_ROLE
value: worker
- name: AI_GATEWAY_ASYNC_QUEUE_WORKER_ENABLED
value: "true"
- name: AI_GATEWAY_DATABASE_MAX_CONNS
value: "32"
- name: AI_GATEWAY_ASYNC_WORKER_INSTANCE_HARD_LIMIT
value: "24"
- name: AI_GATEWAY_MEDIA_MATERIALIZATION_CONCURRENCY
value: "24"
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_UID
valueFrom:
fieldRef:
fieldPath: metadata.uid
- name: EASYAI_SITE
value: hongkong
ports:
- name: health
containerPort: 8088
startupProbe:
httpGet:
path: /healthz
port: health
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 120
readinessProbe:
httpGet:
path: /readyz
port: health
initialDelaySeconds: 3
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 6
livenessProbe:
httpGet:
path: /healthz
port: health
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 6
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 10"]
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: "2"
memory: 2Gi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
readOnlyRootFilesystem: true
volumeMounts:
- name: application-data
mountPath: /app/data
- name: temporary-files
mountPath: /tmp
volumes:
- name: application-data
emptyDir:
sizeLimit: 5Gi
- name: temporary-files
emptyDir:
sizeLimit: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: easyai-web-ningbo
labels:
app.kubernetes.io/name: easyai-web
app.kubernetes.io/component: web
app.kubernetes.io/part-of: easyai-ai-gateway
spec:
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app.kubernetes.io/name: easyai-web
easyai.io/site: ningbo
template:
metadata:
labels:
app.kubernetes.io/name: easyai-web
app.kubernetes.io/component: web
app.kubernetes.io/part-of: easyai-ai-gateway
easyai.io/site: ningbo
spec:
automountServiceAccountToken: false
terminationGracePeriodSeconds: 30
nodeSelector:
easyai.io/site: ningbo
easyai.io/workload: "true"
securityContext:
runAsNonRoot: true
runAsUser: 101
runAsGroup: 101
fsGroup: 101
fsGroupChangePolicy: OnRootMismatch
seccompProfile:
type: RuntimeDefault
containers:
- name: web
image: easyai-web
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 3
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 6
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 6
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 500m
memory: 256Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
add: ["NET_BIND_SERVICE"]
readOnlyRootFilesystem: true
volumeMounts:
- name: nginx-cache
mountPath: /var/cache/nginx
- name: nginx-run
mountPath: /var/run
volumes:
- name: nginx-cache
emptyDir:
sizeLimit: 128Mi
- name: nginx-run
emptyDir:
sizeLimit: 16Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: easyai-web-hongkong
labels:
app.kubernetes.io/name: easyai-web
app.kubernetes.io/component: web
app.kubernetes.io/part-of: easyai-ai-gateway
spec:
replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app.kubernetes.io/name: easyai-web
easyai.io/site: hongkong
template:
metadata:
labels:
app.kubernetes.io/name: easyai-web
app.kubernetes.io/component: web
app.kubernetes.io/part-of: easyai-ai-gateway
easyai.io/site: hongkong
spec:
automountServiceAccountToken: false
terminationGracePeriodSeconds: 30
nodeSelector:
easyai.io/site: hongkong
easyai.io/workload: "true"
securityContext:
runAsNonRoot: true
runAsUser: 101
runAsGroup: 101
fsGroup: 101
fsGroupChangePolicy: OnRootMismatch
seccompProfile:
type: RuntimeDefault
containers:
- name: web
image: easyai-web
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 3
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 6
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 15
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 6
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 500m
memory: 256Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
add: ["NET_BIND_SERVICE"]
readOnlyRootFilesystem: true
volumeMounts:
- name: nginx-cache
mountPath: /var/cache/nginx
- name: nginx-run
mountPath: /var/run
volumes:
- name: nginx-cache
emptyDir:
sizeLimit: 128Mi
- name: nginx-run
emptyDir:
sizeLimit: 16Mi
---
apiVersion: v1
kind: Service
metadata:
name: api
labels:
app.kubernetes.io/name: easyai-api
app.kubernetes.io/component: api
app.kubernetes.io/part-of: easyai-ai-gateway
spec:
type: NodePort
externalTrafficPolicy: Local
selector:
app.kubernetes.io/name: easyai-api
ports:
- name: http
port: 8088
targetPort: http
nodePort: 30088
---
apiVersion: v1
kind: Service
metadata:
name: web
labels:
app.kubernetes.io/name: easyai-web
app.kubernetes.io/component: web
app.kubernetes.io/part-of: easyai-ai-gateway
spec:
type: NodePort
externalTrafficPolicy: Local
selector:
app.kubernetes.io/name: easyai-web
ports:
- name: http
port: 80
targetPort: http
nodePort: 30178
---
apiVersion: v1
kind: Service
metadata:
name: api-ningbo-edge
labels:
app.kubernetes.io/name: easyai-api
app.kubernetes.io/component: api
app.kubernetes.io/part-of: easyai-ai-gateway
easyai.io/site: ningbo
spec:
type: NodePort
externalTrafficPolicy: Local
selector:
app.kubernetes.io/name: easyai-api
easyai.io/site: ningbo
ports:
- name: http
port: 8088
targetPort: http
nodePort: 31088
---
apiVersion: v1
kind: Service
metadata:
name: api-hongkong-edge
labels:
app.kubernetes.io/name: easyai-api
app.kubernetes.io/component: api
app.kubernetes.io/part-of: easyai-ai-gateway
easyai.io/site: hongkong
spec:
type: NodePort
externalTrafficPolicy: Local
selector:
app.kubernetes.io/name: easyai-api
easyai.io/site: hongkong
ports:
- name: http
port: 8088
targetPort: http
nodePort: 31089
---
apiVersion: v1
kind: Service
metadata:
name: web-ningbo-edge
labels:
app.kubernetes.io/name: easyai-web
app.kubernetes.io/component: web
app.kubernetes.io/part-of: easyai-ai-gateway
easyai.io/site: ningbo
spec:
type: NodePort
externalTrafficPolicy: Local
selector:
app.kubernetes.io/name: easyai-web
easyai.io/site: ningbo
ports:
- name: http
port: 80
targetPort: http
nodePort: 31178
---
apiVersion: v1
kind: Service
metadata:
name: web-hongkong-edge
labels:
app.kubernetes.io/name: easyai-web
app.kubernetes.io/component: web
app.kubernetes.io/part-of: easyai-ai-gateway
easyai.io/site: hongkong
spec:
type: NodePort
externalTrafficPolicy: Local
selector:
app.kubernetes.io/name: easyai-web
easyai.io/site: hongkong
ports:
- name: http
port: 80
targetPort: http
nodePort: 31179
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: easyai-api
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: easyai-api
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: easyai-web
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: easyai-web
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: easyai-worker
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: easyai-worker