Ejemplo: configuración de un controlador de entrada de Nginx en un cluster

Descubra cómo configurar y utilizar un controlador de entrada de Nginx de ejemplo en un cluster creado mediante Container Engine for Kubernetes (OKE).

Puede configurar diferentes controladores de entrada de código abierto en clusters que haya creado con Container Engine for Kubernetes para gestionar el tráfico de la aplicación de Kubernetes.

En este tema, se explica cómo configurar un controlador de entrada de Nginx de ejemplo junto con el control de acceso correspondiente en un cluster existente. Una vez haya configurado el controlador de entrada, en este tema se describe cómo utilizar el controlador de entrada con un backend hello-world de ejemplo y cómo verificar que el controlador de entrada funciona como se esperaba. Si desea continuar usando el controlador de entrada de ejemplo, siga las instrucciones de actualización. Y cuando no tenga más uso para el controlador de entrada de ejemplo, en este tema se muestra cómo suprimirlo.

Componentes de ejemplo

El ejemplo incluye un controlador de entrada y un backend hello-world.

Componentes de controlador de entrada

El controlador de entrada comprende:

  • Un despliegue de controlador de entrada llamado ingress-nginx-controller. El despliegue implementa una imagen que contiene el binario para el controlador de entrada y Nginx. El binario manipula y vuelve a cargar el archivo de configuración /etc/nginx/nginx.conf cuando se crea una entrada en Kubernetes. Los flujos ascendentes de Nginx apuntan a servicios que coinciden con selectores especificados.
  • Un servicio de controlador de entrada llamado ingress-nginx-controller. El servicio expone el despliegue de controlador de entrada como un servicio de tipo LoadBalancer. Puesto que Container Engine for Kubernetes utiliza un proveedor en la nube/integración de Oracle Cloud Infrastructure, se creará dinámicamente un equilibrador de carga con los nodos correctos configurados como un juego de backends.

Componentes de backend

El backend hello-world incluye:

  • Un despliegue de backend denominado docker-hello-world. El despliegue maneja las rutas por defecto para las comprobaciones de estado y respuestas 404. Esto se hace utilizando una imagen de stock hello-world que sirve las rutas mínimas necesarias para un backend por defecto.
  • Un servicio de backend denominado docker-hello-world-svc. El servicio expone el despliegue de backend para su consumo por el despliegue de controlador de entrada.

Configuración del controlador de entrada de ejemplo

En esta sección creará las reglas de acceso para la entrada. A continuación, puede crear los componentes de controlador de entrada de ejemplo y confirmar que están en ejecución.

Creación de reglas de acceso para el controlador de entrada

  1. Si todavía no lo ha hecho, siga los pasos para configurar el archivo de configuración kubeconfig del cluster y (si es necesario) defina la variable de entorno KUBECONFIG para que apunte al archivo. Tenga en cuenta que debe configurar su propio archivo kubeconfig. No puede acceder a un cluster utilizando un archivo kubeconfig que haya configurado un usuario diferente. Consulte Configuración del acceso a los clusters.
  2. Si el usuario de Oracle Cloud Infrastructure es un administrador de arrendamiento, vaya al paso siguiente y vaya directamente a Despliegue del controlador de entrada y los recursos asociados.
  3. Si el usuario de Oracle Cloud Infrastructure no es un administrador de arrendamiento, en una ventana de terminal, otorgue al usuario el ClusterRole cluster-admin RBAC de Kubernetes en el cluster introduciendo:

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

    donde:

    • <my-cluster-admin-binding> es la cadena que desea utilizar como nombre para el enlace entre el usuario y el ClusterRole cluster-admin de Kubernetes RBAC. Por ejemplo, jdoe_clst_adm
    • <user-OCID> es el OCID de usuario (obtenido de la Consola ). Por ejemplo, ocid1.user.oc1..aaaaa...zutq (abreviado para leerse mejor).

    Por ejemplo:

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

Despliegue del controlador de entrada y los recursos asociados

La forma de desplegar el controlador de entrada y los recursos asociados (incluidos los enlaces y los roles de RBAC de Kubernetes y el servicio de controlador de entrada ingress-nginx-controller de tipo LoadBalancer) depende de si se está desplegando en un cluster con nodos gestionados/autogestionados o en un cluster con nodos virtuales:

  • Nodos gestionados y nodos autogestionados

    Para desplegar el controlador de entrada de Nginx, ejecute el siguiente comando:

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

    donde <vnum> es el número de versión de la última versión del script de despliegue del controlador de entrada ingress-nginx-controller. Por ejemplo, en el momento de escribir, la última versión del script tiene el número de versión 1.1.3, por lo que el comando que se debe ejecutar es:

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

    Para averiguar el número de versión de la última versión del script, consulte la documentación de kubernetes/ingress-nginx en GitHub.

  • Nodos virtuales

    En los nodos virtuales, debe modificar el manifiesto de despliegue del controlador de entrada y comentar los contextos de seguridad fsgroup, allowprivilegeEscalation y capabilities. Para ver un ejemplo de dicho manifiesto de despliegue modificado, consulte https://github.com/oracle-devrel/oci-oke-virtual-nodes/tree/main/ingress-nginx.

    Para desplegar el controlador de entrada de Nginx basado en este manifiesto modificado, ejecute el siguiente comando:

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

