一、K8s 服务访问与 DNS 解析实践:从命令到网络通信的深入理解

二、环境与基础回顾

先看我们操作涉及的环境资源:

  • Service:有 nginx-svc 等,类型 NodePort,提供网络访问入口;还有 kube-dns 负责集群 DNS 解析 。
  • Pod:比如 dns-test 用于测试服务访问,nginx-deploy 相关 Pod 提供 nginx 服务 。

三、实践操作与原理剖析

(一)服务基本信息查看

1. 查看 Service 列表

执行 kubectl get svc,能看到 nginx-svc 信息:

NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
nginx-svc     NodePort    10.97.11.30     <none>        80:32598/TCP   22h
  • 解读CLUSTER-IP 是集群内虚拟 IP,NodePort 类型通过节点端口(32598 )对外暴露,后续会验证不同方式访问服务。
2. 查看 Service 详情

kubectl describe svc nginx-svc,关键信息:

Selector:                 app=nginx-deploy
IP:                       10.97.11.30
Endpoints:                10.244.1.63:80,10.244.2.72:80
NodePort:                 web  32598/TCP
  • 解读Selector 关联 app=nginx-deploy 的 Pod;Endpoints 是后端 Pod 端点,Service 会把流量转发到这些 Pod;NodePort 是节点暴露的端口,外部可通过 节点IP:32598 访问 。

(二)Pod 内访问 Service 实践

1. 进入测试 Pod

执行 kubectl exec -it dns-test -- sh,进入 dns-test Pod 内部,模拟应用间通信场景。

2. 简单域名访问(短域名)

在 Pod 内执行 wget http://nginx-svc,成功下载 nginx 欢迎页面:

Connecting to nginx-svc (10.97.11.30:80)
index.html           100% |********************************************************************************************************************|   612   0:00:00 ETA
  • 原理:K8s 集群 DNS(由 kube-dnscoredns 提供 )会自动解析服务短域名(nginx-svc )到对应的 CLUSTER-IP ,所以能直接通过服务名访问,这是集群内 Pod 间通信常用方式 。
3. 带命名空间访问(验证解析规则)

尝试 wget http://nginx-svc.default 失败,提示 bad address;改为 wget http://nginx-svc.default.svc.cluster.local 成功:

Connecting to nginx-svc.default.svc.cluster.local (10.97.11.30:80)
index.html           100% |********************************************************************************************************************|   612   0:00:00 ETA
  • 原理:K8s 集群 DNS 解析规则是 服务名.命名空间.svc.cluster.local ,默认命名空间是 default,所以完整域名要符合这个格式。短域名 nginx-svc 能解析,是因为 DNS 会自动补充当前命名空间等信息(在 default 命名空间下,可省略部分 ),但手动写 nginx-svc.default 不符合完整规则,导致解析失败,而完整格式 nginx-svc.default.svc.cluster.local 能正确解析到 CLUSTER-IP

(三)集群 DNS 服务查看

执行 kubectl get svc --all-namespaces,能看到 kube-dns 服务:

NAMESPACE     NAME             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
kube-system   kube-dns         ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP,9153/TCP   21d
  • 作用kube-dns 作为集群 DNS 服务,监听 53 端口(UDP/TCP ),为 Pod 提供域名解析能力,把服务名、Pod 域名等解析成对应的 IP,保障集群内网络通信的域名寻址 。

四、总结:K8s 服务访问与 DNS 解析流程

  1. 服务访问基础:Service 通过 CLUSTER-IP 提供集群内访问,NodePort 提供外部访问;Endpoints 动态关联后端 Pod,实现流量转发。
  2. DNS 解析逻辑:集群 DNS(如 kube-dns )遵循 服务名.命名空间.svc.cluster.local 规则解析域名,Pod 内可通过短域名(自动补充规则 )或完整域名访问服务,让应用间通信无需硬编码 IP,更灵活可靠。
  3. 实践验证:通过 dns-test Pod 内的 wget 操作,验证了短域名、完整域名解析的差异,也体现了 K8s 网络通信中 DNS 自动解析的便利性。

