K8s管理(二)
随着容器化技术的普及,Kubernetes(简称K8s)已成为容器编排领域的事实标准。要熟练运用K8s,首先需吃透其核心概念------它们是构建K8s集群与微服务架构的基石。
一、Kubernetes核心概念:从最小单元到服务发现
K8s的核心概念围绕"资源对象"展开,这些对象协同工作,实现容器的部署、管理、扩展与服务暴露。下面从最基础的单元开始逐一解析。
1. Pod:K8s的最小部署单元
核心定义 :Pod是K8s中可创建和管理的最小可部署计算单元,本质是一组(一个或多个)容器的集合。这些容器共享存储、网络资源以及运行策略,相当于一个"逻辑主机"。
通俗类比:若把容器比作一颗豌豆,Pod就是装着豌豆的豌豆荚;Node(节点)是承载豌豆荚的豌豆藤,而Cluster(集群)则是整片豌豆田。
核心特点:
- 容器的"包装器":统一管理一组关联容器,减少容器间的耦合
- 资源共享:同一Pod内的容器共享网络命名空间(同一IP和端口空间)和存储卷
- 短暂性:Pod是临时实体,故障或重建后IP可能变化,需通过上层组件保证可用性
2. Controller:Pod的"管家"与状态管理者
核心定义 :Controller是用于管理和运维Pod的K8s对象,核心作用是"监控集群状态,将当前状态推向期望状态",实现Pod的高可用、扩展与生命周期管理。
通俗类比:类似房间的温度自动调节器------你设定的目标温度是"期望状态",房间实际温度是"当前状态",调节器通过开关设备(控制动作)让实际温度接近目标温度。
核心逻辑:所有Controller都通过"spec字段"定义资源的期望状态,通过持续监控实现状态收敛。不同Controller针对不同场景设计,常见类型如下:
| Controller类型 | 核心用途 | 典型场景 |
|---|---|---|
| Deployment | 部署无状态应用,管理Pod和ReplicaSet,支持滚动升级 | Web服务、分布式API服务(Pod无顺序、可随意扩缩容) |
| StatefulSet | 部署有状态应用,保证Pod唯一性、有序性和持久存储 | MySQL主从、ZooKeeper集群(Pod有固定身份和启动顺序) |
| DaemonSet | 保证集群每个Node运行一个Pod副本,新节点自动部署 | 日志收集(如Fluentd)、监控代理(如Prometheus Agent) |
| Job | 执行一次性短暂任务,保证任务成功结束 | 数据备份、批量计算 |
| CronJob | 基于时间规则执行周期性任务,本质是定时触发的Job | 定时数据同步、日志清理 |
3. Label与Label Selector:资源的"标签"与"筛选器"
Label和Label Selector是K8s实现资源关联与分组的核心机制,相当于给资源打"标签",再通过"标签筛选"实现精准管理。
Label:资源的柔性标签
- 本质:键值对(key=value),由用户自定义,对K8s系统无意义,仅用于用户管理
- 特性:可附加到Pod、Node、Service等任意资源,支持创建后动态添加/删除
- 核心用途:多维度分组资源,如按环境(dev/prod)、版本(stable/canary)、层级(frontend/backend)分类
- 语法规则:key和value均不超过63字符,以字母/数字开头,可包含连字符、下划线和点;key可加DNS前缀(如kubernetes.io/)
常用Label示例:
yaml
environment: dev # 环境:开发环境
release: stable # 版本:稳定版
tier: frontend # 层级:前端服务
partition: customerA # 分区:客户A专属资源
track: daily # 测试:每日构建版本
Label Selector:标签筛选器
核心作用是通过Label查询资源集合,实现Controller对Pod的管理、Service对Pod的关联等。分为两种类型:
- 基于等式(equality-based):使用=、==、!=操作符,多条件用逗号分隔,如
app=tomcat,env!=prod - 基于集合(set-based):使用in、not in或仅指定key,如
app in (tomcat, nginx)、!app(无app标签的资源)
类比:相当于SQL的WHERE子句,app=redis-slave等价于SELECT * FROM Pod WHERE app='redis-slave'。
4. Service:Pod的"固定入口"与负载均衡器
核心问题:Pod是短暂的,IP会随重建变化,前端如何稳定访问后端Pod?
核心定义:Service是暴露Pod网络服务的抽象,为一组功能相同的Pod提供固定访问地址,并实现负载均衡。
工作原理:
- 通过Label Selector关联后端Pod(如选择
app=tomcat的Pod) - 分配固定的Cluster IP(集群内部可访问)或NodePort(外部可访问)
- 通过iptables/ipvs规则将客户端请求分发到后端Pod,实现负载均衡
示例:3个Tomcat Pod组成后端服务,Service为其分配Cluster IP 10.102.102.19,前端只需访问该IP,无需关心具体Pod的IP变化。
5. Endpoints:Service与Pod的"桥梁"
核心作用是维护Service关联的Pod IP列表。当Pod创建/销毁时,Endpoints会自动更新,确保Service的请求始终能转发到可用的Pod。
例如:tomcat-service的Endpoints为10.244.104.8:8080, 10.244.166.137:8080,即关联两个Tomcat Pod的IP和端口。
6. DNS:K8s的"地址簿"
核心作用:为K8s集群内资源提供名称解析,实现"通过服务名访问"而非记IP。
核心能力:
- 集群内Service解析:将Service名称解析为Cluster IP,如
tomcat-service.default.svc.cluster.local解析为10.102.102.19 - Pod访问互联网:提供外部域名解析能力
K8s默认通过coredns组件实现DNS功能,其Cluster IP固定为10.96.0.10。
二、k8s核心概念间的关联:K8s的协作逻辑
上述概念并非孤立,而是通过Label、Selector等机制形成闭环,共同支撑容器化应用的运行。下面以三个核心关联场景说明。
1. Pod与Controller:通过Label实现状态管控
关联逻辑:Controller通过Label Selector管理Pod,确保Pod数量和状态符合期望。

