Creazione di un Servizio e un Ingress

Questo documento mostra come creare un oggetto Kubernetes Ingress in un cluster utente per i cluster Anthos su VMware (GKE on-prem). Una risorsa Ingress è associata a uno o più Servizi, ognuno dei quali è associato a un insieme di pod.

Prima di iniziare

Ottenere una connessione SSH alla tua workstation di amministrazione:

Creazione di un deployment

Ecco un manifest per un deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-deployment
spec:
  selector:
    matchLabels:
      greeting: hello
  replicas: 3
  template:
    metadata:
      labels:
        greeting: hello
    spec:
      containers:
      - name: hello-world
        image: "gcr.io/google-samples/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50000"
      - name: hello-kubernetes
        image: "gcr.io/google-samples/node-hello:1.0"
        env:
        - name: "PORT"
          value: "8080"

Ai fini di questa esercitazione, ecco i punti importanti da comprendere sul manifest del deployment:

  • Ogni pod che appartiene al deployment ha l'etichetta greeting: hello.

  • Ogni pod ha due container.

  • I campi env specificano che i container hello-app sono in ascolto sulla porta TCP 50000 e i container node-hello in ascolto sulla porta TCP 8080. Per hello-app, puoi vedere l'effetto della variabile di ambiente PORT esaminando il codice sorgente.

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

kubectl apply --kubeconfig USER_CLUSTER_KUBECONFIG -f hello-deployment.yaml

dove USER_CLUSTER_KUBECONFIG è il percorso del file kubeconfig per il tuo cluster utente.

Esponi il tuo deployment con un servizio

Per fornire ai clienti un modo stabile di inviare richieste ai pod del tuo deployment, crea un servizio.

Ecco un manifest per un servizio che espone il deployment ai client all'interno del cluster:

apiVersion: v1
kind: Service
metadata:
  name: hello-service
spec:
  type: ClusterIP
  selector:
    greeting: hello
  ports:
  - name: world-port
    protocol: TCP
    port: 60000
    targetPort: 50000
  - name: kubernetes-port
    protocol: TCP
    port: 60001
    targetPort: 8080

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

kubectl apply --kubeconfig USER_CLUSTER_KUBECONFIG -f hello-service.yaml

Visualizza il servizio:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get service hello-service --output yaml

L'output mostra il valore di clusterIP fornito al servizio. Ad esempio:

apiVersion: v1
kind: Service
metadata:
  annotations:
    ...
spec:
  clusterIP: 10.96.14.249
  clusterIPs:
  - 10.96.14.249
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - name: world-port
    port: 60000
    protocol: TCP
    targetPort: 50000
  - name: kubernetes-port
    port: 60001
    protocol: TCP
    targetPort: 8080
  selector:
    greeting: hello
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

Nell'output precedente, il campo ports è un array di oggetti ServicePort: uno denominato world-port e uno denominato kubernetes-port.

Ecco i modi in cui un cliente può chiamare il servizio:

  • Con world-port: un client in esecuzione su uno dei nodi del cluster invia una richiesta al clusterIP su port. In questo esempio, 10.96.14.249:60000. La richiesta viene inoltrata a un pod di membri il giorno targetPort. In questo esempio, POD_IP_ADDRESS:50000.

  • Con kubernetes-port: un client in esecuzione su uno dei nodi del cluster invia una richiesta al clusterIP il giorno port. In questo esempio, 10.96.14.249:60001. La richiesta viene inoltrata a un pod di membri il giorno targetPort. In questo esempio, POD_IP_ADDRESS:8080.

Componenti in entrata

Ecco alcuni dei componenti del cluster relativi al traffico in entrata:

  • Il deployment istio-ingress. Questo è il proxy in entrata. Il proxy in entrata inoltra il traffico ai servizi interni in base a regole specificate in un oggetto Ingress.

  • Il servizio istio-ingress. Questo servizio espone il deployment istio-ingress.

  • Il deployment istiod. Si tratta del controller in entrata. Il controller Ingress controlla la creazione degli oggetti Ingress e configura di conseguenza il proxy in entrata.

Creare una risorsa Ingress

Ecco un manifest per una risorsa Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - http:
      paths:
      - path: /greet-the-world
        pathType: Exact
        backend:
          service:
            name: hello-service
            port:
              number: 60000
      - path: /greet-kubernetes
        pathType: Exact
        backend:
          service:
            name: hello-service
            port:
              number: 60001

Copia il manifest in un file denominato my-ingress.yaml e crea la risorsa Ingress:

kubectl apply --kubeconfig USER_CLUSTER_KUBECONFIG -f my-ingress.yaml

Quando crei un cluster utente, devi specificare un valore per loadbalancer.ingressVip nel file di configurazione del cluster. Questo indirizzo IP è configurato sul bilanciatore del carico del cluster. Quando crei una risorsa Ingress, questa viene assegnata a questo stesso VIP come indirizzo IP esterno.

Quando un client invia una richiesta al tuo VIP Ingress in cluster, la richiesta viene instradata al bilanciatore del carico. Il bilanciatore del carico utilizza il servizio istio-ingress per inoltrare la richiesta al proxy in entrata in esecuzione nel cluster utente. Il proxy in entrata è configurato per inoltrare la richiesta a backend diversi a seconda del percorso dell'URL della richiesta.

Percorso /greet-the-world

Nel manifest Ingress, puoi vedere una regola che indica che il percorso /greet-the-world è associato a serviceName: hello-service e servicePort: 60000. Ricorda che 60000 è il valore port nella sezione world-port del servizio hello-service.

