diff --git a/docs/examples.md b/docs/examples.md index c191ea0b..a83a2a1e 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -36,7 +36,7 @@ requests: cpu: 1 memory: 1Gi - runtime.properties: + runtime.properties: druid.plaintextPort=8083 druid.service=druid/historical/hot cold: @@ -73,7 +73,7 @@ requests: cpu: 1 memory: 1Gi - runtime.properties: + runtime.properties: druid.plaintextPort=8083 druid.service=druid/historical/cold ... @@ -264,3 +264,83 @@ spec: druid.metadata.storage.connector.password={ "type": "environment", "variable": "METADATA_STORAGE_PASSWORD" } ... ``` + +## Configuration via Environment Variables (Recommended for sensitive data) + +Standard Druid Docker images allow you to convert any environment variable starting with `druid_` into a configuration property (replacing `_` with `.`). This is often more reliable than the JSON replacement method found in `runtime.properties` and allows you to securely inject any configuration using Kubernetes Secrets. + +**Note:** If you define a configuration here via `env`, ensure you remove it from your `runtime.properties` or `common.runtime.properties` to avoid conflicts. + +### Example: Securely Injecting Secrets and Druid Properties + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: prod-druid + namespace: druid +type: Opaque +stringData: + # Sensitive values + AWS_ACCESS_KEY_ID: "AKIA..." + AWS_SECRET_ACCESS_KEY: "SECRET..." + # You can map full property values here + druid.metadata.storage.connector.password: "db-password" + druid.metadata.storage.connector.connectURI: "jdbc:postgresql://..." +--- +apiVersion: druid.apache.org/v1alpha1 +kind: Druid +metadata: + name: druid +spec: + env: + # 1. Standard Env Vars + - name: AWS_REGION + value: "nyc3" + + # 2. Loading Secrets + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: prod-druid + key: AWS_ACCESS_KEY_ID + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: prod-druid + key: AWS_SECRET_ACCESS_KEY + + # 3. Mapping Secrets directly to Druid Properties + # The Docker entrypoint converts 'druid_x_y' -> 'druid.x.y' + + # Maps to: druid.metadata.storage.connector.password + - name: druid_metadata_storage_connector_password + valueFrom: + secretKeyRef: + name: prod-druid + key: druid.metadata.storage.connector.password + + # Maps to: druid.metadata.storage.connector.connectURI + - name: druid_metadata_storage_connector_connectURI + valueFrom: + secretKeyRef: + name: prod-druid + key: druid.metadata.storage.connector.connectURI + + nodes: + coordinators: + nodeType: "coordinator" + # ... + runtime.properties: | + druid.service=druid/coordinator + # Note: AWS Keys and Metadata configs are NOT listed here + # because they are injected via the 'env' section above. + druid.metadata.storage.type=postgresql + druid.metadata.storage.connector.user=druid +``` + +### Notes + +- **Environment variable expansion** (using `env` and `envFrom`) can be used for any Druid configuration property, not just passwords. This is the recommended approach for sensitive data and for properties that may change between environments. +- The JSON replacement method (`{ "type": "environment", "variable": "METADATA_STORAGE_PASSWORD" }`) is only supported for certain password fields in `runtime.properties` and is not as flexible as environment variable expansion. +- If you use both methods for the same property, the environment variable will take precedence, but it's best to avoid duplication to prevent confusion. diff --git a/examples/tiny-cluster-hpa.yaml b/examples/tiny-cluster-hpa.yaml index 7fd45994..db3a6e50 100644 --- a/examples/tiny-cluster-hpa.yaml +++ b/examples/tiny-cluster-hpa.yaml @@ -60,10 +60,8 @@ spec: # Metadata Store druid.metadata.storage.type=derby - druid.metadata.storage.connector.connectURI=jdbc:derby://localhost:1527/druid/data/derbydb/metadata.db;create=true - druid.metadata.storage.connector.host=localhost - druid.metadata.storage.connector.port=1527 druid.metadata.storage.connector.createTables=true + # Other settings are set via environment variables # Deep Storage druid.storage.type=local @@ -96,6 +94,15 @@ spec: path: /tmp/druid/deepstorage type: DirectoryOrCreate env: + - name: druid_metadata_storage_type + value: derby + - name: druid_metadata_storage_connector_connectURI + value: jdbc:derby://localhost:1527/druid/data/derbydb/metadata.db;create=true + - name: druid_metadata_storage_connector_host + value: localhost + - name: druid_metadata_storage_connector_port + value: "1527" + # Other env vars - name: POD_NAME valueFrom: fieldRef: @@ -186,7 +193,7 @@ spec: extra.jvm.options: |- -Xmx512M -Xms512M - + routers: nodeType: "router" druid.port: 8088 @@ -206,7 +213,7 @@ spec: druid.router.coordinatorServiceName=druid/coordinator # Management proxy to coordinator / overlord: required for unified web console. - druid.router.managementProxy.enabled=true + druid.router.managementProxy.enabled=true extra.jvm.options: |- -Xmx512M -Xms512M diff --git a/examples/tiny-cluster.yaml b/examples/tiny-cluster.yaml index c8e637b8..2a6e54a6 100644 --- a/examples/tiny-cluster.yaml +++ b/examples/tiny-cluster.yaml @@ -60,10 +60,8 @@ spec: # Metadata Store druid.metadata.storage.type=derby - druid.metadata.storage.connector.connectURI=jdbc:derby://localhost:1527/druid/data/derbydb/metadata.db;create=true - druid.metadata.storage.connector.host=localhost - druid.metadata.storage.connector.port=1527 druid.metadata.storage.connector.createTables=true + # Other settings are set via environment variables # Deep Storage druid.storage.type=local @@ -259,6 +257,14 @@ spec: path: /tmp/druid/deepstorage type: DirectoryOrCreate env: + - name: druid_metadata_storage_type + value: derby + - name: druid_metadata_storage_connector_connectURI + value: jdbc:derby://localhost:1527/druid/data/derbydb/metadata.db;create=true + - name: druid_metadata_storage_connector_host + value: localhost + - name: druid_metadata_storage_connector_port + value: "1527" - name: POD_NAME valueFrom: fieldRef: @@ -280,15 +286,15 @@ spec: nodeConfigMountPath: "/opt/druid/conf/druid/cluster/query/broker" replicas: 1 volumeClaimTemplates: - - metadata: - name: data-volume - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 2Gi - storageClassName: standard + - metadata: + name: data-volume + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 2Gi + storageClassName: standard runtime.properties: | druid.service=druid/broker # HTTP server threads @@ -344,7 +350,7 @@ spec: extra.jvm.options: |- -Xmx512M -Xms512M - + routers: nodeType: "router" druid.port: 8088 @@ -364,7 +370,7 @@ spec: druid.router.coordinatorServiceName=druid/coordinator # Management proxy to coordinator / overlord: required for unified web console. - druid.router.managementProxy.enabled=true + druid.router.managementProxy.enabled=true extra.jvm.options: |- -Xmx512M -Xms512M