当前位置: 首页 > news >正文

k8s之NDS解析到Ingress服务暴露

Kubernetes 服务发现与外部访问全解析:从 DNS 解析到 Ingress 暴露

在 Kubernetes 集群中,服务间的通信与外部访问是核心功能,而这一切都依赖于 DNS 解析机制和合理的服务暴露策略。本文将系统讲解 Kubernetes 内部服务域名的构成、Pod 的 DNS 配置原理,以及如何通过 Ingress 或 Nginx 将内部服务安全、高效地暴露给外部访问。

一、Kubernetes 内部服务域名:服务发现的基石

Kubernetes 为每个 Service 自动生成固定的内部域名,实现了 Pod 动态 IP 与固定访问入口的解耦。理解域名的构成规则是掌握服务发现的关键。

1. 服务域名的组成与含义

openapi.test.svc.cluster.local 为例,这个域名由四部分组成,遵循严格的命名规则:

  • openapi:Service 资源的名称(对应 metadata.name 字段);
  • test:Service 所在的命名空间(metadata.namespace);
  • svc:固定标识,表明这是一个 Kubernetes Service 资源;
  • cluster.local:集群域名后缀(默认值,可在集群初始化时通过 --cluster-domain 自定义)。

完整含义:该域名指向 test 命名空间下的 openapi 服务,是集群内部 Pod 间通信的固定地址。

2. 服务域名的核心作用

Service 域名的最大价值在于屏蔽 Pod IP 的动态变化。由于 Pod 重启、扩缩容等操作会导致 IP 改变,直接使用 Pod IP 通信极不稳定。而 Service 域名一旦创建便固定不变,无论后端 Pod 如何变化,都能通过域名稳定访问服务。

例如,在集群内任意 Pod 中,可直接通过以下命令访问目标服务:

curl http://openapi.test.svc.cluster.local:9090

二、Pod 的 DNS 配置:如何解析内部域名?

Pod 之所以能通过 Service 域名通信,依赖于其内部的 DNS 配置。Kubernetes 通过 resolv.conf 文件、dnsPolicy 策略和 dnsConfig 自定义配置,构建了一套灵活的域名解析体系。

1. 解析 Pod 中的 /etc/resolv.conf

在任意运行中的 Pod 内执行 cat /etc/resolv.conf,会看到类似以下的配置:

search default.svc.cluster.local svc.cluster.local cluster.local
nameserver 10.96.0.10
options ndots:5

这三行配置分别控制了域名解析的核心逻辑:

(1)search:自动补全域名后缀

search 字段定义了 DNS 搜索路径,作用是为短域名自动补充后缀,简化集群内访问。例如,当 Pod 中查询 nginx 时,系统会按以下顺序尝试解析:

  • nginx.default.svc.cluster.local(当前命名空间 + 服务后缀)
  • nginx.svc.cluster.local(集群通用服务后缀)
  • nginx.cluster.local(集群域名后缀)

这解释了为什么同命名空间的 Service 可直接通过名称访问(如 curl nginx)—— 搜索路径会自动补全完整域名。

搜索路径的生成规则

  • 以 Pod 所在命名空间为起点(如 default);
  • 依次拼接固定前缀 svc 和集群域名后缀(如 cluster.local);
  • 最终形成 [namespace].svc.[cluster-domain]svc.[cluster-domain][cluster-domain] 的层级结构。
(2)nameserver:指定 DNS 服务器

nameserver 10.96.0.10 明确了 Pod 中 DNS 请求的目标服务器,这个 IP 通常是 CoreDNS 服务的 ClusterIP(Kubernetes 内置的 DNS 服务)。

验证这一点可查看 kube-system 命名空间下的 kube-dns 服务:

kubectl -n kube-system get svc kube-dns
# 输出示例:
# NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
# kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   5d

CoreDNS 通过监听 Kubernetes API 中的 Service、Endpoint 等资源变化,实时更新本地缓存,确保域名解析的准确性。

(3)options ndots:5:控制解析策略

ndots:5 是 DNS 解析的关键参数,规则是:当查询的域名中点的数量少于 5 时,优先使用 search 路径补全后缀;否则直接解析原域名

例如:

  • 查询 nginx(0 个点):触发 search 补全;
  • 查询 www.kubernetes.io(3 个点):仍触发 search 补全(3 < 5);
  • 查询 a.b.c.d.e.f(6 个点):直接解析原域名,不使用 search

这一机制既简化了集群内短域名的使用,又避免了对外部域名解析的干扰。

2. DNS 配置的定制:dnsPolicydnsConfig

