次の方法で共有

用于 Azure Kubernetes 服务 (AKS) 的应用程序路由插件的高级 NGINX 入口控制器和入口配置

本文将指导你通过两种方法来配置适用于 Azure Kubernetes 服务(AKS)的应用程序路由加载项中的入口控制器和入口对象。

先决条件

连接到 AKS 群集

若要从本地计算机连接到 Kubernetes 群集,请使用 Kubernetes 命令行客户端 kubectl。 您可以使用 az aks install-cli 命令在本地安装它。

  • 使用 az aks get-credentials 命令将 kubectl 配置为连接到 Kubernetes 群集。

    az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME
    

NGINX 入口控制器的配置属性

应用程序路由加载项使用名为自定义资源定义(CRD)的 Kubernetes NginxIngressController来配置 NGINX 入口控制器。 可以创建更多入口控制器或修改现有配置。

下表列出了用于配置NginxIngressController的属性:

领域 类型 说明 必选 违约
controllerNamePrefix 字符串 托管 NGINX 入口控制器资源的名称。 是的 nginx
customHTTPErrors 数组 出现错误时,将错误代码数组发送到默认后端。
defaultBackendService 对象 用于路由不匹配的 HTTP 流量的服务。 包含嵌套属性:
name 字符串 服务名称。 是的
namespace 字符串 服务命名空间。 是的
defaultSSLCertificate 对象 包含用于访问默认后端服务的默认证书。 包含嵌套属性:
forceSSLRedirect 布尔 设置证书时强制 HTTPS 重定向。 false
keyVaultURI 字符串 某证书存储于密钥保管库机密的 URI。
secret 对象 保存默认 SSL 证书的机密信息。 包含嵌套属性:
  name 字符串 机密名称。 是的
  namespace 字符串 机密命名空间。 是的
httpDisabled 布尔 用于禁用到控制器的 HTTP 流量的标志。
ingressClassName 字符串 控制器使用的 IngressClass 名称。 是的 nginx.approuting.kubernetes.azure.com
loadBalancerAnnotations 对象 通过设置 负载均衡器注释来控制 NGINX 入口控制器服务的行为的注释映射。
scaling 对象 用于缩放控制器的配置。 包含嵌套属性:
maxReplicas 整数 副本上限。 100
minReplicas 整数 副本的下限。 2
threshold 字符串 用于定义缩放积极程度的缩放阈值。 rapid 应对突发高峰快速扩展,steady 注重成本效益,balanced 是一种混合模式。 balanced

控制默认 NGINX 入口控制器配置

当启用使用 NGINX 的应用程序路由附加产品时,它会在 default 中创建一个名为 app-routing-namespace 的入口控制器,该控制器配置有面向公众的 Azure 负载均衡器。 该入口控制器使用入口类名 webapprouting.kubernetes.azure.com

你还可以控制默认配置是要获取公共 IP 还是内部 IP,或者是否在启用加载项时创建全新的配置。

可能的配置选项包括:

  • None:未创建默认 NGINX 入口控制器,如果已存在,则不会将其删除。 如果需要,应手动删除默认 NginxIngressController 自定义资源。
  • Internal:默认的 NGINX 入口控制器是使用内部负载均衡器创建的。 任何为了使自定义资源NginxIngressController可外部访问的批注更改都会被覆盖。
  • External:使用外部负载均衡器创建的默认 NGINX 入口控制器。 任何在 NginxIngressController 自定义资源上为使其变为内部资源而进行的注释更改都会被覆盖。
  • AnnotationControlled (默认值):默认 NGINX 入口控制器是使用外部负载均衡器创建的。 可以编辑默认 NginxIngressController 自定义资源以配置负载均衡器注释。

控制新群集上的默认入口控制器配置

  • 使用az aks create命令和--enable-app-routing--app-routing-default-nginx-controller标志在新群集上启用应用程序路由。 需要将<DefaultIngressControllerType>设置为《控制默认 NGINX Ingress 控制器配置》中所述的配置选项之一。

    az aks create \
      --resource-group $RESOURCE_GROUP \
      --name $CLUSTER_NAME \
      --location $LOCATION \
      --enable-app-routing \
      --app-routing-default-nginx-controller <DefaultIngressControllerType>
    

