Compartir a través de


Crear un controlador de entrada no administrado

Resumen

Un controlador de ingreso es un software que proporciona proxy inverso, enrutamiento de tráfico configurable y terminación de TLS para servicios de Kubernetes. Use recursos de entrada de Kubernetes para configurar las reglas de entrada y las rutas para los servicios individuales de Kubernetes. Al usar un controlador de entrada y reglas de entrada, puede usar una única dirección IP para enrutar el tráfico a varios servicios en un clúster de Kubernetes.

En este artículo se muestra cómo implementar el controlador de entrada NGINX en un clúster de Azure Kubernetes Service (AKS). A continuación, ejecute dos aplicaciones en el clúster de AKS y cada aplicación sea accesible a través de la única dirección IP.

Importante

Para la entrada en AKS, use el complemento de enrutamiento de aplicaciones. Para obtener más información, consulte Nginx Ingress gestionado con la extensión de enrutamiento de aplicaciones.

Nota:

Dos controladores de entrada de código abierto para Kubernetes se basan en NGINX: uno se mantiene mediante la comunidad de Kubernetes (kubernetes/ingress-nginx) y NGINX, Inc. (nginxinc/kubernetes-ingress). En este artículo se usa el controlador de entrada de la comunidad de Kubernetes.

Antes de empezar

  • En este artículo se usa Helm 3 para instalar el controlador de entrada NGINX en una versión compatible de Kubernetes. Asegúrese de que usa la versión más reciente de Helm y de que tiene acceso al repositorio de Helm ingress-nginx. Es posible que los pasos descritos en este artículo no sean compatibles con versiones anteriores del gráfico de Helm, el controlador de entrada NGINX o Kubernetes.
  • En este artículo se da por hecho que ya tiene un clúster de AKS con Azure Container Registry (ACR) integrado. Para más información sobre cómo crear un clúster de AKS con un ACR integrado, consulte Autenticación con Azure Container Registry desde Azure Kubernetes Service.
  • El punto de conexión de estado de la API de Kubernetes, healthz, estaba en desuso en Kubernetes v1.16. En su lugar, puede reemplazar este punto de conexión por los puntos de conexión livez y readyz. Consulte Puntos de conexión de API de Kubernetes para el estado para determinar qué punto de conexión se va a usar para su escenario.
  • Si usa la CLI de Azure, en este artículo es necesario que ejecute la versión 2.0.64 de la CLI de Azure o cualquier versión posterior. Ejecute az --version para encontrar la versión. Si necesita instalar o actualizar, consulte [Instalación de la CLI de Azure][azure-cli-install].
  • Si usa Azure PowerShell, en este artículo es necesario que ejecute la versión 5.9.0 de Azure PowerShell o cualquier versión posterior. Ejecute Get-InstalledModule -Name Az para encontrar la versión. Si necesita instalarla o actualizarla, consulte el artículo sobre la instalación de Azure PowerShell.

Configuración básica del controlador de entrada

Para crear un controlador de entrada NGINX básico sin personalizar los valores predeterminados, use Helm. La configuración siguiente usa la configuración predeterminada para simplificar. Puede agregar parámetros para personalizar la implementación, por ejemplo, --set controller.replicaCount=3.

Nota:

Para habilitar la conservación de IP de cliente de origen para las solicitudes a contenedores en su clúster, agregue --set controller.service.externalTrafficPolicy=Local al comando de instalación de Helm. La dirección IP de origen del cliente se almacena en el encabezado de la solicitud en X-Forwarded-For. Cuando se usa un controlador de ingreso con la conservación de IP de origen del cliente habilitada, el pase directo de TLS no funcionará.

NAMESPACE=ingress-basic

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

helm install ingress-nginx ingress-nginx/ingress-nginx \
  --create-namespace \
  --namespace $NAMESPACE \
  --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \
  --set controller.service.externalTrafficPolicy=Local

Nota:

En este tutorial, establezca service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path a /healthz. Esta configuración significa que si el código de respuesta de las solicitudes a /healthz no es 200, se detiene el controlador de ingreso completo. Puede cambiar el valor a otro URI para que se ajuste a su escenario. No puede eliminar esta parte o anular el valor, o el controlador de entrada se detiene. El ingress-nginx paquete usado en este tutorial, que proporciona Kubernetes oficial, siempre devuelve un 200 código de respuesta para las solicitudes a /healthz. Está diseñado como backend predeterminado para que el usuario pueda empezar a trabajar rápidamente, a menos que una regla de ingreso lo sobrescriba.