Verificación de que el servicio de controlador de entrada ingress-nginx-controller se ejecuta como un servicio del equilibrador de carga

  1. Vea la lista de servicios en ejecución introduciendo:

    kubectl get svc -n ingress-nginx

    La salida del comando anterior muestra los servicios que se están ejecutando:

    
    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
    

    El EXTERNAL-IP para el servicio del controlador de entrada ingress-nginx-controller se muestra como <pending> hasta que el equilibrador de carga se haya creado completamente en Oracle Cloud Infrastructure.

  2. Repita el comando kubectl get svc hasta que se muestre EXTERNAL-IP para el servicio de controlador de entrada ingress-nginx-controller:

    kubectl get svc -n ingress-nginx
    

    La salida del comando anterior muestra EXTERNAL-IP para el servicio de controlador de entrada 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

Creación del secreto TLS

Un secreto TLS se utiliza para la terminación SSL en el controlador de entrada.

  1. Introduzca una nueva clave en un archivo. Por ejemplo, introduzca:

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

    Para generar el secreto para este ejemplo, se utiliza un certificado autofirmado. Esto funciona con las pruebas; para la producción, utilice un certificado firmado por una autoridad de certificación.

    Nota

    En Windows, es posible que necesite reemplazar "/CN=nginxsvc/O=nginxsvc" por "//CN=nginxsvc\O=nginxsvc". Por ejemplo, esto es necesario si ejecuta el comando openssl desde un shell de Git Bash.
  2. Cree el secreto TLS introduciendo:

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

Configuración del backend de ejemplo

En esta sección, se define un despliegue y servicio de backend hello-world.

Creación de la definición del servicio docker-hello-world

  1. Cree el archivo hello-world-ingress.yaml que contenga el siguiente código. Este código utiliza una imagen de hello-world disponible públicamente en Docker Hub. Puede sustituir otra imagen de su elección, que se pueda ejecutar de forma similar.

    
    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
    

    Tenga en cuenta que el tipo del servicio docker-hello-world es ClusterIP, en lugar de LoadBalancer, porque este servicio será dirigido por proxy por el servicio de controlador de entrada ingress-nginx-controller. El servicio docker-hello-world no necesita acceso público directamente a él. En su lugar, el acceso público se enrutará desde el equilibrador de carga al controlador de entrada, así como desde el controlador de entrada al servicio de flujo ascendente.

  2. Cree el nuevo servicio y despliegue hello-world en nodos del cluster ejecutando el siguiente comando:

    kubectl create -f hello-world-ingress.yaml

Uso del controlador de entrada de ejemplo para acceder al backend de ejemplo

En esta sección, puede crear una entrada para acceder al backend mediante el controlador de entrada.

Creación del recurso de entrada

  1. Cree el archivo ingress.yaml e incluya en él este código:

    
    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
    

    Tenga en cuenta que el ejemplo anterior YAML funciona con clusters que ejecutan la versión 1.19.x y posteriores de Kubernetes.

  2. Cree el recurso introduciendo:

    kubectl create -f ingress.yaml

Verificación de que los componentes de ejemplo funcionan como se esperaba

En esta sección, confirme que todos los componentes de ejemplo se han creado correctamente y funcionan como se esperaba. El servicio docker-hello-world-svc debe estar ejecutando como un servicio ClusterIP, mientras que el servicio ingress-nginx-controller debe estar ejecutando como un servicio LoadBalancer. Las solicitudes enviadas al controlador de entrada se deben enrutar a nodos del cluster.

Obtención de la dirección IP externa del equilibrador de carga

Para confirmar que el servicio ingress-nginx-controller se está ejecutando como un servicio LoadBalancer, obtenga la dirección IP externa introduciendo:

kubectl get svc --all-namespaces

La salida del comando anterior muestra los servicios que se están ejecutando:


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