更新现有群集上的默认入口控制器配置

  • 使用带有标志的 az aks approuting update 命令 --nginx 更新现有群集上的应用程序路由默认入口控制器配置。 需要将<DefaultIngressControllerType>设置为《控制默认 NGINX Ingress 控制器配置》中所述的配置选项之一。

    az aks approuting update \
      --resource-group $RESOURCE_GROUP \
      --name $CLUSTER_NAME \
      --nginx <DefaultIngressControllerType>
    

创建另一个面向公众的 NGINX 入口控制器

  1. 将以下 YAML 清单复制到名为 nginx-public-controller.yaml 该文件的新文件中,并将该文件保存到本地计算机。

    apiVersion: approuting.kubernetes.azure.com/v1alpha1
    kind: NginxIngressController
    metadata:
      name: nginx-public
    spec:
      ingressClassName: nginx-public
      controllerNamePrefix: nginx-public
    
  2. 使用 kubectl apply 命令创建 NGINX 入口控制器资源。

    kubectl apply -f nginx-public-controller.yaml
    

    以下示例输出显示了已创建的资源:

    nginxingresscontroller.approuting.kubernetes.azure.com/nginx-public created
    

创建具有专用 IP 地址的内部 NGINX 入口控制器

  1. 将以下 YAML 清单复制到名为 nginx-internal-controller.yaml 该文件的新文件中,并将该文件保存到本地计算机。

    apiVersion: approuting.kubernetes.azure.com/v1alpha1
    kind: NginxIngressController
    metadata:
      name: nginx-internal
    spec:
      ingressClassName: nginx-internal
      controllerNamePrefix: nginx-internal
      loadBalancerAnnotations: 
        service.beta.kubernetes.io/azure-load-balancer-internal: "true"
    
  2. 使用 kubectl apply 命令创建 NGINX 入口控制器资源。

    kubectl apply -f nginx-internal-controller.yaml
    

    以下示例输出显示了已创建的资源:

    nginxingresscontroller.approuting.kubernetes.azure.com/nginx-internal created
    

创建具有静态 IP 地址的 NGINX 入口控制器

  1. 使用 az group create 命令创建 Azure 资源组。

    az group create --name $NETWORK_RESOURCE_GROUP --location $LOCATION
    
  2. 使用命令“az network public ip create”创建静态公共 IP 地址。

    az network public-ip create \
      --resource-group $NETWORK_RESOURCE_GROUP \
      --name $PUBLIC_IP_NAME \
      --sku Standard \
      --allocation-method static
    

    注意

    如果在 AKS 群集中使用基本 SKU 负载均衡器,请在定义公共 IP 时用于Basic--sku参数。 只有 Basic SKU IP 可与基本 SKU 负载均衡器一起使用,只有 Standard SKU IP 可与标准 SKU 负载均衡器一起使用。

  3. 使用 az role assignment create 命令确保 AKS 群集使用的群集标识已将权限委托给公共 IP 的资源组。

    CLIENT_ID=$(az aks show --name $CLUSTER_NAME --resource-group $RESOURCE_GROUP --query identity.principalId -o tsv)
    RG_SCOPE=$(az group show --name $NETWORK_RESOURCE_GROUP --query id -o tsv)
    az role assignment create \
      --assignee ${CLIENT_ID} \
      --role "Network Contributor" \
      --scope ${RG_SCOPE}
    
  4. 将以下 YAML 清单复制到名为 nginx-staticip-controller.yaml 该文件的新文件中,并将该文件保存到本地计算机。

    注意

    可以将 service.beta.kubernetes.io/azure-pip-name 用于公共 IP 名称,或将 service.beta.kubernetes.io/azure-load-balancer-ipv4 用于 IPv4 地址并将 service.beta.kubernetes.io/azure-load-balancer-ipv6 用于 IPv6 地址,如示例 YAML 中所示。 添加service.beta.kubernetes.io/azure-pip-name标注可确保创建最有效的负载均衡器,强烈建议使用此方法以避免潜在的限制。

    apiVersion: approuting.kubernetes.azure.com/v1alpha1
    kind: NginxIngressController
    metadata:
      name: nginx-static
    spec:
      ingressClassName: nginx-static
      controllerNamePrefix: nginx-static
      loadBalancerAnnotations: 
        service.beta.kubernetes.io/azure-pip-name: "$PUBLIC_IP_NAME"
        service.beta.kubernetes.io/azure-load-balancer-resource-group: "$NETWORK_RESOURCE_GROUP"
    
  5. 使用 kubectl apply 命令创建 NGINX 入口控制器资源。

    kubectl apply -f nginx-staticip-controller.yaml
    

    以下示例输出显示了已创建的资源:

    nginxingresscontroller.approuting.kubernetes.azure.com/nginx-static created
    

