初识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);