本文介绍如何在阿里云容器服务Kubernetes集群中同时部署多套独立的Nginx Ingress Controller,以对外提供不同的服务访问。
背景信息
您可以通过配置公网和私网类型的Nginx Ingress Controller来调整ACK集群中默认的Nginx Ingress Controller配置,以使用私网SLB实例。文中提到的两种模式可以满足大部分需求场景,但对于一些特殊场景,如集群内有部分公网服务需要通过公网Ingress方式来对外暴露提供访问,但是有部分私网服务只希望对同VPC内非集群内的服务提供访问,而又不允许能被公网访问到,您可以通过部署两套独立的Nginx Ingress Controller服务,其前端绑定不同网络类型的SLB实例来满足这类需求场景。
注意事项
以下是有关在配置多套 Ingress Controller 时的注意事项,包括配置唯一的IngressClass和Service名称长度限制。
- 配置唯一的 IngressClass - 在使用多套 Ingress Controller 时,为确保正常运行并避免冲突,需为每个Controller配置唯一的IngressClass。您需要修改以下参数: - controller.ingressClassResource.name:为每个Ingress Controller设置独特的名称。 
- controller.ingressClassResource.controllerValue:为每个Ingress Controller指定独特的标识符。 
 
- Service名称长度限制 - 在部署 - ack-ingress-nginx-v1Helm应用时,若使用- ack-ingress-nginx-v1作为应用名,自动创建的Service名称格式为- <应用名称>-ack-ingress-nginx-v1-controller。对于- internal类型的LoadBalancer Service,其名称为- <应用名称>-ack-ingress-nginx-v1-controller-internal。请确保这些名称的长度不超过63个字符,否则可能导致资源创建失败,并显示以下错误信息:- no service with name xxx-open-api-test-inter-ack-ingress-nginx-v1-controller-internal found in namespace open-api-test-inter: services "xxx-open-api-test-inter-ack-ingress-nginx-v1-controller-internal" not found ,- 如遇此错误,请检查并缩短Helm应用名称后重新部署。 
部署新的Nginx Ingress Controller服务
当您成功创建一个ACK集群后,默认情况下,集群内部已经部署了一套拥有2个Pod副本的Nginx Ingress Controller服务,其前端挂载在一个公网SLB实例上。
您可以通过以下步骤在ACK集群中再部署一套完全独立的Nginx Ingress Controller服务。
- 登录容器服务管理控制台,在左侧导航栏选择集群列表。 
- 在集群列表页面,单击目标集群名称,然后在左侧导航栏,选择。 
- 在Helm页面,单击创建。参考如下信息完成基本信息配置。 - 参数 - 示例值 - 应用名 - ack-ingress-nginx 说明- 您可自定义,并注意其Service名称长度限制。 - 命名空间 - kube-system - 来源 - 默认为应用市场 - Chart - 应用场景:选择全部。 
- 支持架构:选择amd64。 
- 搜索框:搜索ack-ingress-nginx。 - 1.20及以下集群选中ack-ingress-nginx。 
- 1.22及以上集群选中ack-ingress-nginx-v1。 
 
 - 选择集群版本对应的Chart名称,单击下一步。 