- name: world-port
    port: 60000
    protocol: TCP
    targetPort: 50000

Il servizio in entrata inoltra la richiesta a clusterIP:50000. La richiesta passa quindi a uno dei pod membri del servizio hello-service. Il container, in quel pod, in ascolto sulla porta 50000, mostra un messaggio Hello World!.

Percorso /greet-kubernetes

Nel manifest Ingress, puoi vedere una regola che indica che il percorso /greet-kubernetes è associato a serviceName: hello-service e servicePort: 60001. Ricorda che 60001 è il valore port nella sezione kubernetes-port del servizio hello-service.

- name: kubernetes-port
    port: 60001
    protocol: TCP
    targetPort: 8080

Il servizio in entrata inoltra la richiesta a clusterIP: 8080. La richiesta passa quindi a uno dei pod membri del servizio hello-service. Il container, in quel pod, in ascolto sulla porta 8080 visualizza un messaggio Hello Kubernetes!.

Test dell'Ingress

Testa l'Ingress utilizzando il percorso /greet-the-world:

curl USER_CLUSTER_INGRESS_VIP/greet-the-world

Sostituisci USER_CLUSTER_INGRESS_VIP con l'indirizzo IP esterno della risorsa Ingress.

L'output mostra un messaggio Hello, world!:

Hello, world!
Version: 2.0.0
Hostname: ...

Testa l'Ingress utilizzando il percorso /greet-kubernetes:

curl USER_CLUSTER_INGRESS_VIP/greet-kubernetes

L'output mostra un messaggio Hello, Kubernetes!:

Hello Kubernetes!

Configurare HTTPS per Ingress

Se vuoi accettare richieste HTTPS dai tuoi client, il proxy in entrata deve avere un certificato che ne consenta la verifica dell'identità. Questo proxy deve anche contenere una chiave privata per completare l'handshake HTTPS.

L'esempio seguente utilizza queste entità:

  • Proxy Ingress: partecipa all'handshake HTTPS, quindi inoltra i pacchetti ai pod membri del servizio hello-service.

  • Dominio per il servizio hello-service: altostrat.com in Organization Org

Segui questi passaggi:

  1. Crea un certificato radice e una chiave privata. In questo esempio viene utilizzata un'autorità di certificazione principale root.ca.example.com nell'organizzazione di esempio di CA radice.

    openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=Root CA Example Inc./CN=root.ca.example.com' -keyout root-ca.key -out root-ca.crt
    
  2. Creare una richiesta di firma di certificato:

    openssl req -out server.csr -newkey rsa:2048 -nodes -keyout server.key -subj "/CN=altostrat.com/O=Example Org"
    
  3. Crea un certificato di gestione per il proxy in entrata.

    openssl x509 -req -days 365 -CA root-ca.crt -CAkey root-ca.key -set_serial 0 -in server.csr -out server.crt
    

    Hai creato i seguenti certificati e chiavi:

    • root-ca.crt: certificato per la CA radice
    • root-ca.key: chiave privata per la CA radice
    • server.crt: gestione del certificato per il proxy in entrata
    • server.key: chiave privata per il proxy in entrata
  4. Crea un Secret Kubernetes che contenga il certificato di gestione e la chiave.

    kubectl create secret tls example-server-creds --key=server.key --cert=server.crt --namespace gke-system
    

    Il Secret risultante è denominato example-server-creds.

Crea un deployment e un servizio

Se hai creato un deployment e un servizio nella parte HTTP di questa guida, lasciali in posizione. In caso contrario, creali ora seguendo i passaggi descritti per HTTP.

Creare una risorsa Ingress

Se hai già creato una risorsa Ingress nella parte HTTP, eliminala prima di procedere.

Elimina l'Ingress:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete ingress my-ingress

Per gestire il traffico per il servizio che hai creato in precedenza, crea una nuova istanza Ingress con una sezione tls. In questo modo verrà attivato il protocollo HTTPS tra i client e il proxy in entrata.

Ecco un manifest per una risorsa Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress-2
spec:
  tls:
  - hosts:
    - altostrat.com
    secretName: example-server-creds
  rules:
  - host: altostrat.com
    http:
      paths:
      - path: /greet-the-world
        pathType: Exact
        backend:
          service:
            name: hello-service
            port:
              number: 60000
      - path: /greet-kubernetes
        pathType: Exact
        backend:
          service:
            name: hello-service
            port:
              number: 60001

Salva il manifest in un file denominato my-ingress-2.yaml e crea la risorsa Ingress:

kubectl apply --kubeconfig USER_CLUSTER_KUBECONFIG -f my-ingress-2.yaml

Conferma facendo una prova.

  • Testa il percorso /gret-the-world:

    curl -v --resolve altostrat.com:443:USER_CLUSTER_INGRESS_VIP https://altostrat.com/greet-the-world --cacert root-ca.crt
    

    Output:

    Hello, world!
    Version: 2.0.0
    Hostname: hello-deployment-5ff7f68854-wqzp7
    
  • Testa il percorso /greet-kubernetes:

    curl -v --resolve altostrat.com:443:USER_CLUSTER_INGRESS_VIP https://altostrat.com/greet-kubernetes --cacert root-ca.crt
    

    Output:

    Hello Kubernetes!
    

Pulizia

Elimina la risorsa Ingress:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete ingress INGRESS_NAME

Sostituisci INGRESS_NAME con il nome del Ingress, ad esempio my-ingress o my-ingress-2.

Elimina il servizio:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete service hello-service

Elimina il deployment:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete deployment hello-deployment