Esposizione delle applicazioni mediante servizi


Questa pagina mostra come creare servizi Kubernetes in un cluster Google Kubernetes Engine (GKE). Per una spiegazione del concetto di Servizio e una discussione dei vari tipi di Servizi, consulta la pagina Servizio.

Introduzione

L'idea di un servizio è raggruppare un insieme di endpoint pod in un'unica risorsa. Puoi configurare vari modi per accedere al raggruppamento. Per impostazione predefinita, ottieni un indirizzo IP del cluster stabile che i client all'interno del cluster possono utilizzare per contattare i pod nel servizio. Un client invia una richiesta all'indirizzo IP stabile, che viene instradata a uno dei pod nel servizio.

Esistono cinque tipi di servizi:

  • ClusterIP (predefinito)
  • NodePort
  • LoadBalancer
  • ExternalName
  • Headless

I cluster Autopilot sono pubblici per impostazione predefinita. Se scegli un cluster Autopilot privato, devi configurare Cloud NAT per effettuare connessioni a internet in uscita, ad esempio eseguendo il pull di immagini da DockerHub.

Su questo argomento ci sono diversi esercizi. In ogni esercizio crei un deployment ed esponi i suoi pod creando un servizio. quindi invii una richiesta HTTP al servizio.

Prima di iniziare

Prima di iniziare, assicurati di aver eseguito le seguenti attività:

  • Abilita l'API Google Kubernetes Engine.
  • Abilita l'API Google Kubernetes Engine
  • Se vuoi utilizzare Google Cloud CLI per questa attività, installa e initialize gcloud CLI. Se hai già installato gcloud CLI, scarica la versione più recente eseguendo gcloud components update.
* Crea un cluster GKE.

Creazione di un servizio di tipo ClusterIP

In questa sezione creerai un servizio di tipo ClusterIP.

kubectl apply

Ecco il manifest per un deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  selector:
    matchLabels:
      app: metrics
      department: sales
  replicas: 3
  template:
    metadata:
      labels:
        app: metrics
        department: sales
    spec:
      containers:
      - name: hello
        image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"

Copia il manifest in un file denominato my-deployment.yaml e crea il deployment:

kubectl apply -f my-deployment.yaml

Verifica che siano in esecuzione tre pod:

kubectl get pods

L'output mostra tre pod in esecuzione:

NAME                            READY   STATUS    RESTARTS   AGE
my-deployment-dbd86c8c4-h5wsf   1/1     Running   0          7s
my-deployment-dbd86c8c4-qfw22   1/1     Running   0          7s
my-deployment-dbd86c8c4-wt4s6   1/1     Running   0          7s

Ecco un manifest per un servizio di tipo ClusterIP:

apiVersion: v1
kind: Service
metadata:
  name: my-cip-service
spec:
  type: ClusterIP
  # Uncomment the below line to create a Headless Service
  # clusterIP: None
  selector:
    app: metrics
    department: sales
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

Il servizio ha un selettore che specifica due etichette:

  • app: metrics
  • department: sales

Ogni pod nel deployment che hai creato in precedenza ha queste due etichette. Quindi i pod nel deployment diventeranno membri di questo servizio.

Copia il manifest in un file denominato my-cip-service.yaml e crea il servizio:

kubectl apply -f my-cip-service.yaml

Attendi un momento che Kubernetes assegni un indirizzo interno stabile al servizio, quindi visualizza il servizio:

kubectl get service my-cip-service --output yaml

L'output mostra un valore per clusterIP:

spec:
  clusterIP: 10.59.241.241

Prendi nota del valore di clusterIP per usarlo in un secondo momento.

Console

Creazione di un deployment

  1. Vai alla pagina Carichi di lavoro nella console Google Cloud.

    Vai a Carichi di lavoro

  2. Fai clic su Esegui il deployment.

  3. In Specifica il contenitore, seleziona Immagine container esistente.

  4. Per Percorso immagine, inserisci us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0.

  5. Fai clic su Fine, poi su Continua.

  6. In Configuration (Configurazione), inserisci my-deployment in Application name (Nome applicazione).

  7. In Etichette, crea le seguenti etichette:

    • Chiave: app e Valore: metrics
    • Chiave: department e Valore: sales
  8. In Cluster, scegli il cluster in cui creare il deployment.

  9. Fai clic su Esegui il deployment.

  10. Quando il deployment è pronto, si apre la pagina Dettagli deployment. In Pod gestiti, puoi vedere che il tuo deployment ha uno o più pod in esecuzione.

