创建并使用Nginx Ingress对外暴露服务

Nginx Ingress作为ACK托管集群中的流量入口网关,通过灵活的路由规则将外部请求精确转发至内部服务。配合使用HTTPS安全加密、灰度发布、通过注解自定义配置等能力,Nginx Ingress可以满足安全、高可用、可扩展的L7层网络访问需求。

重要

因传统型负载均衡CLB按规格计费停止售卖,容器服务 Kubernetes 版20250828日起,通过控制台新安装Nginx Ingress Controller时,将默认使用NLB实例,CLB实例转为白名单开放;对于仍需创建CLB的场景,将默认使用按使用量计费模式。详细内容,请参见【产品变更】关于新建ServiceNginx Ingress Controller默认负载均衡类型与计费方式变更的公告

注意事项

  • 请勿删除Nginx Ingress Controller默认使用的服务。安装组件后将默认创建kube-system命名空间下的nginx-ingress-lb服务,将其删除将会导致组件运行不稳定,严重时会出现崩溃。

  • 请通过组件管理或者OpenAPI方式配置组件的自定义参数。通过其他渠道修改组件配置可能会导致组件功能异常,且会影响组件后续的升级过程。

  • 请优先使用Nginx Ingress配置词典来实现所需功能。若使用SnippetLua代码等方式对组件进行额外配置,所出现的与预期功能不符等问题无法得到技术支持。

  • 请及时升级Nginx Ingress Controller组件,以避免上游社区版组件的Bug或漏洞导致您的业务受损。

前提条件

  • 已安装Nginx Ingress Controller组件。安装完成后,组件将关联一个传统型负载均衡 CLB实例作为Nginx Ingress的流量入口。

    创建集群时安装

    1. 选择组件

    1. 登录容器服务管理控制台,单击创建集群

    2. 组件配置阶段的Ingress参数配置区域,选择安装Nginx Ingress

    image

    2. 选择负载均衡来源

    • 新建:在集群VPC内自动创建一个按规格计费对应实例规格的多可用区公网/私网CLB实例。

    • 使用已有:可选与集群同地域的、未被其他集群关联的公网CLB实例,以及与集群同VPC的、未被其他集群关联的私网CLB实例。

    image

    通过组件管理安装和配置

    通过组件管理安装,将自动创建一个按规格计费简约型I(slb.s1.small)的公网CLB实例,作为Nginx Ingress的流量入口。

    1. 选择和配置组件

    1. 登录容器服务管理控制台,在左侧导航栏选择集群列表

    2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,单击组件管理

    3. 通过搜索栏或者网络页签找到组件,在Nginx Ingress Controller组件卡片的右下角,单击安装

    4. 安装组件 Nginx Ingress Controller对话框,配置相关参数,然后单击确认完成安装。

    image

  • 获取集群KubeConfig并通过kubectl工具连接集群

  • 注册域名,并完成ICP备案

  • 购买正式证书个人测试证书,并完成申请证书,确认待使用的证书处于已签发状态。

创建示例应用

示例应用将部署两个名称分别为coffeetea的无状态工作负载(Deployment)以及对应的coffee-svctea-svc服务(Service)。

控制台

1. 创建资源

  1. 登录容器服务管理控制台,在左侧导航栏选择集群列表

  2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择工作负载 > 无状态

  3. 单击使用YAML创建资源示例模板选择自定义。然后将以下内容复制到模板区域,单击创建

image

示例应用YAML

apiVersion: apps/v1
kind: Deployment
metadata:
  name: coffee
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: coffee
  template:
    metadata:
      labels:
        app: coffee
    spec:
      containers:
      - name: coffee
        image: registry.cn-hangzhou.aliyuncs.com/acs-sample/nginxdemos:latest
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: coffee-svc
  namespace: default
spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
  selector:
    app: coffee
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tea
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: tea
  template:
    metadata:
      labels:
        app: tea
    spec:
      containers:
      - name: tea
        image: registry.cn-hangzhou.aliyuncs.com/acs-sample/nginxdemos:latest
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: tea-svc
  namespace: default
spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
  selector:
    app: tea
  type: ClusterIP

2. 查看创建结果

Yaml 资源创建结果弹窗中,单击资源右侧操作列中的查看,确认创建结果。 

image

