Questa pagina mostra come configurare più certificati SSL per il traffico in entrata nei cluster Google Kubernetes Engine (GKE).
Panoramica
Se vuoi accettare richieste HTTPS dai tuoi clienti, il bilanciatore del carico delle applicazioni deve disporre di un certificato per dimostrare la propria identità ai clienti. Il bilanciatore del carico deve inoltre disporre di una chiave privata per completare handshake HTTPS.
Quando il bilanciatore del carico accetta una richiesta HTTPS da un client, il traffico tra il client e il bilanciatore del carico viene criptato utilizzando TLS. Tuttavia, il bilanciatore del carico termina la crittografia TLS e inoltra la richiesta senza crittografia all'applicazione. Quando configuri un bilanciatore del carico delle applicazioni tramite Ingress, puoi configurare il bilanciatore del carico in modo che presenti fino a dieci certificati TLS al client.
Il bilanciatore del carico utilizza l'indicazione nome server (SNI) per determinare quale certificato presentare al client, in base al nome di dominio nell'handshake TLS. Se il client non utilizza SNI o se il client utilizza un nome di dominio che non corrisponde al Common Name (CN) in uno dei certificati, il caricamento utilizza il primo certificato elencato nella risorsa Ingress.
Il seguente diagramma mostra il bilanciatore del carico che invia il traffico a diversi backend, a seconda del nome di dominio utilizzato nella richiesta:
Puoi fornire un bilanciatore del carico delle applicazioni con certificati SSL utilizzando seguenti metodi:
- Certificati SSL gestiti da Google. Per informazioni su come utilizzarli, fai riferimento alla pagina dei certificati gestiti.
Certificato SSL Google Cloud che gestisci autonomamente. Il certificato SSL utilizza un certificato precondiviso che carichi nel tuo progetto Google Cloud.
Secrets Kubernetes. Il secret contiene un certificato e una chiave creati da te. Aggiungi il nome del secret al campo
tls
del manifest di Ingress.
Puoi utilizzare più di un metodo nella stessa risorsa Ingress. Ciò consente migrazioni senza tempi di inattività tra i metodi.
Panoramica globale
Ecco una panoramica dei passaggi descritti in questo documento:
Creare un deployment.
Crea un servizio.
Crea due file del certificato e due file della chiave o due oggetti
ManagedCertificate
. Devi configurare questi certificati nello stesso progetto e nella lo stesso spazio dei nomi in cui viene eseguito il deployment del bilanciatore del carico.Crea un Ingress che utilizzi i secret o i certificati pre-condivisi. Quando crei l'Ingress, GKE crea e configura un bilanciatore del carico delle applicazioni.
Testa il bilanciatore del carico delle applicazioni.
Prima di iniziare
Prima di iniziare, assicurati di aver eseguito le seguenti operazioni:
- Attiva l'API Google Kubernetes Engine. Abilita l'API Google Kubernetes Engine
- Se vuoi utilizzare Google Cloud CLI per questa attività,
installa e poi
inizializza gcloud CLI. Se hai già installato gcloud CLI, scarica la versione più recente
eseguendo
gcloud components update
.
- Devi possedere due nomi di dominio. I nomi di dominio non devono superare i 63 caratteri.
Limitazioni
- I certificati gestiti da Google sono supportati solo con GKE Ingress che utilizza il bilanciatore del carico delle applicazioni esterno. I certificati gestiti da Google non supportano i controller Ingress di terze parti.
- Per i bilanciatori del carico delle applicazioni interni, devi disattivare HTTP nel manifest Ingress. Non è necessario per il bilanciatore del carico esterno.
- Non devi modificare o aggiornare manualmente la configurazione dell'Application Load Balancer. Ciò significa che non devi modificare nessuno dei componenti del bilanciatore del carico, inclusi proxy di destinazione, mappe URL e servizi di backend. Tutte le modifiche che apporti vengono sovrascritte da GKE.
Creazione di un deployment
Salva il seguente manifest come
my-mc-deployment.yaml
:apiVersion: apps/v1 kind: Deployment metadata: name: my-mc-deployment spec: selector: matchLabels: app: products department: sales replicas: 3 template: metadata: labels: app: products department: sales spec: containers: - name: hello image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0" env: - name: "PORT" value: "50001" - name: hello-again image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0" env: - name: "PORT" value: "50002"
Questo manifest descrive un deployment con tre pod. Ogni pod ha due containerizzati. Un container esegue
hello-app:1.0
e rimane in ascolto sulla porta TCP 50001. L'altro container eseguehello-app:2.0
e rimane in ascolto sulla porta TCP 50002.Applica il manifest al cluster:
kubectl apply -f my-mc-deployment.yaml
Crea un servizio
Salva il seguente manifest come
my-mc-service.yaml
:apiVersion: v1 kind: Service metadata: name: my-mc-service spec: type: NodePort selector: app: products department: sales ports: - name: my-first-port protocol: TCP port: 60001 targetPort: 50001 - name: my-second-port protocol: TCP port: 60002 targetPort: 50002
Questo manifest descrive un servizio con i seguenti campi:
selector
: specifica che tutti i pod con l'etichettaapp: products
e l'etichettadepartment: sales
fa parte di questo servizio.ports
: specifica che quando un client invia una richiesta al servizio sumy-first-port
, GKE inoltra la richiesta a uno dei pod membri sulla porta 50001. Quando un client invia una richiesta al servizio sumy-second-port
, GKE inoltra la richiesta a uno degli sulla porta 50002.
Applica il manifest al cluster:
kubectl apply -f my-mc-service.yaml
Crea certificati e chiavi
Per svolgere gli esercizi in questa pagina, devi disporre di due certificati, ciascuno con una chiave corrispondente. Ogni certificato deve avere un nome comune (CN) uguale a un nome di dominio di tua proprietà.
Puoi creare questi certificati manualmente o utilizzare quelli gestiti da Google.Se hai già due file del certificato con i valori appropriati per il nome comune, puoi andare alla sezione successiva.
Certificati gestiti dall'utente
Crea la tua prima chiave:
openssl genrsa -out test-ingress-1.key 2048
Crea la tua prima richiesta di firma del certificato:
openssl req -new -key test-ingress-1.key -out test-ingress-1.csr \ -subj "/CN=FIRST_DOMAIN"
Sostituisci
FIRST_DOMAIN
con un nome di dominio che hai ad esempioexample.com
.Crea il tuo primo certificato:
openssl x509 -req -days 365 -in test-ingress-1.csr -signkey test-ingress-1.key \ -out test-ingress-1.crt
Crea la seconda chiave:
openssl genrsa -out test-ingress-2.key 2048
Crea la seconda richiesta di firma del certificato:
openssl req -new -key test-ingress-2.key -out test-ingress-2.csr \ -subj "/CN=SECOND_DOMAIN"
Sostituisci
SECOND_DOMAIN
con un altro nome di dominio di tua proprietà, ad esempioexamplepetstore.com
.Crea il secondo certificato:
openssl x509 -req -days 365 -in test-ingress-2.csr -signkey test-ingress-2.key \ -out test-ingress-2.crt
Per ulteriori informazioni sui certificati e sulle chiavi, consulta Panoramica dei certificati SSL.
Ora hai due file del certificato e due file della chiave.
Le attività rimanenti utilizzano i seguenti segnaposto per fare riferimento ai tuoi domini, certificati e chiavi:
FIRST_CERT_FILE
: il percorso del tuo primo certificato .FIRST_KEY_FILE
: il percorso del file della chiave con il primo certificato.FIRST_DOMAIN
: un nome di dominio di tua proprietà.FIRST_SECRET_NAME
: il nome del secret contenente il primo certificato e la prima chiave.SECOND_CERT_FILE
: il percorso del secondo del certificato.SECOND_KEY_FILE
: il percorso del file della chiave con il secondo certificato.SECOND_DOMAIN
: un secondo nome di dominio di tua proprietà.SECOND_SECRET_NAME
: il nome del secret contenente il secondo certificato e la seconda chiave.
Certificati gestiti da Google
Per creare certificati gestiti da Google, devi aggiungere ManagedCertificate
nello spazio dei nomi della risorsa Ingress. Puoi
utilizza il seguente modello per definire i certificati per i tuoi domini:
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
name: FIRST_CERT_NAME
spec:
domains:
- FIRST_DOMAIN
---
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
name: SECOND_CERT_NAME
spec:
domains:
- SECOND_DOMAIN
Sostituisci quanto segue:
FIRST_CERT_NAME
: il nome del primoManagedCertificate
oggetto.FIRST_DOMAIN
: il primo dominio di tua proprietà.SECOND_CERT_NAME
: il nome del secondoManagedCertificate
oggetto.SECOND_DOMAIN
: il secondo dominio di tua proprietà.
I nomi degli oggetti ManagedCertificate
sono diversi dai nomi di
ai certificati che creano. Basta conoscere i nomi
ManagedCertificate
oggetto per utilizzarli nella tua risorsa Ingress.
Specifica i certificati per il traffico in entrata
Il passaggio successivo consiste nel creare un oggetto Ingress. Nel manifest di Ingress, puoi utilizzare uno dei seguenti metodi per fornire i certificati per il bilanciatore del carico:
- Secret
- Certificati precondivisi
- Certificati gestiti da Google
Secret
Crea un secret che contenga il tuo primo certificato e la tua prima chiave:
kubectl create secret tls FIRST_SECRET_NAME \ --cert=FIRST_CERT_FILE \ --key=FIRST_KEY_FILE
Crea un secret che contenga il secondo certificato e la chiave:
kubectl create secret tls SECOND_SECRET_NAME \ --cert=SECOND_CERT_FILE \ --key=SECOND_KEY_FILE
Crea un Ingress
Salva il seguente manifest come
my-mc-ingress.yaml
:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-mc-ingress spec: tls: - secretName: FIRST_SECRET_NAME - secretName: SECOND_SECRET_NAME rules: - host: FIRST_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60001 - host: SECOND_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60002
Sostituisci
FIRST_DOMAIN
eSECOND_DOMAIN
con i nomi di dominio di tua proprietà, ad esempioexample.com
eexamplepetstore.com
.Applica il manifest al cluster:
kubectl apply -f my-mc-ingress.yaml
Descrivi il tuo Ingress:
kubectl describe ingress my-mc-ingress
L'output è simile al seguente:
Name: my-mc-ingress Address: 203.0.113.1 ... TLS: FIRST_SECRET_NAME terminates SECOND_SECRET_NAME terminates Rules: Host Path Backends ---- ---- -------- FIRST_DOMAIN my-mc-service:my-first-port (<none>) SECOND_DOMAIN my-mc-service:my-second-port (<none>) Annotations: ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 3m loadbalancer-controller default/my-mc-ingress Normal CREATE 2m loadbalancer-controller ip: 203.0.113.1
L'output mostra che a Ingress sono associati due secret. L'output mostra anche l'indirizzo IP esterno del bilanciatore del carico. Se l'indirizzo IP esterno non è impostato, attendi qualche minuto e riprova a eseguire il comando.
Certificati precondivisi
Crea un certificato:
gcloud compute ssl-certificates create FIRST_CERT_NAME \ --certificate=FIRST_CERT_FILE \ --private-key=FIRST_KEY_FILE
Sostituisci quanto segue:
FIRST_CERT_NAME
: il nome del primo certificato.FIRST_CERT_FILE
: il tuo primo file di certificato.FIRST_KEY_FILE
: il primo file della chiave.
Crea un secondo certificato:
gcloud compute ssl-certificates create SECOND_CERT_NAME \ --certificate=SECOND_CERT_FILE \ --private-key=SECOND_KEY_FILE
Sostituisci quanto segue:
SECOND_CERT_NAME
: il nome del secondo certificato.SECOND_CERT_FILE
: il secondo file del certificato.SECOND_KEY_FILE
: il secondo file della chiave.
Visualizza le risorse del certificato:
gcloud compute ssl-certificates list
L'output è simile al seguente:
NAME CREATION_TIMESTAMP FIRST_CERT_NAME 2018-11-03T12:08:47.751-07:00 SECOND_CERT_NAME 2018-11-03T12:09:25.359-07:00
Crea un Ingress
Salva il seguente manifest come
my-psc-ingress.yaml
:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-psc-ingress annotations: ingress.gcp.kubernetes.io/pre-shared-cert: "FIRST_CERT_NAME,SECOND_CERT_NAME" spec: rules: - host: FIRST_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60001 - host: SECOND_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60002
Sostituisci
FIRST_DOMAIN
eSECOND_DOMAIN
con i tuoi nomi di dominio.Questo manifest descrive una risorsa Ingress che elenca un certificato precondiviso risorse in un'annotazione.
Applica il manifest al cluster:
kubectl apply -f my-psc-ingress.yaml
Descrivi il tuo Ingress:
kubectl describe ingress my-psc-ingress
L'output è simile al seguente:
Name: my-psc-ingress Address: 203.0.113.2 ... Rules: Host Path Backends ---- ---- -------- FIRST_DOMAIN my-mc-service:my-first-port (<none>) SECOND_DOMAIN my-mc-service:my-second-port (<none>) Annotations: ... ingress.gcp.kubernetes.io/pre-shared-cert: FIRST_CERT_NAME,SECOND_CERT_NAME ... ingress.kubernetes.io/ssl-cert: FIRST_CERT_NAME,SECOND_CERT_NAME Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 2m loadbalancer-controller default/my-psc-ingress Normal CREATE 1m loadbalancer-controller ip: 203.0.113.2
L'output mostra che Ingress è associato a certificati precompartiti denominati
FIRST_CERT_NAME
eSECOND_CERT_NAME
. L'output mostra anche l'indirizzo IP esterno del bilanciatore del carico. Se l'indirizzo IP esterno è non è impostato, attendi qualche minuto e riprova a eseguire il comando.
Certificati gestiti da Google
Crea una risorsa Ingress
Salva il seguente manifest come
my-gmc-ingress.yaml
:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-gmc-ingress annotations: networking.gke.io/managed-certificates: "FIRST_CERT_NAME,SECOND_CERT_NAME" spec: rules: - host: FIRST_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60001 - host: SECOND_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60002
Sostituisci
FIRST_DOMAIN
eSECOND_DOMAIN
con i tuoi nomi di dominio.Questo manifest descrive una risorsa Ingress che elenca un certificato precondiviso risorse in un'annotazione.
Applica il manifest al cluster:
kubectl apply -f my-gmc-ingress.yaml
Descrivi il tuo Ingress:
kubectl describe ingress my-gmc-ingress
L'output è simile al seguente:
Name: my-gmc-ingress Address: 203.0.113.2 ... Rules: Host Path Backends ---- ---- -------- FIRST_DOMAIN my-mc-service:my-first-port (<none>) SECOND_DOMAIN my-mc-service:my-second-port (<none>) Annotations: ... ingress.gcp.kubernetes.io/pre-shared-cert: mcrt-a6e41ce4-2b39-4334-84ce-867ff543c424,mcrt-bbff4116-f014-4800-a43a-4095bffeb4f4 ... ingress.kubernetes.io/ssl-cert: mcrt-a6e41ce4-2b39-4334-84ce-867ff543c424,mcrt-bbff4116-f014-4800-a43a-4095bffeb4f4 networking.gke.io/managed-certificates: FIRST_CERT_NAME,SECOND_CERT_NAME Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 2m loadbalancer-controller default/my-gmc-ingress Normal CREATE 1m loadbalancer-controller ip: 203.0.113.2
L'output mostra che Ingress è associato a certificati gestiti nominati
FIRST_CERT_NAME
eSECOND_CERT_NAME
. GKE compila automaticamente le annotazioniingress.gcp.kubernetes.io/pre-shared-cert
eingress.kubernetes.io/ssl-cert
con i certificati gestiti da Google che hai creato utilizzando gli oggettiManagedCertificate
. L'output mostra anche l'indirizzo IP esterno del carico con il bilanciatore del carico di rete passthrough esterno regionale. Se l'indirizzo IP esterno non è impostato, attendi qualche minuto e riprova a eseguire il comando.
Testa il bilanciatore del carico
Attendi circa cinque minuti affinché GKE completi la configurazione del bilanciatore del carico.
Se hai utilizzato certificati gestiti da Google, potrebbero essere necessari molto più tempo per completare la configurazione, dato che il sistema deve esegui il provisioning dei certificati e verifica la configurazione DNS per determinati domini.Per testare il bilanciatore del carico, devi possedere due nomi di dominio e entrambi devono risolvere l'indirizzo IP esterno del bilanciatore del carico delle applicazioni esterno.
Invia una richiesta al bilanciatore del carico utilizzando il primo nome di dominio:
curl -v https://FIRST_DOMAIN
Potresti dover utilizzare l'opzione
curl -k
per eseguire una configurazione SSL non sicura vengono trasferiti, in modo checurl
accetti certificati autofirmati.L'output è simile al seguente:
... * Trying 203.0.113.1... ... * Connected to FIRST_DOMAIN (203.0.113.1) port 443 (#0) ... * TLSv1.2 (IN), TLS handshake, Certificate (11): ... * Server certificate: * subject: CN=FIRST_DOMAIN ... > Host: FIRST_DOMAIN.com ... Hello, world! Version: 1.0.0 ...
Questa uscita mostra che il primo certificato è stato utilizzato nell'handshake TLS.
Invia una richiesta al bilanciatore del carico utilizzando il secondo nome di dominio:
curl -v https://SECOND_DOMAIN
L'output è simile al seguente:
... * Trying 203.0.113.1... ... * Connected to SECOND_DOMAIN (203.0.113.1) port 443 (#0) ... * Server certificate: * subject: CN=SECOND_DOMAIN ... > Host: SECOND_DOMAIN ... Hello, world! Version: 2.0.0
Questo output mostra che il secondo certificato è stato utilizzato nella crittografia handshake.
Il campo hosts di un oggetto Ingress
Un IngressSpec ha un campo tls
che è un array di oggetti IngressTLS. Ogni oggetto IngressTLS
ha un campo hosts
e un campo SecretName
.
In GKE, il campo hosts
non viene utilizzato. GKE legge il nome comune (CN) dal certificato nello secret. Se il nome comune corrisponde al nome di dominio in una richiesta del client, il bilanciatore del carico presenta il certificato corrispondente al client.
Quale certificato viene presentato?
Il bilanciatore del carico sceglie un certificato in base a queste regole:
Se in Ingress sono elencati sia i secret che i certificati precompartiti, i certificati precompartiti hanno la precedenza sui secret. In altre parole, i secret sono ancora inclusi, ma i certificati precompartiti vengono presentati per primi.
Se nessun certificato ha un nome comune (CN) corrispondente al nome di dominio nella richiesta client, il bilanciatore del carico presenta il certificato principale.
Per i secret elencati nel blocco
tls
, il certificato principale è nel primo Secret nell'elenco.Per i certificati precondivisi elencati nell'annotazione, il certificato principale è il primo certificato dell'elenco.
Best practice per la rotazione dei certificati
Se vuoi ruotare i contenuti del segreto o del certificato pre-condiviso, di seguito sono riportate alcune best practice:
- Crea un nuovo secret o un certificato pre-condiviso con un nome diverso che contenga i dati del nuovo certificato. Collega questa risorsa (insieme a quella esistente) al tuo Ingress seguendo le istruzioni fornite in precedenza. Una volta apportate le modifiche, puoi rimuovere il vecchio certificato da Ingress.
- Se non ti dispiace interrompere il traffico, puoi rimuovere la vecchia risorsa dall'Ingress, eseguire il provisioning di una nuova risorsa con lo stesso nome, ma con contenuti diversi, quindi ricollegarla all'Ingress.
Risoluzione dei problemi
La specifica di secret non validi o inesistenti genera un errore di evento Kubernetes. Puoi controllare gli eventi Kubernetes per una risorsa Ingress come segue:
kubectl describe ingress
L'output è simile al seguente:
Name: my-ingress
Namespace: default
Address: 203.0.113.3
Default backend: hello-server:8080 (10.8.0.3:8080)
TLS:
my-faulty-Secret terminates
Rules:
Host Path Backends
---- ---- --------
* * my-service:443 (10.8.0.3:443)
Events:
Error during sync: cannot get certs for Ingress default/my-ingress:
Secret "my-faulty-ingress" has no 'tls.crt'
Passaggi successivi
- Leggi Panoramica della rete GKE.
- Se hai un'applicazione in esecuzione su più cluster GKE in regioni diverse, configura un Ingress multi-cluster per instradare il traffico a un cluster nella regione più vicina all'utente.