Crea un servizio per esporre il deployment

  1. Nella pagina Dettagli deployment, fai clic su Azioni > Esponi.
  2. Nella finestra di dialogo Esponi, in Mappatura delle porte, imposta i seguenti valori:

    • Porta: 80
    • Porta di destinazione: 8080
    • Protocollo: TCP
  3. Nell'elenco a discesa Tipo di servizio, seleziona IP cluster.

  4. Fai clic su Esponi.

  5. Quando il servizio è pronto, viene visualizzata la pagina Dettagli servizio e puoi visualizzarne i dettagli. In IP cluster, prendi nota dell'indirizzo IP che Kubernetes ha assegnato al servizio. Si tratta dell'indirizzo IP che i client interni possono utilizzare per chiamare il servizio.

Accesso al servizio

Elenca i pod in esecuzione:

kubectl get pods

Nell'output, copia uno dei nomi dei pod che iniziano con my-deployment.

NAME                            READY   STATUS    RESTARTS   AGE
my-deployment-dbd86c8c4-h5wsf   1/1     Running   0          2m51s

Recupera una shell in uno dei container in esecuzione:

kubectl exec -it POD_NAME -- sh

Sostituisci POD_NAME con il nome di uno dei pod in my-deployment.

Nella tua shell, installa curl:

apk add --no-cache curl

Nel container, effettua una richiesta al servizio utilizzando l'indirizzo IP del cluster e la porta 80. Tieni presente che il valore del campo port del servizio è 80. Questa è la porta che utilizzi come client del servizio.

curl CLUSTER_IP:80

Sostituisci CLUSTER_IP con il valore di clusterIP nel servizio.

La tua richiesta viene inoltrata a uno dei pod membri sulla porta TCP 8080, che è il valore del campo targetPort. Tieni presente che ciascuno dei pod membro del servizio deve avere un container in ascolto sulla porta 8080.

La risposta mostra l'output di hello-app:

Hello, world!
Version: 2.0.0
Hostname: my-deployment-dbd86c8c4-h5wsf

Per uscire dalla shell del container, inserisci exit.

Creazione di un servizio di tipo NodePort

In questa sezione creerai un servizio di tipo NodePort.

kubectl apply

Ecco il manifest per un deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment-50000
spec:
  selector:
    matchLabels:
      app: metrics
      department: engineering
  replicas: 3
  template:
    metadata:
      labels:
        app: metrics
        department: engineering
    spec:
      containers:
      - name: hello
        image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50000"

Osserva l'oggetto env nel manifest. L'oggetto env specifica che la variabile di ambiente PORT per il container in esecuzione avrà il valore 50000. L'applicazione hello-app rimane in ascolto sulla porta specificata dalla variabile di ambiente PORT. In questo esercizio, indichi al container di rimanere in ascolto sulla porta 50000.

Copia il manifest in un file denominato my-deployment-50000.yaml e crea il deployment:

kubectl apply -f my-deployment-50000.yaml

Verifica che siano in esecuzione tre pod:

kubectl get pods

Ecco un manifest per un servizio di tipo NodePort:

apiVersion: v1
kind: Service
metadata:
  name: my-np-service
spec:
  type: NodePort
  selector:
    app: metrics
    department: engineering
  ports:
  - protocol: TCP
    port: 80
    targetPort: 50000

Copia il manifest in un file denominato my-np-service.yaml e crea il servizio:

kubectl apply -f my-np-service.yaml

Visualizza il servizio:

kubectl get service my-np-service --output yaml

L'output mostra un valore nodePort:

...
  spec:
    ...
    ports:
    - nodePort: 30876
      port: 80
      protocol: TCP
      targetPort: 50000
    selector:
      app: metrics
      department: engineering
    sessionAffinity: None
    type: NodePort
...

Crea una regola firewall per consentire il traffico TCP sulla porta del nodo:

gcloud compute firewall-rules create test-node-port \
    --allow tcp:NODE_PORT

Sostituisci NODE_PORT con il valore del campo nodePort del servizio.

Console

Creazione di un deployment

  1. Vai alla pagina Carichi di lavoro nella console Google Cloud.

    Vai a Carichi di lavoro

  2. Fai clic su Esegui il deployment.

  3. In Specifica il contenitore, seleziona Immagine container esistente.

  4. In Percorso immagine, inserisci us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0.

  5. Fai clic su Aggiungi variabile di ambiente.

  6. In Chiave, inserisci PORT e in Valore, inserisci 50000.

  7. Fai clic su Fine, poi su Continua.

  8. In Configuration (Configurazione), inserisci my-deployment-50000 in Application name (Nome applicazione).

  9. In Etichette, crea le seguenti etichette:

    • Chiave: app e Valore: metrics
    • Chiave: department e Valore: engineering
  10. In Cluster, scegli il cluster in cui creare il deployment.

  11. Fai clic su Esegui il deployment.

  12. Quando il deployment è pronto, si apre la pagina Dettagli deployment. In Pod gestiti, puoi vedere che il tuo deployment ha uno o più pod in esecuzione.