实操验证:删除Controller管理的Pod后,Controller会自动重建新Pod,维持期望副本数。
bash
# 1. 查看ReplicaSet(Deployment的子组件),期望2个tomcat Pod
[root@master ~]# kubectl get replicasets
NAME DESIRED CURRENT READY AGE
tomcat-test-75469fdc74 2 2 2 46h
# 2. 查看当前tomcat Pod
[root@master ~]# kubectl get pods
NAME DESIRED CURRENT READY AGE
tomcat-test-75469fdc74-24bsh 1/1 Running 0 46h
tomcat-test-75469fdc74-9wzps 1/1 Running 0 46h
# 3. 删除一个Pod
[root@master ~]# kubectl delete pod tomcat-test-75469fdc74-9wzps
pod "tomcat-test-75469fdc74-9wzps" deleted
# 4. 验证新Pod自动创建
[root@master ~]# kubectl get pods
NAME DESIRED CURRENT READY AGE
tomcat-test-75469fdc74-24bsh 1/1 Running 0 46h
tomcat-test-75469fdc74-sjqnt 1/1 Running 0 29s # 新Pod
核心原因:ReplicaSet的Selector为app=tomcat,而Pod的Label恰好匹配,因此能被自动管理。
bash
# 控制器
[root@master ~]# kubectl describe replicasets tomcat-test-75469fdc74
Name: tomcat-test-75469fdc74
Namespace: default
Selector: app=tomcat,pod-template-hash=75469fdc74 # 对应
Labels: app=tomcat
pod-template-hash=75469fdc74
Annotations: deployment.kubernetes.io/desired-replicas: 2
deployment.kubernetes.io/max-replicas: 3
deployment.kubernetes.io/revision: 1
Controlled By: Deployment/tomcat-test
Replicas: 2 current / 2 desired
Pods Status: 2 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=tomcat
pod-template-hash=75469fdc74
Containers:
tomcat:
Image: tomcat:9.0.85-jdk11
Port: 8080/TCP
Host Port: 0/TCP
Environment: <none>
Mounts:
/usr/local/tomcat/webapps/ROOT/index.html from web-content (rw,path="index.html")
Volumes:
web-content:
Type: ConfigMap (a volume populated by a ConfigMap)
Name: tomcat-web-content
Optional: false
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 11m replicaset-controller Created pod: tomcat-test-75469fdc74-sjqnt
# pod
[root@master ~]# kubectl describe pod tomcat-test-75469fdc74-24bsh
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 # 对应
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>
...
2. Pod与Service:通过Selector实现服务发现
关联逻辑:Service通过Label Selector绑定Pod,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并将请求负载分发到后端的各个容器应用上。