Configuración personalizada del controlador de entrada

Como alternativa a la configuración básica presentada en la sección anterior, el siguiente conjunto de pasos muestra cómo implementar un controlador de entrada personalizado. Puede usar una dirección IP estática interna o una dirección IP pública dinámica.

Importar las imágenes utilizadas por el chart de Helm a tu ACR

Para controlar las versiones de la imagen, impórtelas en su propio Azure Container Registry. El chart de Helm del controlador de entrada NGINX se basa en tres imágenes de contenedor. Use az acr import para importar esas imágenes en el ACR.

REGISTRY_NAME=<REGISTRY_NAME>
SOURCE_REGISTRY=registry.k8s.io
CONTROLLER_IMAGE=ingress-nginx/controller
CONTROLLER_TAG=v1.8.1
PATCH_IMAGE=ingress-nginx/kube-webhook-certgen
PATCH_TAG=v20230407
DEFAULTBACKEND_IMAGE=defaultbackend-amd64
DEFAULTBACKEND_TAG=1.5

az acr import --name $REGISTRY_NAME --source $SOURCE_REGISTRY/$CONTROLLER_IMAGE:$CONTROLLER_TAG --image $CONTROLLER_IMAGE:$CONTROLLER_TAG
az acr import --name $REGISTRY_NAME --source $SOURCE_REGISTRY/$PATCH_IMAGE:$PATCH_TAG --image $PATCH_IMAGE:$PATCH_TAG
az acr import --name $REGISTRY_NAME --source $SOURCE_REGISTRY/$DEFAULTBACKEND_IMAGE:$DEFAULTBACKEND_TAG --image $DEFAULTBACKEND_IMAGE:$DEFAULTBACKEND_TAG

Nota:

Además de importar imágenes de contenedor en el ACR, también puede importar gráficos de Helm en el ACR. Para más información, consulte Inserción y extracción de gráficos de Helm en Azure Container Registry.

Crear un controlador de entrada

Para crear el controlador de entrada, use Helm para instalar ingress-nginx. El controlador de entrada se debe programar en un nodo con Linux. Los nodos de Windows Server no deben ejecutar el controlador de entrada. Especifique un selector de nodos mediante el --set nodeSelector parámetro para indicar al programador de Kubernetes que ejecute el controlador de entrada NGINX en un nodo basado en Linux.

Para obtener redundancia agregada, implemente dos réplicas de los controladores de entrada NGINX mediante el --set controller.replicaCount parámetro . Para sacar el máximo provecho de las réplicas en ejecución del controlador de entrada, asegúrese de que hay más de un nodo en el clúster de AKS.

En el siguiente ejemplo se crea un espacio de nombres de Kubernetes para los recursos de entrada denominado ingress-basic y está diseñado para funcionar dentro de ese espacio de nombres. Especifique un espacio de nombres para su propio entorno según sea necesario. Si el clúster de AKS no está habilitado para el control de acceso basado en roles de Kubernetes, agregue --set rbac.create=false a los comandos de Helm.

Nota:

Para habilitar la conservación de IP de cliente de origen para las solicitudes a contenedores en su clúster, agregue --set controller.service.externalTrafficPolicy=Local al comando de instalación de Helm. La dirección IP de origen del cliente se almacena en el encabezado de la solicitud en X-Forwarded-For. Cuando se usa un controlador de ingreso con la conservación de IP de origen del cliente habilitada, el pase directo de TLS no funcionará.

# Add the ingress-nginx repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

# Set variable for ACR location to use for pulling images
ACR_LOGIN_SERVER=<REGISTRY_LOGIN_SERVER>

