Garanzia della compatibilità dei certificati webhook prima di eseguire l'upgrade alla versione 1.23


A partire dalla versione 1.23, Kubernetes non supporta più l'identità server. convalida utilizzando il campo X.509 Common Name (CN) nei certificati. Invece, Kubernetes si baserà solo sulle informazioni contenute nel campo Nome alternativo del soggetto X.509 (SAN).

Per evitare conseguenze sui cluster, devi sostituire i certificati non compatibili senza SAN per i backend di webhook e server API aggregati prima eseguendo l'upgrade dei cluster a Kubernetes alla versione 1.23.

Perché Kubernetes non supporta più i certificati di backend senza SAN

GKE gestisce Kubernetes open source, che utilizza Componente kube-apiserver per contattare i backend webhook e i server API aggregati utilizzando Transport Layer Sicurezza (TLS). Il componente kube-apiserver è scritto nella programmazione Go lingua.

Prima di Go 1.15, i client TLS convalidavano l'identità dei server connessi a un processo in due fasi:

  1. Verifica se il nome DNS (o l'indirizzo IP) del server è presente come uno dei SAN sul certificato del server.
  2. Come riserva, controlla se il nome DNS (o l'indirizzo IP) del server è uguale al CN sul certificato del server.

RFC 6125 completamente la convalida dell'identità del server ritirata in base al campo CN nel 2011. Browser e altre applicazioni critiche per la sicurezza non usano più questo campo.

Per allinearsi al più ampio ecosistema TLS, Go 1.15 rimosso dal passaggio 2 dal processo di convalida, ma ha lasciato un'opzione di debug (x509ignoreCN=0) a abilitare il vecchio comportamento per semplificare il processo di migrazione. Versione Kubernetes 1.19 è stata la prima versione creata utilizzando Go 1.15. dei cluster GKE dalla 1.19 alla 1.22 abilita l'opzione di debug per impostazione predefinita clienti con più tempo per sostituire i certificati per il webhook interessato e backend aggregati di server API.

La versione 1.23 di Kubernetes è creata con Go 1.17, che rimuove l'opzione di debug. Dopo che GKE ha eseguito l'upgrade dei cluster alla versione 1.23, le chiamate non riescono a connettersi dal piano di controllo del cluster a webhook o all'API aggregata che non forniscono un certificato X.509 valido con SAN appropriata.

Identificazione dei cluster interessati

Per i cluster che eseguono versioni di patch almeno 1.21.9 o 1.22.3

Per i cluster con patch 1.21.9 e 1.22.3 o versioni successive con Cloud Logging attivato, GKE offre una Log di Cloud Audit Logs per identificare le chiamate ai backend interessati dal tuo cluster. Puoi utilizzare lo seguente filtro per cercare i log:

logName =~ "projects/.*/logs/cloudaudit.googleapis.com%2Factivity"
resource.type = "k8s_cluster"
operation.producer = "k8s.io"
"invalid-cert.webhook.gke.io"

Se i tuoi cluster non hanno chiamato backend con certificati interessati, non per visualizzare eventuali log. Se visualizzi un log di controllo di questo tipo, includerà il nome host di sul backend interessato.

Di seguito è riportato un esempio della voce di log per un backend webhook ospitato da un servizio denominato example-webhook nello spazio dei nomi default:

{
  ...
  resource {
    type: "k8s_cluster",
    "labels": {
      "location": "us-central1-c",
      "cluster_name": "example-cluster",
      "project_id": "example-project"
    }
  },
  labels: {
    invalid-cert.webhook.gke.io/example-webhook.default.svc: "No subjectAltNames returned from example-webhook.default.svc:8443",
    ...
  },
  logName: "projects/example-project/logs/cloudaudit.googleapis.com%2Factivity",
  operation: {
    ...
    producer: "k8s.io",
    ...
  },
  ...
}

I nomi host dei servizi interessati (ad es. example-webhook.default.svc) sono inclusi come suffissi nei nomi delle etichette che iniziano con invalid-cert.webhook.gke.io/. Puoi anche ottenere il nome del cluster ha effettuato la chiamata dall'etichetta resource.labels.cluster_name, che ha example-cluster in questo esempio.

Approfondimenti sul ritiro

Puoi individuare i cluster che utilizzano certificati incompatibili approfondimenti sul ritiro. Gli insight sono disponibili per con la versione 1.22.6-gke.1000 o successiva.

Altre versioni del cluster

Se disponi di un cluster su una versione di patch precedente alla 1.22.3 nella versione 1.22 una versione secondaria o una versione patch precedente alla 1.21.9, sono disponibili opzioni per determinare se il tuo cluster è interessato da questa deprecazione:

Opzione 1 (consigliata): Esegui l'upgrade del cluster a una patch che supporta identificazione dei certificati interessati con i log. Assicurati che Cloud Logging sia abilitato per il tuo in un cluster Kubernetes. Dopo l'upgrade del cluster, Cloud Audit Logs vengono generati log ogni volta che il cluster tenta di chiamare un servizio che non fornire un certificato con una SAN appropriata. Poiché i log saranno durante un tentativo di chiamata, ti consigliamo di attendere 30 giorni dopo l'upgrade abbastanza tempo per richiamare tutti i percorsi di chiamata.

Poiché questo approccio, ti consigliamo di utilizzare i log per identificare i servizi interessati, riduce al minimo gli sforzi manuali generando automaticamente i log per mostrare le i servizi di machine learning.

Opzione 2: controlla i certificati utilizzati da webhook o dall'API aggregata. ai server dei cluster per determinare se sono interessati con SAN:

  1. Ottieni l'elenco di webhook e aggregati server API nel tuo cluster e ne identificano i backend (servizi o URL).
  2. Esamina i certificati utilizzati dalla di backend.

Dato lo sforzo manuale necessario per ispezionare tutti i certificati in questo modo, deve essere seguito solo se devi valutare l'impatto del di ritiro nella versione 1.23 di Kubernetes prima di eseguire l'upgrade del cluster versione 1.21. Se puoi eseguire l'upgrade del cluster alla versione 1.21, devi eseguirne l'upgrade e poi segui le istruzioni dell'Opzione 1 per evitare di dover eseguire operazioni manuali.

Identificazione dei servizi di backend da ispezionare

Per identificare i backend che potrebbero essere interessati dal ritiro, recupera l'elenco Webhook e servizi API aggregati e relativi backend associati in in un cluster Kubernetes.

Per elencare tutti i webhook pertinenti nel cluster, utilizza il seguente kubectl :

kubectl get mutatingwebhookconfigurations -A   # mutating admission webhooks

kubectl get validatingwebhookconfigurations -A # validating admission webhooks

Puoi ottenere un URL o un servizio di backend associato per un determinato webhook esame di clientConfig.service campo o webhooks.clientConfig.url campo nella configurazione del webhook:

kubectl get mutatingwebhookconfigurations example-webhook -o yaml

L'output di questo comando è simile al seguente:

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
webhooks:
- admissionReviewVersions:
  clientConfig:
    service:
        name: example-service
        namespace: default
        port: 443

Tieni presente che clientConfig può specificare il proprio backend come servizio Kubernetes (clientConfig.service) o come URL (clientConfig.url).

Per elencare tutti i servizi API aggregati pertinenti nel cluster, utilizza quanto segue Comando kubectl:

kubectl get apiservices -A |grep -v Local      # aggregated API services

L'output di questo comando è simile al seguente:

NAME                     SERVICE                      AVAILABLE   AGE
v1beta1.metrics.k8s.io   kube-system/metrics-server   True        237d

Questo esempio restituisce il servizio metric-server dallo spazio dei nomi kube-system.

Puoi ottenere un servizio associato per una determinata API aggregata esaminando Campo spec.service:

kubectl get apiservices v1beta1.metrics.k8s.io -o yaml

L'output di questo comando è simile al seguente:

...
apiVersion: apiregistration.k8s.io/v1
kind: APIService
spec:
  service:
    name: metrics-server
    namespace: kube-system
    port: 443

Ispezione del certificato di un servizio

Dopo aver identificato il backend pertinente ai servizi da esaminare, puoi esaminare il certificato di ogni servizio specifico, ad esempio example-service:

  1. Trova il selettore e la porta di destinazione del servizio:

    kubectl describe service example-service
    

    L'output di questo comando è simile al seguente:

    Name: example-service
    Namespace: default
    Labels: run=nginx
    Selector: run=nginx
    Type: ClusterIP
    IP: 172.21.xxx.xxx
    Port: 443
    TargetPort: 444
    

    In questo esempio, example-service ha il selettore run=nginx e porta di destinazione 444.

  2. Trova un pod corrispondente al selettore:

    kubectl get pods --selector=run=nginx
    

    L'output del comando è simile al seguente:

    NAME          READY   STATUS    RESTARTS   AGE
    example-pod   1/1     Running   0          21m
    
  3. Imposta un port forwarding

    dal tuo localhost kubectl al pod.

    kubectl port-forward pods/example-pod LOCALHOST_PORT:TARGET_PORT # port forwarding in background
    

    Sostituisci quanto segue nel comando:

    • LOCALHOST_PORT: l'indirizzo da ascoltare.
    • TARGET_PORT il TargetPort del passaggio 1.
  4. Utilizza openssl per stampare il certificato utilizzato dal servizio:

    openssl s_client -connect localhost:LOCALHOST_PORT </dev/null | openssl x509 -noout -text
    

    Questo output di esempio mostra un certificato valido (con voci SAN):

    Subject: CN = example-service.default.svc
    X509v3 extensions:
      X509v3 Subject Alternative Name:
        DNS:example-service.default.svc
    

    Questo output di esempio mostra un certificato con una SAN mancante:

    Subject: CN = example-service.default.svc
      X509v3 extensions:
          X509v3 Key Usage: critical
              Digital Signature, Key Encipherment
          X509v3 Extended Key Usage:
              TLS Web Server Authentication
          X509v3 Authority Key Identifier:
              keyid:1A:5F:29:D8:E9:3C:54:3C:35:CC:D8:AB:D1:21:FD:C3:56:25:C0:74
    
  5. Rimuovi la porta forwarding dall'esecuzione in background con quanto segue :

    $ jobs
    [1]+  Running                 kubectl port-forward pods/example-pod 8888:444 &
    $ kill %1
    [1]+  Terminated              kubectl port-forward pods/example 8888:444
    

Ispezione del certificato di un backend di URL

Se il webhook utilizza un url backend, si collegano direttamente al nome host specificato nell'URL. Ad esempio, se l'URL è https://example.com:123/foo/bar, usa questo comando openssl per stampa il certificato utilizzato dal backend:

  openssl s_client -connect example.com:123 </dev/null | openssl x509 -noout -text

Mitigare il rischio dell'upgrade alla versione 1.23

Dopo aver identificato i cluster interessati e utilizzando certificati senza SAN, devi aggiornare a webhook e a backend di server API aggregati per utilizzare certificati con SAN prima di eseguire l'upgrade dei cluster alla versione 1.23.

GKE non eseguirà automaticamente l'upgrade dei cluster alle versioni 1.22.6-gke.1000 o versioni successive con backend che utilizzano certificati incompatibili finché non sostituire i certificati o fino a quando la versione 1.22 non raggiunge fine del supporto standard.

Se il tuo cluster utilizza una versione GKE precedente a 1.22.6-gke.1000, puoi bloccare temporaneamente gli upgrade automatici la configurazione di un esclusione per manutenzione per evitare upgrade di minore entità.

Risorse

Per ulteriori informazioni su questa modifica, consulta le seguenti risorse:

  • Note di rilascio di Kubernetes 1.23
    • Kubernetes è stato creato con Go 1.17. Questa versione di Go rimuove il di utilizzare un'impostazione dell'ambiente GODEBUG=x509ignoreCN=0 per riattiva il comportamento precedente deprecato per il trattamento della Rete Display di Google della pubblicazione X.509 certificati come nome host.
  • Kubernetes 1.19 e Kubernetes 1.20 note di rilascio
    • Il comportamento precedente e ritirato relativo al trattamento del campo CN su X.509 che utilizzano certificati come nome host quando non sono presenti SAN è disabilitata per impostazione predefinita.
  • Note di rilascio di Go 1.17
    • Il flag temporaneo GODEBUG=x509ignoreCN=0 è stato rimosso.
  • Note di rilascio di Go 1.15
    • Il comportamento precedente e ritirato relativo al trattamento del campo CN su X.509 i certificati come host quando non sono presenti SAN è ora disabilitato predefinito.
  • RFC 6125 (pagina 46)
    • Sebbene l'uso del valore CN sia una pratica esistente, è obsoleto, e le autorità di certificazione sono invitate a fornire subjectAltName valori.
  • Webhook di ammissione