五、基础回顾:Service 与 Endpoint 的默认关联

先回顾下常规流程(结合之前实践 ):

  • Service:通过 selector(标签选择器 )自动关联 Pod,K8s 会为其维护对应的 Endpoint,比如 nginx-svc 关联 app=nginx-deploy 的 Pod,Endpoints 动态更新 Pod 端点 。
  • 访问验证:在 dns-test Pod 内,可通过服务名(短域名 )、完整域名访问,依赖 K8s 集群 DNS(如 kube-dns )解析,实现 Pod 间、Pod 与 Service 通信 。

六、进阶实践:自定义 Service 与 Endpoint,对接外部资源

(一)创建无 selector 的 Service

1. 编写 Service 配置文件

创建 nginx-svc-external.yaml,内容:

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc-external
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    targetPort: 80
    name: web
  type: ClusterIP 
  • 关键说明type: ClusterIP 表示服务仅集群内可访问;未设置 selector,K8s 不会自动关联 Pod,需后续手动配置 Endpoint 。
2. 创建并查看 Service

执行 kubectl create -f nginx-svc-external.yaml 创建服务,再用 kubectl get svc 查看:

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
nginx-svc-external   ClusterIP   10.100.247.49   <none>        80/TCP         7s
  • 特点:Service 已创建,但因无 selectorkubectl get ep 中无对应 Endpoint,服务暂时无法转发流量 。

(二)手动配置 Endpoint,对接外部 IP

1. 编写 Endpoint 配置文件

创建 nginx-ep-external.yaml,内容:

apiVersion: v1
kind: Endpoints
metadata:
  labels:
    app: nginx 
  name: nginx-svc-external 
  namespace: default 
subsets:
- addresses:
  - ip: 120.78.159.117 
  ports:
  - name: web 
    port: 80
    protocol: TCP
  • 关键匹配规则
    • metadata.name 需与 Service 名称一致(nginx-svc-external ),让 K8s 识别关联关系。
    • ports.name 需与 Service ports.name 一致(web ),保障端口映射正确。
    • addresses.ip 填写外部目标 IP(这里是通过 ping www.wolfcode.cn 解析的 120.78.159.117 ),实现 Service 流量转发到外部地址。
2. 创建并验证 Endpoint

执行 kubectl create -f nginx-ep-external.yaml 创建 Endpoint,再用 kubectl get ep 查看:

NAME                 ENDPOINTS                                                  AGE
nginx-svc-external   120.78.159.117:80                                          6s
  • 效果:手动为 nginx-svc-external 配置了 Endpoint,指向外部 IP 120.78.159.117:80,Service 现在具备转发集群内部流量到外部资源的能力 。

(三)在内部的 Pod 测试外部服务访问

进入 dns-test Pod(kubectl exec -it dns-test -- sh ),执行 wget http://nginx-svc-external

Connecting to nginx-svc-external (10.100.247.49:80)
Connecting to www.wolfcode.cn (120.78.159.117:80)
index.html           100% |********************************************************************************************************************| 72518   0:00:00 ETA
  • 原理:K8s 集群 DNS 解析 nginx-svc-external 到其 CLUSTER-IP10.100.247.49 ),Service 依据手动配置的 Endpoint,将流量转发到外部 IP 120.78.159.117:80,成功拉取到外部网站内容,实现了 K8s 服务与外部资源的通信 。

七、核心逻辑总结:Service 与 Endpoint 的协作模式

