
在微服务的世界里,最让人头疼的问题之一就是 “我怎么找到你?”。
想象一下,你有几十上百个服务副本,每个 Pod 的 IP 地址都像是临时旅馆的房号——今天住 101,明天就可能换到 307。要是每个调用方都去记 Pod 的 IP,不仅累死人,还容易出错。
这时候,Kubernetes 伸出了一只温柔的手:服务发现(Service Discovery)。它告诉你,不用再管谁在哪,记住一个名字就行,剩下的我来搞定。
接下来,我们就一起来聊聊 Kubernetes 的服务发现机制,看看它是怎么帮我们解决这个“找人”的问题,并结合 Go 语言的代码示例,看看在实战中如何应用。
在传统架构里,运维人员可能要手工维护一份 IP 地址清单,或者通过配置文件告诉应用:“你要去找数据库,就连这个 192.168.1.23;要找 Redis,就去 192.168.1.45。”
但是在 Kubernetes 的世界里,Pod 会被频繁创建和销毁,IP 地址完全不固定。试想一下,如果还靠人来维护这种清单,那简直是灾难。
所以,服务发现的核心目标就是:屏蔽 Pod 动态变化,提供一个稳定的服务访问入口。
当 Pod 启动时,Kubelet 会自动把集群里现有的 Service 信息注入到 Pod 的环境变量里。
举个例子,如果有个叫 redis 的 Service,那么 Pod 内会有类似的环境变量:
REDIS_SERVICE_HOST=10.0.0.15
REDIS_SERVICE_PORT=6379在应用程序里,我们可以直接读取这些环境变量,然后建立连接。
优点:零配置、简单直接。
缺点:Pod 启动之后才创建的 Service,不会被感知。换句话说,这个方式“有点傻”,不太适合动态变化很频繁的场景。
DNS 是 Kubernetes 服务发现的主流方式。它由 CoreDNS 组件负责。
每个 Service 都会被自动分配一个 DNS 名称,比如:
my-service.my-namespace.svc.cluster.local在 Pod 内,你只要直接访问 my-service:port,就能找到对应的服务。完全不需要知道背后有多少 Pod,也不需要记它们的 IP。
更神奇的是,如果你把 Service 定义成 Headless Service(即 ClusterIP: None),那么 DNS 会返回所有 Pod 的 IP。这种方式非常适合需要直连 Pod 的有状态服务(如 MySQL 主从集群)。
光说表面机制可能有点抽象,我们来扒一扒背后到底发生了什么:
一句话总结:
👉 Service 就像一个前台,Endpoints 是员工名单,kube-proxy 则是前台的小秘书,负责把客人引导到对应的员工。
在 Go 代码中,你只需用 Service 名称作为主机名即可:
conn, err := grpc.Dial("my-service:50051", grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}这里的 my-service 会自动解析成 Service 的 ClusterIP,流量再由 kube-proxy 转发到具体的 Pod。
有时候我们想要更多控制,比如写一个客户端负载均衡器。
addrs, _ := net.LookupHost("my-service")
for _, ip := range addrs {
fmt.Println("Pod IP:", ip)
}你可以拿到所有 Pod 的 IP,然后自己决定如何分配请求,比如按哈希取模,或者根据节点健康情况做选择。
如果你想实现更强大的服务发现(比如一个自研的服务治理框架),可以直接通过 client-go 监听 Endpoints 的变化:
config, _ := clientcmd.BuildConfigFromFlags("", "/root/.kube/config")
clientset, _ := kubernetes.NewForConfig(config)
watcher, _ := clientset.CoreV1().
Endpoints("default").
Watch(context.TODO(), metav1.ListOptions{
FieldSelector: "metadata.name=my-service",
})
for event := range watcher.ResultChan() {
fmt.Println("Event:", event.Type, event.Object)
}这样,你可以实时感知 Pod 的上下线,然后动态更新自己的连接池。
注意事项:
my-service.other-ns.svc.cluster.local。如果把 Kubernetes 比作一座大城市,Pod 就是流动的摊贩,每天换地方摆摊。
而 Service 就像是统一的招牌:
这就是 Kubernetes 服务发现的魅力——它让分布式世界的沟通,变得像打电话一样简单。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。