k8s--基础--29.1--ingress--介绍
1.5、7层负载均衡调度器1.5.1、使用步骤部署ingress controller我们ingress controller使用的是nginx创建service,用来分组pod创建pod应用,可以通过控制器创建pod访问k8s内部pod创建ingress http,通过http访问k8s内部pod创建ingress https,通过https访问k8s内部pod1.5.2、客户端访问后端pod的
·
k8s–基础–29.1–ingress–介绍
1、k8s暴露服务的方式
1.1、Ingress
- Ingress 定义规则
- 它可以定义某个域名的请求过来之后转发到集群中指定的 Service。
- 可以通过 Yaml 文件定义
- 可以给一个或多个 Service 定义一个或多个 Ingress 规则。
1.2、Ingress Controller
- 可以理解为控制器
- 它通过不断的跟 Kubernetes API 交互,实时获取后端 Service、Pod 的变化,比如新增、删除等,然后结合 Ingress 定义的规则生成配置,然后动态更新上边的 Nginx 或者trafik负载均衡器,并刷新使配置生效,来达到服务自动发现的作用。
1.3、k8s暴露服务的方式
- LoadBlancer Service
- ExternalName
- NodePort Service
- Ingress
1.4、4层负载均衡调度器
1.4.1、使用步骤
- 创建service,用来分组pod
- 创建pod应用,可以通过控制器创建pod
- 通过访问k8s节点,访问k8s内部pod
1.4.2、客户端访问后端pod的数据包走向
client--->nodeip:port--->service ip:port--->podip:port
1.5、7层负载均衡调度器
1.5.1、使用步骤
- 部署ingress controller
- 我们ingress controller使用的是nginx
- 创建service,用来分组pod
- 创建pod应用,可以通过控制器创建pod
- 访问k8s内部pod
- 创建ingress http,通过http访问k8s内部pod
- 创建ingress https,通过https访问k8s内部pod
1.5.2、客户端访问后端pod的数据包走向
client--->Nodeip:port----->IngressController--->service--->pod
2、k8s集群内部的服务暴露给外界访问会产生的问题
2.1、Pod IP 漂移问题
2.1.1、问题
- k8s具有强大的副本控制能力,能保证在任意副本(Pod)挂掉时自动从其他机器启动一个新的,通俗地说,这个Pod可能在任何时刻死在任何节点上,也可能在任何时刻出现在任何节点上
- 随着Pod的创建和销毁,Pod IP 肯定会动态变化,那么如何把这个动态的Pod IP暴露出去
2.1.2、解决方案
- 借助于k8s的 Service 机制,Service可以以标签的形式选定一组带有指定标签的Pod,并监控和自动负载他们的Pod IP,我们向外只暴露Service IP就行了,这就是NodePort模式
- NodePort模式
- 在每个节点上开起一个端口,然后转发到内部Pod IP上
- 访问方式:http://nodeip:nodeport/
- 工作流程如下
2.2、端口管理问题
2.2.1、NodePort模式会引入一个新问题
服务一旦多起来,NodePort在每个节点上开启的端口会及其庞大,而且难以维护。
2.2.2、解决方案
- 可以使用一个Nginx-Pod直接对内进行转发。
- 原理
- Pod与Pod之间是可以互相通信的,而Pod是可以共享宿主机的网络名称空间,也就是说当在共享网络名称空间时,Pod上所监听的就是Node上的端口。
- 如何实现
- 使用 DaemonSet 在每个Node上监听 80,然后写好规则,因为Nginx外面绑定了宿主机80端口(就像NodePort),本身又在集群内,那么向后直接转发到相应 Service IP 就行了
- 工作流程如下
2.3、域名分配及动态更新问题
2.3.1、Nginx-Pod会引入一个新问题
- 当每次有新服务加入又该如何修改Nginx配置呢?我们知道使用Nginx可以通过虚拟主机域名进行区分不同的服务,而每个服务通过upstream进行定义不同的负载均衡池,再加上location进行负载均衡的反向代理,在日常使用中只需要修改nginx.conf即可实现,那在K8S中又该如何实现这种方式的调度呢?
- 假设后端的服务初始服务只有ecshop,后面增加了bbs和member服务,那么又该如何将这2个服务加入到Nginx-Pod进行调度呢?
2.3.2、解决方案
- 使用Ingress
- Ingress 包含两大组件
- Ingress Controller
- Ingress。
- Ingress简单的理解
- Ingress 可以认为 就是你原来需要改Nginx配置,然后配置各种域名对应哪个 Service,现在把这个动作抽象出来,变成一个 Ingress 对象,你可以用 yaml 创建,每次不要去改Nginx 了,直接改yaml然后创建/更新就行了
- Ingress Controller
- 通过与 k8s API 交互,动态的去感知集群中Ingress规则变化,然后读取他,按照他自己模板生成一段 Nginx 配置,再写到 Nginx Pod 里,最后 reload 一下
- 工作流程如下
3、Ingress
3.1、Ingress是什么?
- Ingress 是k8s API的标准资源类型
- Ingress 是一组基于DNS名称(host)或URL路径把请求转发到指定的Service资源的规则。
- 用于将集群外部的请求流量转发到集群内部,完成服务发布
- 能把集群内Service 配置成外网能够访问的URL,流量负载均衡,提供基于域名访问的虚拟主机
- 可以用来规定HTTP/S请求应该被转发到哪个 Service 上,比如根据请求中不同的Host和url路径让请求落到不同的 Service 上
- Ingress资源自身不能进行"流量穿透",仅仅是一组规则的集合
- 这些集合规则还需要其他功能的辅助,比如监听某套接字,然后根据这些规则的匹配进行路由转发,这些能够为Ingress资源监听套接字并将流量转发的组件就是Ingress Controller。
3.1.1、工作流程
当service关联的后端pod ip地址发生变化,就会把这些变化信息保存在ingress中,由ingress注入到七层负载均衡调度器ingress controller中,也就是把信息传入到七层负载均衡调度器的配置文件中,并且重新加载使配置生效
3.1.2、官方资料
https://kubernetes.io/docs/concepts/services-networking/ingress/
3.2、Ingress Controllers是什么?
- 是一个七层负载均衡调度器,客户端的请求先到达这个七层负载均衡调度器,由七层负载均衡器在反向代理到后端pod、
- 举例:
- 以我们熟悉的nginx为例,假如请求到达nginx,会通过upstream反向代理到后端pod,但是后端pod的ip地址是一直在变化的,因此在后端pod前需要加一个service,这个service只是起到分组的作用,那么我们upstream只需要填写service地址即可。
3.2.1、常见的七层负载均衡调度器
- nginx:需要手动加载配置文件
- traefik:定期自动加载配置文件,不需要手动干预,在微服务中几乎都会使用这种调度器
3.2.2、Ingress Controller 和 Deployment Controller 的区别
Ingress Controller 不直接运行为kube-controller-manager的一部分,它仅仅是k8s集群的一个附件,类似于CoreDNS,需要在集群上单独部署。
4、如何创建Ingress资源
- Ingress资源是基于HTTP虚拟主机或URL的转发规则,需要强调的是,这是一条转发规则。
- Ingress 在资源配置清单中的spec字段中嵌套了rules、backend和tls等字段进行定义。
4.1、定义
spec:
rules:
- hosts: <string>
http:
paths:
- path:
backend:
serviceName: <string>
servicePort: <string>
4.2、说明
4.2.1、rules
- 由一系列的配置的Ingress资源的host规则组成,这些host规则用于将一个主机上的某个URL映射到相关后端Service对象
- 由rules定义规则,或没有匹配到规则时,所有的流量会转发到由backend定义的默认后端
4.2.2、backend
- 默认的后端
- 用于服务那些没有匹配到任何规则的请求,用于让负载均衡器指定一个全局默认的后端。
- 定义Ingress资源时,必须要定义backend或rules两者之一
- backend由2个必要的字段组成
- serviceName:指定流量转发的后端目标 Service资源名称
- servicePort:指定流量转发的后端目标 Service资源端口
4.2.3、tls
- TLS配置
- 目前仅支持通过默认端口443提供服务,如果要配置指定的列表成员指向不同的主机,则需要通过SNI TLS扩展机制来支持该功能。
- tls对象由2个内嵌的字段组成,仅在定义TLS主机的转发规则上使用。
4.2.4、hosts
- 包含使用的TLS证书之内的主机名称字符串列表
- 使用的主机名必须匹配tlsSecret中的名称。
4.2.5、host
- 不支持使用IP地址定义
- 不支持IP:Port的格式
- 该字段留空,代表着通配所有主机名。
4.2.6、secretName
- 用于引用SSL会话的secret对象名称
- 在基于SNI实现多主机路由的场景中,此字段为可选。
4.3、案例
定义了一个Ingress资源,其包含了一个转发规则:将发往tomcat.lucky.com的请求,代理给一个名字为myapp的Service资源。
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-myapp
namespace: default
annotations:
# 表示使用的负载均衡调度器是nginx
kubernetes.io/ingress.class: "nginx"
spec:
rules:
# 需要转发的数据
- host: tomcat.lucky.com
http:
paths:
- path:
backend:
# 需要路由的服务
serviceName: myapp
servicePort: 80
5、Ingress资源类型
- 单Service资源型Ingress
- 基于URL路径进行流量转发
- 基于主机名称的虚拟主机
- TLS类型的Ingress资源
5.1、单Service资源型Ingress
使用Ingress来进行暴露单个服务,只需要为Ingress指定default backend即可,如下示例:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
backend:
serviceName: my-svc
servicePort: 80
Ingress控制器会为其分配一个IP地址接入请求流量,并将其转发至后端my-svc
更多推荐
已为社区贡献55条内容
所有评论(0)