====== Kubernetes Cert-Manager ======
**Kompleksnost:** Visoka \\
**Trajanje:** 2-3 ure za nastavitev \\
**Predpogoj:** Kubernetes 1.25+, Helm
Avtomatsko upravljanje certifikatov v Kubernetes s cert-manager in lastno PKI.
----
===== Arhitektura =====
flowchart TB
subgraph K8S["KUBERNETES GRUČA"]
subgraph CM["cert-manager"]
I[Issuer/ClusterIssuer]
C[Certificate]
CR[CertificateRequest]
end
subgraph APP["Aplikacija"]
P[Pod]
S[Secret]
ING[Ingress]
end
C --> CR --> I
I --> S
S --> P
S --> ING
end
subgraph EXTERNAL["ZUNANJI CA"]
CA[Notranji CA]
V[Vault PKI]
LE[Let's Encrypt]
end
I --> CA
I --> V
I --> LE
style CM fill:#e3f2fd
style I fill:#fff3e0
----
===== Namestitev =====
# Dodajanje Helm repozitorija
helm repo add jetstack https://charts.jetstack.io
helm repo update
# Namestitev cert-manager
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set installCRDs=true \
--set prometheus.enabled=true
# Preverjanje namestitve
kubectl get pods -n cert-manager
----
===== Tipi izdajateljev =====
| Tip izdajatelja | Primer uporabe | PQ podpora |
|-----------------|----------------|------------|
| SelfSigned | Testiranje, zagonsko nalaganje | Ne |
| CA | Notranja PKI | **Da (z WvdS)** |
| Vault | HashiCorp Vault PKI | Delno |
| ACME | Let's Encrypt, javni CA | Ne |
| Venafi | Podjetniška PKI | Delno |
----
===== ClusterIssuer z lastnim CA =====
==== Korak 1: Ustvarjanje CA skrivnosti ====
# CA certifikat in ključ kot Secret
kubectl create secret tls ca-key-pair \
--cert=intermediate-ca.pem \
--key=intermediate-ca.key \
--namespace cert-manager
Ali kot YAML:
# ca-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: ca-key-pair
namespace: cert-manager
type: kubernetes.io/tls
data:
tls.crt:
tls.key:
==== Korak 2: Definicija ClusterIssuer ====
# cluster-issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: internal-ca-issuer
spec:
ca:
secretName: ca-key-pair
kubectl apply -f cluster-issuer.yaml
# Preverjanje statusa
kubectl get clusterissuer internal-ca-issuer
----
===== Vir Certificate =====
# certificate.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: app-tls
namespace: production
spec:
# Secret, ki bo ustvarjen
secretName: app-tls-secret
# Obdobje veljavnosti
duration: 2160h # 90 dni
renewBefore: 360h # 15 dni pred iztekom obnoviti
# Subject
subject:
organizations:
- EMSR DATA
commonName: app.example.com
# Konfiguracija ključa
privateKey:
algorithm: ECDSA
size: 384
rotationPolicy: Always
# Namen uporabe
usages:
- server auth
- client auth
# DNS/IP SAN
dnsNames:
- app.example.com
- app.production.svc.cluster.local
ipAddresses:
- 10.0.0.100
# Referenca na izdajatelja
issuerRef:
name: internal-ca-issuer
kind: ClusterIssuer
kubectl apply -f certificate.yaml
# Preverjanje statusa
kubectl get certificate -n production
kubectl describe certificate app-tls -n production
# Prikaz Secret
kubectl get secret app-tls-secret -n production -o yaml
----
===== Ingress anotacija (samodejno) =====
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
namespace: production
annotations:
# cert-manager samodejno ustvari certifikat
cert-manager.io/cluster-issuer: "internal-ca-issuer"
spec:
tls:
- hosts:
- app.example.com
secretName: app-ingress-tls
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
----
===== Vault PKI integracija =====
# vault-issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: vault-issuer
spec:
vault:
server: https://vault.example.com
path: pki/sign/server-role
caBundle:
auth:
kubernetes:
role: cert-manager
mountPath: /v1/auth/kubernetes
secretRef:
name: vault-token
key: token
**Konfiguracija Vault:**
# Aktivacija PKI Engine
vault secrets enable pki
vault secrets tune -max-lease-ttl=87600h pki
# Generiranje Root-CA (ali uvoz)
vault write pki/root/generate/internal \
common_name="Internal Root CA" \
ttl=87600h
# Vloga za cert-manager
vault write pki/roles/server-role \
allowed_domains="example.com,svc.cluster.local" \
allow_subdomains=true \
max_ttl=720h
# Kubernetes avtentikacija
vault auth enable kubernetes
vault write auth/kubernetes/config \
kubernetes_host="https://kubernetes.default.svc"
----
===== Nadzor =====
==== Prometheus metrike ====
# ServiceMonitor za cert-manager
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: cert-manager
namespace: monitoring
spec:
selector:
matchLabels:
app.kubernetes.io/name: cert-manager
endpoints:
- port: http-metrics
**Pomembne metrike:**
| Metrika | Opis | Prag za opozorilo |
|---------|------|-------------------|
| ''certmanager_certificate_expiration_timestamp_seconds'' | Čas izteka | < 7 dni |
| ''certmanager_certificate_ready_status'' | Status pripravljenosti | != 1 |
| ''certmanager_certificate_renewal_timestamp_seconds'' | Zadnja obnova | - |
==== Pravila za opozorila ====
# PrometheusRule
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: cert-manager-alerts
namespace: monitoring
spec:
groups:
- name: cert-manager
rules:
- alert: CertificateExpiringSoon
expr: |
certmanager_certificate_expiration_timestamp_seconds - time() < 604800
for: 1h
labels:
severity: warning
annotations:
summary: "Certifikat {{ $labels.name }} poteče v < 7 dneh"
- alert: CertificateNotReady
expr: |
certmanager_certificate_ready_status != 1
for: 10m
labels:
severity: critical
annotations:
summary: "Certifikat {{ $labels.name }} ni pripravljen"
----
===== Odpravljanje napak =====
# Status certifikata
kubectl get certificate -A
kubectl describe certificate -n
# Preverjanje CertificateRequest
kubectl get certificaterequest -A
kubectl describe certificaterequest
# Dnevniki cert-manager
kubectl logs -n cert-manager -l app=cert-manager -f
# Dogodki
kubectl get events -n cert-manager --sort-by='.lastTimestamp'
**Pogoste težave:**
| Težava | Vzrok | Rešitev |
|--------|-------|---------|
| ''Issuer not found'' | ClusterIssuer vs. Issuer | Preverite Kind |
| ''Secret not found'' | CA-Secret ni ustvarjen | Ustvarite Secret |
| ''Failed to generate CSR'' | Algoritem ključa | Preverite Algorithm/Size |
| ''Challenge failed'' | Težava z ACME | Preverite DNS/HTTP izziv |
----
===== Post-kvantno z lastnim CA =====
**PQ certifikati s cert-manager:**
Cert-manager sam ne podpira PQ algoritmov, vendar lahko uporabite CA z PQ zmožnostjo in certifikate ustvarite ročno.
// Ustvarjanje Kubernetes Secret s PQ certifikatom
using var intermediate = new X509Certificate2("intermediate.pfx", "password");
// Nalaganje CSR iz Kubernetes
var csr = CertificateRequest.LoadSigningRequest(csrBytes, HashAlgorithmName.SHA384);
// Izdaja PQ hibridnega certifikata
var cert = csr.Create(
intermediate,
DateTimeOffset.UtcNow,
DateTimeOffset.UtcNow.AddDays(90),
Guid.NewGuid().ToByteArray(),
CryptoMode.Hybrid);
// Shranjevanje kot Kubernetes Secret
var secret = new V1Secret
{
Metadata = new V1ObjectMeta { Name = "pq-tls-secret" },
Type = "kubernetes.io/tls",
Data = new Dictionary
{
["tls.crt"] = Encoding.UTF8.GetBytes(cert.ExportCertificatePem()),
["tls.key"] = Encoding.UTF8.GetBytes(cert.GetECDsaPrivateKey().ExportPkcs8PrivateKeyPem())
}
};
----
===== Kontrolni seznam =====
| # | Kontrolna točka | |
|---|-----------------|---|
| 1 | cert-manager nameščen | |
| 2 | ClusterIssuer konfiguriran | |
| 3 | CA-Secret ustvarjen | |
| 4 | Testni certifikat deluje | |
| 5 | Prometheus nadzor aktiven | |
| 6 | Opozorila konfigurirana | |
----
===== Povezana dokumentacija =====
* [[.:acme-integration|ACME integracija]] – Za javne certifikate
* [[..:cloud:hashicorp-vault|HashiCorp Vault]] – Vault PKI zaledje
* [[sl:int:pqcrypt:szenarien:tls:start|TLS/mTLS]] – Uporaba certifikatov
----
<< [[.:cicd-code-signing|← CI/CD podpisovanje kode]] | [[.:scheduled-renewal|→ Načrtovana obnova]] >>
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//
{{tag>kubernetes cert-manager helm vault automatisierung operator}}