更新时间:2024-01-04 GMT+08:00

部署多个Nginx Ingress Controller

应用现状

Nginx Ingress Controller是一款业界流行的开源Ingress控制器,有着广泛的应用。在大规模集群场景下,用户有在集群中部署多套Nginx Ingress Controller的诉求,不同流量使用不同的控制器,将流量区分开。例如,集群中部分服务需要通过公网Ingress方式对外提供访问,但是又有部分对内开放的服务不允许使用公网访问,只支持对同VPC内的其他服务访问,您可以通过部署两套独立的Nginx Ingress Controller,绑定两个不同的ELB实例来满足这类需求场景。

图1 多个Nginx Ingress应用场景

解决方案

CCE提供了基于Nginx Ingress Controller的插件,但是插件不支持在同一个集群中部署多个实例。您可以通过开源Helm包在集群中部署多套Nginx Ingress Controller。

Nginx Ingress Controller启动时可以通过配置ingress-class参数来声明自己监听的 Ingress 配置类范围,其缺省值为nginx。这样在创建Ingress时可以通过选择不同的Nginx Ingress Controller进行流量区分。

前提条件

  • 已创建ELB实例。
  • 安装模板过程中,可能需要拉取公网镜像,因此节点需要绑定EIP。

约束与限制

  • 部署多个Nginx Ingress Controller时,每个Controller需要对接一个ELB,并保证对接的ELB需要拥有至少两个监听器配额,且端口80和443没有被监听器占用。如果使用独享型ELB,需要支持网络型规格。
  • 使用社区提供的nginx-ingress模板与镜像时,使用过程中对于因社区软件本身缺陷导致的业务受损CCE服务不提供额外维护。商用场景请谨慎使用

部署Nginx Ingress Controller

当您在集群中安装nginx-ingress插件时,插件会自动部署一套Nginx Ingress Controller。您可以通过以下步骤在集群中再部署一套完全独立的Nginx Ingress Controller服务。

  1. 获取模板包。

    前往社区模板发布页面,选择合适的版本并下载tgz格式的Helm Chart包。本文以社区4.4.2版本的模板包为例,该模板包适用于v1.21及以上的CCE集群。由于不同版本的模板包配置项可能存在差异,本文中的配置仅对4.4.2版本生效。

  2. 上传模板

    1. 登录CCE控制台,进入集群,在左侧导航栏中选择应用模板,在右上角单击上传模板
    2. 单击添加文件,选中待上传的模板包后,单击上传

  3. 自定义value.yaml

    您可在本地创建一个value.yaml配置文件用于设置安装工作负载参数,在安装时只需导入此配置文件进行自定义安装,其他未指定的参数将会使用默认配置。

    配置内容如下:
    controller:
      image:
        repository: registry.k8s.io/ingress-nginx/controller
        registry: ""
        image: ""
        tag: "v1.5.1"  #controller版本
        digest: ""
      ingressClassResource:
        name: ccedemo         #同一个集群中不同套Ingress Controller名称必须唯一,且不能设置为nginxcce
        controllerValue: "k8s.io/ingress-nginx-demo"  #同一个集群中不同套Ingress Controller的监听标识必须唯一,且不能设置为k8s.io/ingress-nginx
      ingressClass: ccedemo   #同一个集群中不同套Ingress Controller名称必须唯一,且不能设置为nginxcce
      service: 
        annotations: 
          kubernetes.io/elb.id: 5083f225-9bf8-48fa-9c8b-67bd9693c4c0     #ELB ID
          kubernetes.io/elb.class: performance  #仅独享型ELB需要添加此注解
      config:
        keep-alive-requests: 100
      extraVolumeMounts: # 挂载节点上的/etc/localtime文件,进行时区同步
        - name: localtime
          mountPath: /etc/localtime
          readOnly: true
      extraVolumes:
        - name: localtime
          type: Hostpath
          hostPath:
            path: /etc/localtime 
      admissionWebhooks: # 关闭webhook验证开关
        enabled: false
        patch:
          enabled: false
      resources: # 设定controller的资源限制,可根据需求自定义
        requests:
          cpu: 200m
          memory: 200Mi
    defaultBackend: # 设置defaultBackend
      enabled: true
      image: 
        repository: registry.k8s.io/defaultbackend-amd64
        registry: ""
        image: ""
        tag: "1.5"
        digest: ""

    上述参数详情请参见表1

  4. 创建模板实例。

    1. 登录CCE控制台,进入集群,在左侧导航栏中选择“应用模板”。
    2. 在已上传的模板中,单击“安装”。
    3. 填写“实例名称”,选择“命名空间”和“选择版本”。
    4. 单击“配置文件”后的“添加文件”按钮,选择本地创建的YAML配置文件,单击“安装”。
    5. 在“模板实例”页签下可以查看模板实例的安装情况。

