文章目录
简单流程
用户发起请求,请求传送到Ingress
Ingress :作用是定义请求如何转发到service的规则,ingress支持7层代理转发,它可以通过根据不同的域名或者URL访问路径把请求流量转发到不同的service上,实现调度不同业务域、不同URL访问路径的业务流量。
Service: 提供了服务的负载均衡和反向代理的能力,发来的请求通过负载均衡 4层代理转发到它所关联的后端pod上。
KubeDNS:依靠DNS进行解析,将域名解析成DNS获得虚拟IP。
Kube-proxy:对虚拟IP的请求按策略转发给后端,通过不同的工作模式设置不同的转发规则,确定转发到哪个pod上。
一、Ingress
为什么要发明 Ingress 这个概念呢?
其一重要原因:为了便于服务动态发现和负载均衡,利用不同的 path 路径来访问不同的服务,实现负载均衡。
Ingress 可以把进入到集群内部的请求转发到集群中的一些服务上,从而可以把服务映射到集群外部。Ingress 能把集群内 Service 配置成外网能够访问的 URL,流量负载均衡,提供基于域名访问的虚拟主机等。
Ingress Controller 可以理解为控制器,它通过不断的跟 Kubernetes API 交互,实时获取后端
Service、Pod 的变化,比如新增、删除等,结合 Ingress 定义的规则生成配置,然后动态更新上边的 Nginx 或者 trafik 负载均衡器,并刷新使配置生效,来达到服务自动发现的作用
工作流程如下图:
二、Service
1.关键概念
为了方便访问Pod资源,k8s定义了一个统一访问入口:service资源对象。
Service是一个固定接入层,客户端可以通过访问service的IP和端口访问到service关联的后端Pod。Service能够提供负载均衡的能力,但是在使用上有以下限制:只提供 4 层负载均衡能力,而没有 7 层功能,但有时我们可能需要更多的匹配规则来转发请求,这点上 4 层负载均衡是不支持的。
2.Service类型以及使用案例:
1) ClusterIP:
kubernetes :默认类型,是集群内部访问的方式,外部是无法访问的。其主要用于为集群内Pod访问时,提供的固定访问地址,默认是自动分配地址,可使用 ClusterIP 关键字指定固定IP。(特殊用法,无头服务headless,添加字段ClusterIP: None,直连pod)
kind: Service
apiVersion: v1
metadata:
name: my-svc
spec:
type: ClusterIP
selector:
app: nginx
ports:
- port: 80
targetPort: 80
2) NodePort
NodePort 是将主机 IP 和端口跟 kubernetes 集群所需要暴露的 IP 和端口进行关联,方便其对外提供服务。内部可以通过 ClusterIP 进行访问,外部用户可以通过 NodeIP:NodePort 的方式单独访问每个Node 上的实例。(备注,nodeport端口的开放是集群性质的,所以任意节点都可以访问,另外注意如果不指定nodeport端口,默认从30000-32767端口随机分配)
kind: Service
apiVersion: v1
metadata:
name: my-svc
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080 #(此处指定了端口,可不写,用随机指定)
拓展:
service 的三种端口:
port :service 暴露在 cluster IP 上的端口,port 是提供给集群内部客户访问 service 的入口。
nodePort :nodePort 是 k8s 提供给集群外部客户访问 service 入口的一种方式。
targetPort :targetPort 是 pod 中容器实例上的端口,从 port 和 nodePort 上到来的数据最终经过 kube-proxy 流入到后端 pod 的 targetPort 上进入容器。
port、nodePort 总结:
port 和 nodePort 都是 service 的端口,前者暴露给集群内客户访问服务,
后者暴露给集群外客户访问服务。从这两个端口到来的数据都需要经过反向代理 kube-proxy 流入后端 pod 的 targetPort,从而到达 pod 上的容器内。
3) LoadBalancer
对外暴露应用,适用于公有云
LoadBalancer 类型的 service 是可以实现集群外部访问服务的另外一种解决方案。不过并不是所有的k8s集群都会支持,大多是在公有云托管集群中会支持该类型。负载均衡器是异步创建的,关于被提供的负载均衡器的信息将会通过 Service 的 status.loadBalancer 字段被发布出去。是kubernetes针对云服务商提供的svc资源类型,本地无法演示,可以写出来但是资源会处于pending状态。
apiVersion: v1
kind: Service
metadata:
name: loadbalancer
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- port: 80
targetPort: 80
4)ExternalName:
ExternalName Service 是 Service 的一个特例,它没有选择器,也没有定义任何端口或Endpoints。它的作用是返回集群外 Service 的外部别名。它将外部地址经过集群内部的再一次封装(实际上就是集群DNS 服务器将CNAME解析到了外部地址上),实现了集群内部访问即可。例如你们公司的镜像仓库,最开始是用ip 访问,等到后面域名下来了再使用域名访问。你不可能去修改每处的引用。但是可以创建一个 ExternalName,首先指向到ip,等后面再指向到域名。相当于dns的域名回源,用的较少,也得注意kubernetes的dns插件版本,过低的版本是不支持该功能的。
参考 : 文章链接
三、Kube-proxy
1.简介
提供网络代理和负载均衡,是实现 service 的通信与负载均衡机制的重要组件,kube-proxy 负责为 Pod 创建代理服务,从 apiserver 获取所有 service 信息,并根据 service 信息创建代理服务,对虚拟IP的请求按策略转发给后端,通过不同的工作模式设置不同的转发规则,实现 service 到 Pod 的请求路由和转发,从而实现 Kubernetes层级的虚拟转发网络,将到service 的请求转发到后端的 pod 上。
2.三种代理模式的介绍
参考 :文章链接
1)userspace模式:
(该模式已弃用)userspace这种模式下,kube-proxy 持续监听 Service 以及 Endpoints 对象的变化;对每个 Service,它都为其在本地节点开放一个端口,作为其服务代理端口;发往该端口的请求会采用一定的策略转发给与该服务对应的后端 Pod 实体。kube-proxy 同时会在本地节点设置 iptables 规则,配置一个 Virtual IP,把发往 Virtual IP 的请求重定向到与该 Virtual IP 对应的服务代理端口上。其工作流程大体如下:
2)IPtables模式:
iptables 模式与 userspace 相同,kube-proxy 持续监听 Service 以及 Endpoints 对象的变化;但它并不在本地节点开启反向代理服务,而是把反向代理全部交给 iptables (iptables讲解)来实现;即 iptables 直接将对 VIP 的请求转发给后端 Pod,通过 iptables 设置转发策略。其工作流程大体如下:
3)ipvs模式:
与iptables、userspace 模式一样,kube-proxy 依然监听Service以及Endpoints对象的变化, 不过它并不创建反向代理, 也不创建大量的 iptables 规则, 而是通过netlink 创建ipvs规则,并使用k8s Service与Endpoints信息,对所在节点的ipvs规则进行定期同步; netlink 与 iptables 底层都是基于 netfilter 钩子,但是 netlink 由于采用了 hash table 而且直接工作在内核态,在性能上比 iptables 更优。其工作流程大体如下:
四、service与kube-proxy与pod的关系
1.Service:服务访问入口
门口的侍客,承接客人的所有要求。
2.Pod:业务容器
真正干活的人,产出者,接触不到客人。
3.Endpoints:管理 Pod
管理者,接触不到客人。
4.Kube-proxy:转发
大堂联络人,建立侍客与干活人的直接联系,接触不到客人
具有负载均衡模块,建立 iptables 或 ipvs 规则,使客人的要求从侍客直达干活人。