Pod 的 DNS 配置并非固定不变,可通过 dnsPolicy 策略和 dnsConfig 字段灵活调整。

(1)dnsPolicy:定义 DNS 策略

dnsPolicy 是 Pod .spec 中的字段,用于指定 DNS 配置的生成规则,支持 4 种策略:

策略名称说明
Default继承 Pod 所在节点的 /etc/resolv.conf(使用节点的 DNS 服务器)。
ClusterFirst优先使用集群 DNS(CoreDNS),非集群域名转发到节点的上游 DNS。
ClusterFirstWithHostNet用于 hostNetwork: true 的 Pod,强制使用集群 DNS(避免继承节点配置)。
None忽略集群默认配置,完全使用 dnsConfig 自定义。

注意事项

  • 默认策略为 ClusterFirst,适用于绝大多数场景;
  • 使用 hostNetwork: true 的 Pod 需显式设置 ClusterFirstWithHostNet,否则可能无法解析内部域名;
  • 自定义 DNS 需将 dnsPolicy 设为 None,并配合 dnsConfig 配置。
(2)dnsConfig:自定义 DNS 配置

dnsConfig 用于补充或覆盖默认 DNS 配置,支持 nameservers(DNS 服务器列表)、searches(搜索域)、options(解析选项)。

示例

apiVersion: v1
kind: Pod
metadata:name: dns-examplenamespace: default
spec:containers:- name: testimage: nginxdnsPolicy: "None"  # 必须与 dnsConfig 配合dnsConfig:nameservers:- 114.114.114.114  # 外部 DNS 服务器searches:- my-custom.search  # 自定义搜索域options:- name: ndotsvalue: "3"  # 覆盖默认的 ndots:5

生成的 resolv.conf 如下:

search my-custom.search
nameserver 114.114.114.114
options ndots:3

3. /etc/resolv.conf 的生成流程

默认情况下(dnsPolicy: ClusterFirst),resolv.conf 由 kubelet 动态生成,规则如下:

  • nameserver:来自 kubelet 配置的 clusterDNS 字段(通常为 CoreDNS 的 ClusterIP);
  • search:由 Pod 所在命名空间、svc 前缀和集群域名后缀拼接而成;
  • options:固定为 ndots:5(Kubernetes 优化集群内解析的默认设置)。

三、将内部服务暴露给外部:Ingress 与 Nginx 方案

Service 域名仅能在集群内部解析,外部客户端(如用户浏览器)需通过额外配置才能访问。目前主流方案有两种:Ingress Controller(推荐)和独立 Nginx 反向代理

1. 通过 Ingress Controller 暴露服务(生产环境推荐)

Ingress 是 Kubernetes 官方定义的外部访问规则集合,而 Ingress Controller 是实现这些规则的组件(通常基于 Nginx、Traefik 等),负责接收外部请求并转发到内部 Service。

(1)核心组件与流程
  • Ingress 资源:定义“外部域名 → 内部 Service”的映射规则(如 api.example.com 转发到 chogori-openapi.chogori.svc.cluster.local);
  • Ingress Controller:运行在集群中的 Pod,监听 Ingress 资源变化,自动生成代理配置,并暴露外部访问入口(如节点 IP + 端口)。

完整流程
外部客户端 → 访问外部域名(如 api.example.com)→ DNS 解析到 Ingress Controller 入口 IP → Ingress Controller 转发到内部 Service 域名 → Service 转发到后端 Pod。

(2)部署与配置示例(Nginx Ingress Controller)

步骤 1:部署 Ingress Controller
通过官方 YAML 部署 Nginx Ingress Controller:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml

查看其暴露的入口(通常为 NodePort 类型):

kubectl get svc -n ingress-nginx
# 输出示例:
# NAME                                 TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
# ingress-nginx-controller             NodePort   10.109.xx.xx    <none>        80:32080/TCP,443:32443/TCP   5m

外部可通过 节点 IP:32080(HTTP)访问。

步骤 2:创建 Ingress 规则
定义 Ingress 资源,将外部域名 api.example.com 映射到内部 Service:

# ingress-example.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:name: chogori-openapi-ingressnamespace: chogori
spec:ingressClassName: nginx  # 指定使用 Nginx Ingress Controllerrules:- host: api.example.com  # 外部域名(需解析到 Ingress 入口 IP)http:paths:- path: /pathType: Prefixbackend:service:name: chogori-openapi  # 内部 Service 名称port:number: 80  # Service 暴露的端口

应用配置:

kubectl apply -f ingress-example.yaml

