Esempio: impostazione di un controller in entrata Nginx in un cluster

Scopri come impostare e utilizzare un controller di entrata Nginx di esempio in un cluster creato utilizzando Kubernetes Engine (OKE).

Puoi impostare diversi controller di entrata open source nei cluster creati con Kubernetes Engine per gestire il traffico delle applicazioni Kubernetes.

Questo argomento spiega come impostare un controller di entrata Nginx di esempio insieme al controllo di accesso corrispondente su un cluster esistente. Dopo aver impostato il controller in entrata, questo argomento descrive come utilizzare il controller in entrata con un backend di esempio hello-world e come verificare che il controller in entrata funzioni come previsto. Se si desidera continuare a utilizzare il controller di ingresso di esempio, seguire le istruzioni di aggiornamento. E quando non si dispone di ulteriori utilizzi per il controller di ingresso di esempio, questo argomento mostra come eliminarlo.

Componenti di esempio

L'esempio include un controller in entrata e un backend hello-world.

Componenti del controller di ingresso

Il controller di ingresso comprende:

  • Distribuzione del controller di ingresso denominata ingress-nginx-controller. La distribuzione distribuisce un'immagine contenente il file binario per il controller in entrata e Nginx. Il file binario manipola e ricarica il file di configurazione /etc/nginx/nginx.conf quando viene creata un'entrata in Kubernetes. Gli upstream di Nginx puntano ai servizi che corrispondono ai selettori specificati.
  • Servizio di controllo dell'ingresso denominato ingress-nginx-controller. Il servizio espone la distribuzione del controller di ingresso come servizio di tipo LoadBalancer. Poiché Kubernetes Engine utilizza un provider di integrazione/cloud di Oracle Cloud Infrastructure, verrà creato dinamicamente un load balancer con i nodi corretti configurati come set backend.

Componenti backend

Il backend helloworld comprende:

  • Distribuzione backend denominata docker-hello-world. La distribuzione gestisce gli instradamenti predefiniti per i controlli dello stato e 404 risposte. Questo viene fatto utilizzando un'immagine stock hello-world che serve i percorsi minimi richiesti per un backend predefinito.
  • Servizio backend denominato docker-hello-world-svc. Il servizio espone la distribuzione backend per l'utilizzo da parte della distribuzione del controller in entrata.

Impostazione del controller di entrata di esempio

In questa sezione è possibile creare le regole di accesso per l'ingresso. È quindi possibile creare i componenti del controller in entrata di esempio e confermarne l'esecuzione.

Creazione delle regole di accesso per il controller in entrata

  1. Se non è già stato fatto, attenersi alla procedura per impostare il file di configurazione kubeconfig del cluster e (se necessario) impostare la variabile di ambiente KUBECONFIG in modo che punti al file. Si noti che è necessario impostare il proprio file kubeconfig. Non è possibile accedere a un cluster utilizzando un file kubeconfig impostato da un altro utente. Vedere Impostazione dell'accesso al cluster.
  2. Se l'utente di Oracle Cloud Infrastructure è un amministratore della tenancy, saltare il passo successivo e andare direttamente a Distribuzione del controller in entrata e delle risorse associate.
  3. Se l'utente di Oracle Cloud Infrastructure non è un amministratore della tenancy, in una finestra del terminale concedere all'utente il ruolo cluster-admin del cluster RBAC Kubernetes nel cluster immettendo:

    kubectl create clusterrolebinding <my-cluster-admin-binding> --clusterrole=cluster-admin --user=<user-OCID>

    Dove:

    • <my-cluster-admin-binding> è una stringa scelta da utilizzare come nome per l'associazione tra l'utente e il ruolo cluster di amministrazione del cluster RBAC Kubernetes. Ad esempio jdoe_clst_adm
    • <user-OCID> è l'OCID dell'utente (ottenuto dalla console). Ad esempio, ocid1.user.oc1..aaaaa...zutq (abbreviato per leggibilità).

    Ad esempio:

    kubectl create clusterrolebinding jdoe_clst_adm --clusterrole=cluster-admin --user=ocid1.user.oc1..aaaaa...zutq

Distribuzione del controller in entrata e delle risorse associate

