ingress是一种能够暴露k8s集群内部service的方式,用户编辑配置文件定义一个ingress资源便可实现外部网络访问内网service。
ingress controller是来管理全部的Ingress的对象,ingress controller内部实际上是一个nginx的容器,当ingress controll 经过与 Kubernetes API 交互,感知集群中Ingress规则变化时会按照模板文件生成nginx.conf文件,而后reload该配置文件。
相对于kubernetes经过nodePort方式暴露服务来讲,ingress controller能够提供更加高级的特性,尤为对于HTTP服务来讲,他能够实现负载均衡,SSL,虚拟主机等,而且ingress是直接将数据包转发至pod,不会在通过kube-proxy,更加高效。node
用户能够参照官方文档Deployment 进行环境搭建。nginx
通过上面的几步就能够在集群外访问该service了, 可是访问的时候注意ingress controller内部实际上是一个nginx服务器,它也是经过配置文件中的虚拟主机server_name来分辨该转发到后端哪一个service上的,对于http请求必须在请求的header中加上Host字段,因此若是没有配置DNS域名解析,在浏览器里访问时能够修改/etc/hosts文件,也能够用curl -H "Host: xxxxx.com" nodeIp来实现。
对于须要自定义default-backend的同窗能够根据Custom errors 自定义后端的实现,git
上面讲到当咱们建立ingress的时候,Ingress controller会进行relaod,这期间nginx须要替换nginx worker进程, 这将致使服务出现短暂的异常。使用Jmeter进行分布式压测一个服务中,观察到的状况是qps无影响,可是会出现0.01%的错误返回结果,在一些小并发的状况下这能够接收,可是若是是高并发的场景,而且后端服务的service ingress对象较多,此时reload的也会比较频繁,对于一些服务是没法接受的。
有一个解决方式就是在集群里里定义多个Ingress controller对象,而后根据ingress的状况分别注册到不一样的ingress controller之上,这样就能够实现分组的概念,一个组里添加ingress不会致使另外一个组进行reload, 使用时须要在ingress controller 的yaml定义文件中指定--ingress-class选项,而后在Ingress 的yaml 定义文件中添加 annotation : kubernetes.io/ingress.class 关联对应的controll class。
注意若是是在同一台主机之上启动多个ingress controller则须要改变默认配置的端口号,不然会发生端口冲突,须要在镜像的启动参数中添加 --http-port,--https-port, --status-port, --healthz-port这几个选项来改变端口。github
nginx是个功能强大的负载均衡,反向代理服务器,若是仅仅经过默认的模板生成的nginx.conf文件可能不能知足咱们的需求,而且可能存在坑,因此须要自定义配置的话能够经过三种方式实现:后端
nginx支持四层代理,引用到ingress中也一样支持,表现形式与nodePort差很少,都须要在主机上开放一个端口,可是支持一些Nginx的功能,感受比较鸡肋,参见Exposing TCP and UDP services, 实现方式是经过一个configMap 来指定主机端口和内网service的对应关系。api
2019/6/26 update: ingress controller支持四层,可是不太友好,经过一个configmap进行配置。一样存在reload ingress的时候会断开全部的链接,对于长链接来讲彷佛难以接受。浏览器