天天看点

在 Kubernetess 中使用 DNS 和 Headless Service 发现运行中的 Pod

在 Kubernetess 中使用 DNS 和 Headless Service 发现运行中的 Pod

什么是 Headless Service?

部署 Service时,可以设置三种不同的 ​

​ServiceTypes​

​ 以指定所需的 Service 类型:

  • ClusterIP:仅在集群内部 ip 地址上公开 Service,这也是默认的​

    ​ServiceType​

    ​。
  • NodePort:允许通过节点上的静态端口公开 Service。
  • LoadBalancer:允许使用云提供商的外部负载均衡器公开 Service 。

为避免请求在单个 IP 地址后面进行负载均衡,当不需要单个 IP 地址时,我们可以通过指定 Cluster IP(​

​spec.clusterIP​

​​)的值为 ​

​"None"​

​ 来创建 Headless Service。Kubernetes 不会为该 Service 分配任何 IP 地址。这种 Service 就称为 Headless Services。

DNS 解析和 Headless Service

部署 Service 时,Kubernetes 会为其分配一个 DNS 名称。集群中的其他组件可以使用此名称与 DNS 和上游 Pod 通信。DNS 名称遵循以下命名约定:

在 Kubernetess 中使用 DNS 和 Headless Service 发现运行中的 Pod

在 IP 地址上使用可读名称后,其他组件就不需要分配给 Service 实际 IP 地址。

使用正确的 Pod 选择(selector)配置 Headless Service 时,Kubernetes 将为上游选定的 Pod 创建正确端点记录和 DNS 配置。

对于将连接到 Headless Service 的每个已连接 Pod,也会配置 A 或 AAAA 记录。这样就可以对 Headless Service 执行 DNS 查询,以解析所连接 Pod 的所有 IP 地址。

如何实践?

假设存在以下问题:Kubernetes 集群中运行着一组有状态的三个 MongoDB Pod。这三个 Pod 共同构成一个 MongoDB 副本集,这是一个高度可用的数据集。

在 Kubernetess 中使用 DNS 和 Headless Service 发现运行中的 Pod

为了能够将控制台应用程序连接到 MongoDB 副本集,我们使用 MongoDB C# 驱动程序,同时需要显式定义三个 Pod 的地址。

我们用 Headless Service 解决这个问题。假定 MongoDb Pod 都带有 ​

​app=mongodb​

​ 标签,该标签可以在 Headless Service 中用于选择 Pod。

我们定义的 Headless Service 资源如下所示:

在 Kubernetess 中使用 DNS 和 Headless Service 发现运行中的 Pod

通过将 ​

​clusterIp​

​​ 设置为 ​

​"none"​

​​,我们告诉 Kubernetes 将此 Service 视为 Headless Service。由于我们定义了名称和命名空间,因此可以推断出 DNS 名称。我们在集群内部使用 ​

​mongodb-headless-service.infrastructure.svc.cluster.local​

​​ 或 ​

​mongodb-headless-service.infrastructure​

​ 作为地址与 Service 进行通信。

接下来让我们来执行 DNS 查询,以检索连接 Pod 的 IP 地址。​

​Dns.GetHostAddresses​

​​ 方法位于 ​

​System.Net​

​ 命名空间中,可帮助我们执行该 DNS 查询并返回 IP 地址数组。它需要一个主机名或 IP 地址。最后,我们可以使用 MongoDB 创建连接字符串(connection string)。

代码如下:

在 Kubernetess 中使用 DNS 和 Headless Service 发现运行中的 Pod

通过该解决方案,我们可以动态创建连接字符串,其主要优点是,在必须扩展数据库集群时,我们不必手动更改连接字符串。

注意:MongoDB 确实通过 DNS 实现了类似的服务发现过程,只需定义 Headless Service 的 DNS 名称即可,这样我们就不必自己生成连接字符串。

Headless Service

继续阅读