kubectl

  1. 使用以下内容,创建test-deployment-service.yaml文件。

    YAML文件示例

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: coffee
      namespace: default
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: coffee
      template:
        metadata:
          labels:
            app: coffee
        spec:
          containers:
          - name: coffee
            image: registry.cn-hangzhou.aliyuncs.com/acs-sample/nginxdemos:latest
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: coffee-svc
      namespace: default
    spec:
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: coffee
      type: ClusterIP
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: tea
      namespace: default
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: tea
      template:
        metadata:
          labels:
            app: tea
        spec:
          containers:
          - name: tea
            image: registry.cn-hangzhou.aliyuncs.com/acs-sample/nginxdemos:latest
            ports:
            - containerPort: 80
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: tea-svc
      namespace: default
    spec:
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        app: tea
      type: ClusterIP
  2. 执行以下命令,创建DeploymentService。

    kubectl apply -f test-deployment-service.yaml
  3. 执行以下命令,查看coffeetea的创建进度。

    kubectl get deployment coffee tea

    预期输出:

    NAME     READY   UP-TO-DATE   AVAILABLE   AGE
    coffee   2/2     2            2           14m
    tea      2/2     2            2           14m
  4. 执行以下命令,查看coffee-svctea-svc服务。

    kubectl get service coffee-svc tea-svc

    预期输出:

    NAME         TYPE        CLUSTER-IP        EXTERNAL-IP   PORT(S)   AGE
    coffee-svc   ClusterIP   192.168.xxx.xxx   <none>        80/TCP    15m
    tea-svc      ClusterIP   192.168.xxx.xxx   <none>        80/TCP    15m

创建Nginx Ingress

以下示例的规则(rules)中的域名(host)以test-nginx-ingress.com为例,请替换为实际注册域名;规则中的路径映射(paths)以创建示例应用为例,请按实际情况修改。

控制台

1. 创建资源

  1. 登录容器服务管理控制台,在左侧导航栏选择集群列表

  2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择网络 > 路由选择default命名空间后,然后单击创建 Ingress,参考以下示例进行配置。

    • 网关类型Nginx Ingress

    • 名称test-nginx-ingress

    • 域名test-nginx-ingress.com(请替换为实际注册域名)

    • 路径映射

      • 路径/coffee

      • 匹配规则默认(ImplementationSpecific)

      • 服务名称coffee-svc

      • 端口80

  3. 继续单击+添加路径,配置tea-svc服务的路由。

    • 路径映射

      • 路径/tea

      • 匹配规则默认(ImplementationSpecific)

      • 服务名称tea-svc

      • 端口80

  4. 参考以上步骤,继续单击+添加规则,添加www.test-nginx-ingress.com(请替换为实际注册域名)和对应的路径映射,完成后单击确定

image

2. 获取访问地址

创建完成后,等待约1分钟,然后单击右上角刷新按钮。若端点显示对应的弹性公网IP(即关联公网CLB实例的服务地址),说明Nginx Ingress已创建成功。

若长时间未更新端点信息,您可单击路由名称,进入事件页签,进行异常排查。

image