验证是否已创建入口控制器

  • 使用 kubectl get nginxingresscontroller 命令验证 NGINX 入口控制器的状态。

    kubectl get nginxingresscontroller --name $INGRESS_CONTROLLER_NAME
    

    以下示例输出显示了创建的资源。 控制器可能需要几分钟时间才可用:

    NAME           INGRESSCLASS   CONTROLLERNAMEPREFIX   AVAILABLE
    nginx-public   nginx-public   nginx                  True
    

查看入口控制器的条件

  • 查看入口控制器的条件,以使用 kubectl get nginxingresscontroller 命令排查任何问题。

    kubectl get nginxingresscontroller --name $INGRESS_CONTROLLER_NAME -o jsonpath='{range .items[*].status.conditions[*]}{.lastTransitionTime}{"\t"}{.status}{"\t"}{.type}{"\t"}{.message}{"\n"}{end}'
    

    以下示例输出显示了正常入口控制器的情况:

    2023-11-29T19:59:24Z    True    IngressClassReady       Ingress Class is up-to-date
    2023-11-29T19:59:50Z    True    Available               Controller Deployment has minimum availability and IngressClass is up-to-date
    2023-11-29T19:59:50Z    True    ControllerAvailable     Controller Deployment is available
    2023-11-29T19:59:25Z    True    Progressing             Controller Deployment has successfully progressed
    

在入口中使用入口控制器

  1. 将以下 YAML 清单复制到名为 ingress.yaml 该文件的新文件中,并将该文件保存到本地计算机。

    注意

    <HostName> 更新为你的 DNS 主机名。 <IngressClassName> 是你在创建 NginxIngressController 时定义的那个。

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: aks-helloworld
      namespace: hello-web-app-routing
    spec:
      ingressClassName: <IngressClassName>
      rules:
      - host: <HostName>
        http:
          paths:
          - backend:
              service:
                name: aks-helloworld
                port:
                  number: 80
            path: /
            pathType: Prefix
    
  2. 使用 kubectl apply 命令创建群集资源。

    kubectl apply -f ingress.yaml --namespace hello-web-app-routing
    

    以下示例输出显示了已创建的资源:

    ingress.networking.k8s.io/aks-helloworld created
    

验证是否已创建托管入口

  • 使用 kubectl get ingress 命令验证是否已创建托管入口。

    kubectl get ingress --namespace hello-web-app-routing
    

    输出应类似于以下示例输出:

    NAME             CLASS                                HOSTS               ADDRESS       PORTS     AGE
    aks-helloworld   webapprouting.kubernetes.azure.com   myapp.contoso.com   20.51.92.19   80, 443   4m
    

删除入口控制器

通过注释进行每个入口资源的配置

NGINX 入口控制器支持 向特定入口对象添加批注 以自定义其行为。

可以通过在字段中添加相应的注释来metadata.annotations入口对象。

注意

注释键和值只能是字符串。 其他类型(如布尔值或数值)必须带引号。 例如:"true""false""100"

以下部分提供了常见配置的示例。 有关完整列表,请参阅 NGINX 入口注释文档

自定义最大正文大小

对于 NGINX,当请求中的大小超过允许的客户端请求正文最大大小时,将向客户端返回 413 错误。 要替代默认值,请使用以下注释:

nginx.ingress.kubernetes.io/proxy-body-size: 4m

下面是使用此注释的示例入口配置:

注意

<HostName> 更新为你的 DNS 主机名。 <IngressClassName> 是你在创建 NginxIngressController 时定义的那个。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: aks-helloworld
  namespace: hello-web-app-routing
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: 4m
spec:
  ingressClassName: <IngressClassName>
  rules:
  - host: <HostName>
    http:
      paths:
      - backend:
          service:
            name: aks-helloworld
            port:
              number: 80
        path: /
        pathType: Prefix

自定义连接超时

可以更改 NGINX 入口控制器在与您的工作负载断开连接时等待的超时时间。 所有超时值都是无单位的,以秒为单位。 若要替代默认超时,请使用以下注释设置有效的 120 秒代理读取超时:

nginx.ingress.kubernetes.io/proxy-read-timeout: "120"

查看自定义超时和其他配置选项。

