配置Nginx Ingress Controller的网络类型

Nginx Ingress Controller可配置为同时支持公网与私网访问、仅公网访问及仅私网访问三种模式,满足不同网络环境中客户端的访问需求。

工作原理

image

在集群中,负载均衡实例接收客户端请求并转发到Nginx Ingress Controller工作负载,工作负载会将请求转发到其他Service。

配置同时支持公网与私网Nginx Ingress

Nginx Ingress Controller的后端Pod同时部署两个Service,分别关联公网和私网类型的负载均衡实例,即可实现同时支持公网与私网访问。

  1. 查看当前负载均衡网络类型。

    kubectl describe service -n kube-system nginx-ingress-lb | grep "service.beta.kubernetes.io/alibaba-cloud-loadbalancer-address-type"

    如果输出包含intranet,则当前为私网类型;否则为公网类型。

  2. 新建一个Service,确保同时存在公网与私网两种网络类型的Service。

    创建并保存名为nginx-ingress-lb-new.yaml的文件,执行kubectl apply -f nginx-ingress-lb-new.yaml创建Service。

    新增私网类型的Service

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-ingress-lb-intranet
      namespace: kube-system
      labels:
        app: nginx-ingress-lb
      annotations:
        service.beta.kubernetes.io/alibaba-cloud-loadbalancer-address-type: intranet # 指明负载均衡实例地址类型为私网类型。
    spec:
      type: LoadBalancer
      externalTrafficPolicy: "Cluster"
      ports:
      - port: 80
        name: http
        targetPort: 80
      - port: 443
        name: https
        targetPort: 443
      selector:
        app: ingress-nginx

    新增公网类型的Service

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-ingress-lb-internet
      namespace: kube-system
      labels:
        app: nginx-ingress-lb
    spec:
      type: LoadBalancer
      externalTrafficPolicy: "Cluster"
      ports:
      - port: 80
        name: http
        targetPort: 80
      - port: 443
        name: https
        targetPort: 443
      selector:
        app: ingress-nginx
  3. 将下方命令中的<service-name>替换为新建Service名称,然后执行命令。如果返回200则表明新建Service工作正常。

    curl -s -o /dev/null -w "%{http_code}\n" http://$(kubectl get service -n kube-system <service-name> -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
  4. <service-name>替换为新建Service名称后,执行kubectl get service <service-name>,记录ServiceExternal IP,然后根据新建Service类型配置DNS:

    新建私网Service

    1. 登录云解析DNS-内网域名解析,在内网权威 > 用户域名页签下单击添加域名(Zone),如果已添加域名,请执行步骤c。

    2. 内网权威域名 (Zone)中填入域名,其他选项保持默认,然后单击确定

    3. 单击目标域名,在解析记录页签,点击添加记录,参照下方表格中的值填写表单,其余配置项保持默认,然后单击确定

      配置项

      填入值

      记录类型

      A

      主机记录

      根据需要填入子域名前缀

      记录值

      新建ServiceIP地址。

    4. 回到用户域名列表,在目标域名右侧的操作列选择生效范围设置,在生效于阿里云VPC内网选项中选择ACK集群所在的VPC,然后单击确定

    新建公网Service

    1. 登录云解析DNS-公网权威解析单击目标域名进入到解析设置页面。单击添加记录按钮

    2. 参照下方表格中的值填写表单,其余配置项保持默认,然后单击确定

      配置项

      填入值

      记录类型

      A

      主机记录

      根据需要填入子域名前缀。

      记录值

      新建ServiceIP地址。

变更网络类型

重要

