一、将服务暴露给外部客户端
- NodePort:每个集群节点打开一个端口,并将在该端口上收到的流量重定向到该服务
- LoadBalance:NodePort 类型的一种扩展。服务通过一个专用的负载均衡器来访问,负载均衡器将流量重定向到跨所有节点的节点端口
- Ingress:通过一个 IP 地址公开多个服务。它运行在 HTTP 层(网络协议第七层,而服务运行在第四层)
1. 使用 NodePort 类型的服务
1 | apiVersion: v1 |
- 可通过
<node-ips>:30123
或<cluster-ip>:80
访问
2. 使用 LoadBalancer 类型的服务
- 负载均衡器拥有独一无二的可公开访问的 IP 地址,并将连接重定向到服务
- 若 K8s 在不支持 LoadBalancer 服务的环境中运行,则不会调用负载均衡器,此时服务仍表现为 NodePort 服务
1 | spec: |
- 可通过
<external-ip>:80
访问
3. 外部连接的特性
(1) 网络跳数
- 当访问到某个节点的端口,服务随机转发 Pod,此时 Pod 可能不在此节点上,这就需要额外的网络跳转。可将服务配置为仅将外部连接重定向到接收该连接的节点上的 Pod 来阻止跳转:
1 | spec: |
- 如果服务定义包含此配置,若无本地 Pod 存在,连接将挂起,而且可能会导致 Pod 的负载分布不均衡
(2) 客户端 IP 不会被记录
- 当集群内的客户端连接到服务时,支持服务的 Pod 可以获取客户端的 IP 地址。但是当通过节点端口接收到连接时,由于对数据包执行了源网络地址转换(SNAT),因此数据包的源 IP 将发生更改
- Local 外部流量策略会保留客户端 IP,因为接收连接的节点和 Pod 所在节点没有额外跳跃(不执行 SNAT)
二、通过 Ingress 暴露服务
- 每个 LoadBalancer 服务都需要自己的负载均衡器以及独有的公有 IP,而 Ingress 只需一个公网 IP 便可为多个服务提供访问
- 客户端向 Ingress 发送 HTTP 请求时,Ingress 会根据请求的主机名和路径决定请求转发到的服务
- Ingress 在网络栈(HTTP)的应用层,可以提供一些服务不能实现的功能。如基于 Cookie 的会话亲和性
- 只有 Ingress 控制器在集群中运行,Ingress 资源才能正常工作。不同的 K8s 环境使用不同的控制器实现,有些不提供默认控制器
- Ingress 目前支持 L7(网络第七层)(HTTP/HTTPS)负载均衡,计划支持 L4 负载均衡
1. 创建 Ingress 资源
1 | $ cat ig.yaml |
2. Ingress 工作原理
- 客户端首先对 kubia.example.com 执行 DNS 查找,DNS 服务器(或本地操作系统)返回 Ingress 控制器的 IP
- 客户端向 Ingress 控制器发送 HTTP 请求,并在 Host 头中指定 kubia.example.com
- 控制器从该头部确定客户端尝试访问哪个服务,通过与服务关联的 EndPoint 查看 Pod IP,并将请求转发给其中一个 Pod
3. 暴露多个服务
- 将不同的服务映射到不同主机的不同路径
1 | spec: |
4. 处理 TLS 传输
- 当客户端创建到 Ingress 控制器的 TLS 连接时,控制器将终止 TLS 连接。客户端和控制器之间的通信是加密的,而控制器和后端 Pod 之间的通信不是。运行在 Pod 上的应用程序不需要支持 TLS
- 需要将证书和私钥附加到 Ingress :
1 | $ openssl genrsa -out tls.key 2048 |
- 更新 Ingress 对象,让其接收 kubia.example.com 的 HTTPS 请求
1 | $ cat ig.yaml |