一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第26天,点击查看活动详情。
一、Ingress
服务类型 ClusterIP、NodePort、LoadBalancer 来看,使用 Service 提供的负载均衡有以下几种限制:
- 使用方式为
IP:Port,只提供 4 层负载均衡(TCP/IP层),不支持 7 层负载均衡功能。比如:不能按需要的匹配规则自定义转发请求。 - 对于
NodePort Service,需要在集群外部署负载均衡器。 - 对于
LoadBalancer Service,集群必须运行在云服务上。
如果只使用 Service 局限性也比较大,对于提供 HTTP 服务而言,不同的 URL 地址需要不同的后端服务进行处理。
在 Kubernetes v1.1 版本中,添加了 Ingress API(beat 版本),这样就可以提供 7 层负载均衡(HTTP/HTTPS)
Ingress 资源对象可以将客户端对不同 URL 的访问转发到不同的后端 Service,这样就实现了 HTTP/HTTPS 层的路由转发功能。
Tips: Ingress 并不是服务。它是位于多个服务之间,充当集群中的智能路由器或是入口点。
Ingress 不仅可以让外部客户端访问服务,还可以自定义服务的访问策略。
Ingress 只需要一个公网 IP 地址就可以为多个服务提供自定义的访问。
(1)Ingress 和 Ingress Controller
在 Kubernetes 集群中,Ingress 只是一个统称,具体而言由两部分组成:
Ingress:Ingress资源对象,使用YAML文件定义负载均衡的策略(规则)Ingress Controller:控制器,以插件形式存在于集群中,从apiServer中获取Ingress的规则变化
在集群中,需要先部署 Ingress Controller,再创建 Ingress 资源对象。 Ingress Controller 控制器是一个 docker 容器,容器镜像中包含一个负载均衡器(比如:Nginx 或是 HAProxy)和一个 Ingress Controller。
整个底层的实现是这样的: Ingress Controller 从 Kubernetes apiServer 中(实际上是监控 apiServer 的 ingress 接口后端的 backend services)获取 Ingress 的配置信息,然后动态生成一个 Nginx 或 HAProxy 配置文件,重启负载均衡器进程使配置生效。所以,虽然 Ingress Controller 是以插件形式集成在环境中,但依然是由 Kubernetes 管理的负载均衡器。
Ingress Controller 容器中的负载均衡器可以是各种主流的负载均衡软件,比如:Nginx、HAProxy、Traefik 等。 不管具体的软件类型是什么,官方都统称为 Ingress Controller。
(2)原理
当集群使用 Ingress 进行负载分发时,Ingress Controller 基于 Ingress 规则将客户端请求直接转发到 Service 对应的后端 Endpoint(Pod) 上,所以会跳过 kube-proxy 的转发功能,kube-proxy 在这里并不会起作用。这种方式比 LoadBalancer 更加高效。
当客户端访问实验楼(www.shiyanlou.com)时:
-
访问 www.shiyanlou.com/courses 的请求会被路由到后端名为
courses的Service; -
访问 www.shiyanlou.com/louplus 的请求会被路由到后端名为
louplus的Service; -
访问 www.shiyanlou.com/vip 的请求会被路由到后端名为 vip 的 Service;
使用
Ingress不仅可以实现对HTTP的路由,还可以实现基于cookie的会话亲和性、SSL直通/终止等功能。
二、部署 nginx-ingress-controller
在 Kubernetes 集群中,Ingress Controller 是以 Pod 形式运行的。
根据负载均衡器的不同出现了多种 Ingress Controller,比如:
Kubernetes Ingress Controller:Kubernetes官方推荐的控制器,由社区开发,最适合新手。NGINX Ingress Controller:Nginx公司开发的官方产品。有一个基于 NGINX Plus 的商业版。Traefik: 为部署微服务更加便捷而诞生的现代HTTP反向代理、负载均衡工具。支持多种后台来自动化、动态的应用它的配置文件。HAProxy Ingress: 这也是在传统配置时应用非常广泛的负载均衡器。它提供了“软”配置更新(无流量损失)、基于DNS的服务发现和通过API进行动态配置。
(1)举个栗子
- 下载
nginx-ingress-controller.yaml和ingress-service-hodeport.yaml文件
wget https://labfile.oss.aliyuncs.com/courses/1457/nginx-ingress-controller.yaml
wget https://labfile.oss.aliyuncs.com/courses/1457/ingress-service-nodeport.yaml
下载以后可以分别打开这两个文件查看具体的内容:
-
nginx-ingress-controller.yaml文件中,创建了名为ingress-nginx的命名空间(没有使用kube-system系统默认空间),并在该命名空间下分别创建了名为nginx-configuration、tcp-services、udp-services的ConfigMap,创建了相关的服务账户、集群角色、集群角色绑定,最后使用Deployment部署一个名为nginx-ingress-controller-xxx的Pod副本,这个Pod就是Ingress Controller。注意在 Deployment.spec.template.spec 中设置 hostNetwork: true,将 Pod 中所有容器的端口号都映射到 Node 节点上,因为是在本机进行测试,直接使用 NodePort:containerPort 就可以直接访问该控制器。同时由于国外的镜像无法下载,这里使用阿里云提供的镜像 registry.aliyuncs.com/google_containers/nginx-ingress-controller:0.26.1,这个容器有两个端口:80 端口提供 http 访问,443 端口提供 https 访问。
nginx-ingress-controller:0.26.1 镜像实现 Ingress Controller 的基本逻辑为:监听 APIServer,获取在 Ingress 中定义的配置信息;基于 Ingress 配置信息,生成 Nginx 所需的配置文件 /etc/nginx/nginx.conf;执行 nginx -s reload 命令重新加载配置文件内容。
ingress-service-nodeport.yaml文件中,为Ingress Controller Pod创建NodePort类型的Service,接收集群外部的流量。
- 先创建
nginx-ingress-controllerPod
$ kubectl create -f nginx-ingress-controller.yaml
- 为
nginx-ingress-controller Pod创建NodePort类型的Service
$ kubectl create -f ingress-service-nodeport.yaml
service/ingress-nginx created
- 查看
ingress-nginx命令空间下所有创建好的资源对象
$ kubectl get all -o wide -n ingress-nginx
\