云原生之旅 - 8)云原生时代的网关 Ingress Nginx

前言当我们在Kubernetes部署的服务需要暴露给外部用户使用时,有三种选择:LoadBalancer,NodePort,Ingress 。
LoadBalancer类型得结合各个Cloud Provider提供的LB来使用 , 如果需要暴露的service很多 , 需要很多LB以及公网IP , 比较浪费cost 。
NodePort 方式一个端口只能一个服务使用,根据端口划分服务,可用端口范围:30000~32767 ,  同样如果在暴露的servicie很多的情况下会导致节点要开的端口越来越多 , 不好管理 , 平时测试可以用用 。
Ingress是自kubernetes1.1版本后引入的资源类型,在这个资源中我们可以去配置我们的服务路由规则,但是要真正去实现识别这个 Ingress 并提供代理路由功能,还需要安装一个对应的控制器Ingress controller才能实现 。Ingress nginx controller 本质上就是kubernetes 部署的pod 里面有一个 Nginx container,只不过它能根据 Ingress 资源的定义动态生成 Nginx 的配置文件,然后动态 Reload 。可以理解成 Ingress controller是由Kubernetes管理的负载均衡器 。
Ingress controller是以一种插件的形式提供 , 有多种实现,有基于 Nginx 的,也有基于 HAProxy的,还有现在很流行的Envoy,详见:https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/,我后面文章也会介绍基于 Envoy的 Ingress controller 。
本文使用Kubernetes 社区推出的 Ingress Controller: Ingress-nginx (github.com/kubernetes/ingress-nginx) 它是基于Nginx 的扩展版 OpenResty 及诸多第三方模块构建的 , 其基于 OpenResty 的 Lua 嵌入式编程能力,扩展了 Nginx 的功能,并基于 balancer_by_lua 模块实现了 Pod 变化的动态变更功能 。
要注意区分另外一个名字相近由Nginx公司推出的Nginx ingress controller (github.com/nginxinc/kubernetes-ingress) 。Nginx 官方版本提供其基于Go语言开发的 Ingress 控制器 , 并与 Nginx 集成分为 Nginx 开源版和 Nginx Plus 版,开源版仅基于 Nginx 的原始功能,不支持 Pod 变化的动态变更 。Nginx Plus 版则提供了诸多完善的商业功能 , 其支持 Nginx 原生配置指令、JWT 验证、Pod 变化的动态配置及主动健康检查等功能 。
 关键词:Ingress nginx入门,Ingress nginx安装 , 同一集群多Ingress Nginx安装,Ingress nginx使用 安装测试环境

  • Kubernetes 1.22(GKE)
  • Ingress Nginx 1.3.0
  • Kustomize 3.10.0
安装及使用安装方式有多种,我这里介绍使用Kustomize 安装, Kustomize入门可以参考我这篇文章【云原生之旅 - 6)不能错过的一款 Kubernetes 应用编排管理神器 Kustomize】
k8s manifests 参考 my repo
根据需要修改自己所需,这里的例子是为 atlantis namespace 下面的 atlantis serivce 配置一个Ingress
由于Ingress controller 和 Ingress 均安装在dmz namespace ,  和 atlantis 不在同一个namespace下面,我们需要为atlantis serivce 加了一个 ExternalName 类型的service 相当于别名 。
这样dmz namespace 下面 Ingress 就指向 -> ExternalName 类型的service -> 指向 atlantis ns 下面  atlantis svc 。
(Optional)Ingress 和 atlantis 放在同一个namespace 下面 , 就不需要多一个 ExernalName service了 。
apiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: sre-ingress-resourceannotations:nginx.ingress.kubernetes.io/proxy-connect-timeout: "300"nginx.ingress.kubernetes.io/proxy-send-timeout: "300"nginx.ingress.kubernetes.io/proxy-read-timeout: "300"nginx.ingress.kubernetes.io/proxy-body-size: 100mnginx.ingress.kubernetes.io/proxy-buffer-size: 512knginx.ingress.kubernetes.io/client-body-buffer-size: 512kingress.kubernetes.io/ssl-redirect: "true"ingress.kubernetes.io/force-ssl-redirect: "true"spec:ingressClassName: nginxrules:- host: atlantis-demo.wadexu.cloudhttp:paths:- path: /pathType: Prefixbackend:service:name: atlantis-demo-ext-svcport:number: 8080tls:- hosts:- atlantis-demo.wadexu.cloudsecretName: wade-tls-secret---apiVersion: v1kind: Servicemetadata:name:atlantis-demo-ext-svcspec:type: ExternalNameexternalName: atlantis.atlantis.svc.cluster.localports:- name: httpport: 8080targetPort: 4141protocol: TCP因为用了 https ,所以需要一个tls-secret
kubectl create secret -n dmz tls wade-tls-secret \--key ./xxx.key \--cert ./xxx.pembuild and apply
kustomize build ingress-nginx-public/sre-mgmt-dev/ > ~/deploy.yamlkubectl apply -f ~/deploy.yaml多个 Ingress Nginx Controller 部署同一个cluster 如果要安装另一个ingress nginx controller,比如作为内部API网关,该怎么实现呢?
为了避免多个ingress controller 以一种困惑的方式同时争抢更新 ingress status字段 , 需要使用IngressClasses 官方文档

推荐阅读