此操作需要删除并重建Service替换负载均衡实例,会导致Nginx Ingress暂时中断,被删除的负载均衡实例及其对应的IP无法恢复。

  1. 确认现有负载均衡实例没有流量:

    1. 登录容器服务管理控制台。单击目标集群,然后在左侧网络 > 服务页面中,找到处于kube-system命名空间的nginx-ingress-lb,记录该Service外部 IP 地址(External IP)

    2. 登录传统型负载均衡CLB控制台,在上方选择与集群相同的地域后,找到服务地址与上一步中获取的IP地址相同的CLB实例。单击该CLB实例,在监控页签查看负载均衡实例状态,确认连接数为0,然后再执行后续操作。

  2. 删除当前Nginx Ingress Controller使用的Service。

    kubectl delete svc -n kube-system nginx-ingress-lb
  3. 创建并保存名为nginx-ingress-lb.yaml的文件,然后使用kubectl apply -f nginx-ingress-lb.yaml创建Service。

    重要

    新建Service名称必须为nginx-ingress-lb

    私网类型的Service

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-ingress-lb
      namespace: kube-system
      labels:
        app: nginx-ingress-lb
      annotations:
        service.beta.kubernetes.io/alibaba-cloud-loadbalancer-address-type: intranet # 指明负载均衡实例地址类型为私网类型。
    spec:
      type: LoadBalancer
      externalTrafficPolicy: "Cluster"
      ports:
      - port: 80
        name: http
        targetPort: 80
      - port: 443
        name: https
        targetPort: 443
      selector:
        app: ingress-nginx

    公网类型的Service

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-ingress-lb
      namespace: kube-system
      labels:
        app: nginx-ingress-lb
    spec:
      type: LoadBalancer
      externalTrafficPolicy: "Cluster"
      ports:
      - port: 80
        name: http
        targetPort: 80
      - port: 443
        name: https
        targetPort: 443
      selector:
        app: ingress-nginx
  4. 测试新建Service状态,如果返回200则表明新建Service工作正常。

    curl -s -o /dev/null -w "%{http_code}\n" http://$(kubectl get service -n kube-system nginx-ingress-lb -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
  5. 执行kubectl get service nginx-ingress-lb,记录ServiceExternal IP,然后根据新建Service类型配置DNS:

    新建私网Service

    1. 登录云解析DNS-内网域名解析,在内网权威 > 用户域名页签下单击添加域名(Zone),如果已添加域名,请执行步骤c。

    2. 内网权威域名 (Zone)中填入域名,其他选项保持默认,然后单击确定

    3. 单击目标域名,在解析记录页签,点击添加记录,参照下方表格中的值填写表单,其余配置项保持默认,然后单击确定

      配置项

      填入值

      记录类型

      A

      主机记录

      根据需要填入子域名前缀

      记录值

      新建ServiceIP地址。

    4. 回到用户域名列表,在目标域名右侧的操作列选择生效范围设置,在生效于阿里云VPC内网选项中选择ACK集群所在的VPC,然后单击确定

    新建公网Service

    1. 登录云解析DNS-公网权威解析单击目标域名进入到解析设置页面。单击添加记录按钮

    2. 参照下方表格中的值填写表单,其余配置项保持默认,然后单击确定

      配置项

      填入值

      记录类型

      A

      主机记录

      根据需要填入子域名前缀。

      记录值

      新建ServiceIP地址。

常见问题

为什么不能先新建后删除Service

变更Nginx Ingress Controller的网络类型时,无法使用新建Service后再删除旧Service的切换方式,只能在删除旧Service后创建新Service。原因是Nginx Ingress Controller组件升级时,工作负载需要使用Service默认名称(nginx-ingress-lb)进行匹配。而Service无法重名,采取新建Service后再删除旧Service的方式会导致工作负载无法匹配负载均衡实例,从而升级失败。

为什么客户端访问的IP与控制台上显示的端点不一致?

控制台Ingress页面显示的端点是指名称为nginx-ingress-lbService所属负载均衡实例IP地址。当配置多个LoadBalancer类型Service时,Nginx Ingress仍可正常转发所有请求,但控制台不会展示其他Service所属负载均衡IP。客户端实际访问的IP取决于所使用的负载均衡实例(可通过域名解析测试确认),因此可能与控制台显示的端点不一致。

如果删除了nginx-ingress-lb再重新创建同名的Service,对应的Ingress显示的端点需要更新Ingress资源后才能触发刷新。

变更类型操作失误后如何回滚?

请按顺序尽快执行:

  1. 删除新建的Service,避免因同名导致组件无法创建默认Service。

  2. 通过控制台卸载并重新安装Nginx Ingress Controller组件,这将在集群中新建一个默认Service,以恢复Nginx Ingress的入口。

  3. 配置DNS,为新的默认Service(nginx-ingress-lb)添加域名解析,然后测试转发是否正常。

相关文档

关于配置已有的负载均衡实例注释,详情请参见使用已有的负载均衡