kubectl

  1. 使用以下内容,创建test-ingress.yaml文件。

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: test-nginx-ingress
      namespace: default
    spec:
      ingressClassName: nginx
      rules:
      - host: test-nginx-ingress.com # 请替换为实际注册域名
        http:
          paths:
          - path: /coffee
            backend:
              service: 
                name: coffee-svc
                port:
                  number: 80
            pathType: ImplementationSpecific
          - path: /tea
            backend:
              service: 
                name: tea-svc
                port:
                  number: 80
            pathType: ImplementationSpecific
      - host: www.test-nginx-ingress.com # 请替换为实际注册域名
        http:
          paths:
          - path: /coffee
            backend:
              service: 
                name: coffee-svc
                port:
                  number: 80
            pathType: ImplementationSpecific
          - path: /tea
            backend:
              service: 
                name: tea-svc
                port:
                  number: 80
            pathType: ImplementationSpecific

    重点参数说明:

    • name:Ingress的名称。本示例为test-nginx-ingress

    • host:指定服务访问域名。本示例为test-nginx-ingress.com,请替换为实际注册域名。

    • path:指定访问的URL路径。CLB将流量转发到backend之前,所有的入站请求都要先匹配hostpath。本示例为/coffee/tea

    • backend:由服务名称和服务端口组成。

      • 服务名称:Ingress转发的backend服务名称。本示例为coffee-svctea-svc

      • 服务端口:服务暴露的端口。本示例为80

  2. 执行以下命令,创建Ingress。

    kubectl apply -f test-ingress.yaml
  3. 执行以下命令,查看Ingress并获取弹性公网IP,如8.xxx.xxx.117

    kubectl get ingress

    预期输出:

    NAME                 CLASS   HOSTS                                               ADDRESS         PORTS   AGE
    test-nginx-ingress   nginx   test-nginx-ingress.com,www.test-nginx-ingress.com   8.xxx.xxx.117   80      2m39s
  4. 执行以下命令,请使用实际获取的弹性公网IP,验证Nginx Ingress是否生效。

    curl http://8.xxx.xxx.117/coffee -H "Host: test-nginx-ingress.com"

    预期输出:

    ...
    <title>Hello World</title>
    ...
    <p><span>Server&nbsp;address:</span> <span>10.xxx.xxx.19:80</span></p>
    <p><span>Server&nbsp;name:</span> <span>coffee-96d4bc87-l29dh</span></p>
    <p class="smaller"><span>Date:</span> <span>08/Aug/2025:02:21:02 +0000</span></p>
    <p class="smaller"><span>URI:</span> <span>/coffee</span></p>
    ...
        <div id="footer">
            <div id="center" align="center">
                Request ID: 42e2d73c85b16b55b6ab52deb7d995d4<br/>
                &copy; NGINX, Inc. 2018
            </div>
        </div>
    ...

配置域名解析

添加域名的操作仅适用于非阿里云注册域名。若通过阿里云域名注册购买的域名,会自动同步到DNS公网权威解析列表,可直接添加解析记录。

1. 添加域名

  1. 访问云解析DNS-公网权威解析

    权威域名解析 页面中,单击 添加域名

  2. 添加域名对话框中,输入表单内容。

    支持添加主域名或子域:输入您需要设置解析的三方域名。

    绑定实例:选择已经创建的实例(若无,请购买实例),您也可选择免费版(但不承诺可用性、无中国境外解析节点,不建议用于正式业务,适用于产品功能体验)。

image

2. 添加解析记录

  1. 找到目标域名,单击右侧操作列的解析设置。然后单击添加记录,添加一个记录类型为A记录、主机记录为@的解析记录,其中的记录值Nginx Ingress的访问地址

  2. 按照前面的步骤,再添加一个主机记录为www的解析记录。

  3. 单击刚刚创建的解析记录后的生效检测,查看解析结果。

更多详细内容,请参见添加网站解析

image

3. 验证域名和路径生效

在浏览器中访问http://test-nginx-ingress.com/coffee(请替换为实际注册域名),验证通过域名访问业务路径生效。

您还可参考解析生效测试方法进行确认,如发现解析不生效,可参考解析不生效问题快速排查

image

配置HTTPS安全加密(TLS配置)

请先完成前提条件中购买和申请证书的步骤,然后参考以下步骤下载证书并添加TLS配置,从而实现通过HTTPS加密通信的方式访问域名。

控制台

1. 下载证书

  1. 登录数字证书管理服务控制台在左侧导航栏,选择证书管理 > SSL证书管理

  2. 正式证书个人测试证书(原免费证书)页签,选中需要下载的证书,在证书列表左下方单击下载

  3. 在弹出的对话框,选择Nginx服务器类型下载证书包并解压。

更多详细内容,请参见下载SSL证书

image

2. 创建保密字典

  1. 登录容器服务管理控制台,在左侧导航栏选择集群列表

  2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择配置管理 > 保密字典

  3. 保密字典页面,选择default命名空间后,单击左侧创建,在弹出面板中配置新的保密字典。配置完成后,单击确定

    • 名称nginx-ingress-tls

    • 类型TLS证书

    • 证书:已下载并解压的证书文件(.pem)中的完整内容

    • 密钥:已下载并解压的证书私钥文件(.key)中的完整内容

image

3. 添加TLS配置

  1. 然后在左侧导航栏,选择网络 > 路由。在目标路由右侧操作栏中,单击更新

  2. 编辑Ingress页面中,添加以下TLS配置后,单击确定

    • TLS配置:开启

    • 域名test-nginx-ingress.com(请替换为实际注册域名)

    • 保密字典nginx-ingress-tls

image

4. 验证HTTPS访问

