Automatyzacja Certyfikatów SSL w Kubernetes z cert-manager
Jeśli kiedykolwiek zarządzałeś certyfikatami SSL w środowisku Kubernetes, prawdopodobnie wiesz, że może to być prawdziwy ból głowy. Ręczne odnawianie certyfikatów, konfiguracja Secrets, synchronizacja z Ingress… Na szczęście istnieje cert-manager - narzędzie, które automatyzuje cały ten proces i pozwala Ci w końcu spać spokojnie.
Czym Jest cert-manager?
cert-manager to natywny dla Kubernetes kontroler, który automatyzuje zarządzanie i wydawanie certyfikatów TLS z różnych źródeł. Działa jako rozszerzenie Kubernetes API, dodając niestandardowe zasoby (Custom Resources), które pozwalają zdefiniować certyfikaty w sposób deklaratywny.
Główne Zalety
Pełna Automatyzacja
- Automatyczne wydawanie certyfikatów
- Automatyczne odnawianie przed wygaśnięciem
- Integracja z Kubernetes Ingress
- Zero ręcznej interwencji
Wsparcie dla Wielu Źródeł
- Let’s Encrypt (ACME)
- HashiCorp Vault
- Venafi
- Prywatne CA (self-signed)
- External issuers (własne integracje)
Kubernetes-Native
- Deklaratywna konfiguracja
- CRDs (Custom Resource Definitions)
- Integracja z kubectl
- GitOps ready
Instalacja cert-manager
Wymagania Wstępne
Przed instalacją upewnij się, że masz:
- Klaster Kubernetes (wersja 1.22+)
- kubectl skonfigurowany
- Prawa administratora klastra
- Helm 3.x (opcjonalnie, ale zalecane)
Instalacja przez Helm
Najprostszy sposób to użycie Helm:
# Dodaj repozytorium Helm
helm repo add jetstack https://charts.jetstack.io
helm repo update
# Zainstaluj CRDs
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.3/cert-manager.crds.yaml
# Zainstaluj cert-manager
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.13.3
# Weryfikacja instalacji
kubectl get pods -n cert-manager
Instalacja przez kubectl
Jeśli wolisz czysty YAML:
# Instalacja cert-manager z wszystkimi komponentami
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.3/cert-manager.yaml
# Sprawdzenie statusu
kubectl get pods -n cert-manager
kubectl get crds | grep cert-manager
Po instalacji powinieneś zobaczyć trzy pody:
- cert-manager
- cert-manager-cainjector
- cert-manager-webhook
Konfiguracja Let’s Encrypt
ClusterIssuer vs Issuer
cert-manager oferuje dwa typy zasobów do wydawania certyfikatów:
Issuer - działa w ramach jednego namespace ClusterIssuer - działa w całym klastrze (zalecane)
Konfiguracja ClusterIssuer dla Let’s Encrypt
Zacznijmy od środowiska staging (do testów):
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
# Serwer staging Let's Encrypt (wyższe limity, certyfikaty testowe)
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: [email protected] # Twój email do powiadomień
# Secret do przechowywania klucza prywatnego ACME
privateKeySecretRef:
name: letsencrypt-staging
# HTTP-01 challenge
solvers:
- http01:
ingress:
class: nginx # lub traefik, zależnie od Ingress Controller
Dla produkcji:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: [email protected]
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
Zastosuj konfigurację:
kubectl apply -f clusterissuer-staging.yaml
kubectl apply -f clusterissuer-prod.yaml
# Sprawdź status
kubectl get clusterissuer
kubectl describe clusterissuer letsencrypt-prod
Automatyczne Certyfikaty dla Ingress
Podstawowa Konfiguracja Ingress
Najprostszy sposób to dodanie adnotacji do Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
# Opcjonalnie: przekierowanie HTTP -> HTTPS
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- myapp.example.com
secretName: myapp-tls # cert-manager utworzy ten Secret automatycznie
rules:
- host: myapp.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: myapp-service
port:
number: 80
Po zastosowaniu:
kubectl apply -f ingress.yaml
# Monitoruj proces wydawania certyfikatu
kubectl get certificate
kubectl describe certificate myapp-tls
# Sprawdź zdarzenia
kubectl get events --sort-by='.lastTimestamp'
Ręczne Zarządzanie Certyfikatami
Możesz też utworzyć zasób Certificate bezpośrednio:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: myapp-cert
namespace: default
spec:
secretName: myapp-tls
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
commonName: myapp.example.com
dnsNames:
- myapp.example.com
- www.myapp.example.com
# Automatyczne odnawianie 30 dni przed wygaśnięciem
renewBefore: 720h # 30 dni
DNS-01 Challenge dla Wildcard Certificates
Dla certyfikatów wildcard (*.example.com) musisz użyć DNS-01 challenge:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-dns
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: [email protected]
privateKeySecretRef:
name: letsencrypt-dns
solvers:
- dns01:
cloudflare:
email: [email protected]
apiTokenSecretRef:
name: cloudflare-api-token
key: api-token
Stwórz Secret z API token Cloudflare:
kubectl create secret generic cloudflare-api-token \
--from-literal=api-token='your-cloudflare-api-token'
Certificate dla wildcard:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: wildcard-cert
spec:
secretName: wildcard-tls
issuerRef:
name: letsencrypt-dns
kind: ClusterIssuer
dnsNames:
- "example.com"
- "*.example.com"
Monitorowanie i Debugging
Sprawdzanie Statusu Certyfikatów
# Lista wszystkich certyfikatów
kubectl get certificate --all-namespaces
# Szczegóły certyfikatu
kubectl describe certificate myapp-tls
# Status CertificateRequest
kubectl get certificaterequest
kubectl describe certificaterequest <name>
# Status Order (ACME)
kubectl get order
kubectl describe order <name>
# Status Challenge
kubectl get challenge
kubectl describe challenge <name>
Logi cert-manager
# Główny kontroler
kubectl logs -n cert-manager deploy/cert-manager
# Webhook
kubectl logs -n cert-manager deploy/cert-manager-webhook
# CA injector
kubectl logs -n cert-manager deploy/cert-manager-cainjector
# Śledzenie logów na bieżąco
kubectl logs -n cert-manager deploy/cert-manager -f
Najczęstsze Problemy
Problem 1: Certificate w stanie “Pending”
# Sprawdź CertificateRequest
kubectl get certificaterequest
kubectl describe certificaterequest <name>
# Sprawdź Order
kubectl get order
kubectl describe order <name>
Często przyczyną są:
- Błędna konfiguracja DNS
- Brak dostępu do domeny przez Let’s Encrypt
- Problemy z Ingress Controller
Problem 2: HTTP-01 challenge fails
# Sprawdź czy challenge pod został utworzony
kubectl get pods | grep cm-acme-http-solver
# Sprawdź czy Ingress dla challenge został utworzony
kubectl get ingress
Rozwiązanie:
- Sprawdź czy domena wskazuje na klaster
- Sprawdź czy port 80 jest otwarty
- Sprawdź logi Ingress Controller
Problem 3: Zbyt wiele żądań (rate limiting)
Let’s Encrypt ma limity:
- 50 certyfikatów na domenę tygodniowo
- 5 duplikatów tygodniowo
Rozwiązanie:
- Używaj staging podczas testów
- Planuj wdrożenia produkcyjne
Integracja z Monitoringiem
Prometheus Metrics
cert-manager eksportuje metryki:
apiVersion: v1
kind: Service
metadata:
name: cert-manager-metrics
namespace: cert-manager
labels:
app: cert-manager
spec:
ports:
- name: metrics
port: 9402
targetPort: 9402
selector:
app: cert-manager
ServiceMonitor dla Prometheus Operator:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: cert-manager
namespace: cert-manager
spec:
selector:
matchLabels:
app: cert-manager
endpoints:
- port: metrics
interval: 30s
Grafana Dashboard
Importuj dashboard z ID: 11001 (cert-manager overview)
Kluczowe metryki:
certmanager_certificate_expiration_timestamp_seconds- data wygaśnięciacertmanager_certificate_ready_status- status gotowościcertmanager_http_acme_client_request_count- żądania ACMEcertmanager_controller_sync_call_count- wywołania synchronizacji
Alerting
Przykładowy alert Prometheus:
groups:
- name: cert-manager
rules:
- alert: CertificateExpiryIn7Days
expr: (certmanager_certificate_expiration_timestamp_seconds - time()) / 86400 < 7
for: 1h
labels:
severity: warning
annotations:
summary: "Certificate {{ $labels.name }} expires in less than 7 days"
- alert: CertificateNotReady
expr: certmanager_certificate_ready_status == 0
for: 10m
labels:
severity: critical
annotations:
summary: "Certificate {{ $labels.name }} is not ready"
Zaawansowane Konfiguracje
Własne CA (Private Certificate Authority)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: private-ca
spec:
ca:
secretName: ca-key-pair
Stworzenie CA:
# Wygeneruj klucz i certyfikat CA
openssl genrsa -out ca.key 4096
openssl req -new -x509 -key ca.key -out ca.crt -days 3650
# Stwórz Secret
kubectl create secret tls ca-key-pair \
--cert=ca.crt \
--key=ca.key \
--namespace=cert-manager
HashiCorp Vault Integration
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: vault-issuer
spec:
vault:
server: https://vault.example.com
path: pki/sign/example-dot-com
auth:
kubernetes:
mountPath: /v1/auth/kubernetes
role: cert-manager
secretRef:
name: cert-manager-vault-token
key: token
Certificate Policies
Wymuszanie standardów organizacji:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: myapp-cert
spec:
secretName: myapp-tls
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- myapp.example.com
# Minimalna długość klucza
privateKey:
algorithm: RSA
size: 4096
# Dodatkowe rozszerzenia
usages:
- digital signature
- key encipherment
- server auth
- client auth
Best Practices
1. Używaj Namespace dla cert-manager
# Wszystko w dedykowanym namespace
kubectl create namespace cert-manager
2. Limity Zasobów
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 50m
memory: 64Mi
3. Backup Secrets
# Backup certyfikatów
kubectl get secrets -n default -o yaml > certificates-backup.yaml
# Lub użyj Velero do automatycznych backupów
4. Staging przed Produkcją
Zawsze testuj na Let’s Encrypt staging przed produkcją.
5. Monitoring i Alerting
Monitoruj:
- Daty wygaśnięcia
- Status certyfikatów
- Błędy odnowień
6. Dokumentacja
Prowadź dokumentację:
- Lista używanych issuerów
- Procedury odnowienia ręcznego (na wypadek awarii)
- Kontakty i eskalacja
Migracja z Istniejących Certyfikatów
Import Istniejącego Certyfikatu
# Stwórz Secret z istniejącym certyfikatem
kubectl create secret tls existing-cert \
--cert=path/to/cert.crt \
--key=path/to/cert.key
# Stwórz Certificate zarządzany przez cert-manager
kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: existing-cert
spec:
secretName: existing-cert
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- example.com
EOF
Stopniowa Migracja
- Zainstaluj cert-manager obok istniejącego rozwiązania
- Skonfiguruj ClusterIssuers
- Testuj na środowisku staging
- Migruj pojedyncze aplikacje
- Monitoruj i waliduj
- Usuń stare rozwiązanie
Case Study: Migracja 50+ Aplikacji
Wyzwanie: Firma miała 50+ aplikacji w Kubernetes, każda z ręcznie zarządzanymi certyfikatami.
Rozwiązanie:
- Instalacja cert-manager
- Konfiguracja ClusterIssuers (prod + staging)
- Skrypt migracyjny dla wszystkich Ingress
- Automatyczne dodawanie adnotacji
- Monitoring w Grafana
Wyniki:
- 95% redukcja czasu zarządzania certyfikatami
- 0 incydentów z wygasłymi certyfikatami w ciągu roku
- Ujednolicone podejście do SSL/TLS
- Pełna automatyzacja odnowień
Kod skryptu migracyjnego:
#!/bin/bash
# migrate-ingresses.sh
for ingress in $(kubectl get ingress -A -o json | jq -r '.items[] | "\(.metadata.namespace)/\(.metadata.name)"'); do
namespace=$(echo $ingress | cut -d/ -f1)
name=$(echo $ingress | cut -d/ -f2)
echo "Migrating $namespace/$name"
kubectl annotate ingress $name -n $namespace \
cert-manager.io/cluster-issuer=letsencrypt-prod \
--overwrite
echo "Done: $namespace/$name"
done
Podsumowanie
cert-manager to must-have dla każdego klastra Kubernetes, który obsługuje ruch HTTPS. Automatyzacja zarządzania certyfikatami:
- Eliminuje ryzyko wygasłych certyfikatów
- Redukuje czas pracy ops o 90%+
- Zapewnia spójne podejście do SSL/TLS
- Integruje się z ekosystemem Kubernetes
Szybki Start - Checklist
- Zainstaluj cert-manager przez Helm
- Skonfiguruj ClusterIssuer dla Let’s Encrypt staging
- Przetestuj na przykładowej aplikacji
- Skonfiguruj ClusterIssuer produkcyjny
- Dodaj adnotacje do Ingress
- Skonfiguruj monitoring (Grafana + Prometheus)
- Ustaw alerty na wygasające certyfikaty
- Dokumentuj konfigurację
Kolejne Kroki
- Eksploruj external issuers dla niestandardowych CA
- Integruj z Vault dla wrażliwych środowisk
- Automatyzuj backup certyfikatów
- Rozważ certificate policies dla compliance
Chcesz upewnić się, że wszystkie Twoje certyfikaty są monitorowane? Spróbuj CrtMgr - proste narzędzie do śledzenia certyfikatów SSL/TLS z automatycznymi alertami, które współpracuje doskonale z cert-manager.
Automatyzacja to klucz. Z cert-manager i odpowiednim monitoringiem nigdy więcej nie będziesz tracić snu przez wygasłe certyfikaty.