下面是使用此注释的示例入口配置:

注意

<HostName> 更新为你的 DNS 主机名。 <IngressClassName> 是你在创建 NginxIngressController 时定义的那个。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: aks-helloworld
  namespace: hello-web-app-routing
  annotations:
    nginx.ingress.kubernetes.io/proxy-read-timeout: "120"
spec:
  ingressClassName: <IngressClassName>
  rules:
  - host: <HostName>
    http:
      paths:
      - backend:
          service:
            name: aks-helloworld
            port:
              number: 80
        path: /
        pathType: Prefix

后端协议

默认情况下,NGINX 入口控制器使用 HTTP 来访问服务。 若要配置备用后端协议,如HTTPSGRPC,请使用以下注释之一:

# HTTPS annotation
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"

# GRPC annotation
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"

查看后端协议以了解其他配置选项。

下面是使用此注释的示例入口配置:

注意

<HostName> 更新为你的 DNS 主机名。 <IngressClassName> 是你在创建 NginxIngressController 时定义的那个。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: aks-helloworld
  namespace: hello-web-app-routing
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  ingressClassName: <IngressClassName>
  rules:
  - host: <HostName>
    http:
      paths:
      - backend:
          service:
            name: aks-helloworld
            port:
              number: 80
        path: /
        pathType: Prefix

跨源资源共享 (CORS)

若要在入口规则中启用跨域资源共享(CORS),请使用以下注释:

nginx.ingress.kubernetes.io/enable-cors: "true"

查看启用 CORS 以了解其他配置选项。

下面是使用此注释的示例入口配置:

注意

<HostName> 更新为你的 DNS 主机名。 <IngressClassName> 是你在创建 NginxIngressController 时定义的那个。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: aks-helloworld
  namespace: hello-web-app-routing
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"
spec:
  ingressClassName: <IngressClassName>
  rules:
  - host: <HostName>
    http:
      paths:
      - backend:
          service:
            name: aks-helloworld
            port:
              number: 80
        path: /
        pathType: Prefix

禁用 SSL 重定向

如果默认情况下为入口启用了 TLS,控制器会将 (308) 重定向到 HTTPS。 若要禁用特定入口资源的此功能,请使用以下注释:

nginx.ingress.kubernetes.io/ssl-redirect: "false"

查看通过重定向强制实施服务器端 HTTPS,了解其他配置选项。

下面是使用此注释的示例入口配置:

注意

<HostName> 更新为你的 DNS 主机名。 <IngressClassName> 是你在创建 NginxIngressController 时定义的那个。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: aks-helloworld
  namespace: hello-web-app-routing
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
  ingressClassName: <IngressClassName>
  rules:
  - host: <HostName>
    http:
      paths:
      - backend:
          service:
            name: aks-helloworld
            port:
              number: 80
        path: /
        pathType: Prefix

URL 重写

在某些情况下,后端服务中公开的 URL 与入口规则中的指定路径不同。 如果没有重写,则任何请求都将返回 404。 此配置适用于 基于路径的路由 ,你可以在同一域中为两个不同的 Web 应用程序提供服务。 可以使用以下注释设置服务预期的路径:

nginx.ingress.kubernetes.io/rewrite-target: /$2

下面是使用此注释的示例入口配置:

注意

<HostName> 更新为你的 DNS 主机名。 <IngressClassName> 是你在创建 NginxIngressController 时定义的那个。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: aks-helloworld
  namespace: hello-web-app-routing
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  ingressClassName: <IngressClassName>
  rules:
  - host: <HostName>
    http:
      paths:
      - path: /app-one(/|$)(.*)
        pathType: Prefix 
        backend:
          service:
            name: app-one
            port:
              number: 80
      - path: /app-two(/|$)(.*)
        pathType: Prefix 
        backend:
          service:
            name: app-two
            port:
              number: 80

NGINX 运行状况探测路径更新

与 NGINX 入口控制器关联的 Azure 负载均衡器的默认运行状况探测路径必须设置为 "/healthz"。 若要确保进行正确的健康检查,请验证入口控制器服务是否具有以下注解:

metadata:
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path: "/healthz"

如果使用 Helm 管理 NGINX 入口控制器,可以在值文件中定义 Azure 负载均衡器运行状况探测注释,并在升级期间应用它:

controller:
  service:
    annotations:
      service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path: "/healthz"

此配置有助于维护服务可用性,并避免升级期间出现意外流量中断。