Kubernetes——服务暴露
服务暴露
Service 的 IP 地址仅在集群内可达,然而,总会有些服务需要暴露到外部网络中接受各类客户端的访问,例如分层架构应用中的前端 Web 应用程序等。此时,就需要在集群的边缘为其添加一层转发机制,以实现将外部请求流量接入到集群的 Service 资源之上,这种操作也称为发布服务到外部网络中。
一、Service 类型
Kubernetes 的 Service 共有四种类型:ClusterIP、NodePort、LoadBalancer 和 ExternalName。
ClusterIP: 此为默认的 Service 类型,自动分配一个仅 Cluster 内部可以访问的虚拟 IP。
NodePort: 这种类型建立在 ClusterIP 类型之上,其在每个节点的 IP 地址的某静态端口(NodePort)暴露服务,因此,它依然会为 Service 分配集群 IP 地址,并将此作为 NodePort 的路由目标。这种类型的 Servcie 既可如 ClusterIP 一样受到集群内部客户端 Pod 的访问,也会受到集群外部客户端通过套接字 <NodeIP>:<NodePort> 进行的请求。
LoadBalancer:这种类型建立在 NodePort 类型之上,其通过 cloud provider 提供的负载均衡器将服务暴露到集群外部,因此 LoadBalancer 一样具有 NodePort 和 ClusterIP。简单的说,就是一个 LoadBalancer 类型的 Service 会指向关联至 Kubernetes 集群外部的、切实存在的某个负载均衡设备,该设备通过工作节点之上的 NodePort 向集群内部发送请求流量。

EXternalName:其通过将 Service 映射至由 externalName 字段的内容指定的主机名来暴露服务,此主机名需要被 DNS 服务解析至 CNAME 类型的记录。此种类型并非定义由 Kubernetes 集群提供的服务,而是把集群外部的某服务以 DNS CNAME 记录的方式映射到集群内,从而让集群内的 Pod 资源能够访问外部的 Service 的一种实现方式。因此,这种类型的 Service 没有 CluserIP 和 NodePort,也没有标签选择器用于选择 Pod 资源,因此也不会有 Endpoints 存在。
二、NodePort 类型的 Service 资源
NodePort 即节点 Port,通常在安装部署 Kubernetes 集群系统时会预留一个 端口范围用于 NodePort,默认为 30000~32767 之间的端口。
与 ClusterIP 类型的可省略 .spec.type 属性有所不同的是,定义 NodePort 类型的 Service 资源时,需要通过此属性明确指定其类型名称。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | kind: Service apiVersion: v1 metadata: name: XXX-smc-biz namespace: XXX-smc-parent labels: app: XXX-smc-biz app.kubernetes.io /name : XXX-smc-biz app.kubernetes.io /version : v1 XXX-org: XXX annotations: helm.sh /hook : 'pre-install, pre-upgrade' spec: ports: - name: http-8982 protocol: TCP port: 8982 targetPort: 8982 nodePort: 31569 selector: app: XXX-smc-biz app.kubernetes.io /name : XXX-smc-biz app.kubernetes.io /version : v1 XXX-org: XXX clusterIP: 10.233.0.127 type : NodePort sessionAffinity: None externalTrafficPolicy: Cluster |
流量走向:
NodePort 类型的 Service 资源虽然能够于集群外部访问得到,但外部客户端必须得事先得知 NodePort 和集群中至少一个节点的 IP 地址,且选定的节点发生故障时,客户端还得自行选择请求访问其他的节点。另外,集群节点很可能是某 IaaS 云环境中使用私有云 IP 地址的 VM,或者是 IDC 中使用私有地址的物理机,这类地址对互联网客户端不可达,因此一般还应该在集群之外创建一个具有公网 IP 地址的负载均衡器,由它接入外部客户端的请求并调度至集群节点相应的 NodePort 之上。
三、LoadBalance 类型的 Service 资源
IaaS 云计算环境通常提供了 LBaaS(Load Balancer a Service)服务,它允许租户动态地在自己的网络中创建一个负载均衡设备。那些部署于此类环境上的 Kubernetes 集群在创建 Service 资源时,可以直接调用此接口按需创建出一个软负载均衡器,而具有这种功能的 Service 资源即为 LoadBalancer 类型。
下面是一个 LoadBalancer 类型的 Service 资源配置清单,若 Kubernetes 系统满足其使用条件,即可自行进行应用测试。需要注意的是,有些环境中可能还需要为 Service 资源的配置定义添加 Annotations,必须时请自行参考 Kubernetes 官方文档说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 | kind: servic apiVersion: v1 metadata: name: myapp-svc-lb spec: type : LoadBalancer selector: app: myapp ports: - protocol: TCP port: 80 targetPort: 80 nodePort: 3223 |
四、ExternalName Service
ExternalName 类型的 Service 资源用于将集群外部的服务发布到集群中以供 Pod 中的应用程序访问,因此,它不需要使用标签选择器关联任何的 Pod 对象,但必须要使用 spec.externalName 属性定义一个 CNAME 记录用于返回外部真正提供服务的主机的别名,而后通过 CNAME 记录值获取到相关主机的 IP 地址。
下面是一个 ExternalName 类型的 Service 资源示例,名为 external-redis-svc,相应的 externalName 为 "redis.xxx.com":
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | kind: servic apiVersion: v1 metadata: name: external-redis-svc namespace: default spec: type : ExternalName externalName: redis.xxx.com ports: - protocol: TCP port: 6379 targetPort: 6379 nodePort: 0 selector: {} |
待 Service 资源 external-redis-svc 创建完成后,各 Pod 资源对象可通过 external-redis-svc 或其 FQDN 格式的名称 external-redis-svc.default.svc.cluster.local 访问相应的服务。
ClusterDNS 会将此名称以 CNAME 格式解析位 .spec.externalName 字段中的名称,而后通过 DNS 服务将其解析为相应的主机的 IP 地址。
由于 ExternalName 类型的 Service 资源实现基于 DNS 级别,客户端将直接接入外部的服务而完全不需要服务代理,因此,它也无须配置 ClusterIP,此种类型的服务也被称为 Headless Service。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2018-06-21 【SaltStack官方版】—— states教程, part 1 - 基础语法