最近跟朋友聊到了k8s
我: “环境给了就只管用呗,副本自动管理地妥妥的,有啥可以复盘的?“
朋友: “容器的通讯与服务暴露还是有点东西的”
我: “嗯~~(抿嘴点头)k8s端口名称众多,关系错综复杂,若要正确使用,就需要理清它们,复杂程度不亚于看懂明星们的前任关系图 :)”
那就安排~
前言:本篇通过一个demo证实了各端口之间的关系与所起的作用,其过程涉及了容器之间的互相访问与前端反向代理,最终将服务暴露给用户这一E2E过程。
一. 首先了解下k8s service的4种类别:
1.ClusterIP:为k8s内部的其他Pod提供静态的访问服务,因为Pod的ip就像孩子的脸,说变就变,会导致其他pod不能稳定访问到该Pod。
2.NodePort:允许用户从集群从外部访问内部Pod,作用类似DNAT. 但是建议前端用Nginx反向代理,不要用它进行暴露服务。
3.LoadBalancer: 接入公有云实现负载均衡时使用,它对接的组件不在K8s内;注意与下图中的LoadBalancer:Ingress-Nginx-Controller 区分开。后者是部署在k8s内部的,为内部容器提供反向代理。(Ingress-Nginx-Controller 有机会再单独展开)
4.ExternalName:允许从容器内,借助内部与外部的FQDN实现访问外部资源,它不依赖ClusterIP。使用场景:k8s内的应用需要访问外部重型的数据库服务之类(本次画幅有限,不做展开)
二,这个demo表面看起来是这样的:
Pod间进行通讯,且数据持久化保存。
还有这样,前端页面实现负载均衡:
三. 资源看起来是这样的:
四. 背后的资源与端口是这样组织的:(请点开放大观摩)
端口、服务关系确实比较多,几句话难以表述清楚,但是有几个点值得指出:
1.k8s的资源里有各种port(containerPort,targetPort,Port,NodePort),图中标注了它们的位置与关系。同时澄清了一些问题:例如内部服务发现并不依赖NodePort,conteinerPort,证明了都是依赖于标签选择器。
2.service中的ClusterIP扮演了内部访问的重要角色,它与Port(即容器端口)为其他Pod提供服务暴露。
3.容器之间的路由由Kube-proxy维护,保存在IPVS/IPtables,两者从效果上一致,只有大规模部署时的性能差别,本实验用的IPVS,仅作展示。
4.同一个Pod内是可以有多个容器的,它们共用同一个PodIP,它们的containerPort分别一一对应到targetPort,端口号完全相同。但是前者是delpoyment级别的定义,后者是service级别的定义。
5.ingress-nginx-controller是k8s自己发布的LB组件,兼容性最好。管理员通过配置它的规则,让它自动转译为内部nginx容器中的具体配置(可进容器查看到)。本例演示的是单域名,单服务反向代理。多子域名多服务的负载均衡画不下了,见谅,有机会再单独复盘这部分,再局部放大看看。
6.internalTrafficPolicy与externalTrafficPolicy比较容易演示,但是画不下了。需要注意的是如果为local,则服务pod接收到的IP地址是Flannel的地址,而非客户端Pod地址。
7.手动给各个pod内塞了静态页面,并留下文字标记,方便curl侦测最终是哪个Pod在服务。
8.使用了了PV,PVC让数据持久化,即使mysql容器销毁数据也不会丢失,需要展开的话,再说。
9.想到啥再说吧,写多了太难读,图还是更清楚一些。
--- To Be Continued ---