apiVersion: apps/v1 kind: Deployment metadata: name: context-plugin namespace: marketally labels: app: context-plugin version: v1.0.0 component: ai-plugin spec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1 selector: matchLabels: app: context-plugin template: metadata: labels: app: context-plugin version: v1.0.0 annotations: prometheus.io/scrape: "true" prometheus.io/port: "8081" prometheus.io/path: "/metrics" spec: serviceAccountName: context-plugin securityContext: runAsNonRoot: true runAsUser: 1000 runAsGroup: 1000 fsGroup: 1000 containers: - name: context-plugin image: ghcr.io/marketally/context-plugin:latest imagePullPolicy: Always ports: - name: http containerPort: 8080 protocol: TCP - name: metrics containerPort: 8081 protocol: TCP env: - name: ASPNETCORE_ENVIRONMENT value: "Production" - name: CONTEXT_STORAGE_PATH value: "/app/data/.context" - name: CONTEXT_LOG_LEVEL valueFrom: configMapKeyRef: name: context-plugin-config key: log-level - name: CONTEXT_MAX_CONTEXT_SIZE valueFrom: configMapKeyRef: name: context-plugin-config key: max-context-size - name: CONTEXT_RETENTION_DAYS valueFrom: configMapKeyRef: name: context-plugin-config key: retention-days - name: CONTEXT_ENABLE_ENCRYPTION valueFrom: configMapKeyRef: name: context-plugin-config key: enable-encryption - name: CONTEXT_ENCRYPTION_KEY valueFrom: secretKeyRef: name: context-plugin-secrets key: encryption-key - name: OPENAI_API_KEY valueFrom: secretKeyRef: name: context-plugin-secrets key: openai-api-key optional: true resources: requests: memory: "256Mi" cpu: "100m" limits: memory: "512Mi" cpu: "500m" volumeMounts: - name: context-data mountPath: /app/data - name: context-logs mountPath: /app/logs - name: config mountPath: /app/config readOnly: true livenessProbe: httpGet: path: /health port: metrics initialDelaySeconds: 60 periodSeconds: 30 timeoutSeconds: 10 failureThreshold: 3 readinessProbe: httpGet: path: /ready port: metrics initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 startupProbe: httpGet: path: /health port: metrics initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 10 failureThreshold: 6 volumes: - name: context-data persistentVolumeClaim: claimName: context-plugin-data - name: context-logs emptyDir: {} - name: config configMap: name: context-plugin-config imagePullSecrets: - name: ghcr-secret affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - context-plugin topologyKey: kubernetes.io/hostname --- apiVersion: v1 kind: Service metadata: name: context-plugin-service namespace: marketally labels: app: context-plugin annotations: prometheus.io/scrape: "true" prometheus.io/port: "8081" spec: type: ClusterIP ports: - port: 8080 targetPort: 8080 protocol: TCP name: http - port: 8081 targetPort: 8081 protocol: TCP name: metrics selector: app: context-plugin --- apiVersion: v1 kind: ConfigMap metadata: name: context-plugin-config namespace: marketally data: log-level: "Information" max-context-size: "50000" retention-days: "90" enable-encryption: "true" enable-caching: "true" cache-expiration-minutes: "30" max-concurrent-operations: "10" enable-compression: "true" enable-sensitive-data-detection: "true" auto-encrypt-sensitive-data: "true" enable-semantic-search: "false" enable-fuzzy-matching: "true" fuzzy-matching-threshold: "0.7" --- apiVersion: v1 kind: Secret metadata: name: context-plugin-secrets namespace: marketally type: Opaque data: # Base64 encoded values - replace with actual values encryption-key: bXktc2VjcmV0LWVuY3J5cHRpb24ta2V5 # my-secret-encryption-key openai-api-key: "" # Optional: Base64 encoded OpenAI API key --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: context-plugin-data namespace: marketally spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi storageClassName: standard --- apiVersion: v1 kind: ServiceAccount metadata: name: context-plugin namespace: marketally labels: app: context-plugin --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: context-plugin rules: - apiGroups: [""] resources: ["pods", "nodes", "services"] verbs: ["get", "list", "watch"] - apiGroups: ["apps"] resources: ["deployments", "replicasets"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: context-plugin roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: context-plugin subjects: - kind: ServiceAccount name: context-plugin namespace: marketally --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: context-plugin-ingress namespace: marketally annotations: kubernetes.io/ingress.class: nginx cert-manager.io/cluster-issuer: letsencrypt-prod nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/force-ssl-redirect: "true" nginx.ingress.kubernetes.io/rate-limit: "100" nginx.ingress.kubernetes.io/rate-limit-window: "1m" spec: tls: - hosts: - context-api.marketally.com secretName: context-plugin-tls rules: - host: context-api.marketally.com http: paths: - path: / pathType: Prefix backend: service: name: context-plugin-service port: number: 8080 --- apiVersion: policy/v1 kind: PodDisruptionBudget metadata: name: context-plugin-pdb namespace: marketally spec: minAvailable: 2 selector: matchLabels: app: context-plugin --- apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: context-plugin-hpa namespace: marketally spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: context-plugin minReplicas: 3 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 70 - type: Resource resource: name: memory target: type: Utilization averageUtilization: 80 behavior: scaleDown: stabilizationWindowSeconds: 300 policies: - type: Percent value: 10 periodSeconds: 60 scaleUp: stabilizationWindowSeconds: 60 policies: - type: Percent value: 50 periodSeconds: 60