kubernetes集群内的服务, 在集群外是无法访问的, 想访问的话, 必须通过一种方式将请求代理进集群内部, ingress就是最为常用的手段, ingress也有许多开源方案,这里以ingress-nginx为例.Nginx Ingress 也是本人最常用集群外对访问方式.
首先会将nginx ingress部署到集群中,然后会聊了聊它的使用方式.
原理
Nginx ingress 本质上就是nginx+Lua, 所以使用过nginx的,其实对它的原理一看就明白.
首先看一下Nginx 的 反向代理模式
在 k8s 系统中,后端服务的变化是十分频繁的,单纯依靠人工来更新nginx 的配置文件几乎不可能,nginx-ingress 由此应运而生。Nginx-ingress 通过监视 k8s 的资源状态变化实现对 nginx 配置文件的自动更新
同样一看便知, 对于使用nginx ingress来说,知道它是怎么样的工作方式感觉就可以了,源码之类的其实没必要过多去解读.
总结 : Ingress-nginx分为3部分:
- nginx-ingress-controller: 通过与 Kubernetes API 交互,动态的去感知集群中 Ingress 规则变化,然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段 Nginx 配置,再写到 Nginx-ingress-control的 Pod 里,这个 Ingress Contronler 的pod里面运行着一个nginx服务,控制器会把生成的nginx配置写入/etc/nginx.conf文件中,然后 reload 一下 使用配置生效。以此来达到动态更新问题
- Nginx: 反向代理服务
- Ingress: ingress资源对象
部署
DaemonSet
1 | apiVersion: extensions/v1beta1 |
Default http backend
在新版的nginx ingress中,强制需要部署一个默认的后端, 用于处理无法匹配上的请求,就是一个nginx即可.
1 | apiVersion: v1 |
Ingress Rule
1 | apiVersion: extensions/v1beta1 |
规则使用还是比较清晰的, 一看就明白, ingress支持很多个域名, 最终都会转换成nginx里的server的标准配置.
最后将上述资源apply 到集群中即可.
支持TCP/UDP
其实在Nginx 1.9之后的版本就已经支持了TCP转发了, 因此Nginx Ingress默认也是可以直接使用TCP转发的, 使用了Nginx Ingress这么久,从来都没有关注过这个点
查看了官方文档,使用也比较简单
首先,需要在nginx ingress controller 的daemonset中容器的启动参数增加对TCP/UDP的配置
1 | spec: |
--tcp-services-configmap
指定包含tcp的规则的cm, tcp-services这个名字也可以自定义,具体格式下面再说
--udp-services-configmap
指定包含udp的规则的cm
当然,这个configmap可以在其它的namespace下, 比如放在 default的话,则是defalt/tcp-services
来看一下这个tcp-services的cm的内容,非常简单:
1 | apiVersion: v1 |
要关注的只有data
字段,格式为: out_port: namespaces/svc_name:port
, 即out_port为需要对外暴露的tcp端口, 这个例子表示,需要对外暴露9000端口,通过9000端口进来的TCP请求请转发到ns: clickhouse-operator下的svc: clickhouse-1box的9000端口上
总共就需要这2步,就能够实现对外接收tcp请求了,是不是非常方便.
最后来看看在nginx pod中生成的配置,其实就是转换成了nginx 的stram
1 | # 省略... |
Annotation/Configmap
nginx本身强大的原因之一在于它的很多参数都是可以设置的, 在nginx ingress中也是如此,通过增加configmap及annotation可以自定义非常多的选项, 甚至可以使用自定义模板
比如: 我需要自定义nginx的日志,或者调整一些参数配置,那么就可以使用一个nginx-config的cm, 然后在daemonset中指定使用这个cm即可.
1 | apiVersion: v1 |
其它的一些常用配置可参考以下:
问题
- controller启动时提示以下提示:
解决:
nginx-ingress-controller的daemonset中的启动命令中指定了ingress-class, 所以需要相对应
所以最好不要指定ingress-class, 不然以后想增加的时候都会需要与这个对应
- 关于
--annotations-prefix=nginx.ingress.kubernetes.io
在编写ingress规则时经常需要定义一些annotations, annotations-prefix支持使用自定义前缀, 默认值为nginx.ingress.kubernetes.io
,一般情况下不建议修改, 官方支持的annotations列表可参考