K8S 快速入门(七)网络通信原理:外部接入网络(下)
三、外部接入网络1. NodePort先提前强调一下,NodePort是K8s将内部服务对外暴露的基础,后面的LoadBalancer底层有赖于NodePort。如下图所示,首先不妨思考一下,K8s集群中有哪一个角色,即掌握Service网络的所有信息,可以和Service网络以及Pod网络互通互联,同时又可以和节点网络打通?答案是Kube-Proxy。上面我们提到Kube-Proxy是K8s内部
三、外部接入网络
1. NodePort
先提前强调一下,NodePort是K8s将内部服务对外暴露的基础,后面的LoadBalancer底层有赖于NodePort。
如下图所示,首先不妨思考一下,K8s集群中有哪一个角色,即掌握Service网络的所有信息,可以和Service网络以及Pod网络互通互联,同时又可以和节点网络打通?
答案是Kube-Proxy。上面我们提到Kube-Proxy是K8s内部服务发现的一个关键组件,事实上,它还是K8s将内部服务暴露出去的关键组件。Kube-Proxy在K8s集群中所有Worker节点上都部署有一个,它掌握Service网络的所有信息,知道怎么和Service网络以及Pod网络互通互联。如果要将Kube-Proxy和节点网络打通(从而将某个服务通过Kube-Proxy暴露出去),只需要让Kube-Proxy在节点上暴露一个监听端口即可。这种通过Kube-Proxy在节点上暴露一个监听端口,将K8s内部服务通过Kube-Proxy暴露出去的方式,术语就叫NodePort(顾名思义,端口暴露在节点上)。下图是通过NodePort暴露服务的简化概念模型。
如果我们要将K8s内部的一个服务通过NodePort方式暴露出去,可以将服务发布(kind: Service)的type设定为NodePort,同时指定一个30000~32767范围内的端口。服务发布以后,K8s在每个Worker节点上都会开启这个监听端口。这个端口的背后是Kube-Proxy,当K8s外部有Client要访问K8s集群内的某个服务,它通过这个服务的NodePort端口发起调用,这个调用通过Kube-Proxy转发到内部的Servcie抽象层,然后再转发到目标Pod上。
注意,为了直观形象,上图的Service在K8s集群中被画成一个独立组件,实际是没有独立Service这样一个组件的,只是一个抽象概念,之前解释过。
2. LoadBalancer
上面我们提到,将K8s内部的服务通过NodePort方式暴露出去,K8s会在每个Worker节点上都开启对应的NodePort端口。逻辑上看,K8s集群中的所有节点都会暴露这个服务,或者说这个服务是以集群方式暴露的(实际支持这个服务的Pod可能就分布在其中有限几个节点上,但是因为所有节点上都有Kube-Proxy,所以所有节点都知道该如何转发)。既然是集群,就会涉及负载均衡问题,谁负责对这个服务的负载均衡访问?答案是需要引入负载均衡器(Load Balancer)。下图是通过LoadBalancer,将服务对外暴露的概念模型。
假设我们有一套阿里云K8s环境,要将K8s内部的一个服务通过LoadBalancer方式暴露出去,可以将服务发布(Kind: Service)的type设定为LoadBalancer。服务发布后,阿里云K8s不仅会自动创建服务的NodePort端口转发,同时会自动帮我们申请一个SLB,有独立公网IP,并且阿里云K8s会帮我们自动把SLB映射到后台K8s集群的对应NodePort上。这样,通过SLB的公网IP,我们就可以访问到K8s内部服务,阿里云SLB负载均衡器会在背后做负载均衡。
值得一提的是,如果是在本地开发测试环境里头搭建的K8s,一般不支持Load Balancer也没必要,因为通过NodePort做测试访问就够了。但是在生产环境或者公有云上的K8s,例如GCP或者阿里云K8s,基本都支持自动创建Load Balancer。
3. Ingress
k8s 的服务(service)暴露service的三种方式ClusterIP、NodePort与LoadBalance,这
几种方式都是在service的维度提供的,单独用service暴露服务的方式,在实际生产
环境中不太合适:
- ClusterIP的方式只能在集群内部访问。
- NodePort方式的话,测试环境使用还行,当有几十上百的服务在集群中运行时NodePort的端口管理是灾难。
- LoadBalance方式受限于云平台,且通常在云平台部署ELB还需要额外的费用。
所幸k8s还提供了一种集群维度暴露服务的方式,也就是ingress。ingress可以简单理解为service的service,他通过独立的ingress对象来制定请求转发的规则,把请求路由到一个或多个service中。这样就把服务与请求规则解耦了,可以从业务维度统一考虑业务的暴露,而不用为每个service单独考虑。
举个例子,现在集群有api、文件存储、前端3个service,可以通过一个ingress对象来实现图中的请求转发:
ingress规则是很灵活的,可以根据不同域名、不同path转发请求到不同的service,并且支持https/http。
有了前面的NodePort + LoadBalancer,将K8s内部服务暴露到外网甚至公网的需求就已经实现了,那么为啥还要引入Ingress这样一个概念呢?它起什么作用?
我们知道在公有云(阿里云/AWS/GCP)上,公网LB+IP是需要花钱买的。我们回看上图的通过LoadBalancer(简称LB)暴露服务的方式,发现要暴露一个服务就需要购买一个独立的LB+IP,如果要暴露十个服务就需要购买十个LB+IP,显然,从成本考虑这是不划算也不可扩展的。那么,有没有办法只需购买一个(或者少量)的LB+IP,但是却可以按需暴露更多服务出去呢?答案其实不复杂,就是想办法在K8内部部署一个独立的反向代理服务,让它做代理转发。谷歌给这个内部独立部署的反向代理服务起了一个奇怪的名字,就叫Ingress,它的简化概念模型如下图所示:
Ingress就是一个特殊的Service,通过节点的HostPort(80/443)暴露出去,前置一般也有LB做负载均衡。Ingress转发到内部的其它服务,是通过集群内的Service抽象层/ClusterIP进行转发,最终转发到目标服务Pod上。Ingress的转发可以基于Path转发,也可以基于域名转发等方式,基本上你只需给它设置好转发路由表即可,功能和Nginx无本质差别。
注意,上图的Ingress概念模型是一种更抽象的画法,隐去了K8s集群中的节点,实际HostPort是暴露在节点上的。
所以,Ingress并不是什么神奇的东西,首先,它本质上就是K8s集群中的一个比较特殊的Service(发布Kind: Ingress)。其次,这个Service提供的功能主要就是7层反向代理(也可以提供安全认证,监控,限流和SSL证书等高级功能),功能类似Nginx。第三,这个Service对外暴露出去是通过HostPort(80/443),可以和上面LoadBalancer对接起来。有了这个Ingress Service,我们可以做到只需购买一个LB+IP,就可以通过Ingress将内部多个(甚至全部)服务暴露出去,Ingress会帮忙做代理转发。
那么哪些软件可以做这个Ingress?传统的Nginx/Haproxy可以,现代的微服务网关Zuul/SpringCloudGateway/Kong/Envoy/Traefik等等都可以。当然,谷歌别出心裁给这个东东起名叫Ingress,它还是做了一些包装,以简化对Ingress的操作。如果你理解了原理,那么完全可以用Zuul或者SpringCloudGateway,或者自己定制开发一个反向代理,来替代这个Ingress。部署的时候以普通Service部署,将type设定为LoadBalancer即可,如下图所示:
注意,Ingress是一个7层反向代理,如果你要暴露的是4层服务,还是需要走独立LB+IP方式。
4. 总结
- NodePort是K8s内部服务对外暴露的基础,LoadBalancer底层有赖于NodePort。NodePort背后是Kube-Proxy,Kube-Proxy是沟通Service网络、Pod网络和节点网络的桥梁。
- 将K8s服务通过NodePort对外暴露是以集群方式暴露的,每个节点上都会暴露相应的NodePort,通过LoadBalancer可以实现负载均衡访问。公有云(如阿里云/AWS/GCP)提供的K8s,都支持自动部署LB,且提供公网可访问IP,LB背后对接NodePort。
- Ingress扮演的角色是对K8s内部服务进行集中反向代理,通过Ingress,我们可以同时对外暴露K8s内部的多个服务,但是只需要购买1个(或者少量)LB。Ingress本质也是一种K8s的特殊Service,它也通过HostPort(80/443)对外暴露。
- K8s的Service发布主要有3种type,type=ClusterIP,表示仅内部可访问服务,type=NodePort,表示通过NodePort对外暴露服务,type=LoadBalancer,表示通过LoadBalancer对外暴露服务(底层对接NodePort,一般公有云才支持)。
好文推荐:
Kubernetes网络三部曲之一~Pod网络
Kubernetes网络三部曲之二~Service网络
Kubernetes网络三部曲之三 ~ NodePort vs LoadBalancer vs Ingress
kube-proxy 详解
更多推荐
所有评论(0)