Crea un servizio per esporre il deployment

  1. Nella pagina Dettagli deployment, fai clic su Azioni > Esponi.
  2. Nella finestra di dialogo Esponi, in Mappatura delle porte, imposta i seguenti valori:

    • Porta: 80
    • Porta di destinazione: 50000
    • Protocollo: TCP
  3. Dall'elenco a discesa Tipo di servizio, seleziona Porta nodo.

  4. Fai clic su Esponi.

  5. Quando il servizio è pronto, viene visualizzata la pagina Dettagli servizio e puoi visualizzarne i dettagli. In Porte, prendi nota della porta del nodo che Kubernetes ha assegnato al tuo servizio.

Crea una regola firewall per la porta del nodo

  1. Vai alla pagina Criteri firewall nella console Google Cloud.

    Vai a Criteri firewall

  2. Fai clic su Crea regola firewall.

  3. In Nome, inserisci test-node-port.

  4. Dall'elenco a discesa Destinazioni, seleziona Tutte le istanze nella rete.

  5. In Intervalli IPv4 di origine, inserisci 0.0.0.0/0.

  6. In Protocolli e porte, seleziona Protocolli e porte specificati.

  7. Seleziona la casella di controllo tcp e inserisci il valore della porta per il nodo che hai annotato.

  8. Fai clic su Crea.

Ottieni un indirizzo IP del nodo

Trova l'indirizzo IP esterno di uno dei tuoi nodi:

kubectl get nodes --output wide

L'output è simile al seguente:

NAME          STATUS    ROLES     AGE    VERSION        EXTERNAL-IP
gke-svc-...   Ready     none      1h     v1.9.7-gke.6   203.0.113.1

Non tutti i cluster hanno indirizzi IP esterni per i nodi. Ad esempio, i nodi nei cluster privati non hanno indirizzi IP esterni.

Accedi al tuo servizio

Nella barra degli indirizzi del browser, inserisci quanto segue:

NODE_IP_ADDRESS:NODE_PORT

Sostituisci quanto segue:

  • NODE_IP_ADDRESS: l'indirizzo IP esterno di uno dei nodi, trovato durante la creazione del servizio nell'attività precedente.
  • NODE_PORT: il valore della porta del nodo.

L'output è simile al seguente:

Hello, world!
Version: 2.0.0
Hostname: my-deployment-50000-6fb75d85c9-g8c4f

Creazione di un servizio di tipo LoadBalancer

In questa sezione creerai un servizio di tipo LoadBalancer.

kubectl apply

Ecco il manifest per un deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment-50001
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:2.0"
        env:
        - name: "PORT"
          value: "50001"

Nota che i container in questo deployment rimarranno in ascolto sulla porta 50001.

Copia il manifest in un file denominato my-deployment-50001.yaml e crea il deployment:

kubectl apply -f my-deployment-50001.yaml

Verifica che siano in esecuzione tre pod:

kubectl get pods

Ecco un manifest per un servizio di tipo LoadBalancer:

apiVersion: v1
kind: Service
metadata:
  name: my-lb-service
spec:
  type: LoadBalancer
  selector:
    app: products
    department: sales
  ports:
  - protocol: TCP
    port: 60000
    targetPort: 50001

Copia il manifest in un file denominato my-lb-service.yaml, e crea il servizio:

kubectl apply -f my-lb-service.yaml

Quando crei un servizio di tipo LoadBalancer, un controller Google Cloud si riattiva e configura un bilanciatore del carico di rete passthrough esterno. Attendi un minuto che il controller configuri il bilanciatore del carico di rete passthrough esterno e generi un indirizzo IP stabile.

Visualizza il servizio:

kubectl get service my-lb-service --output yaml

L'output mostra un indirizzo IP esterno stabile nel campo loadBalancer:ingress:

...
spec:
  ...
  ports:
  - ...
    port: 60000
    protocol: TCP
    targetPort: 50001
  selector:
    app: products
    department: sales
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.10

Console

Creazione di un deployment

  1. Vai alla pagina Carichi di lavoro nella console Google Cloud.

    Vai a Carichi di lavoro

  2. Fai clic su Esegui il deployment.

  3. In Specifica il contenitore, seleziona Immagine container esistente.

  4. In Percorso immagine, inserisci us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0.

  5. Fai clic su Aggiungi variabile di ambiente.

  6. In Chiave, inserisci PORT e in Valore, inserisci 50001.

  7. Fai clic su Fine, poi su Continua.

  8. In Configuration (Configurazione), inserisci my-deployment-50001 in Application name (Nome applicazione).

  9. In Etichette, crea le seguenti etichette:

    • Chiave: app e Valore: products
    • Chiave: department e Valore: sales
  10. In Cluster, scegli il cluster in cui creare il deployment.

  11. Fai clic su Esegui il deployment.

  12. Quando il deployment è pronto, si apre la pagina Dettagli deployment. In Pod gestiti, puoi vedere che il tuo deployment ha uno o più pod in esecuzione.