测试验证

创建一个工作负载,配置新部署的Nginx Ingress Controller为其提供网络访问。

  1. 创建nginx工作负载。

    1. 登录CCE控制台,进入集群,在左侧导航栏中选择“工作负载”,单击右上角“YAML创建”。
    2. 填写以下内容,并单击“确定”。
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: nginx
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: nginx
        strategy:
          type: RollingUpdate
        template:
          metadata:
            labels:
              app: nginx
          spec:
            containers:
            - image: nginx    #若使用“开源镜像中心”的镜像,可直接填写镜像名称;若使用“我的镜像”中的镜像,请在SWR中获取具体镜像地址。
              imagePullPolicy: Always
              name: nginx
            imagePullSecrets:
            - name: default-secret
      ---
      apiVersion: v1
      kind: Service
      metadata:
        labels:
          app: nginx
        name: nginx
      spec:
        ports:
        - name: service0
          port: 80                 # 访问Service的端口
          protocol: TCP           # 访问Service的协议,支持TCP和UDP
          targetPort: 80           # Service访问目标容器的端口,本例中nginx镜像默认使用80端口
        selector:                  # 标签选择器,Service通过标签选择Pod,将访问Service的流量转发给Pod
          app: nginx
        type: ClusterIP            # Service的类型,ClusterIP表示在集群内访问

  2. 创建Ingress,通过新部署的Nginx Ingress Controller提供网络访问。

    1. 在左侧导航栏中选择“服务”,切换至“路由”页签,单击右上角“YAML创建”。

      对接非插件部署的Nginx Ingress Controller时,只支持使用YAML的方式创建Ingress。

    2. 填写以下内容,并单击“确定”。
      v1.23及以上版本集群:
      apiVersion: networking.k8s.io/v1 
      kind: Ingress 
      metadata: 
        name: ingress-test
        namespace: default 
      spec: 
        ingressClassName: ccedemo  # 填写新创建的nginx ingress controller的ingressClass
        rules: 
        - host: foo.bar.com
          http: 
            paths: 
            - path: / 
              pathType: ImplementationSpecific   #匹配取决于 IngressClass 
              backend: 
                service: 
                  name: nginx    #替换为您的目标服务名称
                  port: 
                    number: 80   #替换为您的目标服务端口
              property: 
                ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH  

      v1.23以下版本集群:

      apiVersion: networking.k8s.io/v1beta1
      kind: Ingress 
      metadata: 
        name: tomcat-t1 
        namespace: test 
        annotations: 
          kubernetes.io/ingress.class: ccedemo  # 填写新创建的nginx ingress controller的ingressClass
      spec: 
        rules: 
          - host: foo.bar.com
            http: 
              paths: 
                - path: / 
                  pathType: ImplementationSpecific 
                  backend: 
                    serviceName: nginx  #替换为您的目标服务名称
                    servicePort: 80     #替换为您的目标服务端口
                  property: 
                    ingress.beta.kubernetes.io/url-match-mode: STARTS_WITH

  3. 登录集群节点,分别通过集群Nginx Ingress插件中的Controller和新部署的Nginx Ingress Controller服务来访问该应用。

    • 通过新建的Nginx Ingress Controller服务来访问该应用(预期返回Nginx页面),其中192.168.114.60为新建的Nginx Ingress Controller服务对应的ELB地址。
      curl -H "Host: foo.bar.com" http://192.168.114.60

    • 通过Nginx Ingress插件中的Controller服务(预期返回404),其中192.168.9.226为Nginx Ingress插件对应的ELB地址。
      curl -H "Host: foo.bar.com" http://192.168.9.226

