|
| 1 | +# Vault Integration Performance Impact Verification |
| 2 | + |
| 3 | +This document provides guidelines for verifying that the Vault integration does not significantly impact pod startup time, which could affect autoscaling performance. |
| 4 | + |
| 5 | +## Performance Benchmarks |
| 6 | + |
| 7 | +### Expected Startup Time Impact |
| 8 | + |
| 9 | +The Vault integration adds the following overhead to pod startup: |
| 10 | + |
| 11 | +| Operation | Expected Time | Notes | |
| 12 | +|-----------|---------------|-------| |
| 13 | +| Vault Authentication | 100-200ms | One-time, cached by sidecar | |
| 14 | +| Secret Retrieval | 50-100ms | One-time, cached by sidecar | |
| 15 | +| Database Credential Generation | 200-300ms | Only on initial startup | |
| 16 | +| **Total Additional Startup Time** | **< 500ms** | Acceptable threshold | |
| 17 | + |
| 18 | +### Baseline Comparison |
| 19 | + |
| 20 | +- **Without Vault**: ~2-3 seconds typical startup time |
| 21 | +- **With Vault**: ~2.5-3.5 seconds typical startup time |
| 22 | +- **Acceptable Increase**: < 20% of baseline |
| 23 | + |
| 24 | +## Verification Methods |
| 25 | + |
| 26 | +### Method 1: Kubernetes Pod Startup Time Measurement |
| 27 | + |
| 28 | +Measure pod startup time using Kubernetes events: |
| 29 | + |
| 30 | +```bash |
| 31 | +# Measure startup time for a new pod |
| 32 | +kubectl get pod -l app=substream-backend -o jsonpath='{.items[0].metadata.creationTimestamp}' |
| 33 | + |
| 34 | +# Wait for pod to be ready |
| 35 | +kubectl wait --for=condition=ready pod -l app=substream-backend --timeout=60s |
| 36 | + |
| 37 | +# Check when pod became ready |
| 38 | +kubectl get pod -l app=substream-backend -o jsonpath='{.items[0].status.conditions[?(@.type=="Ready")].lastTransitionTime}' |
| 39 | +``` |
| 40 | + |
| 41 | +### Method 2: Application-Level Timing |
| 42 | + |
| 43 | +The application logs Vault initialization times. Check logs: |
| 44 | + |
| 45 | +```bash |
| 46 | +# Extract Vault initialization timing |
| 47 | +kubectl logs deployment/substream-backend | grep Vault |
| 48 | +``` |
| 49 | + |
| 50 | +Expected output: |
| 51 | +``` |
| 52 | +[Vault] Vault integration enabled |
| 53 | +[Vault] Vault service initialized successfully |
| 54 | +``` |
| 55 | + |
| 56 | +### Method 3: Vault Sidecar Metrics |
| 57 | + |
| 58 | +The Vault sidecar injector provides metrics on secret injection: |
| 59 | + |
| 60 | +```bash |
| 61 | +# Check sidecar logs for timing information |
| 62 | +kubectl logs <pod-name> -c vault-agent-init |
| 63 | +``` |
| 64 | + |
| 65 | +### Method 4: Continuous Monitoring with Prometheus |
| 66 | + |
| 67 | +Add the following Prometheus queries to monitor startup times: |
| 68 | + |
| 69 | +```promql |
| 70 | +# Average pod startup time over last hour |
| 71 | +avg(kube_pod_container_status_ready_time_seconds{container="substream-backend"} > 0) |
| 72 | +
|
| 73 | +# 95th percentile startup time |
| 74 | +histogram_quantile(0.95, kube_pod_container_status_ready_time_seconds{container="substream-backend"}) |
| 75 | +
|
| 76 | +# Compare with baseline (without Vault) |
| 77 | +avg(kube_pod_container_status_ready_time_seconds{container="substream-backend"}) |
| 78 | +/ |
| 79 | +avg(kube_pod_container_status_ready_time_seconds{container="substream-backend-legacy"}) |
| 80 | +``` |
| 81 | + |
| 82 | +## Performance Testing Procedure |
| 83 | + |
| 84 | +### Test 1: Cold Start Performance |
| 85 | + |
| 86 | +1. Scale down the deployment to 0 replicas: |
| 87 | +```bash |
| 88 | +kubectl scale deployment substream-backend --replicas=0 |
| 89 | +``` |
| 90 | + |
| 91 | +2. Scale up to 3 replicas: |
| 92 | +```bash |
| 93 | +kubectl scale deployment substream-backend --replicas=3 |
| 94 | +``` |
| 95 | + |
| 96 | +3. Measure time for all pods to become ready: |
| 97 | +```bash |
| 98 | +time kubectl wait --for=condition=ready pod -l app=substream-backend --timeout=120s |
| 99 | +``` |
| 100 | + |
| 101 | +4. Record the startup time for each pod: |
| 102 | +```bash |
| 103 | +kubectl get pods -l app=substream-backend -o custom-columns=NAME:.metadata.name,START:.metadata.creationTimestamp,READY:.status.startTime |
| 104 | +``` |
| 105 | + |
| 106 | +**Acceptance Criteria**: All pods should be ready within 60 seconds. |
| 107 | + |
| 108 | +### Test 2: Warm Start Performance (With Vault Cache) |
| 109 | + |
| 110 | +1. Delete a single pod (triggers replacement with cached secrets): |
| 111 | +```bash |
| 112 | +kubectl delete pod -l app=substream-backend --field-selector=status.phase=Running |
| 113 | +``` |
| 114 | + |
| 115 | +2. Measure replacement pod startup time: |
| 116 | +```bash |
| 117 | +kubectl wait --for=condition=ready pod -l app=substream-backend --timeout=30s |
| 118 | +``` |
| 119 | + |
| 120 | +**Acceptance Criteria**: Replacement pod should be ready within 30 seconds (faster due to caching). |
| 121 | + |
| 122 | +### Test 3: Vault Unavailability Impact |
| 123 | + |
| 124 | +1. Temporarily block Vault access: |
| 125 | +```bash |
| 126 | +kubectl exec -it <pod-name> -- iptables -A INPUT -p tcp --dport 8200 -j DROP |
| 127 | +``` |
| 128 | + |
| 129 | +2. Scale deployment to test fallback behavior: |
| 130 | +```bash |
| 131 | +kubectl scale deployment substream-backend --replicas=4 |
| 132 | +``` |
| 133 | + |
| 134 | +3. Verify pods start using environment variable fallback: |
| 135 | +```bash |
| 136 | +kubectl logs deployment/substream-backend | grep -i vault |
| 137 | +``` |
| 138 | + |
| 139 | +Expected output: |
| 140 | +``` |
| 141 | +[Vault] Vault initialization failed, continuing with environment variables: <error message> |
| 142 | +``` |
| 143 | + |
| 144 | +4. Restore Vault access: |
| 145 | +```bash |
| 146 | +kubectl exec -it <pod-name> -- iptables -D INPUT -p tcp --dport 8200 -j DROP |
| 147 | +``` |
| 148 | + |
| 149 | +**Acceptance Criteria**: Pods should start successfully even when Vault is unavailable, using environment variable fallback. |
| 150 | + |
| 151 | +### Test 4: Autoscaling Impact |
| 152 | + |
| 153 | +1. Configure HPA with aggressive scaling: |
| 154 | +```bash |
| 155 | +kubectl autoscale deployment substream-backend --min=3 --max=10 --cpu-percent=50 |
| 156 | +``` |
| 157 | + |
| 158 | +2. Generate load to trigger scale-up: |
| 159 | +```bash |
| 160 | +# Use a load testing tool |
| 161 | +hey -n 10000 -c 100 http://substream-backend-service |
| 162 | +``` |
| 163 | + |
| 164 | +3. Monitor scale-up time: |
| 165 | +```bash |
| 166 | +watch kubectl get hpa substream-backend |
| 167 | +watch kubectl get pods -l app=substream-backend |
| 168 | +``` |
| 169 | + |
| 170 | +**Acceptance Criteria**: New pods should become ready within 60 seconds during scale-up events. |
| 171 | + |
| 172 | +## Performance Optimization Tips |
| 173 | + |
| 174 | +### 1. Enable Vault Sidecar Caching |
| 175 | + |
| 176 | +The Vault sidecar injector caches secrets locally. Ensure caching is enabled in annotations: |
| 177 | + |
| 178 | +```yaml |
| 179 | +vault.hashicorp.com/agent-cache-use-auto-auth-token: "force" |
| 180 | +``` |
| 181 | +
|
| 182 | +### 2. Use Vault Agent Pre-Population |
| 183 | +
|
| 184 | +Pre-populate secrets during pod initialization: |
| 185 | +
|
| 186 | +```yaml |
| 187 | +vault.hashicorp.com/agent-pre-populate-only: "false" |
| 188 | +``` |
| 189 | +
|
| 190 | +### 3. Optimize Database Credential Generation |
| 191 | +
|
| 192 | +Reduce database credential generation time by: |
| 193 | +- Using a high-performance database connection |
| 194 | +- Reducing the number of GRANT statements |
| 195 | +- Using connection pooling |
| 196 | +
|
| 197 | +### 4. Adjust Vault Request Timeouts |
| 198 | +
|
| 199 | +If Vault is slow, adjust timeouts in the VaultService: |
| 200 | +
|
| 201 | +```javascript |
| 202 | +timeout: 5000 // 5 seconds instead of default 10 seconds |
| 203 | +``` |
| 204 | +
|
| 205 | +### 5. Use Kubernetes Readiness Gates |
| 206 | +
|
| 207 | +Configure readiness gates to ensure pods are not marked ready until Vault secrets are loaded: |
| 208 | +
|
| 209 | +```yaml |
| 210 | +readinessGates: |
| 211 | +- conditionType: vault.hashicorp.com/agent-inject-ready |
| 212 | +``` |
| 213 | +
|
| 214 | +## Monitoring and Alerting |
| 215 | +
|
| 216 | +### Prometheus Metrics |
| 217 | +
|
| 218 | +Add these metrics to your monitoring: |
| 219 | +
|
| 220 | +```yaml |
| 221 | +# Vault authentication duration |
| 222 | +vault_auth_duration_seconds |
| 223 | + |
| 224 | +# Secret retrieval duration |
| 225 | +vault_secret_retrieval_duration_seconds |
| 226 | + |
| 227 | +# Pod startup time |
| 228 | +kube_pod_container_status_ready_time_seconds{container="substream-backend"} |
| 229 | +``` |
| 230 | + |
| 231 | +### Alerting Rules |
| 232 | + |
| 233 | +Create alerts for performance degradation: |
| 234 | + |
| 235 | +```yaml |
| 236 | +groups: |
| 237 | +- name: vault_performance |
| 238 | + rules: |
| 239 | + - alert: VaultSlowStartup |
| 240 | + expr: histogram_quantile(0.95, kube_pod_container_status_ready_time_seconds{container="substream-backend"}) > 60 |
| 241 | + for: 5m |
| 242 | + annotations: |
| 243 | + summary: "Vault integration causing slow pod startup" |
| 244 | + description: "95th percentile pod startup time exceeds 60 seconds" |
| 245 | + |
| 246 | + - alert: VaultAuthenticationFailure |
| 247 | + expr: rate(vault_auth_failures_total[5m]) > 0.1 |
| 248 | + for: 2m |
| 249 | + annotations: |
| 250 | + summary: "High Vault authentication failure rate" |
| 251 | + description: "Vault authentication failing at {{ $value }} req/sec" |
| 252 | +``` |
| 253 | +
|
| 254 | +## Troubleshooting Performance Issues |
| 255 | +
|
| 256 | +### Issue: Pods Taking Too Long to Start |
| 257 | +
|
| 258 | +**Symptoms**: Pod startup time > 60 seconds |
| 259 | +
|
| 260 | +**Investigation Steps**: |
| 261 | +1. Check Vault service health: |
| 262 | +```bash |
| 263 | +kubectl exec -it vault-0 -- vault status |
| 264 | +``` |
| 265 | + |
| 266 | +2. Check Vault sidecar logs: |
| 267 | +```bash |
| 268 | +kubectl logs <pod-name> -c vault-agent-init |
| 269 | +``` |
| 270 | + |
| 271 | +3. Check network latency to Vault: |
| 272 | +```bash |
| 273 | +kubectl run ping-test --image=busybox --rm -it -- ping -c 5 vault |
| 274 | +``` |
| 275 | + |
| 276 | +**Solutions**: |
| 277 | +- Ensure Vault is in the same Kubernetes cluster |
| 278 | +- Use a Vault service with low latency |
| 279 | +- Enable Vault caching |
| 280 | +- Increase Vault resource limits |
| 281 | + |
| 282 | +### Issue: Vault Authentication Timeout |
| 283 | + |
| 284 | +**Symptoms**: Logs show "Vault authentication failed" with timeout errors |
| 285 | + |
| 286 | +**Investigation Steps**: |
| 287 | +1. Check Kubernetes service account: |
| 288 | +```bash |
| 289 | +kubectl get sa substream-backend -n substream |
| 290 | +``` |
| 291 | + |
| 292 | +2. Check Vault role configuration: |
| 293 | +```bash |
| 294 | +vault read auth/kubernetes/role/substream-backend |
| 295 | +``` |
| 296 | + |
| 297 | +**Solutions**: |
| 298 | +- Increase timeout in VaultService |
| 299 | +- Check network policies between pod and Vault |
| 300 | +- Verify Kubernetes API server is accessible |
| 301 | + |
| 302 | +### Issue: Database Credential Generation Slow |
| 303 | + |
| 304 | +**Symptoms**: Pod logs show slow database credential generation |
| 305 | + |
| 306 | +**Investigation Steps**: |
| 307 | +1. Test Vault database secrets engine: |
| 308 | +```bash |
| 309 | +vault read database/creds/substream-role |
| 310 | +``` |
| 311 | + |
| 312 | +2. Check database performance: |
| 313 | +```bash |
| 314 | +kubectl exec -it postgresql-0 -- psql -c "SELECT version();" |
| 315 | +``` |
| 316 | + |
| 317 | +**Solutions**: |
| 318 | +- Optimize database connection string |
| 319 | +- Reduce number of GRANT statements |
| 320 | +- Use database connection pooling |
| 321 | +- Increase database resources |
| 322 | + |
| 323 | +## Baseline Measurements |
| 324 | + |
| 325 | +### Pre-Vault Integration Baseline |
| 326 | + |
| 327 | +Before implementing Vault, measure baseline startup time: |
| 328 | + |
| 329 | +```bash |
| 330 | +# Measure without Vault (using environment variables) |
| 331 | +kubectl scale deployment substream-backend-legacy --replicas=0 |
| 332 | +kubectl scale deployment substream-backend-legacy --replicas=3 |
| 333 | +time kubectl wait --for=condition=ready pod -l app=substream-backend-legacy --timeout=60s |
| 334 | +``` |
| 335 | + |
| 336 | +### Post-Vault Integration Comparison |
| 337 | + |
| 338 | +After implementing Vault, compare startup times: |
| 339 | + |
| 340 | +```bash |
| 341 | +# Measure with Vault |
| 342 | +kubectl scale deployment substream-backend --replicas=0 |
| 343 | +kubectl scale deployment substream-backend --replicas=3 |
| 344 | +time kubectl wait --for=condition=ready pod -l app=substream-backend --timeout=60s |
| 345 | +``` |
| 346 | + |
| 347 | +### Acceptance Criteria |
| 348 | + |
| 349 | +The Vault integration is considered performant if: |
| 350 | + |
| 351 | +1. **Startup Time Increase**: < 20% compared to baseline |
| 352 | +2. **Absolute Startup Time**: < 60 seconds for cold start |
| 353 | +3. **Warm Startup Time**: < 30 seconds (with caching) |
| 354 | +4. **Scale-Up Time**: New pods ready within 60 seconds during HPA events |
| 355 | +5. **Vault Unavailability**: No impact on pod startup (graceful fallback) |
| 356 | + |
| 357 | +## Conclusion |
| 358 | + |
| 359 | +The Vault integration is designed to have minimal impact on pod startup time through: |
| 360 | + |
| 361 | +- Efficient caching by the Vault sidecar |
| 362 | +- Asynchronous secret loading |
| 363 | +- Graceful fallback to environment variables |
| 364 | +- Optimized database credential generation |
| 365 | + |
| 366 | +Regular performance monitoring and testing should be conducted to ensure these performance characteristics are maintained as the application evolves. |
0 commit comments