文章目录
- [K8S 核心组件:Controller、Label、Service 与 DNS](#K8S 核心组件:Controller、Label、Service 与 DNS)
-
- 全景链路
- 一、Controller(控制器)
-
- [1.1 是什么](#1.1 是什么)
- [1.2 期望状态从哪来](#1.2 期望状态从哪来)
- [1.3 常见控制器对比](#1.3 常见控制器对比)
- [1.4 实战:删除 Pod 后自动重建](#1.4 实战:删除 Pod 后自动重建)
- [1.5 实战:Pod 的 Label 与归属关系](#1.5 实战:Pod 的 Label 与归属关系)
- 二、Label(标签)
-
- [2.1 概念](#2.1 概念)
- [2.2 常用标签](#2.2 常用标签)
- [2.3 语法与字符集](#2.3 语法与字符集)
- [三、Label Selector(标签选择器)](#三、Label Selector(标签选择器))
-
- [3.1 两种类型](#3.1 两种类型)
- [3.2 写法示例](#3.2 写法示例)
- [3.3 与 SQL 的类比](#3.3 与 SQL 的类比)
- 四、Service(服务)
-
- [4.1 为什么需要 Service](#4.1 为什么需要 Service)
- [4.2 是什么](#4.2 是什么)
- [4.3 举例:图片处理后端](#4.3 举例:图片处理后端)
- 五、Endpoints(端点)
- 六、DNS
- [七、实战串联:Pod → Service → Endpoints → DNS](#七、实战串联:Pod → Service → Endpoints → DNS)
-
- [7.1 Pod 与 Service](#7.1 Pod 与 Service)
- [7.2 查看 Endpoints](#7.2 查看 Endpoints)
- [7.3 Service 与 DNS](#7.3 Service 与 DNS)
- [7.4 用 DNS 解析 Service](#7.4 用 DNS 解析 Service)
- [八、延伸:基于 Kubernetes 的微服务架构](#八、延伸:基于 Kubernetes 的微服务架构)
-
- [8.1 服务部署方式演进](#8.1 服务部署方式演进)
- [8.2 组件之间的关系](#8.2 组件之间的关系)
K8S 核心组件:Controller、Label、Service 与 DNS
!abstract 核心摘要
- Controller :通过「调谐循环」把集群的当前状态 推向期望状态,常见类型有 Deployment、StatefulSet、DaemonSet、Job、CronJob。
- Label :
key=value形式的标签,可附着到任意资源对象上,用于多维度分组管理。- Label Selector:按标签筛选对象,分为基于等式(equality-based)与基于集合(set-based)两类。
- Service:为一组 Pod 提供稳定访问入口,底层是一组 iptables / ipvs 规则,多 Pod 时天然具备负载均衡。
- Endpoints:Service 实际的后端 Pod 列表(IP:Port),随 Pod 创建与销毁自动更新。
- DNS:为集群内 Service 提供名称解析,同时为 Pod 内容器访问互联网提供域名解析。
全景链路
一条主线串起全部组件:
#mermaid-svg-GA4pbWbKOmM3PQrn{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-GA4pbWbKOmM3PQrn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-GA4pbWbKOmM3PQrn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-GA4pbWbKOmM3PQrn .error-icon{fill:#552222;}#mermaid-svg-GA4pbWbKOmM3PQrn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-GA4pbWbKOmM3PQrn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-GA4pbWbKOmM3PQrn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-GA4pbWbKOmM3PQrn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-GA4pbWbKOmM3PQrn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-GA4pbWbKOmM3PQrn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-GA4pbWbKOmM3PQrn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-GA4pbWbKOmM3PQrn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-GA4pbWbKOmM3PQrn .marker.cross{stroke:#333333;}#mermaid-svg-GA4pbWbKOmM3PQrn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-GA4pbWbKOmM3PQrn p{margin:0;}#mermaid-svg-GA4pbWbKOmM3PQrn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-GA4pbWbKOmM3PQrn .cluster-label text{fill:#333;}#mermaid-svg-GA4pbWbKOmM3PQrn .cluster-label span{color:#333;}#mermaid-svg-GA4pbWbKOmM3PQrn .cluster-label span p{background-color:transparent;}#mermaid-svg-GA4pbWbKOmM3PQrn .label text,#mermaid-svg-GA4pbWbKOmM3PQrn span{fill:#333;color:#333;}#mermaid-svg-GA4pbWbKOmM3PQrn .node rect,#mermaid-svg-GA4pbWbKOmM3PQrn .node circle,#mermaid-svg-GA4pbWbKOmM3PQrn .node ellipse,#mermaid-svg-GA4pbWbKOmM3PQrn .node polygon,#mermaid-svg-GA4pbWbKOmM3PQrn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-GA4pbWbKOmM3PQrn .rough-node .label text,#mermaid-svg-GA4pbWbKOmM3PQrn .node .label text,#mermaid-svg-GA4pbWbKOmM3PQrn .image-shape .label,#mermaid-svg-GA4pbWbKOmM3PQrn .icon-shape .label{text-anchor:middle;}#mermaid-svg-GA4pbWbKOmM3PQrn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-GA4pbWbKOmM3PQrn .rough-node .label,#mermaid-svg-GA4pbWbKOmM3PQrn .node .label,#mermaid-svg-GA4pbWbKOmM3PQrn .image-shape .label,#mermaid-svg-GA4pbWbKOmM3PQrn .icon-shape .label{text-align:center;}#mermaid-svg-GA4pbWbKOmM3PQrn .node.clickable{cursor:pointer;}#mermaid-svg-GA4pbWbKOmM3PQrn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-GA4pbWbKOmM3PQrn .arrowheadPath{fill:#333333;}#mermaid-svg-GA4pbWbKOmM3PQrn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-GA4pbWbKOmM3PQrn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-GA4pbWbKOmM3PQrn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GA4pbWbKOmM3PQrn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-GA4pbWbKOmM3PQrn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GA4pbWbKOmM3PQrn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-GA4pbWbKOmM3PQrn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-GA4pbWbKOmM3PQrn .cluster text{fill:#333;}#mermaid-svg-GA4pbWbKOmM3PQrn .cluster span{color:#333;}#mermaid-svg-GA4pbWbKOmM3PQrn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-GA4pbWbKOmM3PQrn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-GA4pbWbKOmM3PQrn rect.text{fill:none;stroke-width:0;}#mermaid-svg-GA4pbWbKOmM3PQrn .icon-shape,#mermaid-svg-GA4pbWbKOmM3PQrn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GA4pbWbKOmM3PQrn .icon-shape p,#mermaid-svg-GA4pbWbKOmM3PQrn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-GA4pbWbKOmM3PQrn .icon-shape .label rect,#mermaid-svg-GA4pbWbKOmM3PQrn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GA4pbWbKOmM3PQrn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-GA4pbWbKOmM3PQrn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-GA4pbWbKOmM3PQrn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 创建 / 管理
携带
Label Selector 选中
自动维护
指向真实 IP
解析 Service 名称
Controller
Pod
Label
Service
Endpoints
CoreDNS
!tip 记忆
Controller 管 Pod → Pod 带 Label → Service 用 Selector 选中一组 Pod → 自动维护 Endpoints → DNS 提供稳定访问名称。
一、Controller(控制器)
1.1 是什么
Controller 是 Kubernetes 中用于管理和运行 Pod 的对象。它持续监控集群的公共状态,并致力于把当前状态 转变为期望状态。
!example 类比:房间里的温度调节器
你设定的温度是期望状态 (Desired state),房间实际温度是当前状态(Current state)。调节器通过开关设备,让当前状态不断接近期望状态------这就是「调谐循环」。
1.2 期望状态从哪来
一个控制器至少追踪一种类型的 Kubernetes 资源。这些对象都有一个代表期望状态的 spec 字段,控制器负责确保资源的当前状态接近期望状态。
1.3 常见控制器对比
不同类型的控制器,控制方式各不相同:
| 控制器 | 定位 | 关键特征 | 典型场景 |
|---|---|---|---|
| Deployment | 部署无状态应用 | 认为所有 Pod 都一样,无顺序要求,不必关心运行在哪个 Node,可随意扩缩容;管理 Pod 与 ReplicaSet;支持部署、滚动升级、回滚 | Web 服务、分布式服务 |
| StatefulSet | 部署有状态应用 | 每个 Pod 独立运行,保持启动顺序与唯一性;有唯一网络标识、固定主机名、稳定持久存储;扩缩容与升级同样按序进行 | MySQL 主从等有状态服务 |
| DaemonSet | 部署守护进程 | 保证每个 Node 上都运行一个容器副本,新加入的 Node 也会自动运行一个 Pod | 集群日志、监控及系统管理应用 |
| Job | 一次性任务 | 处理短暂的一次性任务(short lived one-off tasks),保证一个或多个 Pod 成功结束 | 数据迁移、批处理 |
| CronJob | 周期性定时任务 | 按周期重复触发任务 | 定时备份、定时清理 |
!tip 面试速记
副本可互换用 Deployment,副本有身份用 StatefulSet,每个节点各一个用 DaemonSet。
1.4 实战:删除 Pod 后自动重建
ReplicaSet 控制器持续对比**期望副本数(DESIRED)**与当前实际 Pod 数量,发现少了一个就自动补建,保证副本数稳定。
bash
# 查看 ReplicaSet
[root@master ~]# kubectl get replicasets
NAME DESIRED CURRENT READY AGE
nginx-7854ff8877 3 3 3 20d
tomcat-test-75469fdc74 2 2 2 46h
# 查看 Pod
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-7854ff8877-dfv7g 1/1 Running 0 20d
nginx-7854ff8877-lm7gx 1/1 Running 0 20d
nginx-7854ff8877-ntp7t 1/1 Running 0 20d
tomcat-test-75469fdc74-24bsh 1/1 Running 0 46h
tomcat-test-75469fdc74-9wzps 1/1 Running 0 46h
# 手动删除一个 Pod
[root@master ~]# kubectl delete pod tomcat-test-75469fdc74-9wzps
pod "tomcat-test-75469fdc74-9wzps" deleted
# 立即查看:已自动生成新 Pod(AGE 29s)
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-7854ff8877-dfv7g 1/1 Running 0 20d
nginx-7854ff8877-lm7gx 1/1 Running 0 20d
nginx-7854ff8877-ntp7t 1/1 Running 0 20d
tomcat-test-75469fdc74-24bsh 1/1 Running 0 46h
tomcat-test-75469fdc74-sjqnt 1/1 Running 0 29s # 新 Pod
Pod 命名规律 :控制器名 + ReplicaSet 名 + 序列号
1.5 实战:Pod 的 Label 与归属关系
bash
[root@master ~]# kubectl describe pod tomcat-test-75469fdc74
Name: tomcat-test-75469fdc74-24bsh
Namespace: default
Priority: 0
Service Account: default
Node: node2/192.168.100.129
Start Time: Tue, 08 Jul 2025 18:51:10 +0800
Labels: app=tomcat # 与 Service 的 Selector 对应
pod-template-hash=75469fdc74
Annotations: cni.projectcalico.org/containerID: 869c5a964bae99ff45de03cc69ac4efaaca6afbbaac0a2ea6d5b3e251040381a
cni.projectcalico.org/podIP: 10.244.104.8/32
cni.projectcalico.org/podIPs: 10.244.104.8/32
Status: Running
IP: 10.244.104.8
IPs:
IP: 10.244.104.8
Controlled By: ReplicaSet/tomcat-test-75469fdc74 # 说明归属哪个控制器
Containers:
tomcat:
Container ID: docker://d347b920bd120cc971178481f3444577271f7b84c0c1fd75009b92a3d3307414
Image: tomcat:9.0.85-jdk11
Image ID: docker-pullable://tomcat@sha256:b2a4b6f5e09e147ee81f094051cb43d69efd56a68e76ca5b450b7584c5564c77
Port: 8080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 08 Jul 2025 18:51:11 +0800
Ready: True
Restart Count: 0
Environment: <none>
...
!note 两个关键字段
Labels:Pod 身上的标签,是 Service 筛选它的依据。Controlled By:该 Pod 由哪个控制器(ReplicaSet)管理。


二、Label(标签)
2.1 概念
Label 是附着到 object(例如 Pod)上的键值对 ,可在创建时指定,也可在对象创建后随时修改。Labels 的值对系统本身没有含义,只对用户有意义。
- 一个 Label 就是一个
key=value键值对,key 与 value 都由用户自行指定。 - Label 可附加到各种资源对象上,如 Node、Pod、Service、RC 等。
- 一个资源对象可定义任意数量 的 Label;同一个 Label 也可被添加到任意数量的资源对象上。
- Label 通常在资源对象定义时确定,也可在对象创建后动态添加或删除。
通过对资源对象捆绑一个或多个 Label,可实现多维度的资源分组管理,便于进行资源分配、调度、配置、部署等工作。例如:把不同版本的应用部署到不同环境;或用于日志记录、监控、告警等。
2.2 常用标签
| 类别 | 示例 | 用途 |
|---|---|---|
| 版本标签 | "release":"stable"、"release":"canary" |
区分稳定版与灰度版 |
| 环境标签 | "environment":"dev"、"environment":"production" |
区分开发 / 生产环境 |
| 架构标签 | "tier":"frontend"、"tier":"backend"、"tier":"middleware" |
区分分层架构中的角色 |
| 分区标签 | "partition":"customerA"、"partition":"customerB" |
按租户或分区隔离 |
| 质量管控标签 | "track":"daily"、"track":"weekly" |
标记发布通道或测试节奏 |
!note 为什么要有 Label
给资源对象打上 Label,就相当于贴了一个标签;再用 LabelSelector 查询、筛选拥有某些 Label 的对象。Kubernetes 正是靠这种方式,实现了类似 SQL 的、简单又通用的对象查询机制。
2.3 语法与字符集
Label key 的组成
- 不得超过 63 个字符。
- 可使用前缀,用
/分隔。前缀必须是 DNS 子域,不得超过 253 个字符;由系统自动化组件创建的 Label 必须指定前缀,kubernetes.io/由 Kubernetes 保留。 - 必须以字母(大小写均可)或数字开头和结尾,中间可含连字符
-、下划线_、点.。
Label value 的组成
- 不得超过 63 个字符。
- 必须以字母(大小写均可)或数字开头和结尾,中间可含连字符
-、下划线_、点.。
!tip 面试小提示
Label value 可以为空字符串,这一点偶尔会被问到。
三、Label Selector(标签选择器)
通过 Label Selector,客户端 / 用户可以指定一个 object 集合,并对该集合进行操作,作用类似于 SQL 语句中的 where 查询条件。
3.1 两种类型
| 类型 | 支持的操作符 | 示例 | 说明 |
|---|---|---|---|
| equality-based(基于等式) | =、==、!= |
env=production,tier!=frontend |
多个表达式用逗号分隔,逗号表示逻辑与 |
| set-based(基于集合) | in、notin、! |
environment in (production,qa) |
也可不带操作符,只写某个 key,表示筛选有该 key 的 object,不管 value 是什么;! 表示没有该 label 的 object |
3.2 写法示例
text
# 基于等式:多个表达式用逗号分隔(逻辑与)
env=production,tier!=frontend
# 基于集合
environment in (production, qa)
tier notin (frontend, backend)
# 只写 key:存在 partition 这个 label,值任意
partition
# 加 ! :不存在 partition 这个 label
!partition
3.3 与 SQL 的类比
name=redis-slave 这个 Label Selector 作用于 Pod 时,相当于:
sql
select * from pod where pod.name = 'redis-slave'
四、Service(服务)
4.1 为什么需要 Service
Service 是将运行在一组 Pod 上的应用程序公开为网络服务的抽象方法。
Pod 是非永久性资源对象:用 Controller 运行应用时会动态创建和销毁 Pod,直接访问 Pod IP 并不可靠。
!question 要解决的问题
如果一组 Pod(「后端」)为集群内其他 Pod(「前端」)提供功能,前端如何找出并跟踪要连接的 IP 地址?
4.2 是什么
Service 本质上是一组 iptables 或 ipvs 规则 :把客户端请求转发到服务端(Pod);有多个 Pod 时,还能实现负载均衡。
Service 通过 selector 管控对应的 Pod------根据 Label 与 Selector 建立关联,从而实现负载均衡。
4.3 举例:图片处理后端
一个图片处理后端运行了 3 个副本(Pod),这些副本是可互换的------前端不需要关心自己调用了哪个副本。组成这一组后端的 Pod 实际上可能随时变化,前端不应该、也没必要知道,更不需要去跟踪它们的状态。
!tip 一句话记忆
Service = 一组 Pod 的稳定访问入口 + 负载均衡,屏蔽了 Pod IP 变化带来的影响。
五、Endpoints(端点)
Endpoints 为 Service 管理后端 Pod:当后端 Pod 被创建或销毁时,Endpoints 列表会更新对应的 Pod IP,从而确保 Service 的访问请求始终能被响应。
六、DNS
为 Kubernetes 集群内资源对象的访问提供名称解析,这样就可以通过 DNS 名称而非 IP 地址访问服务:
- 实现集群内 Service 名称解析。
- 为集群内 Pod 中 Container 里的应用访问互联网提供域名解析。
!note 补充
集群内的 DNS 组件通常是 CoreDNS ,以 Pod 形式运行;Service 域名形如
service-name.namespace.svc.cluster.local。
七、实战串联:Pod → Service → Endpoints → DNS
7.1 Pod 与 Service
Service 是为了防止 Pod 失联而提供的服务发现机制,类似微服务的注册中心:定义一组 Pod 的访问策略,为一组功能相同的容器应用提供统一入口,并把请求负载分发到后端各容器上。

bash
# 查看所有 Service
[root@master ~]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20d
nginx NodePort 10.100.123.185 <none> 80:30228/TCP 20d
tomcat-service NodePort 10.102.102.19 <none> 80:30080/TCP 46h
# 查看单个 Service 详情
[root@master ~]# kubectl describe service tomcat-service
Name: tomcat-service
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=tomcat # 对应 Pod 标签
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.102.102.19
IPs: 10.102.102.19
Port: <unset> 80/TCP
TargetPort: 8080/TCP
NodePort: <unset> 30080/TCP
Endpoints: 10.244.104.8:8080,10.244.166.137:8080
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
describe service 关键字段解读
| 字段 | 含义 |
|---|---|
Selector: app=tomcat |
匹配标签为 app=tomcat 的 Pod |
Type: NodePort |
节点端口类型,集群外部可通过 节点IP:30080 访问 |
Cluster-IP: 10.102.102.19 |
Service 的集群内虚拟 IP,仅集群内可访问 |
Port: 80 / TargetPort: 8080 |
Service 的 80 端口转发到 Pod 内的 8080 端口 |
NodePort: 30080 |
宿主机上对外开放的端口 |
Endpoints |
后端真实 Pod 的 IP:Port 列表,是 Selector 匹配成功后的结果 |
7.2 查看 Endpoints
bash
[root@master ~]# kubectl get endpoints
NAME ENDPOINTS AGE
kubernetes 192.168.100.136:6443 20d
nginx 10.244.104.1:80,10.244.104.2:80,10.244.166.129:80 20d
tomcat-service 10.244.104.8:8080,10.244.166.137:8080 46h # 对应 2 个 Pod 的 IP;Pod 重启引起 IP 变化后会自动更新
!summary Endpoints 要点
- 含义:Service 后端真实 Pod 的 IP + 端口清单。
- 联动逻辑:Service 通过 Selector 匹配 Pod → 自动维护 Endpoint 列表。
- 特点:Pod 重建、漂移导致 IP 改变后,Endpoint 自动更新,保证流量转发正常。
7.3 Service 与 DNS
通过 DNS 实现对 Service 名称解析,以此达到访问后端 Pod 的目的。
bash
# 1) 查看 CoreDNS Pod(位于 kube-system 命名空间)
[root@master ~]# kubectl get pods -n kube-system
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-658d97c59c-8nnql 1/1 Running 0 20d
calico-node-5t2r8 1/1 Running 0 3d6h
calico-node-hfkjr 1/1 Running 0 3d6h
calico-node-s8jpz 1/1 Running 0 3d6h
coredns-66f779496c-bcq9q 1/1 Running 0 20d # DNS 组件
coredns-66f779496c-wlphs 1/1 Running 0 20d # DNS 组件
etcd-master 1/1 Running 2 (20d ago) 20d
kube-apiserver-master 1/1 Running 2 (20d ago) 20d
kube-controller-manager-master 1/1 Running 2 (20d ago) 20d
kube-proxy-27r8d 1/1 Running 2 (20d ago) 20d
kube-proxy-6wbkr 1/1 Running 1 (20d ago) 20d
kube-proxy-92wqj 1/1 Running 1 (20d ago) 20d
kube-scheduler-master 1/1 Running 2 (20d ago) 20d
metrics-server-57999c5cf7-ppvqq 1/1 Running 0 3d5h
# 2) 查看 DNS 的 Service,其 ClusterIP 为 10.96.0.10
[root@master ~]# kubectl get service -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 20d
metrics-server ClusterIP 10.106.136.148 <none> 443/TCP 3d5h
!summary CoreDNS 要点
- 作用:K8s 内置 CoreDNS,负责解析 Service 名称,集群内可直接用 Service 名称访问服务。
- 组件 :CoreDNS(以 Pod 形式运行在
kube-system)。- kube-dns ClusterIP :
10.96.0.10。- 端口:53(UDP/TCP)用于解析,9153 为监控端口。
- 访问格式 :
服务名.命名空间.svc.cluster.local(同命名空间内可直接写服务名)。

bash
# 查看 Pod 所在节点与 Pod IP
[root@master ~]# kubectl get pod -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
calico-kube-controllers-658d97c59c-8nnql 1/1 Running 0 20d 10.244.219.67 master <none>
calico-node-5t2r8 1/1 Running 0 3d6h 192.168.100.128 node1 <none>
calico-node-hfkjr 1/1 Running 0 3d6h 192.168.100.129 node2 <none>
calico-node-s8jpz 1/1 Running 0 3d6h 192.168.100.136 master <none>
coredns-66f779496c-bcq9q 1/1 Running 0 20d 10.244.219.66 master <none>
coredns-66f779496c-wlphs 1/1 Running 0 20d 10.244.219.65 master <none>
etcd-master 1/1 Running 2 (20d ago) 20d 192.168.100.136 master <none>
kube-apiserver-master 1/1 Running 2 (20d ago) 20d 192.168.100.136 master <none>
kube-controller-manager-master 1/1 Running 2 (20d ago) 20d 192.168.100.136 master <none>
kube-proxy-27r8d 1/1 Running 2 (20d ago) 20d 192.168.100.136 master <none>
kube-proxy-6wbkr 1/1 Running 1 (20d ago) 20d 192.168.100.128 node1 <none>
kube-proxy-92wqj 1/1 Running 1 (20d ago) 20d 192.168.100.129 node2 <none>
kube-scheduler-master 1/1 Running 2 (20d ago) 20d 192.168.100.136 master <none>
metrics-server-57999c5cf7-ppvqq 1/1 Running 0 3d5h 10.244.166.132 node1 <none>
-o wide 的作用 :额外输出 Pod IP 与所在 Node,常用于查看集群核心组件(CoreDNS、Calico、kube-proxy 等)的运行位置。
7.4 用 DNS 解析 Service
bash
[root@master ~]# dig -t a tomcat-service.default.svc.cluster.local. @10.96.0.10
; <<>> DiG 9.9.4-RedHat-9.9.4-50.el7 <<>> -t a tomcat-service.default.svc.cluster.local. @10.96.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41941
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;tomcat-service.default.svc.cluster.local. IN A
;; ANSWER SECTION:
tomcat-service.default.svc.cluster.local. 30 IN A 10.102.102.19 # 返回解析地址
;; Query time: 3 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: 四 7月 10 17:54:41 CST 2025
;; MSG SIZE rcvd: 125
| 要点 | 说明 |
|---|---|
| 命令 | dig -t a <域名> @<DNS服务器> |
| 域名格式 | 服务名.命名空间.svc.cluster.local |
@10.96.0.10 |
指定用 kube-dns 的 ClusterIP 做解析 |
| 结果 | 成功解析出 tomcat-service 的 ClusterIP 10.102.102.19 |
| 简写 | 同命名空间内访问,可直接写服务名 tomcat-service |
八、延伸:基于 Kubernetes 的微服务架构
8.1 服务部署方式演进
| 架构 | 特征 | 问题 / 收益 |
|---|---|---|
| 单体服务架构 | 所有服务进程运行在同一台主机内 | 单点故障风险高,扩容只能整体扩容 |
| 分布式服务架构 | 服务进程分布于不同主机,一台故障不影响其他主机上的服务 | 解决了单点问题,但部署与运维成本上升 |
| 微服务架构 | 用容器化技术运行分布式服务架构,实现对不同服务进程的高可用与快速发布 | 高可用、快速发布、弹性伸缩 |
8.2 组件之间的关系
以在 Kubernetes 集群中运行 LNMT(Linux、NGINX、MySQL、Tomcat)应用为例:把 Kubernetes 集群看成一个 IDC 机房,把 LNMT 的 Web 架构应用以微服务(Kubernetes 集群资源对象)的方式部署到集群中。