步骤 3:外部访问验证

  1. 在 DNS 服务器中将 api.example.com 解析到 Ingress Controller 所在节点的 IP(如 192.168.1.100);
  2. 外部客户端访问 http://api.example.com:32080,请求会转发到内部服务。
(3)Ingress 的优势
  • 声明式配置:通过 YAML 定义规则,无需手动修改代理配置;
  • 自动更新:监听 Service/Ingress 变化,自动更新转发规则;
  • 功能丰富:支持 HTTPS、路径路由(如 /v1 到服务 A,/v2 到服务 B)、流量控制等。

2. 通过独立 Nginx 暴露服务(测试或简单场景)

若不使用 Ingress,可在集群外部署独立 Nginx 服务器,通过反向代理将外部请求转发到内部 Service 域名。

(1)核心原理

Nginx 配置中,将外部域名(如 api.example.com)的请求转发到集群内 Service 域名(如 http://chogori-openapi.chogori.svc.cluster.local:80)。
前提:Nginx 服务器需能访问集群网络(解析 Service 域名并连接 ClusterIP)。

(2)配置示例

在 Nginx 配置文件(nginx.conf)中添加规则:

server {listen 80;server_name api.example.com;  # 外部域名location / {# 转发到内部 Service 域名proxy_pass http://chogori-openapi.chogori.svc.cluster.local:80;# 传递客户端信息proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;}
}

重启 Nginx 后,外部访问 http://api.example.com 即可转发到内部服务。

(3)注意事项
  • 域名解析:需在 Nginx 服务器的 /etc/resolv.conf 中添加 CoreDNS 的 IP(10.96.0.10),确保能解析 Service 域名;
  • 网络可达:Nginx 需与集群网络打通(如同一 VPC),否则无法连接 Service 的 ClusterIP;
  • 手动维护:Service 域名或端口变化时,需手动更新 Nginx 配置。

3. 两种方案的对比

方式优势劣势适用场景
Ingress Controller声明式配置、自动更新、支持复杂规则需部署额外组件,学习成本稍高生产环境、多服务暴露、动态更新需求
独立 Nginx配置简单、无额外依赖需手动维护、扩展性差测试环境、单服务临时暴露

四、总结

Kubernetes 的服务发现与外部访问体系围绕“固定域名”展开:

  • 内部通过 CoreDNS 实现 Service 域名解析,Pod 的 resolv.conf 配置(searchnameserveroptions)简化了域名使用;
  • 外部通过 Ingress Controller 或独立 Nginx 建立“外部域名 → 内部 Service 域名”的映射,实现跨集群访问。

理解这一体系,不仅能解决日常的通信故障(如域名解析失败),还能根据场景选择合适的服务暴露策略,构建稳定、高效的 Kubernetes 网络架构。

http://www.lryc.cn/news/607065.html

相关文章:

  • Wisdom SSH开启高效管理服务器的大门
  • Git之远程仓库
  • 【全网首个公开VMware vCenter 靶场环境】 Vulntarget-o 正式上线
  • Linux(15)——进程间通信
  • VMware 下 Ubuntu 操作系统下载与安装指南
  • 用 TensorFlow 1.x 快速找出两幅图的差异 —— 完整实战与逐行解析 -Python程序图片找不同
  • Ubuntu-Server-24.04-LTS版本操作系统如何关闭自动更新,并移除不必要的内核
  • 使用 Vive Tracker 替代 T265 实现位姿获取(基于 Ubuntu + SteamVR)
  • 【云计算】云主机的亲和性策略(二):集群节点组
  • 如何理解推理模型
  • 渗透作业3
  • 基于C#和NModbus4库实现的Modbus RTU串口通信
  • ansible简单playbook剧本例子2
  • 团购商城 app 系统架构分析
  • 第三篇:几何体入门:内置几何体全解析
  • 无人机气象监测设备:穿梭云端的 “气象观察员”
  • 丝杆支撑座在电子装配中的关键作用
  • NLP 和 LLM 区别、对比 和关系
  • 深入剖析Spring IOC容器——原理、源码与实践全解析
  • mac系统自带终端崩溃修复
  • PAT 1022 Digital Library
  • 关于“PromptPilot” 之5 -标签词与标签动作的语言模型九宫格
  • HCLP--ospf综合实验
  • 神经网络----卷积层(Conv2D)
  • GitPython07-源码解读
  • 低通滤波器的原理以及作用
  • ctfshow_web签到题
  • 算法49. 字母异位词分组
  • 第11届蓝桥杯Python青少组中/高级组选拔赛(STEMA)2020年5月30日真题
  • Pydantic模块学习