This example demonstrates the full security configuration
- TLS encryption for metrics endpoint
- Basic authentication for access control
- Static configuration with predefined collectors
- Shared secret for both TLS certificates and authentication password
- Production deployment requiring comprehensive security
- Database credentials defined at deploy time
- Need both encryption (TLS) and authentication (basic auth)
- Collectors and targets are known and don't change at runtime
values-example.yaml- Complete Helm values with TLS, auth, and static configsecret-tls-auth.yaml- Shared secret example for TLS + password
kubectl create secret generic sql-exporter-tls-auth \
--from-file=tls.crt=path/to/cert.crt \
--from-file=tls.key=path/to/cert.key \
--from-literal=password='your-secure-password' \
--namespace=your-namespaceFor self-signed certificates:
openssl req -x509 -newkey rsa:4096 -keyout tls.key -out tls.crt -days 365 -nodes
kubectl create secret generic sql-exporter-tls-auth \
--from-file=tls.crt=tls.crt \
--from-file=tls.key=tls.key \
--from-literal=password='your-secure-password' \
--namespace=your-namespaceFor detailed TLS certificate options, see secret-tls-auth.yaml.
helm install sql-exporter ../../helm -f values-example.yaml- HTTPS metrics endpoint with TLS 1.3 encryption
- Basic authentication with bcrypt-hashed passwords
- Static config with predefined collectors and database target
- Shared secret consolidation (one secret for TLS + auth)
- Single init container for password hashing
- tcpSocket health probes (httpGet doesn't support auth)
- Production-ready with resource limits
- ServiceMonitor for Prometheus Operator
# Check pod status
kubectl get pods -l app.kubernetes.io/name=sql-exporter
# Check pod is ready
kubectl describe pod <pod-name>
# Verify config
kubectl exec <pod-name> -- cat /etc/sql_exporter/sql_exporter.yml
# Test metrics endpoint (with TLS + auth)
kubectl port-forward svc/sql-exporter 9399:9399
curl -k -u prometheus:your-secure-password https://localhost:9399/metricsThis example demonstrates shared secret usage:
sql-exporter-tls-authprovides:tls.crt- TLS certificatetls.key- TLS private keypassword- Plaintext password for basic auth
This single secret is:
- Mounted at
/tlsfor main container (TLS certs) - Mounted at
/secret-srcfor init container (password)
Init Container (sql-exporter-init):
- Reads plaintext password from
sql-exporter-tls-authsecret - Hashes password using bcrypt (cost: 12)
- Reads TLS config template (base64-encoded)
- Appends
basic_auth_userssection with hashed password - Writes
web-config.ymlto/etc/web-config/(emptyDir)
Main Container:
- Uses
/etc/sql_exporter/sql_exporter.ymlfor SQL exporter config - Uses
/etc/web-config/web-config.ymlfor web server config (TLS + auth) - Mounts TLS certs from
/tls
When basic auth is enabled, probes use tcpSocket instead of httpGet:
- Why? Kubernetes
httpGetprobes don't support authentication headers - Effect: Opens TCP connection to port 9399 but doesn't complete TLS handshake
- Logs: You'll see harmless
TLS handshake error: EOFmessages - this is expected
Edit values-example.yaml to:
- Add/modify collectors in
config.collectors - Change database target in
config.target.data_source_name - Adjust scrape intervals (
min_interval) - Change bcrypt cost (higher = more secure but slower)
- Configure resource limits
- Add ServiceMonitor selector labels for Prometheus discovery
- Change log level (
logLevel: infoordebug)
✅ This example includes:
- TLS 1.3 encryption with strong cipher suites
- Password hashing with bcrypt
- Static credential management via secrets
- Resource limits
- ServiceMonitor for Prometheus Operator
- Pod labels for organization
Pod stuck in Init:0/1:
- Check if
sql-exporter-tls-authsecret exists - Verify it contains
tls.crt,tls.key, andpasswordkeys - Check init container logs:
kubectl logs <pod> -c sql-exporter-init
Metrics return 401 Unauthorized:
- Verify username/password are correct
- Check
web-config.ymlwas generated:kubectl exec <pod> -- cat /etc/web-config/web-config.yml - Ensure password is correct in secret
TLS handshake EOF errors in logs:
- These are harmless and expected from
tcpSockethealth probes - Can be reduced by setting
logLevel: infoorwarn
Pod fails to start - metrics collection error:
- Verify database target DSN in
config.target.data_source_name - Ensure database is reachable from the pod
- Check pod logs:
kubectl logs <pod> -c sql-exporter
- Plaintext password is only in secret, never in logs
- Password is bcrypt-hashed before being written to config
- TLS certificates should be properly signed (use cert-manager for production)
- All communication to metrics endpoint is encrypted and authenticated