# Use Helm to deploy an NGINX ingress controller
helm install ingress-nginx ingress-nginx/ingress-nginx \
    --version 4.7.1 \
    --namespace ingress-basic \
    --create-namespace \
    --set controller.replicaCount=2 \
    --set controller.nodeSelector."kubernetes\.io/os"=linux \
    --set controller.image.registry=$ACR_LOGIN_SERVER \
    --set controller.image.image=$CONTROLLER_IMAGE \
    --set controller.image.tag=$CONTROLLER_TAG \
    --set controller.image.digest="" \
    --set controller.admissionWebhooks.patch.nodeSelector."kubernetes\.io/os"=linux \
    --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \
    --set controller.service.externalTrafficPolicy=Local \
    --set controller.admissionWebhooks.patch.image.registry=$ACR_LOGIN_SERVER \
    --set controller.admissionWebhooks.patch.image.image=$PATCH_IMAGE \
    --set controller.admissionWebhooks.patch.image.tag=$PATCH_TAG \
    --set controller.admissionWebhooks.patch.image.digest="" \
    --set defaultBackend.nodeSelector."kubernetes\.io/os"=linux \
    --set defaultBackend.image.registry=$ACR_LOGIN_SERVER \
    --set defaultBackend.image.image=$DEFAULTBACKEND_IMAGE \
    --set defaultBackend.image.tag=$DEFAULTBACKEND_TAG \
    --set defaultBackend.image.digest=""

Crear un controlador de entrada mediante una dirección IP interna

De forma predeterminada, un controlador de entrada NGINX usa una dirección IP pública dinámica. Sin embargo, es posible que quiera usar una red interna, privada y una dirección IP. Este enfoque restringe el acceso a los servicios a los usuarios internos, sin acceso externo.

Use los parámetros --set controller.service.loadBalancerIP y --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-internal"=true para asignar una dirección IP interna al controlador de entrada. Proporcione su propia dirección IP interna para el controlador de entrada. Asegúrese de que esta dirección IP no esté ya en uso dentro de la red virtual. Si usa una red virtual y una subred existentes, debe configurar el clúster de AKS con los permisos correctos para administrar la red virtual y la subred. Para más información, consulte Uso de redes kubenet con intervalos de direcciones IP propios en Azure Kubernetes Service (AKS) o Configuración de redes de Azure CNI en Azure Kubernetes Service (AKS).

# Add the ingress-nginx repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

# Set variable for ACR location to use for pulling images
ACR_LOGIN_SERVER=<REGISTRY_LOGIN_SERVER>

# Use Helm to deploy an NGINX ingress controller
helm install ingress-nginx ingress-nginx/ingress-nginx \
    --version 4.7.1 \
    --namespace ingress-basic \
    --create-namespace \
    --set controller.replicaCount=2 \
    --set controller.nodeSelector."kubernetes\.io/os"=linux \
    --set controller.image.registry=$ACR_LOGIN_SERVER \
    --set controller.image.image=$CONTROLLER_IMAGE \
    --set controller.image.tag=$CONTROLLER_TAG \
    --set controller.image.digest="" \
    --set controller.admissionWebhooks.patch.nodeSelector."kubernetes\.io/os"=linux \
    --set controller.service.loadBalancerIP=10.224.0.42 \
    --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-internal"=true \
    --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \
    --set controller.admissionWebhooks.patch.image.registry=$ACR_LOGIN_SERVER \
    --set controller.admissionWebhooks.patch.image.image=$PATCH_IMAGE \
    --set controller.admissionWebhooks.patch.image.tag=$PATCH_TAG \
    --set controller.admissionWebhooks.patch.image.digest="" \
    --set defaultBackend.nodeSelector."kubernetes\.io/os"=linux \
    --set defaultBackend.image.registry=$ACR_LOGIN_SERVER \
    --set defaultBackend.image.image=$DEFAULTBACKEND_IMAGE \
    --set defaultBackend.image.tag=$DEFAULTBACKEND_TAG \
    --set defaultBackend.image.digest="" 

Comprobación del servicio de equilibrador de carga de entrada

Compruebe el servicio del equilibrador de carga mediante kubectl get services.

kubectl get services --namespace ingress-basic -o wide -w ingress-nginx-controller

Al crear el servicio de equilibrador de carga de Kubernetes para el controlador de entrada NGINX, asigna una dirección IP en EXTERNAL-IP, como se muestra en la salida del ejemplo siguiente:

NAME                       TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)                      AGE   SELECTOR
ingress-nginx-controller   LoadBalancer   10.0.65.205   EXTERNAL-IP     80:30957/TCP,443:32414/TCP   1m   app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx

Si navega a la dirección IP externa en esta fase, verá una página 404 mostrada. Esta respuesta aparece porque todavía necesita configurar la conexión a la dirección IP externa, que se realiza en las secciones siguientes.