Envío de solicitudes de cURL al equilibrador de carga

  1. Utilice la dirección IP externa del servicio ingress-nginx-controller (por ejemplo, 129.146.214.219) para corregir una solicitud http introduciendo:

    curl -I http://129.146.214.219
    

    Ejemplo de salida del comando anterior:

    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;
    

    La salida muestra un redireccionamiento 301 y una cabecera de ubicación que sugiere que el tráfico http se redirige a https.

  2. Ejecute cURL con la URL de https o agregue la opción -L para seguir automáticamente la cabecera de ubicación. La opción -k indica a cURL que no verifique los certificados SSL. Por ejemplo, introduzca:
    curl -ikL http://129.146.214.219

    Ejemplo de salida del comando anterior:

    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>
    

    La última línea de la salida muestra el HTML que se devuelve desde el pod cuyo nombre de host es docker-hello-world-1732906117-0ztkm.

  3. Emita la solicitud de cURL varias veces para ver el nombre de host en el cambio de salida de HTML, lo que demuestra que se está produciendo el equilibrio de carga:

    $ 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>

Inspección de nginx.conf

El despliegue del controlador de entrada ingress-nginx-controller manipula el archivo nginx.conf en el pod en el que se está ejecutando.

  1. Busque el nombre del pod que ejecuta el despliegue del controlador de entrada ingress-nginx-controller introduciendo:

    kubectl get po -n ingress-nginx
    

    La salida del comando anterior muestra el nombre del pod que ejecuta el despliegue del controlador de entrada ingress-nginx-controller:

    
    NAME                                       READY     STATUS    RESTARTS   AGE
    ingress-nginx-controller-110676328-h86xg   1/1       Running   0          1h
    
  2. Utilice el nombre del pod que ejecuta el despliegue del controlador de entrada ingress-nginx-controller para mostrar el contenido de nginx.conf introduciendo el siguiente comando kubectl exec:

    kubectl exec -n ingress-nginx -it ingress-nginx-controller-110676328-h86xg -- cat /etc/nginx/nginx.conf
    
  3. Busque proxy_pass en la salida. Habrá uno para el backend por defecto y otro que sea similar a:

    proxy_pass http://upstream_balancer;
    

    Esto muestra que Nginx está enviando mediante proxy solicitudes a un flujo ascendente denominado upstream_balancer.

  4. Localice la definición de flujo ascendente en la salida. Verá algo parecido a esto:

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

    El flujo ascendente sirve de proxy a través de Lua.

(Opcional) Actualización del controlador de entrada de ejemplo

En esta sección opcional, encontrará cómo continuar utilizando el controlador de entrada de ejemplo para la gestión del tráfico de la aplicación Kubernetes, en lugar de eliminarlo inmediatamente.

Si lo desea, puede seguir utilizando el controlador de entrada de ejemplo que creó anteriormente. Sin embargo, tenga en cuenta que las nuevas versiones de Nginx se publican periódicamente. Por lo tanto, si continúa utilizando el controlador de entrada de ejemplo, tendrá que actualizar periódicamente la versión de Nginx que utiliza el controlador de entrada. Normalmente, se recomienda conservar la dirección IP EXTERNA existente del controlador de entrada al actualizar Nginx.

Para actualizar el controlador de entrada existente sin suprimir el equilibrador de carga de Oracle Cloud Infrastructure existente (y, por lo tanto, conservar su dirección IP EXTERNA existente), siga las instrucciones de Actualización de Nginx sin Helm de la documentación de Nginx.

Para determinar a qué imagen de Nginx hacer referencia al actualizar Nginx, consulte la Lista de cambios de Nginx en la documentación de Nginx.

(Opcional) Eliminación del controlador de entrada de ejemplo

En esta sección opcional, puede eliminar el controlador de entrada de ejemplo que creó anteriormente, que incluye:

  • el despliegue del controlador de entrada ingress-nginx-controller
  • los roles y enlaces de RBAC de Kubernetes
  • el servicio de controlador de entrada ingress-nginx-controller de tipo LoadBalancer

Tenga en cuenta que si posteriormente decide aplicar la secuencia de comandos de despliegue del controlador de entrada por segunda vez para volver a crear el controlador de entrada de ejemplo, se crea un nuevo servicio ingress-nginx-controller de tipo LoadBalancer que tiene una dirección EXTERNAL-IP diferente al servicio anterior.

No tiene que eliminar el controlador de entrada de ejemplo si desea continuar usándolo. Sin embargo, si continúa utilizando el controlador de entrada de ejemplo, tendrá que actualizar periódicamente la versión de Nginx que utiliza el controlador de entrada. Consulte (Opcional) Actualización del controlador de entrada de ejemplo.

Eliminación del controlador de entrada de ejemplo

  1. Ejecute el siguiente comando para eliminar el controlador de entrada de ejemplo que creó anteriormente:

    kubectl delete -f <deployment-script-location>

    donde <deployment-script-location> es la ubicación del script de despliegue que utilizó anteriormente para crear el controlador de entrada de ejemplo.

    Por ejemplo:

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