Google Distributed Cloud (GDC) air-gapped fornisce un bilanciatore del carico di livello 4 (L4) gestito integrato, ma molte applicazioni aziendali richiedono funzionalità avanzate di livello 7 (L7), come il routing basato su host, la gestione centralizzata di TLS e la suddivisione complessa del traffico. Storicamente, questa operazione viene eseguita utilizzando l'API Ingress, che ora è considerata una funzionalità bloccata nella community Kubernetes.
Questa architettura di riferimento fornisce una soluzione di bilanciamento del carico di livello 7 autogestita. Eseguendo il deployment del popolare controller open source NGINX Gateway Fabric su un cluster GDC Standard, i clienti possono instradare senza problemi il traffico L7 agli ambienti ibridi. Questa architettura utilizza la terminazione TLS (HTTPRoute) per instradare il traffico in base all'indicazione del nome del server (SNI) sia ai pod containerizzati integrati sia alle applicazioni ospitate su macchine virtuali esterne.
Architettura

I componenti chiave della soluzione includono:
- Client: un'entità che avvia richieste HTTPS per interagire con le applicazioni.
- Cluster GDC Standard: GDC fornisce un modo integrato per creare cluster Kubernetes Vanilla. In questa soluzione, il cluster ospiterà il bilanciatore del carico L7 e i relativi controller, insieme ai carichi di lavoro e al servizio headless per le VM esterne.
- Bilanciatore del carico L4 GDC: il bilanciatore del carico L4 integrato che funge da punto di ingresso, distribuendo il traffico TCP/443 direttamente ai pod Kubernetes che eseguono i controller del gateway.
- Controller del gateway: operatori NGINX in esecuzione nel cluster standard.
Monitorano le risorse dell'API Gateway (come
GatewayeHTTPRoute) e aggiornano dinamicamente i proxy sottostanti. Per la soluzione verrà utilizzato Nginx Gateway Fabric. - Gateway (con HTTPRoute): risorse Kubernetes standardizzate che definiscono la porta di ascolto fisica (443) e le regole di routing host basate su SNI con terminazione TLS.
- Carico di lavoro containerizzato (pod): un deployment Kubernetes standard esposto internamente con un
ServiceKubernetes normale. - Carico di lavoro basato su VM (esterno): un carico di lavoro ospitato su una VM esterna nella rete del progetto, esposto al proxy con un
ServiceKubernetes headless e un endpoint personalizzato contenente l'IP diretto della VM. - Registro Harbor: un registro di container privati utilizzato per archiviare e pubblicare le immagini proxy e delle applicazioni nell'ambiente air-gapped.
Nel cluster standard, crea quattro spazi dei nomi:
Lo spazio dei nomi
nginx-gatewayche ospita le risorse Nginx Gateway Fabric:
Lo spazio dei nomi
load-balancerche ospita le risorseGateway:
Lo spazio dei nomi
vm-appospita l'IP della VM esternavm-app, un servizio headless, unEndpointSliceche punta all'IP esterno e unHTTPRouteper ilGateway:
Lo spazio dei nomi
hello-appospita ilDeployment, unService, unHTTPRoutee unGatewayper il carico di lavoro del container demo:
Prima di iniziare
Prima di eseguire il deployment di questa soluzione, assicurati di aver soddisfatto i seguenti prerequisiti:
- Software necessario: helm, docker, kubectl
Accesso alla CLI e configurazione locale: scarica la CLI gdcloud dalla console GDC e configura l'ambiente in locale.
export USER_NAME="USER_NAME" export PROJECT_ID="PROJECT_ID" export ZONE="ZONE" export ORG_NAME="ORG_NAME" export GDCH_URL="GDC_URL" gdcloud components install gdcloud-k8s-auth-plugin gdcloud config set core/organization_console_url \ https://console.$ORG_NAME.$ZONE.$GDC_URL gdcloud config set core/zone $ZONE gdcloud config set core/project ${PROJECT_ID} gdcloud auth login # use --login-config-cert option in case of TLS errorConfigurazione del progetto: crea un progetto nel tuo ambiente GDC con air gap per contenere le risorse.
gdcloud projects create $PROJECT_IDRuoli IAM: concedi al tuo utente i ruoli Amministratore cluster e Amministratore cluster standard per gestire le risorse Kubernetes e il ruolo Amministratore istanza Harbor per eseguire il push delle immagini.
# Grant standard cluster and cluster admin roles gdcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="user:${USER_NAME}" \ --role=cluster-admin gdcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="user:${USER_NAME}" \ --role=standard-cluster-admin # Grant Harbor instance admin role gdcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="user:${USER_NAME}" \ --role=harbor-instance-admin
Crea un cluster standard
Questa sezione ti guida nella procedura di configurazione di un cluster Kubernetes standard all'interno del tuo ambiente GDC con air gap. Un cluster standard fornisce una base flessibile e solida per il deployment di vari carichi di lavoro, tra cui Nginx Gateway Controller e le tue applicazioni personalizzate. I passaggi seguenti garantiranno che il cluster sia configurato correttamente e accessibile per i deployment successivi.
Identifica i tipi di immagini di macchine virtuali disponibili eseguendo:
gdcloud compute machine-types listSeleziona un tipo di macchina appropriato per i nodi worker del cluster. Per questo tutorial, è consigliato un tipo di macchina con almeno 4 vCPU.
export MACHINE_TYPE="MACHINE_TYPE"Recupera il kubeconfig del server API di gestione e imposta un alias:
export CLUSTER_NAME="CLUSTER_NAME" KUBECONFIG=kubeconfig-admin.yaml gdcloud clusters \ get-credentials ${ORG_NAME}-admin alias km="kubectl --kubeconfig kubeconfig-admin.yaml"Crea un cluster standard con 2 nodi worker:
km create -f - <<EOF apiVersion: cluster.gdc.goog/v1 kind: Cluster metadata: name: ${CLUSTER_NAME} namespace: ${PROJECT_ID} spec: nodePools: - machineTypeName: ${MACHINE_TYPE} nodeCount: 2 name: ${CLUSTER_NAME}-node-pool EOFPer maggiori dettagli sulle opzioni disponibili, consulta la documentazione.
La creazione del cluster standard può richiedere fino a 60 minuti. Per controllare lo stato, utilizza il seguente comando:
km get clusters/${CLUSTER_NAME} \ -n ${PROJECT_ID} \ --watchQuando il cluster è pronto, l'output dovrebbe mostrare lo stato In esecuzione, come di seguito:
NAME STATE K8S VERSION my-cluster Running 1.30.12-gke.300Quando il cluster è pronto, recupera le relative credenziali:
KUBECONFIG=kubeconfig-${CLUSTER_NAME}.yaml gdcloud clusters \ get-credentials ${CLUSTER_NAME} \ --standard \ --project ${PROJECT_ID} \ --zone ${ZONE}Crea un alias per rendere i comandi
kubectlpiù concisi nel resto di questa guida. Questo alias verrà utilizzato per interagire con il cluster standard:alias kk="kubectl --kubeconfig kubeconfig-${CLUSTER_NAME}.yaml"Crea spazi dei nomi per il controller, l'app containerizzata demo "hello-app" e l'app demo basata su VM:
kk create namespace load-balancer kk create namespace hello-app kk create namespace vm-app
Crea e integra il registro Harbor
Harbor è un registro di immagini container con supporto integrato in GDC con air gap. Questa sezione ti guida nei passaggi per integrare un registro Harbor con il tuo cluster standard, inclusa la configurazione di credenziali e secret per consentire il pull e il push sicuri delle immagini.
- Crea un'istanza Harbor nel tuo progetto.
- Crea un progetto Harbor nella tua istanza Harbor.
Imposta le variabili di ambiente:
export HARBOR_INSTANCE_NAME="HARBOR_INSTANCE_NAME" export HARBOR_INSTANCE_URL="HARBOR_INSTANCE_URL" export HARBOR_PROJECT="HARBOR_INSTANCE_PROJECT" export IMAGE_PULL_SECRET_NAME="harbor-secret"Accedi all'istanza Harbor utilizzando un account robot:
docker --config=./docker login ${HARBOR_INSTANCE_URL}Crea i secret nel cluster standard:
kk create secret docker-registry ${IMAGE_PULL_SECRET_NAME} \ --from-file=.dockerconfigjson=./docker/config.json \ -n load-balancer kk create secret docker-registry ${IMAGE_PULL_SECRET_NAME} \ --from-file=.dockerconfigjson=./docker/config.json \ -n hello-app
Esegui il deployment dell'app containerizzata demo
Questa sezione descrive in dettaglio il deployment di un'applicazione containerizzata demo (hello-app) all'interno del cluster Kubernetes GDC con air gap. Creerai le risorse Kubernetes Deployment e Service necessarie per eseguire hello-app ed esporla internamente al cluster, preparandola per l'accesso tramite il bilanciatore del carico L7.
Carica un'immagine di esempio per l'app containerizzata demo in Harbor:
docker pull gcr.io/google-samples/hello-app:1.0 \ --platform linux/amd64 docker tag gcr.io/google-samples/hello-app:1.0 \ ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/hello-app:1.0 docker --config=./docker push \ ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/hello-app:1.0Esegui il deployment del seguente manifest nel cluster standard:
cat << EOF > hello-app.yaml apiVersion: apps/v1 kind: Deployment metadata: name: hello-app namespace: hello-app spec: replicas: 2 selector: matchLabels: app: hello-app template: metadata: labels: app: hello-app spec: containers: - name: hello-server image: ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/hello-app:1.0 ports: - containerPort: 8080 imagePullSecrets: - name: ${IMAGE_PULL_SECRET_NAME} --- apiVersion: v1 kind: Service metadata: name: hello-app namespace: hello-app spec: type: ClusterIP selector: app: hello-app ports: - protocol: TCP port: 80 targetPort: 8080 EOF kk apply -f hello-app.yaml
Quindi verifica che il deployment e il servizio siano presenti:
kk get svc,deploy -n hello-app
Esegui il deployment dell'app demo in una VM
Questa sezione descrive in dettaglio il deployment di un'applicazione demo all'interno di una macchina virtuale (VM) al di fuori del cluster Kubernetes. Configurando un server HTTP su una VM, simulerai un'applicazione esterna che il bilanciatore del carico può esporre, dimostrando la sua capacità di gestire il traffico verso le risorse sia all'interno che all'esterno del cluster.
Innanzitutto, crea una VM per l'app demo
- Apri la console GDC nel browser web.
- Seleziona lo stesso progetto in cui hai creato il cluster Kubernetes standard.
- Apri il menu e fai clic su Macchine virtuali.
- Fai clic su Crea istanza.
- Assegna alla VM il nome
vm-workload. Per l'esempio è sufficiente un'immagine con 2 vCPU. - Per l'immagine del disco di avvio, seleziona una distribuzione Ubuntu 22.04, che viene fornita con Python preinstallato.
- Fai clic su Crea.
- Attendi qualche minuto finché la VM non è pronta.
- Stabilisci una connessione SSH alla VM:
- Nella console GDC, fai clic sulla VM.
- Fai clic su Connetti con SSH.
Dopo aver stabilito la connessione alla console SSH, esegui quanto segue:
mkdir ~/simple-server
cd ~/simple-server
echo 'Welcome to my VM!' > index.html
python3 -m http.server --bind 0.0.0.0 8080 &
Per instradare il traffico a una VM, crea un servizio headless (senza selettori). Questo verrà mappato manualmente all'indirizzo IP interno della VM utilizzando una risorsa EndpointSlice.
kk apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
name: vm-app-svc
namespace: vm-app
spec:
ports:
- protocol: TCP
port: 443
targetPort: 443
EOF
Ottieni l'indirizzo IP della VM vm-workload eseguendo
gdcloud compute instances list --project ${PROJECT_ID} \
| grep workload-vm | awk '{print $3}'
L'output sarà l'indirizzo IP della VM necessario per configurare la risorsa EndpointSlice.
Crea la risorsa EndpointSlice che si connetterà al servizio senza selettori VM-app e indirizzerà l'IP della VM a cui deve essere instradato il traffico.
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: vm-app-endpoints
namespace: vm-app
labels:
kubernetes.io/service-name: vm-app-svc
addressType: IPv4
ports:
- port: 8080
endpoints:
- addresses:
- "VM_IP"
conditions:
ready: true
Crea certificati autofirmati
Questa sezione ti guida nella procedura di generazione di certificati TLS autofirmati per le tue applicazioni. Questa guida utilizza certificati autofirmati per comodità, ma negli ambienti di produzione devi utilizzare certificati di livello di produzione, come descritto in Facoltativo: utilizza certificati pronti per la produzione. Questi certificati sono fondamentali per abilitare la terminazione HTTPS in Nginx Gateway, garantendo la comunicazione criptata tra i client e il bilanciatore del carico per i carichi di lavoro containerizzati e basati su VM.
Crea un certificato per l'app containerizzata:
openssl req -x509 -newkey rsa:2048 -nodes \ -keyout tls-containerized.key \ -out tls-containerized.crt \ -subj "/CN=k8s-app.example.com" \ -days 365 kk create secret tls tls-containerized \ --namespace load-balancer \ --key tls-containerized.key \ --cert tls-containerized.crt kk create secret tls tls-containerized \ --namespace hello-app \ --key tls-containerized.key \ --cert tls-containerized.crtCrea un certificato per l'app VM:
openssl req -x509 -newkey rsa:2048 -nodes \ -keyout tls-vm.key \ -out tls-vm.crt \ -subj "/CN=vm-app.example.com" \ -days 365 kk create secret tls tls-vm \ --namespace load-balancer \ --key tls-vm.key \ --cert tls-vm.crt kk create secret tls tls-vm \ --namespace vm-app \ --key tls-vm.key \ --cert tls-vm.crt
Esegui il deployment di NGINX
Questa sezione descrive i passaggi per eseguire il deployment di Nginx Gateway Controller, inclusa l'installazione delle definizioni di risorse personalizzate (CRD) dell'API Gateway, la configurazione di Nginx Gateway Fabric utilizzando Helm e la verifica dell'installazione all'interno del cluster standard. In questo modo, l'infrastruttura viene preparata per il routing avanzato di livello 7.
Installa le CRD dell'API Gateway
L'API Gateway richiede l'installazione delle definizioni di risorse personalizzate (CRD) nel cluster prima di eseguire il deployment del controller. Utilizzeremo le definizioni di risorse personalizzate (CRD) sperimentali ufficiali del progetto API Gateway (per questa guida viene utilizzata la versione 1.2.0).
Installa le CRD sperimentali:
kk apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/experimental-install.yamlVerifica che le CRD siano state installate correttamente eseguendo
kk get crd gateways.gateway.networking.k8s.io.
Installa NGINX Gateway Fabric
Esegui il deployment di NGINX Gateway Fabric Controller utilizzando Helm. Questo controller monitorerà le risorse dell'API Gateway e configurerà NGINX per gestire il traffico.
Imposta il tag dell'immagine NGINX:
helm template nfg oci://ghcr.io/nginx/charts/nginx-gateway-fabric | grep "image:" # get the tag of the nginx-gateway-fabric (in following case 2.4.2) export NGINX_TAG="2.4.2"Esegui il pull delle immagini NGINX Gateway Fabric e NGINX, quindi esegui il push nel registro Harbor:
docker pull ghcr.io/nginx/nginx-gateway-fabric:${NGINX_TAG} docker tag ghcr.io/nginx/nginx-gateway-fabric:${NGINX_TAG} \ ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/nginx-gateway-fabric:${NGINX_TAG} docker --config=./docker push \ ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/nginx-gateway-fabric:${NGINX_TAG} docker pull nginx:1.27.3 docker tag nginx:1.27.3 \ ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/nginx:1.27.3 docker --config=./docker push \ ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/nginx:1.27.3Crea lo spazio dei nomi
nginx-gatewaye aggiungi il secret di pull dell'immagine Harbor:kk create namespace nginx-gateway kk create secret docker-registry ${IMAGE_PULL_SECRET_NAME} \ --from-file=.dockerconfigjson=./docker/config.json \ -n nginx-gatewayEsegui il deployment di NGINX Gateway Fabric con Helm, puntando alle immagini nel registro Harbor:
KUBECONFIG=kubeconfig-${CLUSTER_NAME}.yaml helm upgrade --install ngf \ oci://ghcr.io/nginx/charts/nginx-gateway-fabric \ --create-namespace -n nginx-gateway \ --set nginxGateway.image.tag="${NGINX_TAG}" \ --set nginxGateway.image.repository="${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/nginx-gateway-fabric" \ --set nginx.image.repository="${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/nginx" \ --set nginxGateway.serviceAccount.imagePullSecret="${IMAGE_PULL_SECRET_NAME}" \ --set nginx.imagePullSecret="${IMAGE_PULL_SECRET_NAME}"Il deployment Kubernetes esegue il pull sicuro delle immagini da Harbor utilizzando il secret fornito (
${IMAGE_PULL_SECRET_NAME}), che contiene le credenziali dell'account robot Harbor.Verifica che le risorse
GatewayClasssiano accettate:kk get gatewayclassDovresti vedere
nginxelencato conACCEPTED = True.
Crea l'istanza del gateway
Definisci l'istanza del bilanciatore del carico logico in ascolto sulla porta 443. La configureremo per la modalità Terminate, il che significa che il gateway eseguirà la terminazione TLS e decripta il traffico prima di passarlo.
Crea e applica gateway.yaml:
cat << EOF > gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
namespace: load-balancer
spec:
gatewayClassName: nginx
listeners:
- name: https-k8s-workload
hostname: "k8s-app.example.com"
port: 443
protocol: HTTPS
allowedRoutes:
namespaces:
from: All
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: tls-containerized
- name: https-vm-workload
hostname: "vm-app.example.com"
port: 443
protocol: HTTPS
allowedRoutes:
namespaces:
from: All
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: tls-vm
EOF
kk apply -f gateway.yaml
Verifica che il deployment del gateway sia andato a buon fine controllando se PROGRAMMED è True:
kk get gateway my-gateway --n load-balancer
Verifica che sia stato eseguito il deployment di un bilanciatore del carico L4 GDC gestito come servizio insieme al gateway
kk get services -n load-balancer
Verifica che il servizio Nginx sia stato creato e configurato. L'output dovrebbe essere simile al seguente:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-gateway-nginx LoadBalancer 10.252.19.148 10.200.32.43 443:30649/TCP 45h
Definisci la logica di routing L7 (HTTPRoute)
Collega HTTPRoute al gateway per definire come deve essere distribuito il traffico in base al nome host richiesto (SNI).
Crea e applica routing.yaml:
cat << EOF > routing.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: k8s-http-route
namespace: hello-app
spec:
parentRefs:
- name: my-gateway
namespace: load-balancer
hostnames:
- "k8s-app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: hello-app
namespace: hello-app
port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: vm-http-route
namespace: vm-app
spec:
parentRefs:
- name: my-gateway
namespace: load-balancer
hostnames:
- "vm-app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: vm-app-svc
namespace: vm-app
port: 443
EOF
kk apply -f routing.yaml
Recupera l'IP del bilanciatore del carico
Esegui il comando per ottenere l'IP del bilanciatore del carico Nginx
kk get services/my-gateway-nginx \
-n load-balancer \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}'
Questo sarà necessario per verificare l'accesso alle app. Questo verrà indicato come LOAD_BALANCER_IP.
Crea una VM client
Segui i passaggi per creare una VM client
- Apri la console GDC nel browser web.
- Apri il menu e fai clic su Macchine virtuali.
- Fai clic su Crea istanza.
- Crea una VM denominata
client, seleziona un tipo di macchina piccolo e seleziona Rocky Linux o Ubuntu, che vengono forniti concurlpreinstallato. - Fai clic su Crea.
- Attendi qualche minuto finché la VM non è pronta.
- Quando la VM è pronta, stabilisci una connessione SSH alla VM:
- Nella console GDC, fai clic sulla VM.
- Fai clic su Connetti con SSH.
Verifica l'accesso e il routing
Per testare il routing, esegui i comandi curl dalla VM client. Puoi connetterti a entrambe le applicazioni utilizzando i nomi host definiti con l'indirizzo IP del bilanciatore del carico.
Passando il flag --resolve in curl, puoi forzare la risoluzione dei nomi di dominio all'indirizzo IP del bilanciatore del carico L4 GDC con air gap.
Tieni presente che passiamo il flag -k per considerare attendibili i certificati autofirmati.
Testa l'app containerizzata Kubernetes:
curl -k --resolve k8s-app.example.com:443:$LOAD_BALANCER_IP https://k8s-app.example.com -v
Testa l'app VM esterna:
curl -k --resolve vm-app.example.com:443:$LOAD_BALANCER_IP https://vm-app.example.com -v
Se configurato correttamente, il controller del gateway fungerà da terminatore TLS e trasmetterà il traffico alla destinazione.
Facoltativo: utilizza certificati pronti per la produzione
Questa sezione descrive come utilizzare il servizio CA GDC con air gap per creare un'autorità di certificazione radice (CA), emettere certificati firmati per i carichi di lavoro e aggiornare in modo sicuro il cluster standard GDC con air gap e le VM client.
Questa sezione descrive come utilizzare il servizio CA GDC con air gap per creare un'autorità di certificazione radice privata ed emettere certificati validi per le tue applicazioni. Installando questa CA radice sulla VM client, puoi verificare che la terminazione TLS funzioni senza problemi con i certificati attendibili, senza dover ignorare gli avvisi SSL (ad esempio, utilizzando curl -k).
Concedi le autorizzazioni necessarie e recupera le credenziali
Per gestire il servizio CA ed emettere certificati, l'utente deve disporre dei ruoli IAM appropriati nel progetto.
Concedi i ruoli
certificate-authority-service-adminecertificate-requester:gdcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member=user:${USER_NAME} \ --role=certificate-authority-service-admin gdcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member=user:${USER_NAME} \ --role=certificate-requesterRecupera le credenziali del server API di gestione:
gdcloud clusters get-credentials ${ORG_NAME}-admin
Crea la CA radice
Creerai un'autorità di certificazione nel server API di gestione all'interno dello spazio dei nomi del progetto.
Applica la risorsa
CertificateAuthority:km apply -f - <<EOF apiVersion: pki.security.gdc.goog/v1 kind: CertificateAuthority metadata: name: my-root-ca namespace: ${PROJECT_ID} spec: caProfile: commonName: "My Root CA" duration: 87600h # 10 years keyAlgorithm: RSA_2048 maxChainLength: 1 caType: ROOT keyLocation: HSM rotationPolicy: cronTime: 0 0 1 1 * EOFkm -n ${PROJECT_ID} get \ certificateauthority.pki.security.gdc.goog/my-root-ca -ojson \ | jq -r ' .status.conditions[] | select( .type as $id | "Ready" | index($id)) .status'
Emetti ed esegui il deployment dei certificati
Quando la CA è pronta, richiedi i certificati sia per l'app containerizzata sia per l'app basata su VM. Queste richieste vengono eseguite nel server API di gestione e le chiavi risultanti devono essere spostate nel cluster standard.
Crea richieste per entrambi i domini:
km apply -f - <<EOF
apiVersion: pki.security.gdc.goog/v1
kind: CertificateRequest
metadata:
name: tls-containerized-req
namespace: ${PROJECT_ID}
spec:
certificateAuthorityRef:
name: my-root-ca
namespace: ${PROJECT_ID}
certificateConfig:
subjectConfig:
commonName: "k8s-app.example.com"
dnsNames:
- "k8s-app.example.com"
signedCertificateSecret: tls-containerized-signed
---
apiVersion: pki.security.gdc.goog/v1
kind: CertificateRequest
metadata:
name: tls-vm-req
namespace: ${PROJECT_ID}
spec:
certificateAuthorityRef:
name: my-root-ca
namespace: ${PROJECT_ID}
certificateConfig:
subjectConfig:
commonName: "vm-app.example.com"
dnsNames:
- "vm-app.example.com"
signedCertificateSecret: tls-vm-signed
EOF
Attendi qualche istante che i certificati vengano emessi. Puoi verificare che siano pronti quando la condizione Ready è True:
km get certificaterequests -n ${PROJECT_ID}
Aggiorna il cluster standard
Se hai seguito le sezioni precedenti di questa guida, nel cluster standard sono presenti secret autofirmati. Devi eliminarli prima di creare le nuove versioni firmate:
kk delete secret tls-containerized -n load-balancer
kk delete secret tls-vm -n load-balancer
kk delete secret tls-containerized -n hello-app
kk delete secret tls-vm -n vm-app
Ora estrai i certificati firmati dal server API di gestione e crea i nuovi secret nel cluster standard.
km get secret -n ${PROJECT_ID} tls-containerized-signed \
-o jsonpath='{.data.tls\.crt}' \
| base64 -d > tls-containerized.crt
km get secret -n ${PROJECT_ID} tls-containerized-signed \
-o jsonpath='{.data.tls\.key}' \
| base64 -d > tls-containerized.key
kk create secret tls tls-containerized \
--namespace load-balancer \
--key tls-containerized.key \
--cert tls-containerized.crt
kk create secret tls tls-containerized \
--namespace hello-app \
--key tls-containerized.key \
--cert tls-containerized.crt
km get secret -n ${PROJECT_ID} tls-vm-signed \
-o jsonpath='{.data.tls\.crt}' \
| base64 -d > tls-vm.crt
km get secret -n ${PROJECT_ID} tls-vm-signed \
-o jsonpath='{.data.tls\.key}' \
| base64 -d > tls-vm.key
kk create secret tls tls-vm \
--namespace load-balancer \
--key tls-vm.key \
--cert tls-vm.crt
kk create secret tls tls-vm \
--namespace vm-app \
--key tls-vm.key \
--cert tls-vm.crt
I nuovi secret verranno ottenuti e aggiornati automaticamente dai bilanciatori del carico.
Configura l'attendibilità del client
Per verificare la configurazione, devi indicare alla VM client di considerare attendibile la nuova CA radice.
Estrai il certificato CA radice in un file:
km get secret -n ${PROJECT_ID} my-root-ca-secret \
-o jsonpath='{.data.tls\.crt}' \
| base64 -d > my-root-ca.crt
Trasferisci il certificato alla VM client. (Puoi copiare i contenuti di my-root-ca.crt e incollarli in un file sulla VM client).
Sulla VM client, aggiorna l'archivio di attendibilità.
Se la VM client è Ubuntu:
sudo cp my-root-ca.crt /usr/local/share/ca-certificates/
sudo chmod 644 /usr/local/share/ca-certificates/my-root-ca.crt
sudo update-ca-certificates
Se la VM client è Rocky Linux:
sudo cp my-root-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust
Verifica l'accesso
Ora puoi accedere alle tue applicazioni utilizzando curl senza il flag -k. La connessione sarà completamente attendibile.
Testa l'app containerizzata Kubernetes:
curl -v --resolve k8s-app.example.com:443:LOAD_BALANDER_IP https://k8s-app.example.com
Testa l'app VM:
curl -v --resolve vm.example.com:443:LOAD_BALANDER_IP https://vm-app.example.com
Se l'operazione va a buon fine, vedrai immediatamente l'output dell'applicazione senza avvisi relativi ai certificati SSL.