与应用程序路由附加产品配合使用的高级 NGINX 入口控制器和入口配置
应用程序路由附加产品支持使用两种方法来配置入口控制器和入口对象:
- NGINX 入口控制器的配置,例如,创建多个控制器、配置专用负载均衡器,以及设置静态 IP 地址。
- 通过注释进行每个入口资源的配置。
先决条件
具有应用程序路由附加产品的 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 入口控制器的配置
应用程序路由附加产品使用称作 NginxIngressController
的 Kubernetes 自定义资源定义 (CRD) 来配置 NGINX 入口控制器。 你可以创建更多入口控制器或修改现有配置。
下面是对可设置为配置 NginxIngressController
的属性的引用。
properties | 说明 |
---|---|
ingressClassName | 将用于 NGINX 入口控制器的 IngressClass 的名称。 默认为 NginxIngressController 的名称(如果未指定)。 |
controllerNamePrefix | 用于为托管 NGINX 入口控制器资源添加前缀的名称。 默认为 nginx 。 |
loadBalancerAnnotations | 用于通过设置负载均衡器注释来控制 NGINX 入口控制器服务的行为的一组注释 |
scaling | NGINX 入口控制器缩放方式的配置选项。 |
scaling.minReplicas | 入口控制器副本数的下限。 默认为 2 个 Pod。 |
scaling.maxReplicas | 入口控制器副本数的上限。 默认为 100 个 Pod。 |
scaling.threshold | 定义 NGINX 入口控制器 Pod 应以多快速度根据工作负载进行缩放。 Rapid 表示入口控制器将快速积极地进行缩放,以处理突发的严重流量高峰。 Steady 通过更少的副本处理更多工作,确定成本效益的优先级。 Balanced 是两者之间适用于大多数用例的良好组合。 如果未指定,此字段默认为 Balanced 。 |
defaultBackendService | NGINX 入口控制器应默认使用的 Kubernetes 服务,其处理 Ingress-NGINX 控制器不了解的所有 URL 路径和主机(即,未使用 Ingress 映射的所有请求)。 该控制器将流量定向到服务的第一个端口。 如果未指定,将使用内置的默认后端。 |
defaultBackendService.namespace | 服务的命名空间。 |
defaultBackendService.name | 服务的名称。 |
defaultSSLCertificate | 此属性引用的机密包含访问默认后端服务时要使用的默认证书。 如果未提供此属性,则 NGINX 将使用自签名证书。 如果未在 Ingress 上设置 tls: 部分,则 NGINX 将提供默认证书,但不会强制执行 HTTPS 重定向。 |
defaultSSLCertificate.forceSSLRedirect | 强制不指定 tls: 部分的 Ingress 进行重定向。 |
defaultSSLCertificate.keyVaultURI | 可在其中找到默认 SSL 证书的 Azure Key Vault URI。 加载项需要配置为使用密钥保管库。 |
defaultSSLCertificate.secret | 配置群集上有默认 SSL 机密的名称和命名空间。 |
defaultSSLCertificate.secret.name | 机密的名称。 |
defaultSSLCertificate.secret.namespace | 机密的命名空间。 |
常见配置
控制默认 NGINX 入口控制器配置(预览版)
注意
API 2024-06-02-preview
、Kubernetes 1.30 或更高版本,以及 aks-preview Azure CLI 扩展版本 7.0.0b5
或更高版本中提供了在启用加载项时控制 NGINX 入口控制器配置的功能。 要查看 AKS 群集版本,请参阅检查可用的 AKS 群集升级。
当启用使用 NGINX 的应用程序路由附加产品时,它会在 app-routing-namespace
中创建一个名为 default
的入口控制器,该控制器配置有面向公众的 Azure 负载均衡器。 该入口控制器使用入口类名 webapprouting.kubernetes.azure.com
。
你还可以控制默认配置是要获取公共 IP 还是内部 IP,或者是否在启用加载项时创建全新的配置。
下面是可能的配置选项:
None
:不创建默认的 Nginx 入口控制器,但如果已存在,也不会将其删除。 如果需要,用户应手动删除默认的NginxIngressController
自定义资源。Internal
:使用内部负载均衡器创建默认的 Nginx 入口控制器。 将覆盖对NginxIngressController
自定义资源进行的任何注释更改(这些更改的目的是使其成为外部资源)。External
:使用外部负载均衡器创建默认的 Nginx 入口控制器。 将覆盖对NginxIngressController
自定义资源进行的任何注释更改(这些更改的目的是使其成为内部资源)。AnnotationControlled
(默认):使用外部负载均衡器创建默认的 Nginx 入口控制器。 用户可以编辑默认的NginxIngressController
自定义资源来配置负载均衡器注释。
创建群集时控制默认入口控制器配置
若要在新群集上启用应用程序路由,请使用 [az aks create
][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 入口控制器,请执行以下操作:
将以下 YAML 清单复制到名为 nginx-public-controller.yaml 的新文件中,并将该文件保存到本地计算机。
apiVersion: approuting.kubernetes.azure.com/v1alpha1 kind: NginxIngressController metadata: name: nginx-public spec: ingressClassName: nginx-public controllerNamePrefix: nginx-public
使用
kubectl apply
命令创建 NGINX 入口控制器资源。kubectl apply -f nginx-public-controller.yaml
以下示例输出显示了已创建的资源:
nginxingresscontroller.approuting.kubernetes.azure.com/nginx-public created
创建具有专用 IP 地址的内部 NGINX 入口控制器
若要创建具有面向内部的 Azure 负载均衡器(使用专用 IP 地址)的 NGINX 入口控制器,请执行以下操作:
将以下 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"
使用
kubectl apply
命令创建 NGINX 入口控制器资源。kubectl apply -f nginx-internal-controller.yaml
以下示例输出显示了已创建的资源:
nginxingresscontroller.approuting.kubernetes.azure.com/nginx-internal created
创建具有静态 IP 地址的 NGINX 入口控制器
若要创建 Azure 负载均衡器使用静态 IP 地址的 NGINX 入口控制器,请执行以下操作:
使用
az group create
命令创建 Azure 资源组。az group create --name myNetworkResourceGroup --location chinanorth3
使用命令“
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
参数使用值 Basic。 仅基本 SKU IP 兼容基本 SKU 负载均衡器,仅标准 SKU IP 兼容标准 SKU 负载均衡器。使用
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}
将以下 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"
使用
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
在入口中使用入口控制器
将以下 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
使用
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
来访问服务。 若要配置备用后端协议(例如 HTTPS
或 GRPC
),请使用以下注释:
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