在浏览器中访问https://test-nginx-ingress.com/coffee(请替换为实际注册域名),验证通过HTTPS加密通信的方式访问域名及业务路径生效。

image

kubectl

  1. 登录数字证书管理服务控制台在左侧导航栏,选择证书管理 > SSL证书管理

  2. 正式证书个人测试证书(原免费证书)页签,选中需要下载的证书,在证书列表左下方单击下载

  3. 在弹出的对话框,选择Nginx服务器类型下载证书包并解压。

  4. 执行以下命令,使用已下载的证书文件(.pem)和证书私钥文件(.key)创建保密字典。

    kubectl create secret tls nginx-ingress-tls --cert test-nginx-ingress.com.pem --key test-nginx-ingress.com.key -n default
  5. 执行以下命令,为test-nginx-ingress路由添加TLS配置。请将命令中的test-nginx-ingress.com替换为实际注册域名。

    kubectl patch ingress test-nginx-ingress -p '{"spec":{"tls":[{"hosts":["test-nginx-ingress.com"],"secretName":"nginx-ingress-tls"}]}}'
  6. 执行以下命令,请使用实际的弹性公网IP,验证通过HTTPS加密通信的方式访问域名及业务路径生效。

    curl -v -k https://8.xxx.xxx.117/coffee -H "Host: test-nginx-ingress.com"
    • 参数说明:

      • -v:显示详细的通信过程,包括TLS握手信息等。

      • -k(或 --insecure):若使用自签名证书可以忽略证书验证。

    • 预期输出:

      ...
      *   Trying 8.xxx.xxx.117:443...
      * Connected to 8.xxx.xxx.117 (8.xxx.xxx.117) port 443
      * ALPN: curl offers h2,http/1.1
      * (304) (OUT), TLS handshake, Client hello (1):
      * (304) (IN), TLS handshake, Server hello (2):
      * (304) (IN), TLS handshake, Unknown (8):
      * (304) (IN), TLS handshake, Certificate (11):
      * (304) (IN), TLS handshake, CERT verify (15):
      * (304) (IN), TLS handshake, Finished (20):
      * (304) (OUT), TLS handshake, Finished (20):
      ...
      <title>Hello World</title>
      ...
      <p><span>Server&nbsp;address:</span> <span>10.xxx.xxx.159:80</span></p>
      <p><span>Server&nbsp;name:</span> <span>coffee-96d4bc87-6cstv</span></p>
      <p class="smaller"><span>Date:</span> <span>14/Aug/2025:09:27:42 +0000</span></p>
      <p class="smaller"><span>URI:</span> <span>/coffee</span></p>
      ...
          <div id="footer">
              <div id="center" align="center">
                  Request ID: fee5fe107106748a35d99a2dbbbc6652<br/>
                  &copy; NGINX, Inc. 2018
              </div>
          </div>
      ...

更多配置

灰度发布

当对服务进行版本更新升级时,需要使用到滚动升级、分批暂停发布、蓝绿发布以及灰度发布等发布方式。详细操作,请参见通过Nginx Ingress实现灰度发布和蓝绿发布

后端服务协议

指定后端服务的协议,设置后会添加注解nginx.ingress.kubernetes.io/backend-protocol。支持HTTP、HTTPS、gRPC、gRPCS四种服务协议。配置示例,请参见Nginx Ingress Controller后端部署gRPC服务

重写路径

当您在使用Nginx Ingress Controller的时候,Nginx会将路径完整转发到后端(如,从Ingress访问的/service1/api路径会直接转发到后端Pod/service1/api/路径)。如果您后端的服务路径为/api,则会出现路径错误,导致404的情况。该情况下,您可以通过配置nginx.ingress.kubernetes.io/rewrite-target的方式,来将路径重写至需要的目录。

详细操作,请参见配置URL重定向的路由服务

添加注解

Nginx Ingress支持通过添加注释(Annotations)来启用更多功能。详细操作,请参见Nginx Ingress配置词典Nginx Ingress高级用法

可观测性

在创建集群时启用日志服务,然后在阿里云日志服务SLS查看Nginx Ingress的访问日志分析报表和监控Nginx Ingress实时状态。相关内容,请参见Nginx Ingress访问日志分析与监控

高负载场景

关于如何提升Nginx Ingress Controller高负载场景下的性能和稳定性,请参见配置高负载场景的Nginx Ingress ControllerNginx Ingress Controller使用建议

常见问题

