Ingress原理
Ingress为K8S中所有service提供对外部的代理,其核心工作组件为Ingress Controller,这里的Ingress Controller有很多种具体实现,包括Nginx、HAProxy、Envoy、Traefik 等,我用到的是nginx-ingress-controller。
Ingress的部署
首先需要部署一个nginx-ingress-controller,我们可以直接通过ingress-nginx官网的yaml文件进行部署
1 | kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml |
这里的yaml文件具体内容为
1 | apiVersion: v1 |
可以看到这里虽然内容很多,但核心就是定义了一个Deployment,这里的Deployment定义的就是我们需要创建的nginx-ingress-controller这个pod。
创建完之后为了能够从外部访问到该controller,需要通过一个service对外暴露该服务,创建过程如下
1 | kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/service-nodeport.yaml |
其具体内容为
1 | apiVersion: v1 |
可以看到其实质就是定义了一个NodePort类型的service来代理ingress-nginx的pod,从而可以通过宿主机的地址来访问ingress。
注:这里没有配置nodePort,系统会随机生成一个对外开放的nodePort,可以通过以下命令查看分配的端口,另外,ingress对应的namespace都在ingress-nginx下,查询的时候需要注意。
1 | kubectl svc -n ingress-nginx |
到这里ingress的部署就完成了,但要想实际使用ingress,还需要配置rule规则。
Ingress规则配置
ingress-controller开放了rules规则的配置,可以在部署完成之后动态更新rules,其实质是通过Nginx Lua方式实现的,具体配置的例子如下:
1 | apiVersion: extensions/v1beta1 |
rules生效后,即可以通过域名加开放端口访问到对应的服务上。这里需要说明的是host项必须为域名,当然这个域名不是随便填的,需要确保域名能解析到宿主机对应的ip地址,这里更像是一种安全机制吧。
注:虽然可以通过配本地hosts文件的方式来使用,但这种方式未免有些繁琐,这里其实可以通过curl请求来绕过域名限制。经测试,这里的域名用于验证请求头中的域名,因此可以通过下述方式来访问
1 | curl --header "Host:cafe.example.com" http://127.0.0.1 |
如果是较新版本的curl就更方便了,直接用下述方式即可
1 | curl --resolve cafe.example.com:80:127.0.0.1 http://cafe.example.com |