配置参数说明

表1 nginx-ingress主要参数配置

参数

描述

controller.image.repository

ingress-nginx镜像地址,建议与CCE提供的Nginx Ingress插件镜像一致,也可自定义。

  • Nginx Ingress插件镜像:Nginx Ingress插件的镜像地址可通过已安装插件实例的YAML文件查看。
  • 自定义:自定义地址需要保证镜像可拉取。

controller.image.registry

镜像仓库域名,该参数需要与controller.image.image同时填写。

如已填写controller.image.repository,则无需再填写该参数,建议将controller.image.registry和controller.image.image设为空值。

controller.image.image

镜像名称。该参数需要与controller.image.registry同时填写。

如已填写controller.image.repository,则无需再填写该参数,建议将controller.image.registry和controller.image.image设为空值。

controller.image.tag

ingress-nginx镜像版本,建议与CCE提供的Nginx Ingress插件镜像一致,也可自定义。

Nginx Ingress插件的镜像版本可通过已安装插件实例的YAML文件查看,需要根据插件版本进行替换。

controller.ingressClass

设置Ingress Controller所对应的IngressClass的名称。

说明:

同一个集群中不同套Ingress Controller名称必须唯一,且不能设置为nginxccenginx是集群默认Nginx Ingress Controller的监听标识,cce则是使用ELB Ingress Controller的配置)。

示例:ccedemo

controller.image.digest

建议为空值,该参数非空时可能无法拉取CCE提供的Nginx Ingress插件镜像。

controller.ingressClassResource.name

需要与ingressClass值相同。

示例:ccedemo

controller.ingressClassResource.controllerValue

同一个集群中不同套Ingress Controller的监听标识必须唯一,且不能设置为k8s.io/ingress-nginxk8s.io/ingress-nginx是默认Nginx Ingress Controller的监听标识)。

示例:k8s.io/ingress-nginx-demo

controller.config

nginx配置参数,配置参数范围请参考社区文档。不在范围内的参数配置不会生效。

建议增加如下配置:

"keep-alive-requests": "100"

controller.extraInitContainers

init容器,在主容器启动前执行,可用于Pod参数的初始化配置。

配置参数示例请参见高并发业务场景参数优化

controller.admissionWebhooks.enabled

是否开启admissionWebhooks,可以对Ingress对象进行有效性校验,避免因配置错误导致ingress-controller不断重新加载资源,导致业务中断。

此处设置为false,表示不开启。如需开启,请参见admissionWebhook配置示例。

controller.admissionWebhooks.patch.enabled

同上,表示是否开启admissionWebhooks。此处设置为false。

controller.service.annotations

Key: value类型,此处需加上ELB ID,如下所示:

kubernetes.io/elb.id: 5083f225-9bf8-48fa-9c8b-67bd9693c4c0

独享型负载均衡还需要加上elb.class,如下所示:

kubernetes.io/elb.class: performance

controller.resources.requests.cpu

Nginx controller的CPU资源申请值,可根据需求自定义。

controller.resources.requests.memory

Nginx controller的内存资源申请值,可根据需求自定义。

defaultBackend.image.repository

default-backend镜像地址,建议与CCE提供的Nginx Ingress插件镜像一致,也可自定义。

  • Nginx Ingress插件镜像:Nginx Ingress插件的镜像地址可通过已安装插件实例的YAML文件查看。
  • 自定义:自定义地址需要保证镜像可拉取。

defaultBackend.image.tag

default-backend镜像版本,建议与CCE提供的Nginx Ingress插件镜像一致,也可自定义。

更多参数配置说明请参见ingress-nginx