Kubernetes 暴露服务的方式目前只有三种:LoadBlancer Service、NodePort Service、Ingress;下面详细的了解下Ingress
。
根据前面对 Service 的使用说明,我们知道 Service 的表现形式为IP:Port
,工作在TCP/IP
层,而对于基于 HTTP 的服务来说,不同的URL地址经常对应到不同的后端服务或者虚拟服务器,这些应用层的转发机制仅通过kubernetes的Service机制是无法实现的。kubernetes V1.1版本中新增Ingress
将不同URL的访问请求转发到后端不同的Service
,以实现HTTP层的业务路由机制。
Ingress由两部分组成:Ingress Controller 和 Ingress 服务。
核心逻辑:Ingress Contronler 通过与 Kubernetes API 交互,动态的去感知集群中 Ingress 规则变化,然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段 Nginx 配置,再写到 Nginx-ingress-control的 Pod 里,这个 Ingress Contronler 的pod里面运行着一个nginx服务,控制器会把生成的nginx配置写入/etc/nginx.conf文件中,然后 reload 一下 使用配置生效。以此来达到域名分配置及动态更新。
- 对
https://mywebsite.com/api
的访问将被路由到后端名为"api"的 Service。
- 对
https://mywebsite.com/web
的访问将被路由到后端名为"web"的 Service。
- 对
https:/mywebsite.com/doc
的访问将被路由到后端名为"doc"的 Service。
下面通过一个例子分三步说明Ingress Controller
和Ingress 策略
和客户端
如何访问 Ingress 提供的服务。
部署
ingress控制器有两种:nginx和haproxy 这里是以nginx为讲解。
本文使用谷歌提供的 nginx-ingress-controller 镜像创建ingress-controller
,并以 Pod + Service 方式运行,其中 Service 使用 nodePort 方式将80
,443
端口映射至物理机上。
部署过程中使用到的文档参考:https://github.com/kubernetes/ingress-nginx/tree/master/deploy
-
下载各所需的yaml文件
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/namespace.yaml >namespace.yaml
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/default-backend.yaml>default-backend.yaml
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/configmap.yaml>configmap.yaml
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/tcp-services-configmap.yaml>tcp-services-configmap.yaml
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/udp-services-configmap.yaml > udp-services-configmap.yaml
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/without-rbac.yaml>without-rbac.yaml
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/rbac.yaml>rbac.yaml
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/with-rbac.yaml > with-rbac.yaml
curl https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml >service-nodeport.yaml
-
启动上述yaml文件
kubectl create -f namespace.yaml
kubectl create -f configmap.yaml
kubectl create -f default-backend.yaml
kubectl create -f tcp-services-configmap.yaml
kubectl create -f udp-services-configmap.yaml
kubectl create -f rbac.yaml
kubectl create -f with-rbac.yaml
kubectl create -f service-nodeport.yaml
上述yaml文件中可以不用修改,直接运行。
-
default-backend.yaml
文件定义了默认的ingress服务,即客户端访问的URL地址不存在时,默认返回的页面,这个服务使用任何应用实现都可以,只需要能够返回一个404应答,并且提供/healthz路径实现健康检查,另外服务名称需要设置为default-backend-service
,因为该镜像中nginx默认通过default-backend-service
访问默认backend
。
-
rabc.yaml
是kubernetes实现鉴权的方式
-
with-rbac.yaml
文件中定义了一个Deployment,运行ingress-controller;需要注意的是如果修改了yaml文件中使用的镜像,部分参数可能需要更改,这个具体情况具体分析
-
service-nodeport.yaml
文件定义了一个服务,并且以nodePort方式监听80以及443端口,为客户端提供访问入口。
ingress规则编写
下面是一个简单的例子:
# cat mytest.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
annotations:
ingress.kubernetes.io/ssl-redirect: "false" ##关闭强制使用HTTPS的设置
spec:
rules:
## 根据URL路径实现转发,域名为 *
- https:
paths:
- path: /demo
backend:
serviceName: mydemo
servicePort: 8080
- path: /test
backend:
serviceName: mytest
servicePort: 8080
根据域名实现转发:
$ cat mytest.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: pand-ingress
annotations:
ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
## 根据域名实现转发
- host: www.mywebsite1.com
https:
paths:
- backend:
serviceName: mydemo
servicePort: 8080
- host: www.mywebsite2.com
https:
paths:
- backend:
serviceName: mytest
servicePort: 8080
创建上述ingress,在客户端配置好域名解析,实现访问。
也可以通过curl指定解析访问:
curl --resolve www.mywebsite1.com:80:172.10.18.3 www.mywebsite1.com/mydemo
总结
优点:Ingress支持L7负载均衡;Ingress基于Pod部署,并将Pod网络设置成external network;Ingress controller支持Nginx、Haproxy,能够满足企业内部使用。
缺点:因为pod是临时的,由于Ingress Controller也是基于Pod部署,这样Ingress对外的IP会发生变化。在企业内部都会在防火墙上给Service的访问IP设定规则,而IP变动对这一机制是致命的,因为企业不可能经常手动修改防火墙规则。
链接:https://www.orchome.com/1452
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。