k8的service和DNS服务发现机制
Service介紹
Kubernetes 之所以需要 Service,一方面是因為 Pod的IP不是固定的,另一方面則是因為一組 Pod 實例之間總會有負載均衡的需求
Service是由Kube-proxy組件加上iptables來共同實現的
Service vip(vip 是k8s自動為Service分配的)到Pod的轉發
iptables 對流入的IP包還設置了一個“標志”(–set-xmark)
只有處于Running狀態,且readinessProbe檢查通過的Pod,才會出現在Service的Endpoints 列表里.并且,當某一個 Pod 出現問題時,Kubernetes會自動把它從Service里摘除掉
Service基本原理
當用戶把一個service yaml文件提交給k8s后,kube-proxy組件通過Service的Informer感知到一個Service對象的添加,作為對這個事件的響應它就會在宿主機上創建一條iptables規則 可以通過iptables-save命令來查看
Service的VIP地址只是一條iptables規則上的配置 并沒有真正的網絡設備 所以ping這個地址 是不會有任何響應的
DNAT的作用,就是在PREROUTING檢查點之前,也就是在路由之前,將流入IP包的目的地址和端口,改成–to-destination指定的新目的地址和端口
訪問Service VIP的IP包經過上述 iptables 處理之后,就已經變成了訪問具體某一個后端Pod的IP包了.
不難理解,這些 Endpoints 對應的iptables規則,正是kube-proxy通過監聽Pod的變化事件,在宿主機上生成并維護的
iptables模式和ipvs模式
kube-proxy通過iptables處理Service的過程,其實需要在宿主機上設置相當多的iptables規則
當你的宿主機上有大量Pod的時候,成百上千條iptables規則不斷地被刷新,會大量占用該宿主機的CPU資源
IPVS模式
IPVS模式的工作原理,其實跟iptables模式類似.當我們創建了前面的Service之后,kube-proxy首先會在宿主機上創建一個虛擬網卡(叫作:kube-ipvs0)并為它分配ServiceVIP作為IP地址
kube-proxy就會通過Linux的IPVS 模塊,為這個IP地址設置三個IPVS 虛擬主機,并設置這三個虛擬主機之間使用輪詢模式 (rr) 來作為負載均衡策略
而相比于iptables,IPVS在內核中的實現其實也是基于Netfilter的NAT模式,所以在轉發這一層上,理論上IPVS并沒有顯著的性能提升.但是IPVS并不需要在宿主機上為每個Pod設置iptables規則,而是把對這些“規則”的處理放到了內核態,極大地降低了維護這些規則的代價
不過需要注意的是,IPVS 模塊只負責上述的負載均衡和代理功能.而一個完整的 Service 流程正常工作所需要的包過濾,SNAT等操作,還是要靠iptables來實現.只不過,這些輔助性的 iptables 規則數量有限,也不會隨著Pod數量的增加而增加
Service和DNS的關系
在kubernetes中,所有的Service和Pod都會被分配一條對應的DNS A記錄( 通過域名解析到IP地址的記錄 )
clusterIP Service的分配方式
ClusterIP模式的Service來說,它的A記錄的格式是:myservicename.mynamespace.svc.cluster.local 當你訪問這條A記錄的時候,它解析到的就是該Service的VIP地址
Headliness Service的分配方式
ClusterIP=None 的 Headless Service 來說,它的 A 記錄的格式也是:myservicename.mynamespace.svc.cluster.local 當你訪問這條A記錄的時候,它返回的是所有被代理的Pod的IP地址的集合.當然,如果你的客戶端沒辦法解析這個集合的話,它可能會只會拿到第一個Pod的IP地址
clusterIP Service被代理Pod的分配方式
對于ClusterIP模式的Service來說,它代理的Pod被自動分配的A記錄的格式是:PodIP.mynamespace.pod.cluster.local 這條記錄指向Pod的IP地址
Headliness Service被代理Pod的分配方式
1.對HeadlessService來說,它代理的Pod被自動分配的A記錄的格式是:mypodname.myservicename.mynamespace.svc.cluster.local 這條記錄也指向Pod的IP地址
2.如果Pod本身聲明了hostname和subdomain字段,那么這時候Pod的A記錄就會變成: podhostname.mysubdomain.mynamespace.svc.cluster.local
在上面這個Service和Pod被創建之后,你就可以通過busybox-1.default-subdomain.default.svc.cluster.local 解析到這個Pod的IP地址了
在 Kubernetes 里,/etc/hosts 文件是單獨掛載的,這也是為什么kubelet能夠對hostname進行修改并且Pod 重建后依然有效的原因這跟 Docke的Init層是一個原理
用途
ClusterIP模式的Service為你提供的,就是一個Pod的穩定的IP地址,即VIP. 并且,這里Pod和Service的關系是可以通過Label確定的
HeadlessService為你提供的,則是一個Pod的穩定的DNS名字,并且,這個名字是可以通過Pod名字和Service名字拼接出來
服務發現: 即當我的一個服務(Pod)的IP地址是不固定的且沒辦法提前獲知時,該如何通過一個固定的方式訪問到這個Pod
總結
以上是生活随笔為你收集整理的k8的service和DNS服务发现机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 快手怎么开美颜和滤镜直播
- 下一篇: java修饰类的关键字_JAVA中的修饰