La modalità di distribuzione del controller in entrata e delle risorse associate (inclusi i ruoli e le associazioni RBAC Kubernetes e il servizio del controller in entrata ingress-nginx-controller di tipo LoadBalancer) dipende dal fatto che si stia eseguendo la distribuzione in un cluster con nodi gestiti/autogestiti o in un cluster con nodi virtuali.

  • Nodi gestiti e nodi auto gestiti

    Per distribuire il controller di entrata Nginx, eseguire il comando seguente:

    kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v<vnum>/deploy/static/provider/cloud/deploy.yaml

    dove <vnum> è il numero di versione dell'ultima versione dello script di distribuzione del controller in entrata ingress-nginx-controller. Ad esempio, al momento della scrittura, l'ultima versione dello script ha il numero di versione 1.1.3, quindi il comando da eseguire è:

    kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/cloud/deploy.yaml

    Per conoscere il numero di versione dell'ultima versione dello script, consultare la documentazione di kubernetes/ingress-nginx all'indirizzo GitHub.

  • Nodi virtuali

    Nei nodi virtuali, è necessario modificare il file manifesto di distribuzione del controller in entrata e commentare i contesti di sicurezza fsgroup, allowprivilegeEscalation e capabilities. Per un esempio di file manifesto di distribuzione modificato di questo tipo, vedere https://github.com/oracle-devrel/oci-oke-virtual-nodes/tree/main/ingress-nginx.

    Per distribuire il controller di entrata Nginx in base a questo file manifesto modificato, eseguire il comando seguente:

    kubectl apply -f https://raw.githubusercontent.com/oracle-devrel/oci-oke-virtual-nodes/main/ingress-nginx/deploy.yaml

Verifica dell'esecuzione del servizio controller ingress-nginx-controller in entrata come servizio del load balancer

  1. Visualizzare la lista dei servizi in esecuzione immettendo:

    kubectl get svc -n ingress-nginx

    L'output del comando precedente mostra i servizi in esecuzione:

    
    NAME                       TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)                       AGE
    ingress-nginx-controller   LoadBalancer   10.96.229.38   <pending>      80:30756/TCP,443:30118/TCP    1h
    

    L'IP ESTERNO per il servizio controller in entrata ingress-nginx-controller viene visualizzato come <pending> finché il load balancer non è stato completamente creato in Oracle Cloud Infrastructure.

  2. Ripetere il comando kubectl get svc finché non viene visualizzato un IP ESTERNO per il servizio del controller in entrata ingress-nginx-controller:

    kubectl get svc -n ingress-nginx
    

    L'output del comando precedente mostra l'IP ESTERNO per il servizio del controller di entrata ingress-nginx-controller:

    
    NAME                       TYPE           CLUSTER-IP     EXTERNAL-IP       PORT(S)                       AGE
    ingress-nginx-controller   LoadBalancer   10.96.229.38   129.146.214.219   80:30756/TCP,443:30118/TCP    1h

Creazione del segreto TLS

Un segreto TLS viene utilizzato per l'interruzione SSL sul controller in entrata.

  1. Output di una nuova chiave in un file. Ad esempio, immettendo:

    openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc"

    Per generare il segreto per questo esempio, viene utilizzato un certificato autofirmato. Mentre questo va bene per i test, per la produzione, utilizzare un certificato firmato da un'autorità di certificazione.

    Nota

    In Windows potrebbe essere necessario sostituire "/CN=nginxsvc/O=nginxsvc" con "//CN=nginxsvc\O=nginxsvc". Ciò è necessario, ad esempio, se si esegue il comando openssl da una shell Git Bash.
  2. Creare il segreto TLS immettendo:

    kubectl create secret tls tls-secret --key tls.key --cert tls.crt

Impostazione del backend di esempio

In questa sezione è possibile definire un servizio e una distribuzione backend hello-world.

Creazione della definizione del servizio docker-hello-world

  1. Creare il file hello-world-ingress.yaml contenente il codice seguente. Questo codice utilizza un'immagine del mondo disponibile pubblicamente da Docker Hub. Puoi sostituire un'altra immagine a tua scelta che può essere eseguita in modo simile.

    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: docker-hello-world
      labels:
        app: docker-hello-world
    spec:
      selector:
        matchLabels:
          app: docker-hello-world
      replicas: 3
      template:
        metadata:
          labels:
            app: docker-hello-world
        spec:
          containers:
          - name: docker-hello-world
            image: scottsbaldwin/docker-hello-world:latest
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: docker-hello-world-svc
    spec:
      selector:
        app: docker-hello-world
      ports:
        - port: 8088
          targetPort: 80
      type: ClusterIP
    

    Si noti che il tipo di servizio docker-hello-world è ClusterIP, anziché LoadBalancer, poiché questo servizio verrà sottoposto a proxy dal servizio controller in entrata ingress-nginx-controller. Il servizio docker-hello-world non ha bisogno dell'accesso pubblico direttamente ad esso. L'accesso pubblico verrà invece instradato dal load balancer al controller in entrata e dal controller in entrata al servizio a monte.

  2. Creare la nuova distribuzione e il nuovo servizio hello-world sui nodi del cluster eseguendo il comando seguente:

    kubectl create -f hello-world-ingress.yaml

