Initial public release v1.0.7
- Streamlined README focused on quick start - Complete examples for all major use cases - Decision tree for choosing right pattern - Comprehensive troubleshooting guide
This commit is contained in:
316
examples/EXAMPLES-SUMMARY.md
Normal file
316
examples/EXAMPLES-SUMMARY.md
Normal file
@@ -0,0 +1,316 @@
|
||||
# ManagedSecret Operator - Examples Summary
|
||||
|
||||
This directory contains comprehensive examples for the ManagedSecret Operator, demonstrating various rotation strategies and use cases.
|
||||
|
||||
## Files Overview
|
||||
|
||||
### Documentation
|
||||
- **README.md** - Complete installation and usage guide with new features
|
||||
- Added `keepPreviousVersion` and `previousVersionTTL` documentation
|
||||
- Added Reloader integration guide
|
||||
- Updated best practices and architecture diagrams
|
||||
|
||||
### Example Files
|
||||
|
||||
#### Example 1: No Rotation (Simple API Key)
|
||||
**File:** `example-1-no-rotation.yaml`
|
||||
|
||||
**Use Case:** Long-lived API keys that don't need rotation
|
||||
|
||||
**Key Features:**
|
||||
- Generated once and kept indefinitely
|
||||
- No Reloader needed (secret never changes)
|
||||
- Perfect for external service API keys
|
||||
|
||||
**When to Use:**
|
||||
- Third-party API keys (Stripe, SendGrid, etc.)
|
||||
- Service identifiers
|
||||
- Static configuration values
|
||||
|
||||
---
|
||||
|
||||
#### Example 2: Simple Rotation with Reloader (Container Registry)
|
||||
**File:** `example-2-registry-rotation-simple.yaml`
|
||||
|
||||
**Use Case:** Docker/Container registry with HTTP basic auth
|
||||
|
||||
**Key Features:**
|
||||
- Password rotates every 90 days
|
||||
- InitContainer regenerates htpasswd on pod restart
|
||||
- Reloader automatically restarts pods
|
||||
- **No `keepPreviousVersion` needed** - htpasswd is regenerated fresh
|
||||
|
||||
**Rotation Flow:**
|
||||
1. ManagedSecret generates new password → Updates Vault → Updates K8s Secret
|
||||
2. Reloader detects Secret change → Triggers pod restart
|
||||
3. InitContainer runs → Reads new password → Generates fresh htpasswd
|
||||
4. Registry starts with new htpasswd
|
||||
|
||||
**When to Use:**
|
||||
- Container registries (Docker Registry, Harbor)
|
||||
- Web servers with htpasswd (Apache, Nginx)
|
||||
- Any service where credentials are regenerated at startup
|
||||
|
||||
---
|
||||
|
||||
#### Example 3: Complex Rotation with Previous Password (PostgreSQL)
|
||||
**File:** `example-3-postgres-rotation-previous.yaml`
|
||||
|
||||
**Use Case:** PostgreSQL user password that requires authentication to change
|
||||
|
||||
**Key Features:**
|
||||
- Password rotates every 90 days
|
||||
- `keepPreviousVersion: true` creates `-previous` secret
|
||||
- CronJob uses old password to authenticate, sets new password
|
||||
- `previousVersionTTL: 1h` cleans up after grace period
|
||||
|
||||
**Rotation Flow:**
|
||||
1. ManagedSecret creates both `postgres-secret` and `postgres-secret-previous`
|
||||
2. CronJob (every 5 min) detects rotation
|
||||
3. Authenticates with OLD password: `PGPASSWORD=$OLD_PASSWORD psql`
|
||||
4. Changes password: `ALTER USER app_user PASSWORD '$NEW_PASSWORD'`
|
||||
5. Verifies new password works
|
||||
6. After 1 hour, `-previous` secret is deleted
|
||||
|
||||
**When to Use:**
|
||||
- PostgreSQL, MySQL, MariaDB
|
||||
- Any database requiring authentication to change passwords
|
||||
- Services with `ALTER USER` or similar commands
|
||||
|
||||
---
|
||||
|
||||
#### Example 4: MinIO Admin Password Rotation
|
||||
**File:** `example-4-minio-rotation-previous.yaml`
|
||||
|
||||
**Use Case:** MinIO admin credentials with rotation
|
||||
|
||||
**Key Features:**
|
||||
- Password rotates every 60 days
|
||||
- Uses MinIO Client (mc) to change password
|
||||
- `keepPreviousVersion: true` with 2h TTL
|
||||
- CronJob handles rotation via `mc admin user password`
|
||||
|
||||
**Special Considerations:**
|
||||
- MinIO does NOT reload credentials from environment variables
|
||||
- Manual pod restart required after rotation
|
||||
- Consider using a sidecar to monitor and restart
|
||||
|
||||
**Rotation Flow:**
|
||||
1. ManagedSecret creates both secrets
|
||||
2. CronJob authenticates with old credentials: `mc alias set oldminio`
|
||||
3. Changes password: `mc admin user password myminio admin $NEW_PASSWORD`
|
||||
4. Verifies new credentials
|
||||
5. **Important:** MinIO pods must be restarted manually
|
||||
|
||||
**When to Use:**
|
||||
- MinIO object storage
|
||||
- Any service that doesn't auto-reload credentials
|
||||
- Services requiring separate admin tools for password changes
|
||||
|
||||
---
|
||||
|
||||
#### Example 5: MySQL User Password Rotation
|
||||
**File:** `example-5-mysql-rotation-previous.yaml`
|
||||
|
||||
**Use Case:** MySQL application user with automated rotation
|
||||
|
||||
**Key Features:**
|
||||
- Password rotates every 90 days
|
||||
- Multiple password change methods (ALTER USER, SET PASSWORD)
|
||||
- Root credentials as fallback
|
||||
- `keepPreviousVersion: true` with 1h TTL
|
||||
|
||||
**Rotation Flow:**
|
||||
1. ManagedSecret creates both secrets
|
||||
2. CronJob tries multiple approaches:
|
||||
- Method 1: `ALTER USER` as root (preferred)
|
||||
- Method 2: `SET PASSWORD` as root
|
||||
- Method 3: `SET PASSWORD` as user with old password
|
||||
3. Flushes privileges
|
||||
4. Verifies new password
|
||||
|
||||
**When to Use:**
|
||||
- MySQL 5.7+, MySQL 8.0
|
||||
- MariaDB
|
||||
- Any MySQL-compatible database
|
||||
|
||||
---
|
||||
|
||||
#### Example 6: Comprehensive Multi-Service Deployment
|
||||
**File:** `example-6-comprehensive-multi-service.yaml`
|
||||
|
||||
**Use Case:** Complete application stack showing all strategies together
|
||||
|
||||
**Components:**
|
||||
1. **PostgreSQL** - Rotates with previous version (90 days)
|
||||
2. **Redis** - Rotates without previous version (30 days)
|
||||
3. **API Keys** - No rotation (managed externally)
|
||||
4. **TLS Certificates** - No rotation (cert-manager)
|
||||
5. **JWT Secret** - Simple rotation with Reloader (180 days)
|
||||
|
||||
**Demonstrates:**
|
||||
- Multiple secrets with different rotation schedules
|
||||
- Mixed rotation strategies in one application
|
||||
- How Reloader restarts pods for all credential changes
|
||||
- Real-world production setup
|
||||
|
||||
**When to Use:**
|
||||
- As a template for complex applications
|
||||
- To understand how different strategies work together
|
||||
- For learning all features in one example
|
||||
|
||||
---
|
||||
|
||||
## Quick Decision Tree
|
||||
|
||||
### Does your service need the OLD password to set the NEW password?
|
||||
|
||||
**YES** (PostgreSQL, MySQL, MinIO, LDAP):
|
||||
- Use `keepPreviousVersion: true`
|
||||
- Set appropriate `previousVersionTTL`
|
||||
- Create CronJob to handle rotation
|
||||
- See Examples 3, 4, or 5
|
||||
|
||||
**NO** (Registry, Redis, Web servers):
|
||||
- Use simple rotation with Reloader
|
||||
- InitContainer or startup script regenerates credentials
|
||||
- No CronJob needed
|
||||
- See Example 2
|
||||
|
||||
**NOT ROTATING** (API keys, Certificates):
|
||||
- Set `rotation.enabled: false`
|
||||
- No Reloader annotation needed
|
||||
- See Example 1
|
||||
|
||||
---
|
||||
|
||||
## Rotation Schedule Recommendations
|
||||
|
||||
- **High Security** (User passwords, admin credentials): 30-90 days
|
||||
- **Medium Security** (Application credentials, service accounts): 90-180 days
|
||||
- **Low Security** (Read-only API keys, development): 180+ days or disabled
|
||||
- **Previous Version TTL**:
|
||||
- Automated rotation: 1h
|
||||
- Manual intervention: 2-4h
|
||||
- Complex workflows: 24h
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites for All Examples
|
||||
|
||||
1. **OpenBao/Vault** deployed and initialized
|
||||
2. **ManagedSecret Operator** installed
|
||||
3. **Reloader** installed (for rotation examples)
|
||||
4. **cert-manager** (optional, for TLS examples)
|
||||
|
||||
## Installation Order
|
||||
|
||||
```bash
|
||||
# 1. Install OpenBao
|
||||
kubectl create namespace openbao
|
||||
helm install openbao openbao/openbao -n openbao
|
||||
|
||||
# 2. Install ManagedSecret Operator
|
||||
kubectl apply -f managedsecret-operator/
|
||||
|
||||
# 3. Install Reloader
|
||||
kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml
|
||||
|
||||
# 4. Deploy your application with examples
|
||||
kubectl apply -f example-X-your-usecase.yaml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing Rotation
|
||||
|
||||
### Force Immediate Rotation
|
||||
```bash
|
||||
# Trigger rotation for any ManagedSecret
|
||||
kubectl annotate managedsecret <name> -n <namespace> \
|
||||
reconcile="$(date +%s)" --overwrite
|
||||
```
|
||||
|
||||
### Watch the Flow
|
||||
```bash
|
||||
# Terminal 1: Watch secrets
|
||||
kubectl get secrets -n <namespace> -w
|
||||
|
||||
# Terminal 2: Watch pods
|
||||
kubectl get pods -n <namespace> -w
|
||||
|
||||
# Terminal 3: Watch jobs (for CronJobs)
|
||||
kubectl get jobs -n <namespace> -w
|
||||
|
||||
# Terminal 4: Reloader logs
|
||||
kubectl logs -n reloader -l app=reloader -f
|
||||
```
|
||||
|
||||
### Verify Rotation Completed
|
||||
```bash
|
||||
# Check if -previous secret exists (should only exist during grace period)
|
||||
kubectl get secret <name>-previous -n <namespace>
|
||||
|
||||
# View rotation job logs
|
||||
kubectl logs -n <namespace> -l job-name=<rotation-job>
|
||||
|
||||
# Test connection with new credentials
|
||||
kubectl exec -it -n <namespace> <pod> -- <test-command>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Issues and Solutions
|
||||
|
||||
### Issue: Pod not restarting after rotation
|
||||
**Solution:** Check Reloader is installed and annotation is correct
|
||||
```bash
|
||||
kubectl get pods -n reloader
|
||||
kubectl get deployment <app> -o yaml | grep reloader
|
||||
```
|
||||
|
||||
### Issue: Rotation job failing
|
||||
**Solution:** Check if previous secret exists and credentials work
|
||||
```bash
|
||||
kubectl get secret <name>-previous -n <namespace>
|
||||
kubectl logs -n <namespace> -l job-name=<rotation-job>
|
||||
```
|
||||
|
||||
### Issue: Application still using old credentials
|
||||
**Solution:** Verify pod actually restarted after secret change
|
||||
```bash
|
||||
kubectl get pods -n <namespace> -o wide
|
||||
# Check pod start time vs secret update time
|
||||
```
|
||||
|
||||
### Issue: Previous secret not cleaned up
|
||||
**Solution:** Check operator logs for cleanup job
|
||||
```bash
|
||||
kubectl logs -n managedsecret-operator-system -l control-plane=controller-manager | grep cleanup
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices Summary
|
||||
|
||||
1. ✅ **Always use Reloader** with rotating secrets
|
||||
2. ✅ **Use `keepPreviousVersion`** for services requiring old password
|
||||
3. ✅ **Set realistic `previousVersionTTL`** based on your workflow
|
||||
4. ✅ **Test rotation** before production deployment
|
||||
5. ✅ **Monitor rotation jobs** for failures
|
||||
6. ✅ **Document rotation procedures** for your team
|
||||
7. ✅ **Use appropriate rotation schedules** based on security requirements
|
||||
8. ✅ **Backup Vault regularly** - it's your source of truth
|
||||
9. ✅ **Never modify K8s Secrets manually** - always use ManagedSecret or Vault
|
||||
10. ✅ **Set up alerts** for failed rotations
|
||||
|
||||
---
|
||||
|
||||
## Support and Contributing
|
||||
|
||||
For issues or questions about these examples:
|
||||
- Check the main README.md for troubleshooting
|
||||
- Review operator logs for detailed error messages
|
||||
- Test in development environment before production
|
||||
|
||||
Remember: Vault/OpenBao is ALWAYS the source of truth. All changes should go through ManagedSecret resources or directly in Vault, never by manually editing Kubernetes Secrets.
|
||||
Reference in New Issue
Block a user