之前搭建并使用了微软云Azure托管的K8S平台AKS,最近又在华为云上搭建了CCE,加上测试使用的AWS和阿里云的K8S平台,逐渐掌握了一些主流公有云厂商基于K8S原生服务的使用方式,学而不思则罔,如果实践是检验真理的唯一标准,那实践后的总结就是在创造真理,K8S涉及的内容太多,其中网络最为复杂,而网络又分集群入口、出口网络,以及Pod间的Networkpolicy等等,光是Calico网络模型估计就能连载几篇,本文主要针对公有云托管模式下的K8S集群对外暴露服务的Ingress,废话少说,开整
我们都知道K8S中工作负载有很多种,最常用的是无状态负载(Depolyment),其他还包括有状态负载(StatetfulSet),守护进程(DaemonSet)以及各种任务(Job和CronJob),不同的工作负载适合不同的场景,这里不过多赘述,工作负载调用的最小单元是Pod,负载通过副本数量控制Pod数量,而工作负载需要被访问或者访问别的负载,这时候就引入了Service的概念,K8S集群内部可以直接通过Service名称进行访问,但Service是基于四层TCP和UDP协议转发的,而在实际使用场景中,四层Service无法满足应用层存在的大量HTTP/HTTPS访问需求,因此又引入了Ingress的概念来暴露服务,使用方式如下:
对于自建K8S集群来说,负载均衡器可能需要自己实现,比如F5、Nginx、LVS等,而负载均衡作为公有云最常见的PaaS服务,显然只要和托管的K8S平台结合一下就OK了,你能想到,K8S官方和公有云厂商显然早就看穿一切了,于是K8S官方的Service类型从Nodeport,ClusterIP,又加入了Loadbalancer类型,而公有云厂商也支持通过YAML创建云上服务,比如Azure的beta版service.beta.kubernetes.io/azure-load-balancer-internal: "true",这样一来事情就变得简单了,不过好像上图有个概念忘记说明了,那就是Ingress Controller,这是一个抽象的概念,你可以这样理解:Ingress资源:一组基于域名或URL把请求转发到指定Service实例的访问规则,是Kubernetes的一种资源对象,Ingress实例被存储在对象存储服务etcd中,通过接口服务实现增、删、改、查的操作。
Ingress Controller:请求转发的执行器,用以实时监控资源对象Ingress、Service、End-point、Secret(主要是TLS证书和Key)、Node、ConfigMap的变化,解析Ingress定义的规则并负责将请求转发到相应的后端Service。
这个Ingress Controller需要借助一些插件实现,比如最常用的NGINX Ingress Controller,HAProxy也是一种,而公有云厂商大都会自研网络插件,说是自研,其实就是在托管的K8S集群上帮你实现了很多插件的功能,这样一来,大多云厂商的托管平台就会出现两种服务的暴露方式,一种是使用开源Ingress-controller插件
第二种是使用自研的网络插件:
这两种模式云厂商给的区别都模棱两可,通过使用大概总结如下:
1.Ingress-controller高可用:
1.ELB类型的高可用由厂商负责,因为会保证ELB的SLA以及Master节点的性能
2.Nginx类型的服务插件需要自己保证服务高可用,可以使用node污点或者守护进程的方式实现
2.ELB和Service类型兼容:
1.ELB类型的ELB(有点绕)其实是七层的负载均衡,因为是直接调用Service,所以这种类型调用的Service需要是Nodeport或者Loadbalancer类型,ClusterIp类型是不可以的,而Nodeport类型的服务只要节点能被访问,就意味着这个服务也能被访问,那也就是说Node如果绑定了公网IP,它上面的服务还用啥ingress了,直接都可以访问了,所以这种模式需要配合权限控制来使用
2.Nginx类型的ELB是四层的,它只需把请求透传过来就可以,真正起作用的是部署的Nginx-Ingress,所以这种类型调用的service任何类型都可以
补充:华为的四层和七层的ELB都是一个服务,主要看你怎么用,而Azure的四层叫ALB,七层却叫Application gateway,这可不是注册API的那个服务,那个服务它叫API Management service,真是马虎不得啊,AWS七层的叫ALB,四层的叫NLB(是不有又涨知识了)
3.日志Log:
1.网安法最常见的两个要求,日志保存六个月和保留访问的源IP,ELB类型的主要日志都在PaaS级别的ELB服务,实现这两个要求简直小case
2.Nginx类型的就麻烦了,四层的负载均衡几乎没有任何有意义的日志,而且它还会做NAT,使后端的应用捕获不到访问源IP,所以你需要对它进行设置,而且这还不算完,你还要把这个源ip在集群安全组下放行,要不然根本进不来集群
补充:监控等metric指标同样适用,根本区别就是公有云PaaS服务和自建负载的区别
4.路由规则配置:
1.ELB类型的捕获日志是很方便,但是配置规则就是基于ELB服务本身,不支持路由重定向
2.Nginx类型的就方便多了,你只要会配置Nginx.conf就可以了,nginx本身的那些规则都支持
5.其他区别:
1.ELB类型一个集群支持多个ELB实例,Nginx类型一个集群只支持一个ELB实例
2.ELB类型占用Master节点,不占用工作节点,Nginx类型占用Worker节点,需要Nginx组件运行成本
如果你使用主流公有云托管的K8S平台,同时又要暴露你的服务,那你大概率会遇到同样的问题,但是服务网格Istio使用Istio Gateway,可以理解它是Ingress的加强版,比如灰度发布的流量比例控制就是靠它实现的(有时间再细讲,这都是后话了),K8S复杂又强大,这只是它的冰山一角,如果你管理的核心应用(几千台节点)正运行在K8S上,那你一定幸运的发现了很多细微的问题,时间总是把一部分人推向海边,使他们成为最早看见太阳的那一批人。