Utilizzo del controller di entrata di esempio per accedere al backend di esempio

In questa sezione è possibile creare un'entrata per accedere al backend utilizzando il controller in entrata.

Creazione della risorsa in entrata

  1. Creare il file ingress.yaml e inserirlo con questo codice:

    
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: hello-world-ing
      annotations:
        kubernetes.io/ingress.class: "nginx"
    spec:
      tls:
      - secretName: tls-secret
      rules:
      - http:
          paths:
            - path: /
              pathType: Prefix
              backend:
                service:
                  name: docker-hello-world-svc
                  port:
                    number: 8088
    

    Si noti che l'esempio precedente YAML funziona con i cluster che eseguono Kubernetes versione 1.19.x e successive.

  2. Creare la risorsa immettendo:

    kubectl create -f ingress.yaml

Verifica del funzionamento previsto dei componenti di esempio

In questa sezione si conferma che tutti i componenti di esempio sono stati creati correttamente e funzionano come previsto. Il servizio docker-hello-world-svc deve essere in esecuzione come servizio ClusterIP e il servizio ingress-nginx-controller deve essere in esecuzione come servizio LoadBalancer. Le richieste inviate al controller in entrata devono essere instradate ai nodi nel cluster.

Recupero dell'indirizzo IP esterno del load balancer

Per confermare che il servizio ingress-nginx-controller è in esecuzione come servizio LoadBalancer, ottenere il proprio indirizzo IP esterno immettendo:

kubectl get svc --all-namespaces

L'output del comando precedente mostra i servizi in esecuzione:


NAMESPACE       NAME                          TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)                      AGE
default         docker-hello-world-svc      ClusterIP      10.96.83.247    <none>           8088/TCP                     16s
default         kubernetes                  ClusterIP      10.96.0.1       <none>           443/TCP                      1h
ingress-nginx   ingress-nginx-controller    LoadBalancer   10.96.229.38    129.146.214.219  80:30756/TCP,443:30118/TCP   5m			
kube-system     kube-dns                    ClusterIP      10.96.5.5       <none>           53/UDP,53/TCP                1h

Invio di richieste cURL al load balancer

  1. Utilizzare l'indirizzo IP esterno del servizio ingress-nginx-controller (ad esempio, 129.146.214.219) per arricciare una richiesta http immettendo:

    curl -I http://129.146.214.219
    

    Esempio di output dal comando precedente:

    HTTP/1.1 301 Moved Permanently
    Via: 1.1 10.68.69.10 (McAfee Web Gateway 7.6.2.10.0.23236)
    Date: Thu, 07 Sep 2017 15:20:16 GMT
    Server: nginx/1.13.2
    Location: https://129.146.214.219/
    Content-Type: text/html
    Content-Length: 185
    Proxy-Connection: Keep-Alive
    Strict-Transport-Security: max-age=15724800; includeSubDomains;
    

    L'output mostra un reindirizzamento 301 e un'intestazione Location che suggeriscono che il traffico http viene reindirizzato a https.

  2. cURL rispetto all'URL https o aggiungere l'opzione -L per seguire automaticamente l'intestazione della posizione. L'opzione -k indica a cURL di non verificare i certificati SSL. Ad esempio, immettendo:
    curl -ikL http://129.146.214.219

    Esempio di output dal comando precedente:

    HTTP/1.1 301 Moved Permanently
    Via: 1.1 10.68.69.10 (McAfee Web Gateway 7.6.2.10.0.23236)
    Date: Thu, 07 Sep 2017 15:22:29 GMT
    Server: nginx/1.13.2
    Location: https://129.146.214.219/
    Content-Type: text/html
    Content-Length: 185
    Proxy-Connection: Keep-Alive
    Strict-Transport-Security: max-age=15724800; includeSubDomains;
    
    HTTP/1.0 200 Connection established
    
    HTTP/1.1 200 OK
    Server: nginx/1.13.2
    Date: Thu, 07 Sep 2017 15:22:30 GMT
    Content-Type: text/html
    Content-Length: 71
    Connection: keep-alive
    Last-Modified: Thu, 07 Sep 2017 15:17:24 GMT
    ETag: "59b16304-47"
    Accept-Ranges: bytes
    Strict-Transport-Security: max-age=15724800; includeSubDomains;
    
    <h1>Hello webhook world from: docker-hello-world-1732906117-0ztkm</h1>
    

    L'ultima riga dell'output mostra l'HTML restituito dal pod il cui nome host è docker-hello-world-1732906117-0ztkm.

  3. Eseguire più volte la richiesta cURL per visualizzare il nome host nella modifica dell'output HTML, dimostrando che si sta verificando il bilanciamento del carico:

    $ curl -k https://129.146.214.219
    
    <h1>Hello webhook world from: docker-hello-world-1732906117-6115l</h1>
    
    $ curl -k https://129.146.214.219
    
    <h1>Hello webhook world from: docker-hello-world-1732906117-7r89v</h1>
    
    $ curl -k https://129.146.214.219
    
    <h1>Hello webhook world from: docker-hello-world-1732906117-0ztkm</h1>

