前置资料
Service
  • Service 是为一组 Pod 提供相同的 DNS, 并且可以在它们之间进行负载均衡。

虚拟 IP 和 Service 代理
  • Kubernetes 集群中,每个 Node 运行一个 kube-proxy 进程。 kube-proxy 负责为 Service 实现了一种 VIP(虚拟 IP) 的形式,而不是 ExternalName 的形式。

为什么不使用 DNS 轮询?
  • 不使用 DNS 轮询,有以下几个原因
    • DNS 实现的历史由来已久,它不遵守记录 TTL,并且在名称查找到结果后对其进行缓存。
    • 有些应用程序仅执行一次 DNS 查找,并无限期地缓存结果
    • 即使应用和库进行了适当的重新解析,DNS 记录上的 TTL或为可能会给 DNS 带来高负载,从而使管理变得困难

Service 类型
  • ClusterIP:通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。 这也是默认的 ServiceType

  • NodePort:通过每个节点上的 IP 和静态端口(NodePort)暴露服务。 NodePort 服务会路由到自动创建的 ClusterIP 服务。 通过请求 <节点 IP>:<节点端口>,你可以从集群的外部访问一个 NodePort 服务。

  • LoadBalancer:使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上。

  • ExternalName:通过返回 CNAME 和对应值,可以将服务映射到 externalName 字段的内容(例如,foo.bar.example.com。 无需创建任何类型代理。



无头服务(Headless Service)

Pod 与 Service 的 DNS

  • 有的时候你不需要或者不想要负载均衡,或者不想要单独的 Service IP
    • 这种情况,可以通过指定 Cluster IP(spec.clusterIP) 的值为 "None" 来创建 Headless Service
    • 你可以使用 无头Service 与其他服务发现机制进行接口,而不必与 Kubernetes 的实现捆绑在一起。
    • 对于无头Service K8S 不会分配Cluster IPkube-proxy 也不会处理它们,而且平台也不会为它们进行负载均衡路由

  • 那么想要在 K8S 中使用它,我们可以通过 k8s 的 DNS来找到它,那么DNS又是根据什么配置的呢?
    • DNS 如何实现自动配置,依赖于 Service 是否定义了选择器(spec.selector)。

实战,创建3种不同的Service

关注后解锁




ExternalName 类型

类型为 ExternalName 的ServiceService名称 映射到 DNS,而不是使用典型的选择算符。 你可以使用 spec.externalName 参数指定外部服务地址
例如,以下 Service 定义将 prod 命名空间中的 my-service 服务映射到 my.database.example.com

apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com
警告

对于一些常见的协议,包括 HTTPHTTPS,你使用 ExternalName 可能会遇到问题。如果你使用 ExternalName,那么集群内客户端使用的主机名ExternalName 引用的名称不同

对于使用主机名的协议,此差异可能会导致错误或意外响应。 HTTP 请求将具有源服务器无法识别的 Host: 标头TLS 服务器将无法提供与客户端连接的主机名匹配的证书。




分类: Kubernetes

毛巳煜

高级软件开发全栈架构师