====== 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}}