K8s 中,“集群”是一个逻辑概念,而不是物理位置。只要这些 Pod 和 Service 是通过同一个集群的 API Server 创建和管理的,它们就属于同一个集群,无论它们被调度到了哪个物理节点上。
kubectl get pods -o wide (观察 NODE 列,它们可能分布在不同节点)。kubectl get endpoints <service-name>。如果 Endpoints 列表中包含了你创建的 Pod 的 IP,说明它们不仅在同一集群,而且 Service 已经成功发现了这些 Pod。kubectl 命令行工具当前连接的是哪个集群使用 kubectl cluster-info 命令,它会直接显示当前正在交互的 Kubernetes 控制平面(API Server)的地址:Kubernetes control plane is running at https://172.20.0.1:6443 CoreDNS is running at https://172.20.0.1:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
https://172.20.0.1:6443 就是当前管理你所有资源的 API Server 地址。kubectl 是通过读取本地的配置文件(通常位于 ~/.kube/config)来获取集群连接信息的kubectl config view --raw
clusters: - cluster: server: https://172.20.0.1:6443 # 这就是 API Server 地址 name: kubernetes
想知道运行在集群内部的 Pod 是否连接到同一个 API Server,可以进入 Pod 内部查看环境变量。Kubernetes 会自动为每个 Pod 注入以下环境变量:env | grep KUBERNETES_SERVICE
这里的 KUBERNETES_SERVICE_HOST 是集群内部通过 Service 访问 API Server 的虚拟 IP(ClusterIP),而你在外部通过 kubectl cluster-info 看到的通常是负载均衡器或控制平面节点的真实 IP。虽然 IP 不同,但它们指向的是同一个集群的同一个 API Server。
其实只要是通过执行 kubeadm join 命令成功加入的节点,它们就毫无疑问属于同一个 Kubernetes 集群。它们都持有合法的 Token,并且成功向同一个 kube-apiserver 注册,它们就在逻辑上属于同一个集群,共享同一个 etcd 数据库,受同一个调度器(Scheduler)管理。
第二个问题:
整个集群共用一套 CoreDNS。
CoreDNS 是集群级别的全局组件,通常部署在 kube-system 命名空间下。当你在集群中创建 Service 或特定的 Pod 时,CoreDNS 会自动监听这些资源的变化,并为其生成相应的 DNS 记录。集群内的所有 Pod 都会将 CoreDNS 作为默认的域名解析服务器。
第三个问题:
nslookup my-service。nslookup my-service.another-namespace。<service-name>.<namespace>.svc.cluster.local。hostname 和 subdomain,并且 subdomain 与某个 Service 的名称相同,那么该 Pod 就可以被解析,格式为 <hostname>.<subdomain>.<namespace>.svc.cluster.local。nslookup 时,Pod 会查看自己的 /etc/resolv.conf 文件。Kubelet 在创建 Pod 时,默认会将该文件中的 nameserver 指向集群的 CoreDNS 地址(即 kube-dns 的 ClusterIP),从而保证集群内所有节点上的 Pod 都能通过统一的 CoreDNS 进行服务发现。