chore: establish local platform baseline

This commit is contained in:
Codex Local
2026-08-26 06:41:54 +08:00
commit 29bdf4900f
575 changed files with 95644 additions and 0 deletions
+135
View File
@@ -0,0 +1,135 @@
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: api
namespace: voice-platform
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: voice-platform-api
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: callbacks
namespace: voice-platform
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: voice-platform-callbacks
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: worker
namespace: voice-platform
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: voice-platform-worker
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web
namespace: voice-platform
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: voice-platform-web
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api
namespace: voice-platform
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api
minReplicas: 2
maxReplicas: 10
behavior:
scaleDown:
stabilizationWindowSeconds: 300
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: callbacks
namespace: voice-platform
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: callbacks
minReplicas: 2
maxReplicas: 8
behavior:
scaleDown:
stabilizationWindowSeconds: 300
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: worker
namespace: voice-platform
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: worker
minReplicas: 2
maxReplicas: 8
behavior:
scaleDown:
stabilizationWindowSeconds: 300
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web
namespace: voice-platform
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web
minReplicas: 2
maxReplicas: 6
behavior:
scaleDown:
stabilizationWindowSeconds: 300
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
+73
View File
@@ -0,0 +1,73 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: voice-platform-config
namespace: voice-platform
data:
APP_ENV: stage
LOG_LEVEL: info
REDIS_ADDR: redis.example.invalid:6379
REDIS_DB: "0"
AUTH_ISSUER_URL: https://identity.example.invalid/realms/voice
AUTH_JWKS_URL: https://identity.example.invalid/realms/voice/protocol/openid-connect/certs
AUTH_AUDIENCE: voice-platform-web
OTEL_EXPORTER_OTLP_ENDPOINT: otel-collector.monitoring.svc.cluster.local:4317
DEPENDENCY_TIMEOUT: 3s
EXTERNAL_PROBE_INTERVAL: 30s
SHUTDOWN_TIMEOUT: 20s
RATE_LIMIT_RPS: "50"
RATE_LIMIT_BURST: "100"
RATE_LIMIT_USER_RPS: "20"
RATE_LIMIT_USER_BURST: "40"
RATE_LIMIT_TENANT_RPS: "200"
RATE_LIMIT_TENANT_BURST: "400"
RATE_LIMIT_DEVICE_RPS: "10"
RATE_LIMIT_DEVICE_BURST: "20"
PROVIDER_START_RPS: "20"
PROVIDER_START_BURST: "40"
PROVIDER_MAX_ACTIVE_TASKS: "100"
DEVICE_CLOCK_SKEW: 5m
RTC_APP_ID: "000000000000000000000000"
RTC_TOKEN_ISSUER: volcengine
RTC_TOKEN_TTL: 5m
CONVERSATION_ALLOCATION_TTL: 30s
HEARTBEAT_INTERVAL_SECONDS: "15"
PROVIDER_CALLBACK_CLOCK_SKEW: 5m
PROVIDER_REQUEST_TIMEOUT: 5s
PROVIDER_FAILURE_THRESHOLD: "3"
PROVIDER_CIRCUIT_COOLDOWN: 1m
RECOVERY_SCAN_INTERVAL: 5s
RECOVERY_STARTING_AFTER: 20s
RECOVERY_STOPPING_AFTER: 20s
OBJECT_STORE_ENDPOINT: object-storage.example.invalid:443
OBJECT_STORE_PUBLIC_ENDPOINT: downloads.example.invalid:443
OBJECT_STORE_EXPORT_BUCKET: private-exports
OBJECT_STORE_REGION: cn-beijing
OBJECT_STORE_SECURE: "true"
EXPORT_DOWNLOAD_TTL: 10m
EXPORT_OBJECT_TTL: 24h
VOICE_PROVIDER: volcengine
VOLC_RTC_BASE_URL: https://rtc.volcengineapi.com
VOLC_RTC_REGION: cn-north-1
VOLC_RTC_API_VERSION: "2024-12-01"
CONTENT_GENERATOR: ark
CONTENT_SAFETY_PROVIDER: managed_http
CONTENT_SAFETY_ENDPOINT: https://content-safety.example.invalid/v1/classify
CONTENT_SAFETY_POLICY_REF: replace-with-approved-content-safety-policy
CONTENT_SAFETY_TIMEOUT: 5s
EMBEDDING_PROVIDER: ark
ARK_BASE_URL: https://ark.cn-beijing.volces.com/api/v3
ARK_CONTENT_MODEL: replace-with-ark-content-endpoint-id
ARK_EMBEDDING_MODEL: replace-with-ark-embedding-endpoint-id
ARK_REQUEST_TIMEOUT: 30s
WORKER_POLL_INTERVAL: 2s
ALERT_WEBHOOK_TIMEOUT: 5s
---
apiVersion: v1
kind: ConfigMap
metadata:
name: voice-platform-web-config
namespace: voice-platform
data:
WEB_OIDC_AUTHORITY: https://identity.example.invalid/realms/voice
WEB_OIDC_CLIENT_ID: voice-platform-web
+452
View File
@@ -0,0 +1,452 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: voice-platform
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
selector:
matchLabels:
app.kubernetes.io/name: voice-platform-api
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/path: /metrics
prometheus.io/port: "8080"
labels:
app.kubernetes.io/name: voice-platform-api
app.kubernetes.io/component: api
spec:
serviceAccountName: voice-platform-api
automountServiceAccountToken: false
terminationGracePeriodSeconds: 30
securityContext:
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
fsGroup: 65532
seccompProfile:
type: RuntimeDefault
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/name: voice-platform-api
containers:
- name: api
image: registry.example.invalid/voice-platform/backend:0.1.0
imagePullPolicy: IfNotPresent
command: ["/app/api"]
envFrom:
- configMapRef:
name: voice-platform-config
env:
- name: HTTP_ADDR
value: 0.0.0.0:8080
- name: DATABASE_URL_FILE
value: /var/run/secrets/voice-platform/common/database-url
- name: REDIS_PASSWORD_FILE
value: /var/run/secrets/voice-platform/common/redis-password
- name: DEVICE_SECRET_DIRECTORY
value: /var/run/secrets/voice-platform/devices
- name: RTC_APP_KEY_FILE
value: /var/run/secrets/voice-platform/api/rtc-app-key
- name: CURSOR_SIGNING_SECRET_FILE
value: /var/run/secrets/voice-platform/api/cursor-signing-secret
- name: SHARE_TOKEN_SIGNING_SECRET_FILE
value: /var/run/secrets/voice-platform/api/share-token-signing-secret
- name: OBJECT_STORE_ACCESS_KEY_FILE
value: /var/run/secrets/voice-platform/model-storage/object-store-access-key
- name: OBJECT_STORE_SECRET_KEY_FILE
value: /var/run/secrets/voice-platform/model-storage/object-store-secret-key
- name: ARK_API_KEY_FILE
value: /var/run/secrets/voice-platform/model-storage/ark-api-key
ports:
- name: http
containerPort: 8080
startupProbe:
httpGet:
path: /health/live
port: http
periodSeconds: 2
failureThreshold: 30
readinessProbe:
httpGet:
path: /health/ready
port: http
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 3
livenessProbe:
httpGet:
path: /health/live
port: http
periodSeconds: 15
timeoutSeconds: 2
failureThreshold: 3
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: "1"
memory: 768Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumeMounts:
- name: common-secrets
mountPath: /var/run/secrets/voice-platform/common
readOnly: true
- name: api-secrets
mountPath: /var/run/secrets/voice-platform/api
readOnly: true
- name: model-storage-secrets
mountPath: /var/run/secrets/voice-platform/model-storage
readOnly: true
- name: device-secrets
mountPath: /var/run/secrets/voice-platform/devices
readOnly: true
volumes:
- name: common-secrets
secret:
secretName: voice-platform-common-secrets
- name: api-secrets
secret:
secretName: voice-platform-api-secrets
- name: model-storage-secrets
secret:
secretName: voice-platform-model-storage-secrets
- name: device-secrets
secret:
secretName: voice-platform-device-secrets
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: callbacks
namespace: voice-platform
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
selector:
matchLabels:
app.kubernetes.io/name: voice-platform-callbacks
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/path: /metrics
prometheus.io/port: "8081"
labels:
app.kubernetes.io/name: voice-platform-callbacks
app.kubernetes.io/component: callbacks
spec:
serviceAccountName: voice-platform-callbacks
automountServiceAccountToken: false
terminationGracePeriodSeconds: 30
securityContext:
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
fsGroup: 65532
seccompProfile:
type: RuntimeDefault
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/name: voice-platform-callbacks
containers:
- name: callbacks
image: registry.example.invalid/voice-platform/backend:0.1.0
imagePullPolicy: IfNotPresent
command: ["/app/callbacks"]
envFrom:
- configMapRef:
name: voice-platform-config
env:
- name: HTTP_ADDR
value: 0.0.0.0:8081
- name: DATABASE_URL_FILE
value: /var/run/secrets/voice-platform/common/database-url
- name: REDIS_PASSWORD_FILE
value: /var/run/secrets/voice-platform/common/redis-password
- name: PROVIDER_CALLBACK_SECRET_FILE
value: /var/run/secrets/voice-platform/callbacks/provider-callback-secret
ports:
- name: http
containerPort: 8081
startupProbe:
httpGet:
path: /health/live
port: http
periodSeconds: 2
failureThreshold: 30
readinessProbe:
httpGet:
path: /health/ready
port: http
periodSeconds: 5
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /health/live
port: http
periodSeconds: 15
timeoutSeconds: 2
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 384Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumeMounts:
- name: common-secrets
mountPath: /var/run/secrets/voice-platform/common
readOnly: true
- name: callbacks-secrets
mountPath: /var/run/secrets/voice-platform/callbacks
readOnly: true
volumes:
- name: common-secrets
secret:
secretName: voice-platform-common-secrets
- name: callbacks-secrets
secret:
secretName: voice-platform-callbacks-secrets
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: worker
namespace: voice-platform
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
selector:
matchLabels:
app.kubernetes.io/name: voice-platform-worker
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/path: /metrics
prometheus.io/port: "8082"
labels:
app.kubernetes.io/name: voice-platform-worker
app.kubernetes.io/component: worker
spec:
serviceAccountName: voice-platform-worker
automountServiceAccountToken: false
terminationGracePeriodSeconds: 30
securityContext:
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
fsGroup: 65532
seccompProfile:
type: RuntimeDefault
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/name: voice-platform-worker
containers:
- name: worker
image: registry.example.invalid/voice-platform/backend:0.1.0
imagePullPolicy: IfNotPresent
command: ["/app/worker"]
envFrom:
- configMapRef:
name: voice-platform-config
env:
- name: HTTP_ADDR
value: 0.0.0.0:8082
- name: DATABASE_URL_FILE
value: /var/run/secrets/voice-platform/common/database-url
- name: REDIS_PASSWORD_FILE
value: /var/run/secrets/voice-platform/common/redis-password
- name: VOLC_ACCESS_KEY_ID_FILE
value: /var/run/secrets/voice-platform/worker/volc-access-key-id
- name: VOLC_SECRET_ACCESS_KEY_FILE
value: /var/run/secrets/voice-platform/worker/volc-secret-access-key
- name: VOLC_VOICE_CHAT_TEMPLATE_FILE
value: /var/run/secrets/voice-platform/worker/voice-chat-template.json
- name: OBJECT_STORE_ACCESS_KEY_FILE
value: /var/run/secrets/voice-platform/model-storage/object-store-access-key
- name: OBJECT_STORE_SECRET_KEY_FILE
value: /var/run/secrets/voice-platform/model-storage/object-store-secret-key
- name: ARK_API_KEY_FILE
value: /var/run/secrets/voice-platform/model-storage/ark-api-key
- name: CONTENT_SAFETY_API_KEY_FILE
value: /var/run/secrets/voice-platform/model-storage/content-safety-api-key
ports:
- name: http
containerPort: 8082
startupProbe:
httpGet:
path: /health/live
port: http
periodSeconds: 2
failureThreshold: 30
readinessProbe:
httpGet:
path: /health/ready
port: http
periodSeconds: 5
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /health/live
port: http
periodSeconds: 15
timeoutSeconds: 2
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: "1"
memory: 768Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumeMounts:
- name: common-secrets
mountPath: /var/run/secrets/voice-platform/common
readOnly: true
- name: worker-secrets
mountPath: /var/run/secrets/voice-platform/worker
readOnly: true
- name: model-storage-secrets
mountPath: /var/run/secrets/voice-platform/model-storage
readOnly: true
volumes:
- name: common-secrets
secret:
secretName: voice-platform-common-secrets
- name: worker-secrets
secret:
secretName: voice-platform-worker-secrets
- name: model-storage-secrets
secret:
secretName: voice-platform-model-storage-secrets
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: voice-platform
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
selector:
matchLabels:
app.kubernetes.io/name: voice-platform-web
template:
metadata:
labels:
app.kubernetes.io/name: voice-platform-web
app.kubernetes.io/component: web
spec:
serviceAccountName: voice-platform-web
automountServiceAccountToken: false
terminationGracePeriodSeconds: 30
securityContext:
runAsNonRoot: true
runAsUser: 101
runAsGroup: 101
fsGroup: 101
seccompProfile:
type: RuntimeDefault
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/name: voice-platform-web
containers:
- name: web
image: registry.example.invalid/voice-platform/web:0.1.0
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c"]
args: ["/docker-entrypoint.d/40-runtime-config.sh && exec nginx -g 'daemon off;'"]
envFrom:
- configMapRef:
name: voice-platform-web-config
ports:
- name: http
containerPort: 8080
startupProbe:
httpGet:
path: /runtime-config.js
port: http
periodSeconds: 2
failureThreshold: 15
readinessProbe:
httpGet:
path: /runtime-config.js
port: http
periodSeconds: 5
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /runtime-config.js
port: http
periodSeconds: 15
timeoutSeconds: 2
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 250m
memory: 192Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir:
sizeLimit: 32Mi
+55
View File
@@ -0,0 +1,55 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: voice-platform
namespace: voice-platform
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: 10m
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- voice-stage.example.invalid
secretName: voice-platform-tls
rules:
- host: voice-stage.example.invalid
http:
paths:
- path: /callbacks
pathType: Prefix
backend:
service:
name: callbacks
port:
number: 8081
- path: /device
pathType: Prefix
backend:
service:
name: api
port:
number: 8080
- path: /api
pathType: Prefix
backend:
service:
name: api
port:
number: 8080
- path: /health
pathType: Prefix
backend:
service:
name: api
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 8080
+16
View File
@@ -0,0 +1,16 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- configmap.yaml
- serviceaccounts.yaml
- deployments.yaml
- services.yaml
- ingress.yaml
- availability.yaml
- network-policies.yaml
labels:
- pairs:
app.kubernetes.io/part-of: voice-platform
includeSelectors: true
includeTemplates: true
+9
View File
@@ -0,0 +1,9 @@
apiVersion: v1
kind: Namespace
metadata:
name: voice-platform
labels:
app.kubernetes.io/part-of: voice-platform
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
@@ -0,0 +1,59 @@
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: voice-platform
spec:
podSelector: {}
policyTypes:
- Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-controller
namespace: voice-platform
spec:
podSelector:
matchExpressions:
- key: app.kubernetes.io/component
operator: In
values: [api, callbacks, web]
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
ports:
- protocol: TCP
port: 8080
- protocol: TCP
port: 8081
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-monitoring
namespace: voice-platform
spec:
podSelector:
matchExpressions:
- key: app.kubernetes.io/component
operator: In
values: [api, callbacks, worker]
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
ports:
- protocol: TCP
port: 8080
- protocol: TCP
port: 8081
- protocol: TCP
port: 8082
@@ -0,0 +1,27 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: voice-platform-api
namespace: voice-platform
automountServiceAccountToken: false
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: voice-platform-callbacks
namespace: voice-platform
automountServiceAccountToken: false
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: voice-platform-worker
namespace: voice-platform
automountServiceAccountToken: false
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: voice-platform-web
namespace: voice-platform
automountServiceAccountToken: false
+59
View File
@@ -0,0 +1,59 @@
apiVersion: v1
kind: Service
metadata:
name: api
namespace: voice-platform
labels:
app.kubernetes.io/name: voice-platform-api
spec:
selector:
app.kubernetes.io/name: voice-platform-api
ports:
- name: http
port: 8080
targetPort: http
---
apiVersion: v1
kind: Service
metadata:
name: callbacks
namespace: voice-platform
labels:
app.kubernetes.io/name: voice-platform-callbacks
spec:
selector:
app.kubernetes.io/name: voice-platform-callbacks
ports:
- name: http
port: 8081
targetPort: http
---
apiVersion: v1
kind: Service
metadata:
name: worker
namespace: voice-platform
labels:
app.kubernetes.io/name: voice-platform-worker
spec:
selector:
app.kubernetes.io/name: voice-platform-worker
ports:
- name: http
port: 8082
targetPort: http
---
apiVersion: v1
kind: Service
metadata:
name: web
namespace: voice-platform
labels:
app.kubernetes.io/name: voice-platform-web
spec:
selector:
app.kubernetes.io/name: voice-platform-web
ports:
- name: http
port: 8080
targetPort: http
@@ -0,0 +1,62 @@
# Copy this file into an environment-owned directory and replace every provider
# and parameters block according to the installed Secrets Store CSI provider.
# Every provider object must use the exact mounted filename documented below.
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: voice-platform-common
namespace: voice-platform
spec:
provider: replace-with-installed-provider
parameters:
objects: replace-with-provider-specific-database-url-and-redis-password
---
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: voice-platform-api
namespace: voice-platform
spec:
provider: replace-with-installed-provider
parameters:
objects: replace-with-provider-specific-rtc-app-key-cursor-and-share-secrets
---
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: voice-platform-callbacks
namespace: voice-platform
spec:
provider: replace-with-installed-provider
parameters:
objects: replace-with-provider-specific-callback-secret
---
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: voice-platform-worker
namespace: voice-platform
spec:
provider: replace-with-installed-provider
parameters:
objects: replace-with-provider-specific-volc-credentials-and-voice-template
---
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: voice-platform-model-storage
namespace: voice-platform
spec:
provider: replace-with-installed-provider
parameters:
objects: replace-with-provider-specific-object-store-ark-and-content-safety-credentials
---
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: voice-platform-devices
namespace: voice-platform
spec:
provider: replace-with-installed-provider
parameters:
objects: replace-with-provider-specific-per-device-secrets
@@ -0,0 +1,35 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../migration
patches:
- target:
group: batch
version: v1
kind: Job
name: voice-platform-migrate
patch: |-
- op: remove
path: /spec/template/spec/containers/0/env
- op: add
path: /spec/template/spec/containers/0/command
value: ["/bin/sh", "-ec"]
- op: replace
path: /spec/template/spec/containers/0/args
value:
- 'database_url=""; IFS= read -r database_url < /var/run/secrets/voice-platform/common/database-url || [ -n "$database_url" ]; exec migrate -path=/migrations -database "$database_url" up'
- op: add
path: /spec/template/spec/containers/0/volumeMounts
value:
- name: common-secrets
mountPath: /var/run/secrets/voice-platform/common
readOnly: true
- op: add
path: /spec/template/spec/volumes
value:
- name: common-secrets
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: voice-platform-common
+52
View File
@@ -0,0 +1,52 @@
apiVersion: batch/v1
kind: Job
metadata:
name: voice-platform-migrate
namespace: voice-platform
labels:
app.kubernetes.io/name: voice-platform-migrate
app.kubernetes.io/part-of: voice-platform
spec:
backoffLimit: 2
activeDeadlineSeconds: 600
ttlSecondsAfterFinished: 600
template:
metadata:
labels:
app.kubernetes.io/name: voice-platform-migrate
app.kubernetes.io/part-of: voice-platform
spec:
restartPolicy: Never
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
seccompProfile:
type: RuntimeDefault
containers:
- name: migrate
image: registry.example.invalid/voice-platform/migrate:0.1.0
imagePullPolicy: IfNotPresent
args:
- -path=/migrations
- -database=$(DATABASE_URL)
- up
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: voice-platform-common-secrets
key: database-url
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 250m
memory: 192Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
@@ -0,0 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- job.yaml
images:
- name: registry.example.invalid/voice-platform/migrate
newName: registry.example.invalid/voice-platform/migrate
newTag: production
@@ -0,0 +1,86 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: voice-platform
spec:
template:
spec:
volumes:
- $patch: replace
- name: common-secrets
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: voice-platform-common
- name: api-secrets
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: voice-platform-api
- name: model-storage-secrets
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: voice-platform-model-storage
- name: device-secrets
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: voice-platform-devices
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: callbacks
namespace: voice-platform
spec:
template:
spec:
volumes:
- $patch: replace
- name: common-secrets
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: voice-platform-common
- name: callbacks-secrets
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: voice-platform-callbacks
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: worker
namespace: voice-platform
spec:
template:
spec:
volumes:
- $patch: replace
- name: common-secrets
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: voice-platform-common
- name: worker-secrets
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: voice-platform-worker
- name: model-storage-secrets
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: voice-platform-model-storage
@@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../production
patches:
- path: csi-volumes.yaml
@@ -0,0 +1,7 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: voice-platform-config
namespace: voice-platform
data:
APP_ENV: prod
@@ -0,0 +1,49 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: voice-platform
namespace: voice-platform
spec:
tls:
- hosts:
- voice.example.invalid
secretName: voice-platform-tls
rules:
- host: voice.example.invalid
http:
paths:
- path: /callbacks
pathType: Prefix
backend:
service:
name: callbacks
port:
number: 8081
- path: /device
pathType: Prefix
backend:
service:
name: api
port:
number: 8080
- path: /api
pathType: Prefix
backend:
service:
name: api
port:
number: 8080
- path: /health
pathType: Prefix
backend:
service:
name: api
port:
number: 8080
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 8080
@@ -0,0 +1,14 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
images:
- name: registry.example.invalid/voice-platform/backend
newName: registry.example.invalid/voice-platform/backend
newTag: production
- name: registry.example.invalid/voice-platform/web
newName: registry.example.invalid/voice-platform/web
newTag: production
patches:
- path: config-patch.yaml
- path: ingress-patch.yaml
@@ -0,0 +1,7 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: voice-platform-config
namespace: voice-platform
data:
APP_ENV: stage
@@ -0,0 +1,13 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
images:
- name: registry.example.invalid/voice-platform/backend
newName: registry.example.invalid/voice-platform/backend
newTag: staging
- name: registry.example.invalid/voice-platform/web
newName: registry.example.invalid/voice-platform/web
newTag: staging
patches:
- path: config-patch.yaml