Ispezione di nginx.conf

La distribuzione del controller di entrata ingress-nginx-controller modifica il file nginx.conf nel pod in cui è in esecuzione.

  1. Trovare il nome del pod che esegue la distribuzione del controller in entrata ingress-nginx-controller immettendo:

    kubectl get po -n ingress-nginx
    

    L'output del comando precedente mostra il nome del pod che esegue la distribuzione del controller in entrata ingress-nginx-controller:

    
    NAME                                       READY     STATUS    RESTARTS   AGE
    ingress-nginx-controller-110676328-h86xg   1/1       Running   0          1h
    
  2. Utilizzare il nome del pod che esegue la distribuzione del controller in entrata ingress-nginx-controller per mostrare il contenuto di nginx.conf immettendo il seguente comando kubectl exec:

    kubectl exec -n ingress-nginx -it ingress-nginx-controller-110676328-h86xg -- cat /etc/nginx/nginx.conf
    
  3. Cercare proxy_pass nell'output. Ce ne sarà uno per il backend predefinito e un altro simile a:

    proxy_pass http://upstream_balancer;
    

    Questo mostra che Nginx sta proxyando le richieste a un upstream chiamato upstream_balancer.

  4. Individuare la definizione a monte nell'output. Sembrerà simile a:

    upstream upstream_balancer {
                    server 0.0.0.1:1234; # placeholder
    
                    balancer_by_lua_block {
                            tcp_udp_balancer.balance()
                    }
            }
    
    

    L'upstream è proxying tramite Lua.

(Opzionale) Aggiornamento del controller di entrata di esempio

In questa sezione facoltativa viene descritto come continuare a utilizzare il controller di entrata di esempio per la gestione del traffico delle applicazioni Kubernetes, anziché rimuoverlo immediatamente.

Se lo si desidera, è possibile continuare a utilizzare il controller di entrata di esempio creato in precedenza. Tuttavia, si noti che le nuove versioni di Nginx vengono rilasciate periodicamente. Pertanto, se si continua a utilizzare il controller di entrata di esempio, sarà necessario aggiornare periodicamente la versione di Nginx utilizzata dal controller di entrata. In genere, durante l'aggiornamento di Nginx, è consigliabile conservare l'indirizzo EXTERNAL-IP esistente del controller in entrata.

Per eseguire l'upgrade del controller in entrata esistente senza eliminare il load balancer di Oracle Cloud Infrastructure esistente (e quindi conservare il relativo indirizzo EXTERNAL-IP esistente), seguire le istruzioni per l'aggiornamento di Nginx senza Helm nella documentazione di Nginx.

Per determinare a quale immagine Nginx fare riferimento durante l'aggiornamento di Nginx, vedere Nginx Changelog nella documentazione di Nginx.

(Opzionale) Rimozione del controller di entrata di esempio

In questa sezione facoltativa è possibile rimuovere il controller di entrata di esempio creato in precedenza, tra cui:

  • la distribuzione del controller di ingresso ingress-nginx-controller
  • ruoli e associazioni RBAC Kubernetes
  • il servizio del controller di ingresso ingress-nginx-controller di tipo LoadBalancer

Tenere presente che se in seguito si decide di applicare lo script di distribuzione del controller in entrata per la seconda volta per ricreare il controller in entrata di esempio, viene creato un nuovo servizio ingress-nginx-controller di tipo LoadBalancer con un indirizzo IP esterno diverso rispetto al servizio precedente.

Non è necessario rimuovere il controller di entrata di esempio se si desidera continuare a utilizzarlo. Tuttavia, se si continua a utilizzare il controller di entrata di esempio, sarà necessario aggiornare periodicamente la versione di Nginx utilizzata dal controller di entrata. Vedere (Opzionale) Aggiornamento del controller di entrata di esempio.

Rimozione del controller di entrata di esempio

  1. Eseguire il comando seguente per rimuovere il controller di entrata di esempio creato in precedenza:

    kubectl delete -f <deployment-script-location>

    dove <deployment-script-location> è la posizione dello script di distribuzione utilizzato in precedenza per creare il controller in entrata di esempio.

    Ad esempio:

    kubectl delete -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.3/deploy/static/provider/cloud/deploy.yaml