Crea un servizio per esporre il deployment

  1. Nella pagina Dettagli deployment, fai clic su Azioni > Esponi.
  2. Nella finestra di dialogo Esponi, in Mappatura delle porte, imposta i seguenti valori:

    • Porta: 60000
    • Porta di destinazione: 50001
    • Protocollo: TCP
  3. Dall'elenco a discesa Tipo di servizio, seleziona Bilanciatore del carico.

  4. Fai clic su Esponi.

  5. Quando il servizio è pronto, viene visualizzata la pagina Dettagli servizio e puoi visualizzarne i dettagli. In Bilanciatore del carico, prendi nota dell'indirizzo IP esterno del bilanciatore del carico.

Accedi al tuo servizio

Attendi qualche minuto per consentire a GKE di configurare il bilanciatore del carico.

Nella barra degli indirizzi del browser, inserisci quanto segue:

LOAD_BALANCER_ADDRESS:60000

Sostituisci LOAD_BALANCER_ADDRESS con l'indirizzo IP esterno del bilanciatore del carico.

La risposta mostra l'output di hello-app:

Hello, world!
Version: 2.0.0
Hostname: my-deployment-50001-68bb7dfb4b-prvct

Tieni presente che il valore di port in un servizio è arbitrario. L'esempio precedente lo dimostra utilizzando un valore port pari a 60.000.

Creazione di un servizio di tipo ExternalName

In questa sezione creerai un servizio di tipo ExternalName.

Un servizio di tipo ExternalName fornisce un alias interno per un nome DNS esterno. I client interni effettuano le richieste utilizzando il nome DNS interno e le richieste vengono reindirizzate al nome esterno.

Ecco un manifest per un servizio di tipo ExternalName:

apiVersion: v1
kind: Service
metadata:
  name: my-xn-service
spec:
  type: ExternalName
  externalName: example.com

Nell'esempio precedente, il nome DNS è my-xn-service.default.svc.cluster.local. Quando un client interno effettua una richiesta a my-xn-service.default.svc.cluster.local, la richiesta viene reindirizzata a example.com.

Utilizzo di kubectl expose per creare un servizio

In alternativa alla scrittura di un manifest del servizio, puoi creare un servizio utilizzando kubectl expose per esporre un deployment.

Per esporre my-deployment, mostrato in precedenza in questo argomento, puoi inserire questo comando:

kubectl expose deployment my-deployment --name my-cip-service \
    --type ClusterIP --protocol TCP --port 80 --target-port 8080

Per esporre my-deployment-50000, mostralo in precedenza in questo argomento, potresti inserire questo comando:

kubectl expose deployment my-deployment-50000 --name my-np-service \
    --type NodePort --protocol TCP --port 80 --target-port 50000

Per esporre my-deployment-50001, mostrato in precedenza in questo argomento, puoi inserire questo comando:

kubectl expose deployment my-deployment-50001 --name my-lb-service \
    --type LoadBalancer --port 60000 --target-port 50001

Eseguire la pulizia

Dopo aver completato gli esercizi su questa pagina, segui questi passaggi per rimuovere le risorse ed evitare addebiti indesiderati sul tuo account:

kubectl apply

Eliminazione dei servizi

kubectl delete services my-cip-service my-np-service my-lb-service

Eliminazione dei deployment

kubectl delete deployments my-deployment my-deployment-50000 my-deployment-50001

Eliminazione della regola firewall in corso...

gcloud compute firewall-rules delete test-node-port

Console

Eliminazione dei servizi

  1. Vai alla pagina Servizi nella console Google Cloud.

    Vai a Servizi

  2. Seleziona i servizi che hai creato per questo esercizio, quindi fai clic su Elimina.

  3. Quando ti viene richiesto di confermare, fai clic su Elimina.

Eliminazione dei deployment

  1. Vai alla pagina Carichi di lavoro nella console Google Cloud.

    Vai a Carichi di lavoro

  2. Seleziona i deployment creati in questo esercizio e fai clic su Elimina.

  3. Quando ti viene chiesto di confermare, seleziona la casella di controllo Elimina i scalabilità automatica orizzontale dei pod associati ai deployment selezionati, quindi fai clic su Elimina.

Eliminazione della regola firewall in corso...

  1. Vai alla pagina Criteri firewall nella console Google Cloud.

    Vai a Criteri firewall

  2. Seleziona la casella di controllo test-node-port, quindi fai clic su Elimina.

  3. Quando ti viene richiesto di confermare, fai clic su Elimina.

Passaggi successivi