集群内访问
假设我们在一个K8S的集群里面发布了两个应用,前端应用frontend和后端应用backend,前端应用要访问后端应用,那么有以下两种方式。
使用应用名进行访问
假设在K8S集群中发布的后端应用的名称为backend,它监听8080端口,那么在前端应用的容器中,可以直接使用后端应用的名称加端口
http://backend:8080 进行访问,K8S会自动转发到后端的某个容器实例。如下所示:
注意,上面的转发其实是四层转发,即如果后端应用是mysql类型的,可使用tcp://backend:8080进行访问,如果后端应用为web应用,可使用 http://backend:8080进行访问。
另外,上面的访问方式要求前端应用和后端应用要在K8S集群的同一个命名空间内。如果二者不在同一个命名空间,比如后端应用在命名空间ns2中,那么前端应用应该使用 http://backend.ns2:8080 进行访问(即应用名后面要加上命名空间)
使用微服务架构自己的注册机制
如果业务开发者使用的微服务架构有注册机制,那么可以直接使用微服务框架的注册机制来做负载均衡。如下:
后端应用容器实例把自己的IP与端口注册到zookeeper或eureka,前端应用容器实例去注册中心获取后端应用的实例列表,然后前端应用的实例自己决定访问哪一个实例。
注册中心zookeeper/eureka集群可以部署在K8S集群内,也可以部署在集群外,这个需要业务方自己去部署。
集群外访问
假设我们要从浏览器上访问上面的前端应用,下面我们来介绍几种方法:
NodePort
最简单的方法就是使用NodePort。我们只需要为前端应用在K8S集群中创建一个Service对象,在这个对象中指定一个主机端口比如为30000,那么,每台主机上的kube-proxy(部署K8S集群时已部署好)便会监听30000端口。当访问主机的30000端口时,kube-proxy便会转发到前端应用的容器实例去。如下:
由于容器在K8S集群的Master主机上安装了keepalived,绑定了一个VIP,所以我们可以通过http://vip:30000来访问,保证了访问入口的高可用。
NodePort+Nginx
在上面的NodePort方案中,kube-proxy处是没有办法设置HTTPS证书的,所以上面的方案只支持HTTP,不支持HTTPS。
如果要支持HTTPS,则需要在kube-proxy的前面手动搭建Nginx集群,在Nginx处手动配置HTTPS证书,手动配置转发规则;两个Nginx主机上还要安装Keepalived绑定一个VIP,以保证高可用。如下:
上面的Nginx可以搭建在K8S集群的外面,也可以搭建在K8S集群的主机上(是物理部署在主机上,不是部署在容器内),但不要部署在K8S集群的Master主机上,因为Master主机上已经部署了keepalived,以免和Nginx的keepliaved冲突。
NodePort+LVS
NodePort的方案中,VIP只在一台主机上,可能承受不了大流量的访问。此时,我们可以在NodePort的前面手动搭建LVS,如下:
LVS需要手动搭建,LVS主机上还要安装keepalived绑定VIP以保证入口的高可用;LVS配置DR模式转发到多台K8S主机上;kube-proxy处每开放一个主机端口,在LVS处也需要配置这个端口;该方案不支持HTTPS,因为LVS处是四层转发,不支持配置HTTPS。
NodePort+Nginx+LVS
如果流量大,还需要支持HTTPS,则需要使用该种方案。
在kube-proxy的前面手动搭建Nginx,在Nginx的前面手动搭建LVS,如下:
LVS需要手动安装,同时需要安装keepalived绑定VIP,以保证访问入口的高可用; Nginx需要手动安装,手动配置HTTPS证书 ;LVS处只需要配置一个端口,转发到Nginx的同端口;Nginx只需要监听一个端口,通过不同的域名,转发到kube-proxy上不同的端口;kube-proxy根据不同的端口,转发到的集群内的不同的应用。
Ingress
Ingress是一种不同于NodePort的方案,如下:
IngressController只监听一个端口,通过不同的域名转发到K8S集群中不同的应用;所以该方案只支持域名访问,不支持IP访问。
只有K8S的Master主机上才会有IngressController,Master主机上已经有VIP,所以DNS服务器把域名解析为VIP,即可保证入口的高可用。
在云容器引擎管理台页面上,通过为应用创建不同的Ingress对象,来为不同的应用指定不同的域名。
IngressController目前不支持配置HTTPS证书,后续会支持。所以该方案目前不支持HTTPS,只支持HTTP。
Ingress+LVS
上面的Ingress方案,由于VIP只在一台主机上,所以不适合大访问量的场景。如果访问量较大,可以使用Ingress+LVS,如下:
LVS需要手动安装与配置,LVS主机上需要安装keepalived绑定VIP以保证入口高可用 。LVS只需要监听一个端口(IngressController监听的端口) 。浏览器通过域名访问,DNS服务器把域名解析为LVS的VIP,LVS把请求转给其中某个IngressController,IngressController通过域名转发到不同的集群内的应用。该方案与上面方案一样,目前不支持HTTPS,后续会支持。
对比:
方案 | 四层或七层转发 | 支持高可用 | 支持HTTPS | 优缺点 | 适用场景 |
---|---|---|---|---|---|
NodePort | 四层 | 是 | 否 | 优点:使用简单,无须额外配置 | TCP或HTTP服务、访问量不大 |
NodePort+Nginx | 七层 | 是 | 是 | 缺点:需要额外手动部署与配置Nginx | HTTPS服务,访问量不大 |
NodePort+LVS | 四层 | 是 | 否 | 缺点:需要额外手动部署与配置LVS | TCP或HTTP服务,访问量大 |
NodePort+Nginx+LVS | 七层 | 是 | 是 | 缺点:需要额外手动部署与配置Nginx和LVS | HTTPS服务,访问量大 |
Ingress | 七层 | 是 | 当前不支持,后续会支持 | 优点:使用简单;缺点:只支持域名访问,不支持IP访问,需要自行配置DNS服务器 | HTTP服务(后续支持HTTPS服务),访问量不大 |
Ingress+LVS | 七层 | 是 | 当前不支持,后续会支持 | 缺点:需要额外部署LVS,只支持域名访问,不支持IP访问,需自行配置DNS服务器 | HTTP服务(后续支持HTTPS服务),访问量大 |