Compartir a través de

适用于 Azure Kubernetes 服务(AKS)的高级 NGINX 入口控制器和入口配置,以及应用路由加载项

重要

Kubernetes SIG Network和安全响应委员会宣布即将停用Ingress NGINX项目, 维护将于2026年3月结束。 目前,使用 NGINX 的应用程序路由附加组件的 AKS 群集无需立即执行任何操作。 Microsoft将在 2026 年 11 月前为应用程序路由加载项 NGINX 入口资源提供关键安全修补程序的官方支持。

AKS 正在迁移到 网关 API,这将作为入口和 L7 流量管理的长期标准,以便与上游 Kubernetes 社区保持一致。 建议根据当前设置开始规划迁移路径:

  • 应用程序路由加载项用户:生产工作负荷将继续得到全面支持,直至2026年11月。 AKS 将继续通过网关 API 对齐方式不断演变应用程序路由加载项。 无需移动到其他入口产品。
  • OSS NGINX 用户 有多个选项:
  • 服务网格用户:如果计划采用服务网格,请考虑 基于 Istio 的服务网格加载项。 今天使用 Istio 入口,计划在正式发布为 GA 时迁移到 Istio 网关 API 支持。

本文将指导你通过应用程序路由加载项,为 Azure Kubernetes Service (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 入口控制器的配置属性

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

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

领域 类型 说明 必选 违约
controllerNamePrefix 字符串 托管 NGINX 入口控制器资源的名称。 是的 nginx
customHTTPErrors 数组 出现错误时,将错误代码数组发送到默认后端。
defaultBackendService 对象 用于路由不匹配的 HTTP 流量的服务。 包含嵌套属性:
name 字符串 服务名称。 是的
namespace 字符串 服务命名空间。 是的
defaultSSLCertificate 对象 包含用于访问默认后端服务的默认证书。 包含嵌套属性:
forceSSLRedirect 布尔 设置证书时强制 HTTPS 重定向。 false
keyVaultURI 字符串 用于存储证书的 Key Vault 机密的 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 启用应用程序路由附加组件时,它会在配置有公共 Azure 负载均衡器的 default 中创建名为 app-routing-namespace 的 Ingress 控制器。 该入口控制器使用入口类名 webapprouting.kubernetes.azure.com

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

可能的配置选项包括:

  • None:未创建默认 NGINX 入口控制器,如果已存在,则不会将其删除。 如果需要,应手动删除默认 NginxIngressController 自定义资源。
  • Internal:默认的 NGINX Ingress 控制器是使用内部负载均衡器创建的。 任何为了使自定义资源NginxIngressController可外部访问的批注更改都会被覆盖。
  • External:由外部负载均衡器创建的默认 NGINX Ingress 控制器。 任何在 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 群集中使用 Basic SKU load balancer,请在定义公共 IP 时对 Basic 参数使用 --sku。 只有 Basic SKU IP 适用于 Basic SKU load balancer,并且只有 Standard SKU IP 与 Standard SKU 负载均衡器配合使用。

  3. 确保 AKS 群集使用的群集标识通过 az role assignment create 命令将委托权限授予公共 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 名称,也可以对 IPv4 地址使用 service.beta.kubernetes.io/azure-load-balancer-ipv4,对 IPv6 地址使用 service.beta.kubernetes.io/azure-load-balancer-ipv6,如示例 YAML 所示。 添加 service.beta.kubernetes.io/azure-pip-name 批注可确保创建效率最高的Load Balancer,强烈建议这样做以避免潜在的限制。

    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"

查看 backend 协议以获取其他配置选项。

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

注意事项

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

查看 enable 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。 此配置适用于基于 path 的路由,可以在同一域中为两个不同的 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 Load Balancer的默认运行状况探测路径必须设置为 "/healthz"。 若要确保进行正确的健康检查,请验证入口控制器服务是否具有以下注解:

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

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

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

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