为什么从集群内访问集群LoadBalancer的外部地址不通?

问题现象

集群中有部分节点下的Pod通过Nginx Ingress Controller外部地址(负载均衡实例IP地址)无法访问后端Pod,有部分能够访问。

问题原因

该问题由Controller所属ServiceexternalTrafficPolicy配置导致,该配置决定了外部流量的处理规则:当设置为local时,仅有与Controller所属Pod处于同一节点的后端Pod可以成功接收请求;当设置为cluster时,则可以正常访问。而集群中的资源使用LoadBalancer的外部地址访问时,请求也会被作为外部流量处理。

解决方案

  • (推荐)在Kubernetes集群内通过Nginx IngressClusterIP或者服务名访问,其中Nginx Ingress的服务名为nginx-ingress-lb.kube-system

  • 执行kubectl edit svc nginx-ingress-lb -n kube-system命令,修改Nginx Ingress的服务。将LoadBalancerServiceexternalTrafficPolicy修改为Cluster。如果集群容器网络插件为Flannel,请求会丢失客户端源IP,如果使用Terway则可保留源IP。

    示例如下:

    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        service.beta.kubernetes.io/backend-type: eni   # 直通ENI。
      labels:
        app: nginx-ingress-lb
      name: nginx-ingress-lb
      namespace: kube-system
    spec:
      externalTrafficPolicy: Cluster

关于ServiceAnnotation的更多信息,请参见通过Annotation配置传统型负载均衡CLB

如何支持客户端Header或者Cookie过大的请求?

若客户端请求Header或者Cookie过大,访问Nginx Ingress时遇到报错信息类似"400 Request Header Or Cookie Too Large /Bad request"时,您需要调整相关buffer size 配置。具体有如下两个配置参数:

您可通过执行kubectl edit cm -n kube-system nginx-configuration编辑ConfigMap并修改这两个配置参数。例如:

client-header-buffer-size: "16k"
large-client-header-buffers: "4 32k" 

配置完之后,请确认配置在Nginx数据面是否生效。您可通过执行kubectl exec <nginx-ingress-pod> -n kube-system -- cat /etc/nginx/nginx.conf | vim -查看nginx.conf配置,确认是否与ConfigMap中的修改同步。

Nginx Ingress如何配置跨域?

通过在Ingress资源的metadata.annotations部分添加指定注解来实现跨域。更多内容,请参见Nginx Ingress跨域配置说明

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: default
  annotations:
    nginx.ingress.kubernetes.io/enable-cors: "true"     # 启用CORS。
    nginx.ingress.kubernetes.io/cors-allow-origin: "*"  # 允许所有域访问。
    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, PATCH, OPTIONS"  # 允许的HTTP方法。
     # 允许的自定义请求头。
    nginx.ingress.kubernetes.io/cors-allow-headers: "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range" 
    nginx.ingress.kubernetes.io/cors-expose-headers: "Content-Length,Content-Range"  # 暴露的响应头。
    nginx.ingress.kubernetes.io/cors-max-age: "86400"  # 预检请求缓存时间。
spec:
  ingressClassName: nginx
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: example-service
            port:
              number: 80

如何配置透传客户端IP?

Nginx Ingress默认会通过X-Forwarded-ForX-Real-IP来透传客户端IP,但是当客户端主动在请求头里指定了X-Forwarded-ForX-Real-IP时,会导致服务端无法获取到真实的客户端IP。

您可以执行kubectl edit cm -n kube-system nginx-configuration命令在ConfigMap中添加配置,以实现Ingress L7透传客户端IP。关于透传客户端IPIPv6场景,请参见透传客户端IPv6IP地址

compute-full-forwarded-for: "true"
forwarded-for-header: "X-Forwarded-For"
use-forwarded-headers: "true"

如果在Nginx Ingress之前有多层代理,您需要根据proxy-real-ip-cidr参数对配置进行调整,将前置代理的IP地址以CIDR格式添加到proxy-real-ip-cidr中,多个CIDR之间用逗号分隔。详细信息请参见使用WAF

proxy-real-ip-cidr:  "0.0.0.0/0,::/0"  

IPv6场景下,如果Nginx Ingress收到的X-Forwarded-For头为空,并且前置有CLB可以启用CLB 的Proxy Protocol来获取客户端IP。关于Proxy Protocol详细信息,请参见后端服务器通过CLB四层监听获取客户端真实IP

相关文档