閱讀英文

共用方式為

与应用程序路由附加产品配合使用的高级 NGINX 入口控制器和入口配置

应用程序路由附加产品支持使用两种方法来配置入口控制器和入口对象:

先决条件

具有 应用程序路由加载项的 AKS 群集。

连接到 AKS 群集

若要从本地计算机连接到 Kubernetes 群集,请使用 Kubernetes 命令行客户端 kubectl。 可以使用 az aks install-cli 命令在本地安装它。 如果使用的是 Azure Cloud Shell,则 kubectl 已安装。

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

az aks get-credentials --resource-group <ResourceGroupName> --name <ClusterName>

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> 设置为前面所述的配置选项之一。

az aks create \
--resource-group <ResourceGroupName> \
--name <ClusterName> \
--location <Location> \
--enable-app-routing \
--app-routing-default-nginx-controller <DefaultIngressControllerType>

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

若要更新现有群集上的应用程序路由默认入口控制器配置,请使用 az aks approuting update 命令并指定 --nginx 标志。 需要将 <DefaultIngressControllerType> 设置为前面所述的配置选项之一。

az aks approuting update --resource-group <ResourceGroupName> --name <ClusterName> --nginx <DefaultIngressControllerType>

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

若要创建具有面向公众的 Azure 负载均衡器的另一个 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 入口控制器

若要创建具有面向内部的 Azure 负载均衡器(使用专用 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 入口控制器

若要创建 Azure 负载均衡器使用静态 IP 地址的 NGINX 入口控制器,请执行以下操作:

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

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

    az network public-ip create \
        --resource-group myNetworkResourceGroup \
        --name myIngressPublicIP \
        --sku Standard \
        --allocation-method static
    

    注意

    如果在 AKS 群集中使用基本 SKU 负载均衡器,请在定义公共 IP 时对参数使用 --sku。 只有 基本 SKU IP 适用于 基本 SKU 负载均衡器,并且只有 标准 SKU IP 使用 标准 SKU 负载均衡器。

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

    注意

    <ClusterName><ClusterResourceGroup> 更新为你的 AKS 群集的名称和资源组名称。

    CLIENT_ID=$(az aks show --name <ClusterName> --resource-group <ClusterResourceGroup> --query identity.principalId -o tsv)
    RG_SCOPE=$(az group show --name myNetworkResourceGroup --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 批注可确保创建最有效的 LoadBalancer,强烈建议避免潜在的限制。

    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: "myIngressPublicIP"
        service.beta.kubernetes.io/azure-load-balancer-resource-group: "myNetworkResourceGroup"
    
  5. 使用 kubectl apply 命令创建 NGINX 入口控制器资源。

    kubectl apply -f nginx-staticip-controller.yaml
    

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

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

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

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

注意

<IngressControllerName> 替换为你创建 NginxIngressController 时使用的名称。

kubectl get nginxingresscontroller -n <IngressControllerName>

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

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

你还可以查看情况来排查任何问题:

kubectl get nginxingresscontroller -n <IngressControllerName> -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 -n hello-web-app-routing
    

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

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

验证是否已创建托管 Ingress

可以使用 kubectl get ingress 命令验证是否已创建托管 Ingress。

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

以下示例输出显示了创建的托管入口。 入口类、主机和 IP 地址可能有所不同:

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

入口控制器的清理

你可以使用 kubectl delete nginxingresscontroller 命令移除 NGINX 入口控制器。

注意

<IngressControllerName> 替换为你创建 NginxIngressController 时使用的名称。

kubectl delete nginxingresscontroller -n <IngressControllerName>

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

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),请使用以下注释:

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

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

后续步骤