Kubernetes TLS Certifikát Rotácia: Výpadok o 3:00 Ráno
TLS rotacia vyzera nudne, kym polka clustera nevie komunikovat. 3:00 ráno. PagerDuty. A TLS certifikát si povedal, že dnes už nebude spolupracovať.
cert-manager bol nainštalovaný, takže sme mali pocit, že rotácia je „vyriešená“. Lenže automatické systémy vedia zlyhať potichu: cert-manager sa pokúsil obnoviť certifikát 30 dní pred expiráciou, no renewal stále padal, lebo expiroval API kľúč k DNS providerovi. Logy to kričali, monitoring mlčal. Tridsať dní.
V tomto článku dávam checklist, aby bola rotácia certifikátov nudná (v dobrom): alerty na expiráciu, monitoring cert-managera a testovanie renewalu ešte predtým, než príde víkend.
Testované na: Kubernetes 1.28, cert-manager 1.13, Let’s Encrypt
Problém
Prečo Certifikáty Expirujú
Životný cyklus certifikátu (90-dňový Let's Encrypt cert):
Deň 0: Certifikát vydaný
Deň 60: cert-manager pokúša renewal (30 dní pred expiráciou)
Deň 60: Renewal ZLYHÁ (DNS nedostupné, rate limit, webhook down)
Deň 60: cert-manager naplánuje retry...
Deň 61: Retry zlyhá (rovnaký problém)
...
Deň 89: Stále zlyháva, žiadne alerty nakonfigurované
Deň 90: Certifikát EXPIRUJE o 3:00 ráno
Deň 90: 3:00 PagerDuty: "Connection refused" od všetkých klientov
Časová os ku katastrofe:
┌─────────────────────────────────────────────────────────────┐
│ Nikto si nevšimol že CertificateRequest zostáva "False" │
│ Žiadne alerty na cert-manager errors │
│ Žiadny monitoring na čas expirácie certifikátu │
│ Žiadne testovanie renewal procesu │
└─────────────────────────────────────────────────────────────┘
Bežné Zlyhania Renewalu
# Skontroluj prečo sa certifikát neobnovuje
kubectl describe certificaterequest -n namespace
# Bežné dôvody zlyhania:
# 1. DNS-01 challenge: DNS provider API kľúč expiroval
# 2. HTTP-01 challenge: Ingress zle nakonfigurovaný
# 3. Rate limit: Príliš veľa neúspešných pokusov
# 4. ClusterIssuer: ACME account problémy
# 5. Webhook: cert-manager webhook neodpovedá
Detekcia Problémov s Certifikátmi
Monitoruj Expiráciu Certifikátu
# Prometheus alerting rules
groups:
- name: certificates
rules:
# Alert 30 dní pred expiráciou
- alert: CertificateExpiringSoon
expr: |
certmanager_certificate_expiration_timestamp_seconds - time() < 86400 * 30
for: 1h
labels:
severity: warning
annotations:
summary: "Certifikát {{ $labels.name }} expiruje za < 30 dní"
# Alert 7 dní pred expiráciou (kritický)
- alert: CertificateExpiringCritical
expr: |
certmanager_certificate_expiration_timestamp_seconds - time() < 86400 * 7
for: 1h
labels:
severity: critical
annotations:
summary: "Certifikát {{ $labels.name }} expiruje za < 7 dní"
# Alert keď certifikát nie je ready
- alert: CertificateNotReady
expr: |
certmanager_certificate_ready_status{condition="False"} == 1
for: 1h
labels:
severity: warning
annotations:
summary: "Certifikát {{ $labels.name }} nie je ready"
Skontroluj Status Certifikátu
# Vypíš všetky certifikáty a ich status
kubectl get certificates -A
# Detailný status
kubectl describe certificate <name> -n <namespace>
# Skontroluj CertificateRequest status
kubectl get certificaterequests -A
# Pozri cert-manager logy pre errory
kubectl logs -n cert-manager deploy/cert-manager -f
Riešenia
1. Správny Monitoring Setup
# ServiceMonitor pre cert-manager
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: cert-manager
namespace: monitoring
spec:
selector:
matchLabels:
app.kubernetes.io/name: cert-manager
namespaceSelector:
matchNames:
- cert-manager
endpoints:
- port: http-metrics
interval: 30s
2. Testuj Renewal Pred Produkciou
# Staging issuer pre testovanie
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: [email protected]
privateKeySecretRef:
name: letsencrypt-staging-key
solvers:
- http01:
ingress:
class: nginx
# Vynúť test renewalu
kubectl cert-manager renew <certificate-name> -n <namespace>
# Skontroluj výsledok
kubectl describe certificaterequest -n <namespace> | grep -A20 "Status:"
3. Záložná Stratégia Certifikátov
# Maj fallback self-signed issuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned-fallback
spec:
selfSigned: {}
Checklist Rotácie
#!/bin/bash
# certificate-health-check.sh
echo "=== Certificate Health Check ==="
# Skontroluj všetky certifikáty
echo -e "\n## Status Certifikátov"
kubectl get certificates -A -o wide
# Nájdi expirujúce čoskoro (7 dní)
echo -e "\n## Expirujúce Do 7 Dní"
kubectl get certificates -A -o json | jq -r '
.items[] |
select(.status.notAfter) |
select((.status.notAfter | fromdateiso8601) - now < 604800) |
"\(.metadata.namespace)/\(.metadata.name): \(.status.notAfter)"
'
Checklist
## Správa Certifikátov
### Monitoring
- [ ] Alert na expiráciu < 30 dní (warning)
- [ ] Alert na expiráciu < 7 dní (critical)
- [ ] Alert keď certifikát nie je ready
- [ ] Dashboard ukazujúci všetky cert statusy
### Testovanie
- [ ] Testuj renewal proces v stagingu
- [ ] Over že DNS-01/HTTP-01 challenge funguje
- [ ] Testuj manuálny renewal: kubectl cert-manager renew
### Záloha
- [ ] Maj nakonfigurovaný fallback issuer
- [ ] Zdokumentuj emergency rotation procedúru
- [ ] Ukladaj kópie certov v externom secret store
Záver
Výpadky certifikátov sú predchádzateľné:
- Monitoruj čas expirácie s alertami na 30 a 7 dní
- Alertuj na zlyhania renewalu okamžite
- Testuj renewal pravidelne, nie len pri počiatočnom setup
- Maj fallback stratégiu pre emergency rotáciu
Nastav alerty teraz, nie po 3:00 výpadku.
Súvisiace články
- JWT Revokovanie Stratégie - Token security
- Kubernetes DNS Caching - DNS problémy ovplyvňujúce cert challenges
Súvisiace články
Prometheus remote_write backpressure: keď monitoring zaplní disk a ešte aj stratí dáta
Runbook pre výpadky remote_write: ako zmerať lag, odhadnúť time-to-disk-full, bezpečne ladiť queue_config a vedome zvoliť trade-off medzi prežitím a stratou.
Certifikat nie je expirnuty, vas node ano: Time Drift rozbitie TLS a JWT v Kubernetes
Sporadicke TLS handshake zlyhania a JWT zamietnutia napriec sluzbami. Vsetko prejde ked to skontrolujete. Vinik: hodiny nodu sa posunuli alebo skocili, a NTP to opravilo skor nez ste to stihli zachytit.
CI/CD pre monorepo: Rýchlosť, cache, selektívne testy a supply-chain bezpečnosť
Kompletný blueprint pre efektívny CI/CD pipeline v monorepo - od path filters cez remote cache až po SBOM a SLSA. Praktické riešenia, nie teória.
Tail-based sampling v OpenTelemetry: Sizing, pamäťové pády a cost model
Praktický sizing guide pre tail sampling v OpenTelemetry Collector. Od decision_wait cez memory limity až po cost-benefit analýzu.
Citujte tento článok
Ak na článok odkazujete, pridajte pôvodnú URL a uveďte autora.