场景 Service 配置特点 Endpoint 关联方式 应用场景
常规 Pod 关联 selector(如 app=nginx-deploy K8s 自动根据 selector 关联 Pod,动态维护 Endpoint 集群内 Pod 提供服务,需动态扩容、自愈场景
对接外部资源 selector 手动创建 Endpoint,指定外部 IP、端口,通过名称、标签、端口匹配关联 需将集群内服务流量转发到外部(如 legacy 系统、公网服务 ),或自定义特殊端点场景

简单说,Service 是流量入口,Endpoint 定义流量出口:

  • 常规模式下,K8s 自动关联 Pod,适配集群内动态服务;
  • 手动模式下,我们可灵活对接外部资源,拓展 K8s 服务边界 。

K8s 服务类型全解析:从 ClusterIP 到 ExternalName 的实践与原理

一、开篇

在 Kubernetes 里,Service 是保障应用网络通信的核心组件,不同的 Service 类型 决定了服务的暴露方式和访问范围。从集群内访问的 ClusterIP,到对接外部域名的 ExternalName,再到面向集群外的 NodePort,每种类型都有独特应用场景。这篇博客结合实操,带大家吃透 K8s 主流 Service 类型,掌握服务暴露的关键逻辑 。

二、Service 类型分类与实操解析

(一)ClusterIP:集群内专属的虚拟 IP(基础且常用)

1. 配置与创建(回顾)

nginx-svc-external.yaml 为例:

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc-external
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    targetPort: 80
    name: web
  type: ClusterIP 

执行 kubectl create -f nginx-svc-external.yaml 创建,通过 kubectl get svc 查看:

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
nginx-svc-external   ClusterIP   10.100.247.49   <none>        80/TCP         22m
2. 核心特点
  • 访问范围:仅集群内部可访问,依赖 K8s 集群 DNS 解析服务名(如 nginx-svc-external )到 CLUSTER-IP10.100.247.49 ),适合集群内 Pod 间通信 。
  • 自动/手动关联 Endpoint:若配置 selector,K8s 自动关联 Pod 生成 Endpoint;也可手动配置 Endpoint 对接外部资源(如之前实践的外部 IP ),灵活度高但需关注资源稳定性 。

(二)ExternalName:对接外部域名的“别名”服务(拓展集群边界)

1. 配置与创建

编写 nginx-svc-external-name.yaml

apiVersion: v1
kind: Service
metadata:
  labels:
    app: wolfcode-external-domain
  name: wolfcode-external-domain
spec:
  type: ExternalName
  externalName: www.wolfcode.cn 

执行 kubectl create -f nginx-svc-external-name.yaml 创建,查看服务:

NAME                       TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)        AGE
wolfcode-external-domain   ExternalName   <none>          www.wolfcode.cn   <none>         3s
2. 核心逻辑(解析“CNAME 别名”)
  • DNS 转发机制:当 Pod 内访问 wolfcode-external-domain 时,K8s 集群 DNS 会将其解析为 externalName 定义的域名(www.wolfcode.cn ),实际是 CNAME 记录转发 。比如在 dns-test Pod 内 wget wolfcode-external-domain,会先解析到 www.wolfcode.cn 的 IP(120.78.159.117 ),再访问对应资源 。
  • 应用场景:适合将集群内服务流量导向外部域名(如关联企业外部系统、公网服务 ),无需关心外部 IP 变化(DNS 自动解析更新 ),但依赖外部域名的稳定性 。

(三)NodePort:集群外可访问的节点端口(简单但有局限)

1. 配置与特点(以 nginx-svc.yaml 为例)

配置片段:

spec:
  type: NodePort 
  ports:
  - port: 80 
    targetPort: 80 
    nodePort: 32598 

(注:nodePort 可不显式指定,K8s 会自动分配 30000 - 32767 间的端口 )
通过 kubectl get svc 查看:

NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
nginx-svc     NodePort    10.97.11.30     <none>        80:32598/TCP   22h
2. 工作原理与场景
  • 流量转发流程
    1. K8s 在每个节点(k8s-node1k8s-node2 等 )的 kube-proxy 组件上,绑定 nodePort(如 32598 )。
    2. 集群外访问时,通过 任意节点 IP + nodePort(如 192.168.132.131:32598 ),kube-proxy 会将流量转发到 Service 关联的 Pod(依据 Endpoint )。
  • 优缺点与适用场景
    • 优点:配置简单,快速实现集群外访问;适合测试环境、小规模应用临时暴露服务 。
    • 缺点
      • 端口需在 30000 - 32767 范围,端口管理混乱(多服务易冲突 )。
      • 依赖节点网络,若节点 IP 变化或节点故障,需更新访问地址;生产环境中,节点直接暴露端口也存在安全风险(需额外做防火墙、负载均衡等防护 )。
    • 生产替代方案:推荐结合 Ingress(七层负载均衡,统一域名、路径转发 ),或使用云厂商 LoadBalancer 类型(自动关联云负载均衡器,更稳定、易管理 )。

