K8s Service 工作原理及使用 笔记(Kubernetes v1.29 配套教程)
1. 前置说明
- 本部分为前期口误内容的更正与实验注意事项:
- 前期讲解存在口误,对两个相似的Service参数选项说明有误,现重新讲解。
- 实验规范:做K8s实验时务必清理之前不关联的实验残留,禁止在旧实验环境上直接新建实验,避免出现不可预知的异常问题。
2. NodePort 类型与 externalTrafficPolicy 参数
externalTrafficPolicy参数用于定义NodePort的外部流量路由策略,有两个可选值:Cluster(默认):开启跨节点负载均衡,访问任意节点的NodePort,流量会被负载到集群内所有运行对应Pod的节点。Local:仅将流量路由到当前访问节点上的对应Pod,若当前节点无对应Pod,则直接丢弃请求,无跨节点转发。
- 实验验证:
- 资源清单说明:
- 第一个资源为Deployment:3副本,配置3组key-value标签,Pod模板需包含匹配Deployment标签的标签,使用指定镜像,容器端口为80。
- 第二个资源为Service:类型为NodePort,选择器匹配Deployment的标签,端口配置为集群端口80、后端Pod端口80、外部节点端口30010。
- 实验现象:
- 默认
externalTrafficPolicy为Cluster时,访问任意节点的30010端口,均可实现负载均衡,请求会被分发到不同节点的Pod。 - 将
externalTrafficPolicy修改为Local(注意首字母大写)后:- 访问运行了对应Pod的节点(如master01、node01)的30010端口,请求仅会被路由到当前节点的Pod,无负载均衡效果。
- 访问未运行对应Pod的节点(如master03)的30010端口,无法访问,请求被丢弃。
- 默认
- 资源清单说明:
3. NodePort 的局限性与 LoadBalancer 类型
- NodePort 的高可用局限性:
- 纯NodePort方案无法实现高可用:若某节点宕机,该节点的NodePort将无法访问,虽然其他节点的NodePort仍可用,但无法自动故障转移。
- 私有环境通常需要前置四层/七层负载均衡器(如F5、LVS、Nginx等)实现高可用,将用户流量负载到多个节点的NodePort上,单节点故障不影响服务。
- LoadBalancer 类型:
- 定位:在NodePort基础上,由云服务商直接提供公网负载均衡能力,无需自行搭建前置负载,自动实现高可用。
- 适用场景:仅适用于云环境(如阿里云、华为云、百度云等),目前开源模拟云厂商LBaaS(负载均衡即服务)的方案稳定性不足,不推荐在生产环境使用。
- 工作原理:用户请求先到达云厂商的负载均衡实例,负载均衡将流量转发到集群各节点的NodePort,再通过集群内IPVS将流量负载到对应Pod,单节点故障时流量自动切换到其他正常节点。
- 阿里云LoadBalancer资源清单核心配置:
annotations中需配置阿里云负载均衡实例的ID、默认同意协议等云厂商专属参数。- Service标签、命名空间、端口配置(集群端口80、节点端口80、协议TCP)、选择器匹配对应Pod标签,类型设置为
LoadBalancer,创建后会自动绑定公网IP。
- Labels 与 Annotations 的核心区别:
- Labels:是K8s官方定义的键值对,主要用于集群内部资源的筛选匹配,是官方通用的规则,如Service通过标签选择Pod、Deployment通过标签管理Pod、kubectl通过标签删除资源等,所有K8s原生组件均支持Labels的使用。
- Annotations:是用户/第三方组件自定义的非官方键值对,是自定义约定的配置项,仅约定的双方(如K8s与云厂商、K8s与Ingress控制器)识别,其他组件写入无意义,如云厂商的负载均衡ID就配置在Annotations中,仅对应云厂商的K8s插件会识别。
4. ExternalName 类型
- 核心特性:
- 是四种Service类型中最特殊的一种,不需要IPVS参与,仅靠集群CoreDNS插件即可实现功能。
- 作用:将集群外部服务通过DNS别名映射到集群内部,解决外部服务IP/域名变更时,集群内多个Pod需要批量修改配置的问题,实现内外服务解耦。
- 工作原理:
- 创建
ExternalName类型的Service,指定externalName字段为外部服务的域名/IP。 - 集群内Pod访问该Service的专属DNS域名(格式为
<service-name>.<namespace>.svc.cluster.local)时,CoreDNS会直接返回externalName对应的解析结果,相当于做了一个CNAME别名。
- 创建
- 资源清单核心配置:
- Service类型设置为
ExternalName,仅需配置metadata(名称、命名空间)和externalName字段,无需配置ClusterIP、端口、选择器等参数。 - 资源清单的字段顺序无要求,仅需保证层级关系正确即可。
- Service类型设置为
- 实验验证:
- 创建ExternalName Service,
externalName设置为www.baidu.com。 - 进入集群内Pod,ping该Service的DNS域名,可解析到百度的公网IP(110.232.68.4),访问该IP可正常打开百度首页,验证别名生效。
- 创建ExternalName Service,
- 注意事项:
- ExternalName仅集群内部Pod/工具可访问,集群外部客户端无法使用,因为外部客户端的DNS不会指向集群的CoreDNS,无法完成别名解析。
- 若外部服务的地址发生变更,仅需修改ExternalName Service的
externalName字段,所有关联Pod的访问配置无需修改,维护成本极低。
5. 四种Service类型总结
- ClusterIP:默认类型,仅支持集群内部访问,用于Pod之间、不同集群之间的服务调用,依赖IPVS实现负载。
- NodePort:ClusterIP的加强版,暴露节点物理IP的端口,支持集群外部访问,依赖IPVS,支持配置
externalTrafficPolicy调整路由策略。 - LoadBalancer:在NodePort基础上增加云厂商公网负载均衡能力,自动实现高可用,无需自行搭建前置负载,仅适用于云环境,依赖IPVS。
- ExternalName:不依赖IPVS,仅靠CoreDNS实现,将集群外部服务映射为集群内部域名,实现内外服务解耦,仅集群内部可用。
6. 补充:ClusterIP 会话保持配置
- 参数说明:
sessionAffinity参数用于开启ClusterIP的会话保持(亲和性),可选值为None(默认,关闭)、ClientIP(开启,基于客户端IP保持会话)。 - 默认超时时间:开启会话保持后,默认会话持久时间为3小时,超时后亲和性记录自动失效。
- 适用场景:主要用于HTPS服务的负载均衡,保证同一客户端的请求始终路由到同一个Pod,避免会话丢失问题。
- 配置与查看方式:可通过
kubectl edit svc <service-name>修改Service的sessionAffinity参数,也可通过ipvsadm -L命令查看IPVS的亲和性记录。
AI 总结
本视频为Kubernetes Service类型的实战教学,首先纠正了前期参数讲解的口误,明确了实验需清理残留的规范要求;接着通过实验验证了NodePort的externalTrafficPolicy参数(Cluster/Local)的流量路由差异,明确了Local策略仅路由到当前节点Pod、无Pod则丢弃的特性;随后分析了NodePort的高可用局限性,引出仅适用于云环境的LoadBalancer类型,同时厘清了K8s官方Labels与第三方自定义Annotations的核心区别;最后讲解了无需IPVS、仅靠CoreDNS实现的ExternalName类型,用于解决集群外部服务的访问解耦问题,最终梳理了四种Service类型的定位、适用场景与核心配置,补充了ClusterIP会话保持的配置方法与适用场景,帮助学习者全面掌握K8s Service的核心原理与使用方法。