前置资料
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)
- 有的时候你不需要或者不想要负载均衡,或者不想要单独的 Service IP。
- 这种情况,可以通过指定 Cluster IP(spec.clusterIP) 的值为
"None"
来创建 Headless Service。- 你可以使用 无头Service 与其他服务发现机制进行接口,而不必与 Kubernetes 的实现捆绑在一起。
- 对于无头Service K8S 不会分配
Cluster IP
,kube-proxy 也不会处理它们,而且平台也不会为它们进行负载均衡
和路由
。
- 那么想要在 K8S 中使用它,我们可以通过 k8s 的 DNS来找到它,那么DNS又是根据什么配置的呢?
- DNS 如何实现自动配置,依赖于 Service 是否定义了选择器(spec.selector)。
实战,创建3种不同的Service
关注后解锁
ExternalName 类型
类型为 ExternalName 的Service 将 Service名称 映射到 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
警告
:
对于一些常见的协议,包括 HTTP 和 HTTPS,你使用 ExternalName 可能会遇到问题。如果你使用 ExternalName,那么集群内客户端使用的主机名与 ExternalName 引用的名称不同。
对于使用主机名的协议,此差异可能会导致错误或意外响应。 HTTP 请求将具有源服务器无法识别的
Host: 标头
; TLS 服务器将无法提供与客户端连接的主机名匹配的证书。