Ejecución de aplicaciones de demostración para pruebas de entrada

Para ver el controlador de entrada en acción, ejecute dos aplicaciones de demostración en el clúster de AKS. En este ejemplo, use kubectl apply para implementar dos instancias de una sencilla aplicación Hola mundo .

  1. Cree el archivo aks-helloworld-one.yaml y cópielo en el ejemplo siguiente de YAML:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: aks-helloworld-one  
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: aks-helloworld-one
      template:
        metadata:
          labels:
            app: aks-helloworld-one
        spec:
          containers:
          - name: aks-helloworld-one
            image: mcr.microsoft.com/azuredocs/aks-helloworld:v1
            ports:
            - containerPort: 80
            env:
            - name: TITLE
              value: "Welcome to Azure Kubernetes Service (AKS)"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: aks-helloworld-one  
    spec:
      type: ClusterIP
      ports:
      - port: 80
      selector:
        app: aks-helloworld-one
    
  2. Cree el archivo aks-helloworld-two.yaml y cópielo en el ejemplo siguiente de YAML:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: aks-helloworld-two  
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: aks-helloworld-two
      template:
        metadata:
          labels:
            app: aks-helloworld-two
        spec:
          containers:
          - name: aks-helloworld-two
            image: mcr.microsoft.com/azuredocs/aks-helloworld:v1
            ports:
            - containerPort: 80
            env:
            - name: TITLE
              value: "AKS Ingress Demo"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: aks-helloworld-two  
    spec:
      type: ClusterIP
      ports:
      - port: 80
      selector:
        app: aks-helloworld-two
    
  3. Ejecute las dos aplicaciones de demostración mediante kubectl apply:

    kubectl apply -f aks-helloworld-one.yaml --namespace ingress-basic
    kubectl apply -f aks-helloworld-two.yaml --namespace ingress-basic
    

Creación de reglas de enrutamiento de entrada

Ambas aplicaciones ahora se ejecutan en el clúster de Kubernetes. Para enrutar el tráfico a cada aplicación, cree un recurso de entrada de Kubernetes. El recurso de entrada configura las reglas de enrutamiento del tráfico a una de las dos aplicaciones.

En el ejemplo siguiente, el tráfico a la dirección EXTERNAL_IP/hello-world-one se enruta al servicio denominado aks-helloworld-one. El tráfico a la dirección EXTERNAL_IP/hello-world-two se enruta al servicio aks-helloworld-two. El tráfico a la dirección EXTERNAL_IP/static se enruta al servicio denominado aks-helloworld-one para los recursos estáticos.

  1. Cree un archivo denominado hello-world-ingress.yaml y cópielo en el ejemplo siguiente de YAML:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: hello-world-ingress
      annotations:
        nginx.ingress.kubernetes.io/ssl-redirect: "false"
        nginx.ingress.kubernetes.io/use-regex: "true"
        nginx.ingress.kubernetes.io/rewrite-target: /$2
    spec:
      ingressClassName: nginx
      rules:
      - http:
          paths:
          - path: /hello-world-one(/|$)(.*)
            pathType: Prefix
            backend:
              service:
                name: aks-helloworld-one
                port:
                  number: 80
          - path: /hello-world-two(/|$)(.*)
            pathType: Prefix
            backend:
              service:
                name: aks-helloworld-two
                port:
                  number: 80
          - path: /(.*)
            pathType: Prefix
            backend:
              service:
                name: aks-helloworld-one
                port:
                  number: 80
    ---
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: hello-world-ingress-static
      annotations:
        nginx.ingress.kubernetes.io/ssl-redirect: "false"
        nginx.ingress.kubernetes.io/rewrite-target: /static/$2
    spec:
      ingressClassName: nginx
      rules:
      - http:
          paths:
          - path: /static(/|$)(.*)
            pathType: Prefix
            backend:
              service:
                name: aks-helloworld-one
                port: 
                  number: 80
    
  2. Cree el recurso de entrada con el comando kubectl apply.

    kubectl apply -f hello-world-ingress.yaml --namespace ingress-basic
    

Probar el enrutamiento del controlador de entrada

Para probar las rutas para el controlador de entrada, vaya a las dos aplicaciones. Abra un explorador web en la dirección IP de su controlador de entrada NGINX, como EXTERNAL_IP. La primera aplicación de demostración aparece en el explorador web, como se muestra en el ejemplo siguiente:

