初識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),通過nslookup 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);