【Kubernetes】基础k8s服务内部访问,与DNS解析,手动配置Endpoint,与Service协作对接外部资源,ExternalName实现的CNAME转发
服务访问基础:Service 通过CLUSTER-IP提供集群内访问,NodePort提供外部访问;Endpoints动态关联后端 Pod,实现流量转发。DNS 解析逻辑:集群 DNS(如kube-dns)遵循 服务名.命名空间.svc.cluster.local规则解析域名,Pod 内可通过短域名(自动补充规则 )或完整域名访问服务,让应用间通信无需硬编码 IP,更灵活可靠。实践验证:通过dns
一、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-dns或coredns提供 )会自动解析服务短域名(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 解析流程
- 服务访问基础:Service 通过
CLUSTER-IP提供集群内访问,NodePort提供外部访问;Endpoints动态关联后端 Pod,实现流量转发。 - DNS 解析逻辑:集群 DNS(如
kube-dns)遵循服务名.命名空间.svc.cluster.local规则解析域名,Pod 内可通过短域名(自动补充规则 )或完整域名访问服务,让应用间通信无需硬编码 IP,更灵活可靠。 - 实践验证:通过
dns-testPod 内的wget操作,验证了短域名、完整域名解析的差异,也体现了 K8s 网络通信中 DNS 自动解析的便利性。
五、基础回顾:Service 与 Endpoint 的默认关联
先回顾下常规流程(结合之前实践 ):
- Service:通过
selector(标签选择器 )自动关联 Pod,K8s 会为其维护对应的 Endpoint,比如nginx-svc关联app=nginx-deploy的 Pod,Endpoints 动态更新 Pod 端点 。 - 访问验证:在
dns-testPod 内,可通过服务名(短域名 )、完整域名访问,依赖 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 已创建,但因无
selector,kubectl 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需与 Serviceports.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,指向外部 IP120.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-IP(10.100.247.49),Service 依据手动配置的 Endpoint,将流量转发到外部 IP120.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-IP(10.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-testPod 内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. 工作原理与场景
- 流量转发流程:
- K8s 在每个节点(
k8s-node1、k8s-node2等 )的kube-proxy组件上,绑定nodePort(如32598)。 - 集群外访问时,通过
任意节点 IP + nodePort(如192.168.132.131:32598),kube-proxy会将流量转发到 Service 关联的 Pod(依据 Endpoint )。
- K8s 在每个节点(
- 优缺点与适用场景:
- 优点:配置简单,快速实现集群外访问;适合测试环境、小规模应用临时暴露服务 。
- 缺点:
- 端口需在 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 |
四、总结与实践建议
- 核心选型逻辑:
- 集群内 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)
- DNS 解析流程:
K8s 集群 DNS(如kube-dns/coredns)会自动识别服务名nginx-svc,并根据 命名空间(默认default) 补充完整域名规则,解析为nginx-svc.default.svc.cluster.local。
最终通过集群 DNS 记录,找到nginx-svc对应的CLUSTER-IP(如10.97.11.30)。 - 流量转发:
Pod 发起的请求(http://nginx-svc)被转发到CLUSTER-IP:80,再由 Service 依据Endpoints转发到后端 Pod(如nginx-deploy的 Pod ),拿到 nginx 欢迎页。
(二)完整域名访问(wget http://nginx-svc.default.svc.cluster.local)
- DNS 解析流程:
直接使用 K8s 集群 DNS 的 完整域名规则(服务名.命名空间.svc.cluster.local),无需自动补充,直接解析到CLUSTER-IP。 - 本质:
和短域名访问逻辑一致,只是手动写全了域名,验证了 K8s 集群 DNS 的解析规则。
(三)NodePort 外部访问(curl 192.168.132.133:32598)
- 流量路径:
集群外通过节点 IP + NodePort(如192.168.132.133:32598)访问时,请求先到节点的kube-proxy,它会根据 Service 的Endpoints,将流量转发到后端 Pod 。 - 区别:
这是集群外访问方式,依赖节点网络和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
-
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 转发 。 -
实际访问流程(
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的页面 )。
- 第一步:Pod 里执行
(二)与常规 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-IP和Endpoints),依赖 K8s 的网络组件(kube-proxy、Endpoints等 )保障通信。
比如访问nginx-svc时,即使后端 Pod 重建,K8s 会自动更新Endpoints,保证服务可用。
(二)ExternalName 访问(wolfcode-external-domain)
- 流量跳出 K8s 集群,依赖外部 DNS:
请求通过 CNAME 跳转到外部域名,完全依赖外部 DNS 解析和外部服务器的可用性。
比如www.wolfcode.cn的 IP 变化时,K8s 不关心(因为它只负责 CNAME 转发 ),但如果外部域名解析出问题(如域名过期、DNS 故障 ),访问就会失败。
四、总结:何时用 ExternalName?
-
典型场景:
- 集群内服务需要访问外部固定域名(如企业已有的外部系统、第三方公网服务 )。
- 希望利用 K8s 的服务发现机制,统一管理“外部域名访问”(用 K8s 服务名替代硬编码的外部域名 )。
-
注意事项:
- 依赖外部域名的稳定性(需确保外部域名 DNS 解析正常、服务器可达 )。
- 无法利用 K8s 的服务治理能力(如负载均衡、熔断、重试 ),因为流量直接跳出集群了。
「智能机器人开发者大赛」官方平台,致力于为开发者和参赛选手提供赛事技术指导、行业标准解读及团队实战案例解析;聚焦智能机器人开发全栈技术闭环,助力开发者攻克技术瓶颈,促进软硬件集成、场景应用及商业化落地的深度研讨。 加入智能机器人开发者社区iRobot Developer,与全球极客并肩突破技术边界,定义机器人开发的未来范式!
更多推荐
所有评论(0)