Captura de pantalla de la primera aplicación de demostración que se ejecuta detrás del controlador de entrada no administrado en AKS.

A continuación, agregue la ruta de acceso /hello-world-two a la dirección IP, como EXTERNAL_IP/hello-world-two. Aparece la segunda aplicación de demostración con el título personalizado:

Captura de pantalla de la segunda aplicación de demostración que se ejecuta detrás del controlador de entrada no administrado en AKS.

Prueba de una dirección IP interna

  1. Cree un pod de prueba y asóciele una sesión de terminal.

    kubectl run -it --rm aks-ingress-test --image=mcr.microsoft.com/dotnet/runtime-deps:6.0 --namespace ingress-basic
    
  2. Realice la instalación de curl en el pod utilizando apt-get.

    apt-get update && apt-get install -y curl
    
  3. Acceda a la dirección del controlador de entrada de Kubernetes mediante curl, como http://10.224.0.42. Proporcione su propia dirección IP interna, que especificó al implementar el controlador de entrada.

    curl -L http://10.224.0.42
    

    No proporcionó una ruta de acceso con la dirección, por lo que el controlador de entrada tiene como valor predeterminado la / ruta. Se devuelve la primera aplicación de demostración, tal como se muestra en la siguiente salida de ejemplo reducido:

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <link rel="stylesheet" type="text/css" href="/static/default.css">
        <title>Welcome to Azure Kubernetes Service (AKS)</title>
    [...]
    
  4. Agregue la ruta de acceso /hello-world-two a la dirección, como http://10.224.0.42/hello-world-two.

    curl -L -k http://10.224.0.42/hello-world-two
    

    Se devuelve la segunda aplicación de demostración con el título personalizado, tal como se muestra en la siguiente salida de ejemplo reducido:

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <link rel="stylesheet" type="text/css" href="/static/default.css">
        <title>AKS Ingress Demo</title>
    [...]
    

Limpieza de recursos

En este artículo, se usa Helm para instalar los componentes de entrada y las aplicaciones de ejemplo. Al implementar un gráfico de Helm, se crean muchos recursos de Kubernetes. Estos recursos incluyen pods, implementaciones y servicios. Para limpiar estos recursos, puede eliminar todo el espacio de nombres de ejemplo o eliminar los recursos individuales.

Eliminación del espacio de nombres de ejemplo y de todos los recursos

Para eliminar el espacio de nombres de ejemplo completo, use el comando kubectl delete y especifique el nombre del espacio de nombres. Este comando elimina todos los recursos del espacio de nombres.

kubectl delete namespace ingress-basic

Eliminación de recursos individualmente

Como alternativa, puede eliminar los recursos individuales creados para un enfoque más pormenorizado.

  1. Enumere las versiones de Helm mediante el helm list comando .

    helm list --namespace ingress-basic
    

    Busque los gráficos denominados ingress-nginx y aks-helloworld, tal y como se muestra en la salida del ejemplo siguiente:

    NAME                    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                   APP VERSION
    ingress-nginx           ingress-basic   1               2020-01-06 19:55:46.358275 -0600 CST    deployed        nginx-ingress-1.27.1    0.26.1  
    
  2. Desinstale las versiones mediante el helm uninstall comando .

    helm uninstall ingress-nginx --namespace ingress-basic
    
  3. Quite las dos aplicaciones de ejemplo.

    kubectl delete -f aks-helloworld-one.yaml --namespace ingress-basic
    kubectl delete -f aks-helloworld-two.yaml --namespace ingress-basic
    
  4. Elimine la ruta de entrada que dirige el tráfico a las aplicaciones de ejemplo.

    kubectl delete -f hello-world-ingress.yaml
    
  5. Elimine el espacio de nombres mediante el comando kubectl delete y especifique el nombre de su espacio de nombres.

    kubectl delete namespace ingress-basic
    

Pasos siguientes

Para configurar TLS con los componentes de ingreso existentes, consulte Uso de TLS con un controlador de ingreso.

Para configurar el clúster de AKS para usar el enrutamiento de aplicaciones, consulte Complemento de enrutamiento de aplicaciones.

En este artículo se incluyen algunos componentes externos para AKS. Para más información sobre estos componentes, consulte las siguientes páginas del proyecto: