初識headless型別的service

第一次使用rancher搭建了一個k8s叢集,迫不及待地按照官方文件開始新增workload,ingress進行測試,使用自己地程式碼自己打包的映象進行簡單的測試。在新增一個ingressA之後,在service discovery tab中看到自動也給我新建了一個serviceA,自己在叢集中再啟動了一個ubuntu的映象,嘗試著直接curl serviceA 卻發現一直報錯80埠拒絕訪問。我的後端服務是8080埠,可是在ingressA和這個servuceA中我明明都加了埠對映的,即targetPort=8080,port=80,serviceA的型別也是ClusterIP的,按照kubernetes的官方介紹來看我在叢集內部訪問這個服務應該是用80端口才對,然而卻一直報80埠拒絕訪問。然後使用curl serviceA:8080,竟然意外地訪問通了!然後使用kubectl describe svc serviceA檢視詳細資訊的時候才發現這個service的clusterip竟然是none。接著在kubernetes官方檢視service的描述,才發現一個關鍵詞:headless

開始研究headless型別的service

檢視官方文件,發現這種型別的service主要是用來返回一系列ip地址的,所謂的這種型別的service只是新增了一條dns記錄,不會進行負載均衡,也不會走kubeproxy,似懂非懂的查找了一些列資料之後終於找到了一篇描述的比較詳細的文章https://medium.com/swlh/discovering-running-pods-by-using-dns-and-headless-services-in-kubernetes-7002a50747f4

headless型別的service之我的理解



即新增這種型別的service的時候,會在叢集內部新增一條dns記錄,這條dns記錄表示通過這個服務名字可以訪問到的後端服務ip地址(一組pod的內部ip地址,endpoints),通過nslooklook serviceA 或者dig +search serviceA命令可以檢視到該條dns記錄

當時也還是不明白返回這樣一條dns記錄有什麼用,後邊才明白,在程式內部可以通過這個服務名稱進行dns解析得到一組ip地址,然後在自己的程式內部進行比如負載均衡流量控制之類的操作,比如返回的有三個pod的redis的地址,redis客戶端程式可以自定義連線建立的演算法,自己決定某個時刻連線哪個ip的服務。有的時候恰好就有這種的需求,比如redis、mongodb叢集,這種需要客戶端自定義負載均衡演算法和管理連線,瞬間清晰了。

System.Net.IPAddress[] ipAddresses = Dns.GetHostAddresses("serviceA");
string connectionString = "";
foreach(IPAddress in ipAddresses)
{
if(connectionString = "")
connectionString = "mongodb://";
else
connectionString += ",";
connectionString += $"{IPAddress.ToString()}:27017";
}
connectionString += "/database";
var client = new MongoClient(connectionString);