实操验证 :查看tomcat-service的配置,其Selector明确指向app=tomcat的Pod,Endpoints自动关联Pod IP。
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
# 查看tomcat-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>
# 查看endpoints
[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变化,会重新添加到此处
3. Service与DNS:通过名称解析实现便捷访问
关联逻辑:DNS将Service名称解析为Cluster IP,实现"服务名访问"。
实操验证:通过dig命令解析tomcat-service的DNS名称,返回其Cluster IP。
bash
# 查看dns的pod
[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
# 查看service获取集群IP,dns的地址为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
# 查看dns对应的pod地址
[root@master ~]# kubectl get endpoints -n kube-system
NAME ENDPOINTS AGE
kube-dns 10.244.219.65:53,10.244.219.66:53,10.244.219.65:53 + 3 more... 20d
metrics-server 10.244.166.132:10250 3d5h
# 或者也可以这样查看
[root@master ~]# kubectl get pod -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
calico-kube-controllers-658d97c59c-8nnql 1/1 Running 0 20d 10.244.219.67 master <none> <none>
calico-node-5t2r8 1/1 Running 0 3d6h 192.168.100.128 node1 <none> <none>
calico-node-hfkjr 1/1 Running 0 3d6h 192.168.100.129 node2 <none> <none>
calico-node-s8jpz 1/1 Running 0 3d6h 192.168.100.136 master <none> <none>
coredns-66f779496c-bcq9q 1/1 Running 0 20d 10.244.219.66 master <none> <none>
coredns-66f779496c-wlphs 1/1 Running 0 20d 10.244.219.65 master <none> <none>
etcd-master 1/1 Running 2 (20d ago) 20d 192.168.100.136 master <none> <none>
kube-apiserver-master 1/1 Running 2 (20d ago) 20d 192.168.100.136 master <none> <none>
kube-controller-manager-master 1/1 Running 2 (20d ago) 20d 192.168.100.136 master <none> <none>
kube-proxy-27r8d 1/1 Running 2 (20d ago) 20d 192.168.100.136 master <none> <none>
kube-proxy-6wbkr 1/1 Running 1 (20d ago) 20d 192.168.100.128 node1 <none> <none>
kube-proxy-92wqj 1/1 Running 1 (20d ago) 20d 192.168.100.129 node2 <none> <none>
kube-scheduler-master 1/1 Running 2 (20d ago) 20d 192.168.100.136 master <none> <none>
metrics-server-57999c5cf7-ppvqq 1/1 Running 0 3d5h 10.244.166.132 node1 <none> <none>
# 使用dns解析tomcat-service!!!!
[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
# 检验地址对应
[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 47h
# 验证地址对应
三、K8s与微服务:以LNMT应用为例
K8s是微服务架构的理想载体,通过核心概念的协作,实现微服务的部署、高可用与服务治理。下面以LNMT(Linux、Nginx、MySQL、Tomcat)应用为例,说明核心概念的实际应用。
1. 三种服务架构对比
| 架构类型 | 部署特点 | 可靠性 | 扩展能力 |
|---|---|---|---|
| 单体架构 | 所有服务运行在同一主机 | 单点故障导致整体不可用 | 整体扩展,资源浪费 |
| 分布式架构 | 服务分布在不同主机 | 单主机故障不影响整体 | 服务级扩展,配置复杂 |
| 微服务架构 | 容器化部署,K8s管理 | Controller保证高可用 | Pod级弹性扩缩容,灵活高效 |
2. LNMT应用的K8s部署方案
将K8s集群类比为IDC机房,LNMT各组件以K8s资源对象的形式部署,组件间通过Service和DNS通信:
- Nginx:无状态服务,用Deployment部署,2个副本保证高可用;通过Service(NodePort类型)暴露80端口,供外部访问。
- Tomcat:无状态服务,用Deployment部署,3个副本;通过Service(Cluster IP类型)暴露8080端口,仅集群内部访问,供Nginx反向代理。
- MySQL:有状态服务,用StatefulSet部署,主从架构;通过Headless Service提供固定访问入口,持久存储卷保存数据。
- 通信逻辑:外部请求→Nginx Service(NodePort)→Nginx Pod→Tomcat Service(通过DNS解析)→Tomcat Pod→MySQL Service→MySQL Pod。
核心优势:单个组件故障时,Controller自动重建;访问量激增时,通过kubectl scale命令快速扩容Tomcat Pod,应对流量压力。

四、总结:K8s核心概念的核心价值
K8s的核心概念围绕"解耦"和"自动化"设计:
- Pod解耦容器与主机:让容器成为可移植的单元
- Controller解耦运维与业务:实现Pod的自动化管理
- Label与Selector解耦资源关联:实现灵活的资源分组
- Service与DNS解耦访问与IP:实现服务的稳定发现