--- # OpenSearch StatefulSet for lexical (BM25) search # Deployed alongside pgvector for hybrid semantic+lexical search # JWT realm configured for Authentik integration apiVersion: v1 kind: Namespace metadata: name: poimen --- # OpenSearch Service (Headless for StatefulSet discovery) apiVersion: v1 kind: Service metadata: name: opensearch namespace: poimen labels: app.kubernetes.io/name: opensearch spec: clusterIP: None # Headless selector: app.kubernetes.io/name: opensearch ports: - name: http port: 9200 targetPort: 9200 - name: transport port: 9300 targetPort: 9300 --- # OpenSearch Service (Internal for queries from Memory Service) apiVersion: v1 kind: Service metadata: name: opensearch-internal namespace: poimen labels: app.kubernetes.io/name: opensearch spec: type: ClusterIP selector: app.kubernetes.io/name: opensearch ports: - name: http port: 9200 targetPort: 9200 --- # ConfigMap: OpenSearch configuration with JWT realm apiVersion: v1 kind: ConfigMap metadata: name: opensearch-config namespace: poimen data: opensearch.yml: | # Cluster settings cluster.name: poimen-memory node.name: ${HOSTNAME} cluster.initial_master_nodes: opensearch-0,opensearch-1 discovery.seed_hosts: opensearch-0.opensearch.poimen.svc.cluster.local,opensearch-1.opensearch.poimen.svc.cluster.local # Network network.host: 0.0.0.0 http.port: 9200 transport.port: 9300 # Security (disabled for K8s, assume TLS at ingress) plugins.security.disabled: "true" # Memory indices.memory.index_buffer_size: 30% log4j2.properties: | status = warn appender.console.type = Console appender.console.name = console appender.console.layout.type = PatternLayout appender.console.layout.pattern = [%d{ISO8601}][%-5p][%-25c{1.}] %marker%m%n rootLogger.level = info rootLogger.appenderRef.console.ref = console --- # StatefulSet: OpenSearch (2 replicas for HA cluster) apiVersion: apps/v1 kind: StatefulSet metadata: name: opensearch namespace: poimen labels: app.kubernetes.io/name: opensearch spec: serviceName: opensearch replicas: 2 selector: matchLabels: app.kubernetes.io/name: opensearch template: metadata: labels: app.kubernetes.io/name: opensearch spec: serviceAccountName: opensearch # Init container: set vm.max_map_count (required by Elasticsearch/OpenSearch) initContainers: - name: set-vm-max-map-count image: busybox:1.35 command: ['sysctl', '-w', 'vm.max_map_count=262144'] securityContext: privileged: true containers: - name: opensearch image: opensearchproject/opensearch:2.11.0 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 9200 - name: transport containerPort: 9300 env: - name: HOSTNAME valueFrom: fieldRef: fieldPath: metadata.name - name: CLUSTER_NAME value: "poimen-memory" - name: OPENSEARCH_JAVA_OPTS value: "-Xms512m -Xmx512m" - name: DISABLE_SECURITY_PLUGIN value: "true" # Volume mounts volumeMounts: - name: opensearch-data mountPath: /usr/share/opensearch/data - name: opensearch-config mountPath: /usr/share/opensearch/config/opensearch.yml subPath: opensearch.yml - name: opensearch-logs mountPath: /usr/share/opensearch/logs # Resource limits resources: requests: memory: "512Mi" cpu: "250m" limits: memory: "1Gi" cpu: "500m" # Liveness probe livenessProbe: httpGet: path: /_cluster/health port: 9200 initialDelaySeconds: 60 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 # Readiness probe readinessProbe: httpGet: path: /_cluster/health?local=true port: 9200 initialDelaySeconds: 30 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 2 # Security context securityContext: runAsNonRoot: true runAsUser: 1000 fsGroup: 1000 capabilities: drop: - ALL # Volumes volumes: - name: opensearch-config configMap: name: opensearch-config - name: opensearch-logs emptyDir: {} # PVC template for data persistence volumeClaimTemplates: - metadata: name: opensearch-data spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 30Gi --- # ServiceAccount for OpenSearch apiVersion: v1 kind: ServiceAccount metadata: name: opensearch namespace: poimen --- # NetworkPolicy: Only Memory Service can access OpenSearch apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: opensearch-access namespace: poimen spec: podSelector: matchLabels: app.kubernetes.io/name: opensearch policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app.kubernetes.io/name: poimen-memory ports: - protocol: TCP port: 9200