(四)LoadBalancer:云环境专属的负载均衡(生产常用扩展)

1. 原理与关联(补充说明)

LoadBalancer 类型 Service 通常结合云厂商(如 AWS ELB、阿里云 SLB )的负载均衡器使用:

  • 配置 type: LoadBalancer 后,K8s 会向云平台申请创建负载均衡器,自动将其 IP 作为 Service 的 EXTERNAL-IP
  • 外部流量通过负载均衡器的公网 IP 进入,由负载均衡器转发到集群节点的 nodePort,再经 kube-proxy 到 Pod,流程类似 NodePort,但由云厂商负载均衡器统一管理入口,更稳定、可靠 。
2. 与 NodePort 对比
维度 NodePort LoadBalancer
外部访问入口 节点 IP + nodePort 负载均衡器公网 IP
端口管理 手动/自动分配 30000 - 32767 端口 云负载均衡器自动管理端口(无需关注 )
适用环境 测试环境、小规模临时暴露 生产环境,需稳定外部访问入口
依赖组件 kube-proxy、节点网络 云厂商负载均衡器、kube-proxy

四、总结与实践建议

  1. 核心选型逻辑
    • 集群内 Pod 通信 → ClusterIP(灵活关联 Pod 或外部资源 )。
    • 对接外部域名 → ExternalName(利用 DNS 转发,解耦集群内外域名 )。
    • 测试环境暴露 → NodePort(快速实现,但注意端口冲突、节点依赖 )。
    • 生产环境暴露 → LoadBalancer + Ingress(云环境用 LoadBalancer 做入口,Ingress 做七层路由,更安全、易管理 )。

深入解析 K8s ExternalName 服务的 CNAME 解析逻辑与实践对比

一、常规 Service(ClusterIP/NodePort)的 DNS 解析逻辑回顾

nginx-svc(ClusterIP 类型 )为例,在 dns-test Pod 内访问时:

(一)短域名访问(wget http://nginx-svc

  1. DNS 解析流程
    K8s 集群 DNS(如 kube-dns/coredns )会自动识别服务名 nginx-svc,并根据 命名空间(默认 default 补充完整域名规则,解析为 nginx-svc.default.svc.cluster.local
    最终通过集群 DNS 记录,找到 nginx-svc 对应的 CLUSTER-IP(如 10.97.11.30 )。
  2. 流量转发
    Pod 发起的请求(http://nginx-svc )被转发到 CLUSTER-IP:80,再由 Service 依据 Endpoints 转发到后端 Pod(如 nginx-deploy 的 Pod ),拿到 nginx 欢迎页。

(二)完整域名访问(wget http://nginx-svc.default.svc.cluster.local

  1. DNS 解析流程
    直接使用 K8s 集群 DNS 的 完整域名规则服务名.命名空间.svc.cluster.local ),无需自动补充,直接解析到 CLUSTER-IP
  2. 本质
    和短域名访问逻辑一致,只是手动写全了域名,验证了 K8s 集群 DNS 的解析规则。

(三)NodePort 外部访问(curl 192.168.132.133:32598

  1. 流量路径
    集群外通过 节点 IP + NodePort(如 192.168.132.133:32598 )访问时,请求先到节点的 kube-proxy,它会根据 Service 的 Endpoints,将流量转发到后端 Pod 。
  2. 区别
    这是集群外访问方式,依赖节点网络和 kube-proxy 的端口转发,和集群内 DNS 解析逻辑无关,但最终都通过 Endpoints 找到 Pod 。

二、ExternalName 服务的 CNAME 解析逻辑(以 wolfcode-external-domain 为例)

(一)配置与核心机制

wolfcode-external-domain 的配置:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: wolfcode-external-domain
  name: wolfcode-external-domain
spec:
  type: ExternalName
  externalName: www.wolfcode.cn 
  1. DNS 解析的特殊逻辑
    当在 Pod 内访问 wolfcode-external-domain 时,K8s 集群 DNS 不会解析为 CLUSTER-IP,而是返回一个 CNAME 记录,把 wolfcode-external-domain 指向 externalName 定义的域名 www.wolfcode.cn
    举个例子:你访问 wolfcode-external-domain,集群 DNS 会告诉你“去访问 www.wolfcode.cn 吧”,这就是 CNAME 转发

  2. 实际访问流程(wget wolfcode-external-domain

    • 第一步:Pod 里执行 wget wolfcode-external-domain,先向集群 DNS 查询 wolfcode-external-domain 的解析。
    • 第二步:集群 DNS 返回 CNAME www.wolfcode.cn,Pod 再去查询 www.wolfcode.cn 的 IP(如 120.78.159.117 )。
    • 第三步:Pod 直接向 120.78.159.117:80 发起请求,拿到外部网站内容(如 www.wolfcode.cn 的页面 )。

(二)与常规 Service 的核心区别对比

对比维度 常规 Service(ClusterIP/NodePort) ExternalName Service
DNS 解析结果 解析为 K8s 集群内的 CLUSTER-IP(虚拟 IP ) 解析为外部域名的 CNAME 记录(如 www.wolfcode.cn
流量转发路径 Pod → Service(CLUSTER-IP )→ Endpoints → Pod(或外部 IP ) Pod → 外部域名(通过 CNAME 跳转 )→ 外部服务器
依赖的 K8s 资源 必须关联 Endpoints(自动/手动 ),依赖 K8s 网络组件(kube-proxy 不依赖 Endpoints,完全依赖外部域名的 DNS 解析
应用场景 集群内服务通信、集群内外暴露(NodePort/LoadBalancer ) 集群内服务需访问外部域名(如企业外部系统、公网服务 )
是否经过 K8s 转发 是(Service/Endpoints 转发 ) 否(直接跳转外部域名,绕开 K8s 转发逻辑 )

三、实践场景对比:两种访问方式的本质差异

(一)常规 Service 访问(nginx-svc

  • 流量闭环在 K8s 集群内
    不管是短域名还是完整域名访问,请求都在 K8s 集群内部流转(通过 CLUSTER-IPEndpoints ),依赖 K8s 的网络组件(kube-proxyEndpoints 等 )保障通信。
    比如访问 nginx-svc 时,即使后端 Pod 重建,K8s 会自动更新 Endpoints,保证服务可用。

(二)ExternalName 访问(wolfcode-external-domain

  • 流量跳出 K8s 集群,依赖外部 DNS
    请求通过 CNAME 跳转到外部域名,完全依赖外部 DNS 解析和外部服务器的可用性。
    比如 www.wolfcode.cn 的 IP 变化时,K8s 不关心(因为它只负责 CNAME 转发 ),但如果外部域名解析出问题(如域名过期、DNS 故障 ),访问就会失败。

四、总结:何时用 ExternalName?

  1. 典型场景

    • 集群内服务需要访问外部固定域名(如企业已有的外部系统、第三方公网服务 )。
    • 希望利用 K8s 的服务发现机制,统一管理“外部域名访问”(用 K8s 服务名替代硬编码的外部域名 )。
  2. 注意事项

    • 依赖外部域名的稳定性(需确保外部域名 DNS 解析正常、服务器可达 )。
    • 无法利用 K8s 的服务治理能力(如负载均衡、熔断、重试 ),因为流量直接跳出集群了。

https://github.com/0voice

Logo

「智能机器人开发者大赛」官方平台,致力于为开发者和参赛选手提供赛事技术指导、行业标准解读及团队实战案例解析;聚焦智能机器人开发全栈技术闭环,助力开发者攻克技术瓶颈,促进软硬件集成、场景应用及商业化落地的深度研讨。 加入智能机器人开发者社区iRobot Developer,与全球极客并肩突破技术边界,定义机器人开发的未来范式!

更多推荐