- 在参数配置页面,选择Chart 版本,然后单击确定。 说明- Chart版本4.0.17(对应组件版本v1.8.0-aliyun.1)及以上的ack-ingress-nginx-v1仅支持1.22及以上版本集群。若您的集群版本为1.20,需要选择4.0.16版本(对应组件版本v1.2.1-aliyun.1)进行部署。 - ack-ingress-nginx-v1主要参数如下表。 - 参数 - 描述 - controller.image.repository - ingress-nginx镜像地址。 - controller.image.tag - ingress-nginx镜像版本,请参见Nginx Ingress Controller。 - controller.ingressClassResource.name - 设置Ingress Controller所对应的IngressClass的名称。 重要- 该参数作为1.22以下版本模板中controller.ingressClass参数的替代,可以在kubernetes.io/ingress.class注解中正常使用。同一个集群中不同套Ingress Controller创建的IngressClass名称必须唯一,且不能设置为nginx关键字(nginx是集群默认Ingress Controller的监听标识)。 - controller.ingressClassResource.controllerValue - 设置Ingress Controller所对应的Controller Class。 重要- 同一个集群中不同套Ingress Controller创建的Controller Class必须唯一,且不能设置为k8s.io/ingress-nginx关键字(k8s.io/ingress-nginx是集群默认Ingress Controller的监听标识)。 - controller.replicaCount - 设置该Ingress Controller Pod的副本数。 - controller.service.enabled - 是否启用SLB访问(包括公网和私网)。 - controller.service.external.enabled - 是否开启公网SLB访问,不需要开启则设置为false。 - controller.service.internal.enabled - 是否开启私网SLB访问,需要开启则设置为true。 - controller.kind - 设置IngressController部署形态,可选值:Deployment和DaemonSet。 - controller.electionID - 选主时使用的ID,用于更新Ingress端点状态。 重要- 若通过应用市场部署多套Nginx Ingress Controller至同一命名空间下,需要将electionID设置为不同的值,避免选主冲突。 - controller.metrics.enabled - 是否开启ingress-nginx的metrics。 - controller.metrics.serviceMonitor.enabled - 是否开启serviceMonitor,配置抓取规则。 说明- 建议开启ingress-nginx的metrics后,同时开启此选项,以此来自动配置Prometheus的抓取规则。 - controller.service.internal.loadBalancerClass- Service使用传统型负载均衡 CLB或网络型负载均衡 NLB。 - "alibabacloud.com/clb":使用CLB。
- "alibabacloud.com/nlb":使用NLB。
 - 不填入值时,使用CLB。 
- 查看部署的Nginx Ingress Controller服务。 - 返回在Helm页面,可以看到新的Nginx Ingress Controller服务已经成功部署。 
访问测试
本文部署一个测试应用,并配置通过新部署的Nginx Ingress Controller来对外暴露服务访问。
- 部署一个Nginx测试应用。 - apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: replicas: 1 selector: matchLabels: run: nginx template: metadata: labels: run: nginx spec: containers: - image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 imagePullPolicy: Always name: nginx ports: - containerPort: 80 protocol: TCP restartPolicy: Always --- apiVersion: v1 kind: Service metadata: name: nginx spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: run: nginx sessionAffinity: None type: NodePort
- 通过Ingress来对外暴露提供服务访问。 - apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx spec: # 注意这里要设置为您前面配置的INGRESS_CLASS。 ingressClassName: "<YOUR_INGRESS_CLASS>" rules: - host: foo.bar.com http: paths: - path: / backend: service: name: nginx port: number: 80 pathType: ImplementationSpecific说明- 您需要配置注释 - kubernetes.io/spec.ingressClassName。- 在完成部署应用后,执行以下操作,查看该Ingress资源对应的端点IP地址与新部署的Nginx Ingress Controller服务的IP地址。 - 执行以下命令查看集群默认部署的nginx-ingress-lb服务对应的公网SLB地址。 - kubectl -n kube-system get svc nginx-ingress-lb- 预期输出: - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-ingress-lb LoadBalancer 172.19.XX.XX 192.0.XX.XX 80:31429/TCP,443:32553/TCP 2d
- 执行以下命令查看新部署的nginx-ingress-lb服务对应的公网SLB地址。 - kubectl -n <YOUR_NAMESPACE> get svc nginx-ingress-lb- 预期输出: - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-ingress-lb LoadBalancer 172.19.XX.XX 198.51.XX.XX 80:30969/TCP,443:31325/TCP 39m
- 执行以下命令查看该应用的Ingress配置。 - kubectl get ing- 预期输出: - NAME HOSTS ADDRESS PORTS AGE nginx foo.bar.com 198.51.XX.XX 80 5m
 - 通过以上预期输出可得,该Ingress资源对应的端点IP地址与新部署的Nginx Ingress Controller服务的一致。 
- 分别通过集群默认的Nginx Ingress Controller服务和新部署的Nginx Ingress Controller服务来访问该应用。 - curl -H "Host: foo.bar.com" http://192.0.XX.XX- 预期输出: - <html> <head><title>404 Not Found</title></head> <body> <center><h1>404 Not Found</h1></center> <hr><center>nginx</center> </body> </html>- 通过新部署的服务访问: - curl -H "Host: foo.bar.com" http://198.51.XX.XX- 预期输出: - <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
从上文测试访问情况可以看到,通过不同的Nginx Ingress Controller暴露的服务彼此完全是独立的,这特别适用于同一集群内部分服务需要提供公网访问能力,但又有部分服务仅仅希望为同VPC内非Kubernetes集群的其他服务提供访问的场景。