Kubernetes (K8s) 学习笔记
一、Kubernetes 是什么
- 定义:Kubernetes 是一个开源的容器编排平台,用于自动化部署、扩缩容和管理容器化应用。
- 核心能力:声明式配置、自动调度、自愈、服务发现与负载均衡、密钥与配置管理、存储编排、批量执行等。
- 简称:K8s(K 与 s 之间有 8 个字母)。
二、核心基础概念
2.1 Cluster(集群)
- 含义:由一组**控制平面节点(Master)和若干工作节点(Node)**组成的整体。
- 作用:在集群内统一调度、运行和管理容器化应用。
- 关系:一个集群 = 1 个控制平面 + N 个 Node。
2.2 Node(节点)
-
含义:集群中的一台机器(物理机或虚拟机),是 Pod 实际运行的地方。
-
分类:
- Control Plane Node(控制平面节点):运行集群控制逻辑,不跑业务 Pod(也可配置为可调度)。
- Worker Node(工作节点):运行业务 Pod,受控制平面管理。
-
组件:每个 Node 上通常有 kubelet、kube-proxy、容器运行时(如 containerd/CRI-O)。
-
云服务器和 Node / Pod 的关系(常见误解):
在 AWS、阿里云、腾讯云、Google Cloud 等买的云服务器(如 EC2、ECS、CVM、GCE 实例),是虚拟机(VM)或物理机,不是 K8s 的 Pod。云厂商卖给你的是“一台机器”这种计算单元,和 K8s 无关。- 若你自己用这些云服务器搭建 K8s:每台云服务器在集群里就是 Node(控制平面或工作节点),Pod 是跑在这些 Node 上的,由 K8s 调度、创建、销毁。
- 若你使用云厂商的托管 K8s(如 EKS、ACK、TKE、GKE):云厂商负责控制平面,你购买或挂载的“节点”仍然是 VM/实例,在 K8s 里对应 Node;你的业务跑在 Pod 里,Pod 跑在这些 Node 上。
总结:云服务器 ≈ 机器(VM)→ 在 K8s 里是 Node;Pod 是 K8s 在 Node 上创建的运行单元,不是云厂商“分配给你的那一台服务器”。
2.3 Pod
- 含义:K8s 中最小可部署单元,由一个或多个容器组成,共享网络和存储。
- 一个 Pod 里可以有几个容器?
- 单容器 Pod:最常见,一个 Pod 只跑一个业务容器,多数 Deployment 都是这种。
- 多容器 Pod:一个 Pod 里可以定义多个容器,它们共享同一 Network Namespace(同一 IP、同一
localhost,用不同端口区分)和挂载的 Volume,且总是被一起调度到同一台节点上。典型用法是 Sidecar(边车):主容器跑业务,另一个容器跑日志采集、代理或监控等,需要与主容器紧密配合、共享网络或磁盘时,就放在同一个 Pod 里。
- 特点:
- 同一 Pod 内容器共享 Network Namespace(同一 IP、端口空间)和 Volume。(Volume 即“一块存储/目录”;挂载即把这块存储接到容器里某个路径,容器内通过该路径读写文件;同一 Pod 里多个容器可挂载同一 Volume,从而共享文件。)
- Pod 是短暂的,会被调度、迁移、重建;一般不直接创建裸 Pod,而是通过 Deployment 等控制器管理。
- 用途:单容器时就是普通应用;多容器时用于把强耦合、需要紧密协作的容器放在一个 Pod 里(如应用 + 边车)。
2.4 Namespace(命名空间)
- 含义:集群内的逻辑隔离,用于多租户、多环境(dev/test/prod)划分资源。
- 作用:资源名称在 Namespace 内唯一,不同 Namespace 下可以有同名资源;可配合 RBAC 做权限隔离。(RBAC = Role-Based Access Control,基于角色的访问控制:通过 Role/ClusterRole 定义“能对哪些资源做哪些操作”,通过 RoleBinding/ClusterRoleBinding 把角色绑定到用户或服务账号,从而限制谁能在哪个 Namespace 里做什么。)
- 常见:
default、kube-system、kube-public、kube-node-lease等,也可自建。
2.5 Label(标签)与 Selector(选择器)
- Label:键值对,挂在 Pod、Node、Service 等对象上,用于标识和分类(如
env=prod、app=web)。 - Selector:按 Label 筛选资源。例如 Deployment(见 2.7)用
selector指定要管理的 Pod;Service(见 2.8)用selector指定后端 Pod。- Deployment:一种控制器,负责维护一组 Pod 的副本数、做滚动更新/回滚,常用于无状态应用。
- Service:为 Pod 提供固定访问入口(稳定 IP/DNS)和负载均衡,通过 Label Selector 找到要转发的 Pod。
- 常用:
matchLabels、matchExpressions(支持 In、NotIn、Exists、DoesNotExist)。
2.6 Annotation(注解)
- 含义:键值对,用于存非标识性元数据(说明、配置、工具用信息),不参与对象选择。
- 与 Label 区别:Label 用于选择和分组;Annotation 用于记录信息,可存较大或结构化数据。
2.7 Controller(控制器)与声明式 API
- 声明式:用户描述“期望状态”(如 3 个副本、用某镜像),控制器负责让当前状态不断逼近期望状态。
- 常见控制器:
- Deployment:无状态应用,支持滚动更新、回滚。Deployment 创建并管理 ReplicaSet 来控制 Pod 的部署和扩展。
- ReplicaSet:只做一件事——维护 Pod 副本数量(例如“始终保持 3 个带某 Label 的 Pod”)。通常不直接写 ReplicaSet,而是写 Deployment;Deployment 会创建并管理一个或多个 ReplicaSet,由 ReplicaSet 去创建/删除 Pod。可以理解为:Deployment = 上层(负责版本、更新策略),ReplicaSet = 下层(负责具体维持多少个 Pod)。
- StatefulSet:有状态应用,稳定网络标识和持久化存储。
- DaemonSet:每个 Node 上跑一个 Pod(如日志采集、网络插件)。
- Job:执行一次性任务,任务完成后 Pod 自动终止。
- CronJob:按 cron 表达式定期执行 Job。
2.8 Service(服务)
- 含义:为 Pod 提供稳定的访问入口(固定 ClusterIP/DNS 名),做服务发现与负载均衡。
- 原因:Pod IP 会变,不能直接依赖;Service 通过 Label Selector 找到后端 Pod,并做负载均衡。
- 类型:
- ClusterIP:集群内访问,默认类型。
- NodePort:在每个 Node 上开端口,从集群外通过
NodeIP:NodePort访问。 - LoadBalancer:对接云厂商负载均衡器,对外暴露。
- ExternalName:把 Service 映射到外部 DNS 名。
2.9 Ingress 与 Ingress Controller
Ingress(Ingress 资源)
- 是什么:K8s 里的一种 API 资源,用 YAML 描述“HTTP/HTTPS 流量怎么路由”——按主机名(如
a.example.com)、路径(如/api)把请求转发到不同的 Service。 - 作用:用一个入口(一个对外 IP/域名)暴露多个后端服务,可做 TLS 终结(在入口处 HTTPS 解密)、虚拟主机(按域名区分)、路径路由(如
/web→ web-svc,/api→ api-svc)。注意:Ingress 只是“路由规则”的声明,本身不会处理流量,需要由 Ingress Controller 来具体实现。
Ingress Controller(Ingress 控制器)
- 是什么:集群里真正干活的组件,一般以 Deployment + Pod 的形式运行。它会监听集群中的 Ingress 资源,根据规则去配置并驱动一个反向代理(如 Nginx、Traefik、Envoy),由这个代理接收外部 HTTP/HTTPS 流量并按 Ingress 规则转发到对应 Service(再经 Service 到 Pod)。
- 常见实现:Nginx Ingress Controller、Traefik、HAProxy Ingress、Istio Gateway 等;不同实现支持的注解(annotation)和高级功能略有差异。
- 与 Ingress 的关系:Ingress = 你写的“路由规则”(声明式);Ingress Controller = 读取这些规则并配置反向代理的程序。没有安装并运行 Ingress Controller,创建 Ingress 资源也不会生效。
小结
| 概念 | 角色 |
|---|---|
| Ingress | 声明“哪个主机/路径 → 转发到哪个 Service”的 K8s 资源 |
| Ingress Controller | 监听 Ingress、配置反向代理并实际转发流量的控制器程序 |
2.10 ConfigMap 与 Secret
- ConfigMap:存非敏感配置(如配置文件、环境变量),以键值或文件形式挂到 Pod。
- Secret:存敏感数据(密码、证书、Token),以 Base64 或加密形式存储,挂到 Pod;生产建议配合加密或外部 Secret 方案。
2.11 Volume(卷)与持久化
- Volume 与挂载(通俗理解):Volume 就是 Pod 里的一块“存储/目录”。挂载是指把这块存储接到容器内的某个路径(如
/data),容器里访问这个路径就是在读写这块存储。同一 Pod 里多个容器可以把同一 Volume 挂载到各自路径,从而共享同一份文件;Pod 重建或迁移后,若用的是持久化 Volume,数据仍可保留。 - Volume:Pod 内挂载的存储,生命周期可与 Pod 绑定(emptyDir)或独立(PVC)。
- PV(PersistentVolume):集群级存储资源,由管理员或动态供给创建。
- PVC(PersistentVolumeClaim):用户“申请”一块存储,绑定到 PV;Pod 通过 PVC 使用持久化存储。
- StorageClass:定义动态供给的“存储类型”,按 PVC 自动创建 PV(如云盘、NFS)。
三、控制平面组件(Control Plane)
控制平面负责集群的全局决策与协调,通常部署在 Master 节点(或高可用多节点)。
3.1 kube-apiserver(API 服务器)
- 作用:K8s 集群的唯一入口,所有组件都通过 REST API 与 apiserver 交互。
- 功能:认证、鉴权、校验、持久化资源到 etcd;提供 Watch 机制供控制器和调度器感知变更。
- 特点:无状态、可水平扩展,高可用时多副本 + 负载均衡。
3.2 etcd
- 作用:分布式键值存储,保存集群的全部状态数据(Pod、Service、ConfigMap 等)。
- 特点:强一致性、高可用(多副本);只有 apiserver 直接读写 etcd,其他组件不直接访问。
- 注意:需定期备份,并做好资源与网络隔离。
3.3 kube-scheduler(调度器)
- 作用:为未调度的 Pod 选择合适的 Node 并完成绑定。
- 流程:过滤(Filter):筛掉不满足条件的节点;打分(Score):对剩余节点打分,选最优。
- 考虑因素:资源请求/限制、亲和/反亲和、污点与容忍、拓扑等;可扩展与二次开发。
3.4 kube-controller-manager(控制器管理器)
- 作用:运行多种内置控制器,通过 apiserver 监听资源变化,驱动“当前状态”向“期望状态”收敛。
- 包含:Node Controller、Replication Controller、Deployment Controller、Endpoints Controller、Service Account & Token Controller 等。
- 形式:多控制器在同一进程中,通过 goroutine 并发运行。
3.5 cloud-controller-manager(云控制器管理器,可选)
- 作用:与云厂商 API 对接,处理与云相关的逻辑(如节点生命周期、负载均衡、存储)。
- 目的:把云相关代码从 kube-controller-manager 中拆出,便于云厂商定制和 K8s 核心升级。
四、节点组件(Node Components)
运行在每个工作节点上,负责维护 Pod 生命周期与网络。
4.1 kubelet
- 作用:节点上的代理,负责:
- 向 apiserver 注册本节点;
- 接收 Pod 清单(来自 apiserver 或静态 Pod 配置);
- 拉取镜像、启动/停止容器、执行探针;
- 汇报 Pod 与节点状态。
- 特点:不通过 apiserver 创建的容器,kubelet 不会管理;是节点上最核心的组件。
4.2 kube-proxy
- 作用:在节点上实现 Service 的负载均衡与转发(如 ClusterIP 到后端 Pod 的流量)。
- 模式:iptables 或 ipvs,将访问 Service VIP 的流量转发到对应 Pod;支持会话亲和等。
4.3 容器运行时(Container Runtime)
- 作用:在节点上真正拉取镜像、创建/运行容器。
- 接口:通过 CRI(Container Runtime Interface) 与 kubelet 对接。
- 常见:containerd、CRI-O;Docker 作为运行时已被弃用,但镜像仍通用。
五、附加组件(Add-ons)
常以 Pod 形式部署在集群内,提供扩展能力。
- DNS:CoreDNS 等,为 Service/ Pod 提供集群内 DNS(如
svc-name.namespace.svc.cluster.local)。 - 网络插件:Calico、Flannel、Cilium 等,实现 Pod 网络(CNI)与可选网络策略。
- Ingress Controller:如 Nginx Ingress、Traefik,实现 Ingress 规则并转发流量。
- Dashboard:Web UI,可视化管理集群(需配合鉴权与网络策略)。
六、请求流转小结(便于记忆)
- 用户通过 kubectl 或 API 向 kube-apiserver 提交 YAML(如创建 Deployment)。
- apiserver 校验并写入 etcd,其他组件通过 Watch 感知变更。
- kube-controller-manager 中的 Deployment 等控制器创建 ReplicaSet/Pod 等资源。
- kube-scheduler 为未调度的 Pod 选 Node,写回 apiserver(Pod 的 nodeName)。
- 目标 Node 上的 kubelet 从 apiserver 拿到 Pod 清单,通过 容器运行时 拉镜像、起容器。
- kube-proxy 与 网络插件 提供 Service 访问与 Pod 网络;DNS 提供集群内解析。
七、进阶知识点
7.1 RBAC(基于角色的访问控制)
- 目的:控制谁能对哪些资源执行哪些操作(get、list、create、delete、patch 等),实现细粒度权限与多租户隔离。
- 核心资源:
- Role:定义一组权限,作用范围限定在某个 Namespace(如对
pods的 get/list)。 - ClusterRole:同上,但作用范围是集群级(如对所有 ns 的 Pod 只读,或对节点、PV 等集群资源的权限)。
- RoleBinding:把某个 Role/ClusterRole 绑定到用户、组或 ServiceAccount,仅在该 Namespace 内生效。
- ClusterRoleBinding:把 ClusterRole 绑定到主体,集群范围内生效。
- Role:定义一组权限,作用范围限定在某个 Namespace(如对
- 常用:为不同团队绑定不同 Namespace 的 Role;为 Pod 使用的 ServiceAccount 绑定最小权限的 Role,供应用访问 K8s API 或某 ns 内资源。
7.2 网络策略(Network Policy)
- 目的:在集群内做Pod 间/入站/出站流量的访问控制(类似防火墙规则),实现“默认拒绝”或“仅允许某 Pod 访问某服务”。
- 前提:需要网络插件支持 NetworkPolicy(如 Calico、Cilium、Weave 等);仅创建 NetworkPolicy 资源而插件不支持则无效。
- 常见用法:按 Namespace 或 Label 选择 Pod,规定 Ingress(谁可以访问我)/ Egress(我可以访问谁)的规则(协议、端口、对端 Pod/命名空间或 IP 段)。
- 注意:默认多数集群“全通”;一旦某 Namespace 存在一条 NetworkPolicy,该 NS 内未匹配到任何规则的流量通常会被拒绝,需显式放行。
7.3 调度策略(亲和 / 反亲和、污点与容忍)
- 节点亲和(Node Affinity):在 Pod 上声明“优先或必须”调度到带某 Label 的节点(如
node-type=GPU、zone=cn-hangzhou),用于把负载放到特定机型或可用区。 - Pod 亲和 / 反亲和(Pod Affinity / Anti-Affinity):根据“已运行的 Pod”所在节点做调度,例如:同一应用的 Pod 尽量打散到不同节点(反亲和),或与某缓存 Pod 尽量同节点(亲和)。
- 污点与容忍(Taint & Toleration):在节点上打 Taint(如
dedicated=app:NoSchedule),只有带对应 Toleration 的 Pod 才能被调度上去;用于“专用节点”(如只跑 GPU 任务、只跑 Ingress),避免普通 Pod 被调度到这些节点。 - 小结:亲和/反亲和表达“想和谁在一起/分开”;污点与容忍表达“只有符合条件的 Pod 才能上这类节点”。
7.4 Helm
- 是什么:K8s 的包管理工具,把一组 YAML(Deployment、Service、ConfigMap 等)打包成 Chart,支持参数化(变量、环境区分)和版本管理。
- 作用:一键安装/升级/回滚复杂应用(如 MySQL、Redis、Prometheus);通过 values.yaml 覆盖默认配置,避免手改大量 YAML。
- 核心概念:Chart(应用包)→ Release(在集群中安装后的实例,有名字和版本);
helm install、helm upgrade、helm rollback、helm uninstall。 - 常用:使用官方或社区 Chart(如
helm repo add bitnami https://charts.bitnami.com/bitnami),或为公司内部应用编写私有 Chart。
7.5 Operator
- 是什么:一种扩展 K8s 的方式:用自定义资源(CRD)+ 控制器来管理“有状态或复杂逻辑”的应用,把运维知识编码成代码,通过声明式资源驱动(如创建一个
MySQLCluster资源,Operator 自动创建 StatefulSet、Service、备份等)。 - 与普通控制器的区别:Operator 针对特定应用/中间件(如 etcd、Prometheus、MySQL、Kafka),不仅管 Pod 数量,还管配置、扩缩容、升级、备份恢复等领域逻辑。
- 常见:Prometheus Operator、ETCD Operator、MySQL Operator、Kafka Operator 等;也可用 Operator SDK 或 KubeBuilder 自研 Operator。
- 价值:把“人肉运维”变成“声明式 + 自动化”,更贴近“K8s 原生”的使用方式。
八、Kubernetes Goat 靶场环境探索
8.1 环境搭建
Kubernetes Goat 是一个故意设计的安全漏洞靶场环境,专门用于学习和实践 Kubernetes 安全概念。
环境搭建方式
方式一:在已有集群上部署(推荐)
1 | # 1. 确保集群正常运行 |
方式二:一键建集群并部署
1 | # 直接在 Kind 中创建集群并部署 Goat |
环境验证
1 | # 查看集群状态 |
8.2 核心基础概念
8.2.1 Cluster(集群)
含义:由一组**控制平面节点(Master)和若干工作节点(Node)**组成的整体。
在 Goat 环境中的体现:
1 | # 查看集群信息 |

1 | # 查看节点状态 |

当前集群状态:
- 控制平面节点:1个 (my-k8s-lab-control-plane)
- 工作节点:1个 (my-k8s-lab-worker)
- 版本:v1.35.0
8.2.2 Node(节点)
含义:集群中的一台机器(物理机或虚拟机),是 Pod 实际运行的地方。
控制面板节点
1 | # 查看 控制平面节点 详情 |


控制平面节点 (my-k8s-lab-control-plane):
-
角色:control-plane
-
污点:node-role.kubernetes.io/control-plane:NoSchedule(阻止业务Pod调度)
-
容量:10 CPU核心,8GB内存,最多110个Pod
-
架构:ARM64,运行Debian 12
-
容器运行时:containerd 2.2.0
-
Pod网络:10.244.0.0/24
-
当前负载:9个系统Pod,CPU使用9%,内存使用3%
-
运行组件:API Server、etcd、Scheduler、Controller Manager等
工作节点
1 | # 查看 工作节点 详情 |


工作节点 (my-k8s-lab-worker):
- 角色:
(纯工作节点) - 污点:无(可以正常调度业务Pod)
- 容量:10 CPU核心,8GB内存,最多支持110个Pod
- 架构:ARM64,运行Debian 12
- 容器运行时:containerd 2.2.0
- Pod网络:10.244.1.0/24
- 当前负载:13个Pod,CPU使用率3%,内存使用率6%
- 运行组件:kubelet、kube-proxy、kindnet(网络插件)
- 业务Pod:运行所有kubernetes-goat应用组件(主页、构建服务、健康检查、代理、数据库等)
节点标签和状态
1 | # 查看节点标签和状态 |

节点标签是键值对,用于标识节点的特性,在Pod调度和节点选择中发挥重要作用:
当前集群节点标签详解:
控制平面节点 (my-k8s-lab-control-plane) 标签:
beta.kubernetes.io/arch=arm64:Beta版本架构标签,表示ARM64架构beta.kubernetes.io/os=linux:Beta版本OS标签,表示Linux操作系统kubernetes.io/arch=arm64:稳定版架构标签,标识节点CPU架构kubernetes.io/hostname=my-k8s-lab-control-plane:节点主机名kubernetes.io/os=linux:稳定版OS标签,标识操作系统node-role.kubernetes.io/control-plane=:节点角色标签,标识为控制平面节点node.kubernetes.io/exclude-from-external-load-balancers=:排除外部负载均衡器标签
工作节点 (my-k8s-lab-worker) 标签:
beta.kubernetes.io/arch=arm64:Beta版本架构标签beta.kubernetes.io/os=linux:Beta版本OS标签kubernetes.io/arch=arm64:稳定版架构标签kubernetes.io/hostname=my-k8s-lab-worker:节点主机名kubernetes.io/os=linux:稳定版OS标签
标签作用说明:
- 架构标签 (
kubernetes.io/arch):用于调度需要特定CPU架构的Pod - OS标签 (
kubernetes.io/os):用于调度需要特定操作系统的Pod - 角色标签 (
node-role.kubernetes.io/*):标识节点类型,影响调度策略 - 主机名标签 (
kubernetes.io/hostname):节点唯一标识,可用于节点亲和性 - Beta标签:Kubernetes的Beta API标签,可能在未来版本中移除
这些标签可以被Pod的nodeSelector、nodeAffinity等调度策略使用,实现精细化的Pod placement控制。
8.2.3 Pod
含义:K8s 中最小可部署单元,由一个或多个容器组成,共享网络和存储。
在 Goat 环境中的体现:
1 | # 查看所有 Pod |

当前集群中的单容器Pod示例:
- metadata-db (default):数据库服务,IP 10.244.1.2
- build-code-deployment (default):构建服务,IP 10.244.1.4
- health-check-deployment (default):健康检查服务,IP 10.244.1.6
- poor-registry-deployment (default):镜像仓库服务,IP 10.244.1.10
- system-monitor-deployment (default):系统监控服务,IP 10.244.1.11
- kubernetes-goat-home-deployment (default):主页服务,IP 10.244.1.9
- batch-check-job (default):批处理任务,IP 10.244.1.3
- hidden-in-layers (default):隐藏层服务,IP 10.244.1.12
- hunger-check-deployment (big-monolith):饥饿检查服务,IP 10.244.1.7
- cache-store-deployment (secure-middleware):缓存存储服务,IP 10.244.1.5
多容器Pod示例:
- internal-proxy-deployment (default):内部代理服务,包含2个容器,IP 10.244.1.8
单容器Pod
大部分应用服务都是单容器Pod,例如:
1 | # 查看特定 Pod 详情 |


kubernetes-goat-home Pod 示例:
- Pod名称:kubernetes-goat-home-deployment-cd46cd955-xsz9c
- 命名空间:default
- 状态:Running(运行中)
- 调度节点:my-k8s-lab-worker (172.19.0.2)
- 标签:app=kubernetes-goat-home, pod-template-hash=cd46cd955
- 容器信息:
- 容器名:kubernetes-goat-home
- 镜像:madhuakula/k8s-goat-home
- 端口:80/TCP
- 资源配置:CPU 30m/30m, 内存 50Mi/50Mi (Guaranteed QoS)
- 控制器:由ReplicaSet/kubernetes-goat-home-deployment-cd46cd955管理
- 网络:Pod IP 10.244.1.9
- 存储:挂载service account token卷用于API访问
- 容忍:默认容忍节点not-ready和unreachable状态
多容器Pod
internal-proxy-deployment (default):多容器Pod示例
1 | # 查看多容器 Pod |


- Pod名称:internal-proxy-deployment-c59c45d94-sqnpw
- 状态:Running(运行中)
- 调度节点:my-k8s-lab-worker (172.19.0.2)
- 网络:Pod IP 10.244.1.8
- 容器详情:
- internal-api容器:
- 镜像:madhuakula/k8s-goat-internal-api
- 端口:3000/TCP
- 资源:CPU 30m/50m, 内存 40Mi/60Mi
- info-app容器:
- 镜像:madhuakula/k8s-goat-info-app
- 端口:5000/TCP
- 资源:CPU 30m/30m, 内存 40Mi/50Mi
- internal-api容器:
- QoS等级:Burstable(资源请求 < 限制)
- 共享存储:两个容器都挂载service account token卷
- 控制器:由ReplicaSet/internal-proxy-deployment-c59c45d94管理
这个多容器Pod展示了Sidecar模式:两个容器共享同一网络命名空间和存储卷,但提供不同的功能服务。
8.2.4 Namespace(命名空间)
含义:集群内的逻辑隔离,用于多租户、多环境划分资源。
所有命令空间
1 | # 查看所有命名空间 |

7个命名空间:
- default:默认命名空间,所有未指定命名空间的资源所在
- kube-system:Kubernetes系统组件命名空间
- kube-public:公共资源命名空间,所有用户可读
- kube-node-lease:节点租约,用于节点心跳检测
- big-monolith:大型单体应用命名空间
- secure-middleware:安全中间件命名空间
- local-path-storage:本地存储组件命名空间
所有命名空间状态均为Active,运行时间约9小时。
命名空间的资源分布
1 | # 查看各命名空间的资源分布 |


Goat 环境的命名空间架构:
-
default (10个Pod, 8个Deployment, 8个ReplicaSet, 7个Service, 2个Job):
- 主应用命名空间,包含大部分业务服务
- 包括主页、构建服务、健康检查、数据库、注册表等核心组件
- 还有批处理任务和隐藏服务
-
big-monolith (1个Pod, 1个Deployment, 1个ReplicaSet, 1个Service):
- 大型单体应用命名空间,模拟传统应用架构
- 包含饥饿检查(hunger-check)服务
-
secure-middleware (1个Pod, 1个Deployment, 1个ReplicaSet, 1个Service):
- 安全中间件命名空间,包含缓存存储服务
- 提供Redis风格的缓存功能
-
local-path-storage (1个Pod, 1个Deployment, 1个ReplicaSet):
- 本地存储组件命名空间
- 运行local-path-provisioner提供本地持久化存储
-
kube-system:系统组件命名空间(包含API Server、etcd、CoreDNS等)
-
kube-public:公共资源命名空间
-
kube-node-lease:节点租约命名空间
8.2.5 Label(标签)与 Selector(选择器)
Label:键值对,挂在 Pod、Node、Service 等对象上,用于标识和分类。
Selector:按 Label 筛选资源。
Pod标签
1 | # 查看 Pod 标签 |

展示了Pod标签的丰富多样性:
Deployment管理的Pod标签模式:
app=<service-name>:应用标识标签,如app=kubernetes-goat-homepod-template-hash=<hash>:模板哈希,用于版本控制,如pod-template-hash=cd46cd955
Job管理的Pod标签模式:
batch.kubernetes.io/job-name=<name>:作业名称,如batch.kubernetes.io/job-name=batch-check-jobbatch.kubernetes.io/controller-uid=<uid>:控制器UID,用于唯一标识job-name=<name>:简化作业名称标签
系统组件标签模式:
component=<component-name>:组件类型,如component=etcdtier=control-plane:层级标识,标记控制平面组件k8s-app=<app-name>:Kubernetes应用标识,如k8s-app=kube-dnsapp=<app-name>:应用名称,如app=kindnet
Helm管理的Pod标签(metadata-db):
app.kubernetes.io/instance=<release-name>:Helm发布实例名app.kubernetes.io/name=<chart-name>:Helm Chart名称
这些标签构成了Kubernetes资源管理的基石,支持服务发现、负载均衡、滚动更新等核心功能。
Deployment 的选择器
1 | # 查看 Deployment 的选择器 |

kubernetes-goat-home-deployment 的选择器: app=kubernetes-goat-home
通过这个选择器,Deployment 能够找到并管理所有带有 app=kubernetes-goat-home 标签的 Pod。这个选择器确保了 Deployment 只管理属于主页应用的 Pod 实例。
Service 的选择器
1 | # 查看 Service 的选择器 |

kubernetes-goat-home-service 的选择器: app=kubernetes-goat-home
- 服务类型:ClusterIP (集群内部访问)
- 服务IP:10.96.38.30
- 端口映射:80/TCP → 80/TCP
- 后端端点:10.244.1.9:80 (匹配的Pod IP和端口)
- 会话亲和性:None (不保持会话粘性)
通过选择器 app=kubernetes-goat-home,Service 能够发现并负载均衡到所有带有此标签的 Pod。
Goat环境中的实际标签模式:
业务应用标签:
app=kubernetes-goat-home:主页应用标识app=build-code:构建服务标识app=health-check:健康检查服务标识app=internal-proxy:内部代理服务标识app=metadata-db:数据库服务标识app=poor-registry:镜像仓库服务标识app=system-monitor:系统监控服务标识app=hunger-check:饥饿检查服务标识 (big-monolith命名空间)app=cache-store:缓存存储服务标识 (secure-middleware命名空间)
控制器生成标签:
pod-template-hash=<hash>:Deployment/ReplicaSet生成的Pod模板哈希batch.kubernetes.io/job-name=<name>:Job生成的Pod作业名称controller-uid=<uid>:控制器实例唯一标识
8.2.6 Annotation(注解)
含义:键值对,用于存非标识性元数据,不参与对象选择。
Pod注解
1 | # 查看 Pod 注解 |

kubernetes-goat-home Pod 的注解: 无注解 (<none>)
这个 Pod 没有配置任何注解,这在简单的应用部署中是常见的。注解通常用于存储非标识性元数据,如配置信息、工具说明等。
Deployment注解
1 | # 查看 Deployment 注解 |

metadata-db Deployment 的注解:
deployment.kubernetes.io/revision: 1:Kubernetes 自动生成的部署版本号,表示这是第1个版本meta.helm.sh/release-name: metadata-db:Helm Chart 的发布名称meta.helm.sh/release-namespace: default:Helm Chart 发布的命名空间
这些注解提供了部署版本控制和 Helm 管理的元数据信息。
8.2.7 Controller(控制器)与声明式 API
声明式:用户描述"期望状态",控制器负责让"当前状态"不断逼近"期望状态"。
Deployment
1 | # 查看所有 Deployment(最常见的控制器) |

共 11 个 Deployment,分布在 5 个命名空间中:
- default: 7个(kubernetes-goat-home、build-code、health-check、internal-proxy、metadata-db、poor-registry、system-monitor)
- big-monolith: 1个(hunger-check)
- secure-middleware: 1个(cache-store)
- kube-system: 1个(coredns)
- local-path-storage: 1个(local-path-provisioner)
控制器主要作用:
- 状态调谐:持续监控实际状态与期望状态的差异
- 自动修复:当Pod异常退出时,自动创建新的Pod维持期望副本数
- 声明式管理:用户只需声明"期望状态",控制器负责实现
- 扩展伸缩:支持动态调整Pod副本数量
- 滚动更新:支持应用版本的无缝升级和回滚
控制器是Kubernetes实现自动化和自愈能力的核心组件。
ReplicaSet
1 | # 查看 Deployment 管理的 ReplicaSet |

ReplicaSet 详解:
共 11 个 ReplicaSet,全都由 Deployment 自动创建和管理:
- 10个单副本 RS:每个维护1个Pod实例(DESIRED=1, CURRENT=1, READY=1)
- 1个双副本 RS:coredns 维护2个Pod实例(DESIRED=2, CURRENT=2, READY=2)
ReplicaSet 主要作用:
- 副本保证:确保指定数量的Pod副本始终运行,即使节点故障或Pod异常退出
- 自动修复:当Pod失败时,立即在合适节点创建新的Pod替换
- 扩缩容支持:通过修改期望副本数实现Pod的动态伸缩
- 标签管理:通过标签选择器精确匹配和管理目标Pod
- 版本控制:每个Deployment版本对应一个ReplicaSet,支持回滚
ReplicaSet 是实现 Kubernetes 自愈和弹性伸缩的核心控制器。
Job
1 | # 查看 Job(一次性任务控制器) |

2个 Job,用于执行一次性批处理任务:
- batch-check-job:运行中,0/1 完成,持续运行31小时
- hidden-in-layers:运行中,0/1 完成,持续运行31小时
Job 主要作用:
- 一次性执行:运行完成后自动终止,不像Deployment那样持续运行
- 完成保证:确保任务至少执行一次,失败时自动重试
- 并行处理:支持同时运行多个Pod实例处理同一任务
- 资源清理:任务完成后自动删除关联的Pod,节省资源
- 定时任务基础:CronJob 通过定期创建Job来实现定时执行
Job 适用于数据处理、备份、迁移等需要执行一次就结束的任务。
8.2.8 Service(服务)
含义:为 Pod 提供稳定的访问入口,做服务发现与负载均衡。
所有服务
1 | # 查看所有服务 |

共 12 个 Service,提供稳定的网络访问:
- 11个 ClusterIP 服务:集群内部访问(默认类型)
- 1个 NodePort 服务:通过节点端口从外部访问
- 1个系统 DNS 服务:kube-dns 提供域名解析
Service 主要作用:
- 网络抽象:为Pod组提供稳定的虚拟IP和DNS名,屏蔽Pod的动态变化
- 负载均衡:自动将请求分发到多个Pod实例,实现高可用
- 服务发现:通过DNS或环境变量让应用找到其他服务
- 流量控制:支持会话亲和性、端口映射等高级功能
- 多访问方式:ClusterIP(内)、NodePort(外)、LoadBalancer(云)
Service 是 Kubernetes 实现微服务通信和网络抽象的核心组件。
服务详情
1 | # 查看服务详情 |

kubernetes-goat-home-service 详情分析:
Service 详情包含以下主要内容:
基本信息:
- 名称和命名空间:kubernetes-goat-home-service / default
- 标签和注解:用于标识和存储元数据
核心配置:
- 选择器:
app=kubernetes-goat-home- 用于匹配后端Pod - 服务类型:ClusterIP - 集群内部访问
- 虚拟IP:10.96.38.30 - 服务稳定访问地址
端口配置:
- 服务端口:80/TCP - 外部访问端口
- 目标端口:80/TCP - Pod内容器端口
后端状态:
- 端点:10.244.1.9:80 - 实际Pod的IP和端口
- 会话亲和性:None - 不保持会话粘性
Service 通过选择器找到匹配的Pod,并提供稳定的网络访问端点。
服务端点
1 | # 查看服务端点 |

共 12 个 Endpoints,记录 Service 后端 Pod 的实际地址:
Endpoints 是 Service 的"地址簿",记录了所有匹配 Pod 的 IP 和端口:
Endpoints 主要作用:
- 地址记录:维护 Service 选择器匹配到的所有 Pod 的 IP:Port
- 动态更新:当 Pod 启动、停止或重启时,自动更新端点列表
- 负载均衡基础:Service 使用 Endpoints 信息进行流量分发
- 健康过滤:只包含 Ready 状态的 Pod 端点
- 网络桥梁:连接 Service 的虚拟 IP 与 Pod 的实际地址
示例分析:
kubernetes-goat-home-service→10.244.1.9:80(单个Pod)kube-dns→ 多个端点(2个Pod提供DNS服务)kubernetes→172.19.0.3:6443(API Server端点)
Endpoints 确保 Service 始终知道如何找到可用的后端 Pod。
Goat 环境中的服务类型统计:
ClusterIP (11个):集群内部访问的默认服务类型
- 所有业务应用服务:主页、构建、健康检查、数据库、注册表等
- 系统服务:kubernetes (API Server)、kube-dns (DNS服务)
NodePort (1个):通过节点端口从外部访问
internal-proxy-info-app-service:端口映射 5000→30003
服务类型说明:
- ClusterIP:只在集群内部访问,提供稳定的虚拟IP
- NodePort:在每个节点上开放端口,允许外部访问
- LoadBalancer:在云环境中自动创建负载均衡器(当前环境未使用)
8.2.9 Ingress 与 Ingress Controller
Ingress:描述 HTTP/HTTPS 流量路由规则的 K8s 资源。
Ingress Controller:实际处理流量的控制器。
Ingress资源
1 | # 查看 Ingress 资源 |

Goat环境中没有使用Ingress,而是通过以下方式进行流量路由:
主要流量路由方式:
-
Service直接暴露:
- ClusterIP:11个服务通过集群内部虚拟IP访问
- NodePort:1个服务通过节点端口30003暴露给外部
-
端口转发:
- 使用
kubectl port-forward或bash access-kubernetes-goat.sh脚本 - 将集群内部服务映射到本地端口(如1234)
- 使用
-
应用层路由:
- 某些服务在应用内部实现自己的路由逻辑
- 如internal-proxy服务处理多个端口的流量分发
Ingress Controller(如果存在)
1 | # 查看 Ingress Controller(如果存在) |

**当前状态:**Goat 环境未配置 Ingress,主要是通过 NodePort 和端口转发访问。
8.2.10 ConfigMap 与 Secret
ConfigMap:存非敏感配置。
Secret:存敏感数据。
ConfigMap
1 | # 查看所有 ConfigMap |

共 15 个 ConfigMaps,分布在 6 个命名空间中:
ConfigMaps 主要作用:
- 配置存储:以键值对形式存储非敏感配置数据
- 环境变量注入:将配置传递给Pod作为环境变量
- 挂载为文件:将配置挂载到Pod的文件系统中
- 应用配置管理:管理应用的配置文件、环境设置等
ConfigMap 分类:
系统ConfigMaps (12个):
kube-root-ca.crt:Kubernetes根证书,在每个命名空间都有cluster-info:集群连接信息coredns:DNS服务配置kube-proxy:代理服务配置kubelet-config:节点代理配置local-path-config:本地存储配置
业务ConfigMaps (3个):
extension-apiserver-authentication:扩展API认证配置kubeadm-config:集群初始化配置kube-apiserver-legacy-service-account-token-tracking:服务账户令牌跟踪配置
ConfigMaps 提供了将配置与应用代码分离的最佳实践方式。
Secret
1 | # 查看所有 Secret |

共 4 个 Secrets,存储敏感数据:
Secrets 主要作用:
- 敏感数据存储:以Base64编码形式存储密码、密钥、证书等敏感信息
- 安全传递:将敏感数据安全地传递给Pod,避免明文暴露
- 访问控制:通过RBAC控制Secrets的访问权限
- 加密存储:在etcd中加密存储,支持密钥轮换
Secrets vs ConfigMaps:
- Secrets:存储敏感数据,Base64编码,在内存中解密
- ConfigMaps:存储非敏感配置,明文存储
当前Secrets详解:
- goatvault (default): 应用密钥存储
- vaultapikey (big-monolith): API密钥
- webhookapikey (big-monolith): Webhook密钥
- sh.helm.release.v1.metadata-db.v1 (default): Helm发布信息
Secrets 提供了在Kubernetes中管理敏感数据的安全机制。
Secret详情
1 | # 查看特定 Secret 详情 |

goatvault Secret 的详情分析:
Secret 详情包含以下主要信息:
基本信息:
- 名称:goatvault
- 命名空间:default
- 类型:Opaque(通用类型Secret)
- 标签和注解:无(未设置标识信息)
数据内容:
- 密钥名称:k8sgoatvaultkey
- 数据大小:41字节(Base64编码后的长度)
- 实际值:出于安全考虑,describe命令不显示明文值
安全特性:
- 编码存储:数据以Base64格式存储
- 访问控制:需要适当的RBAC权限才能访问
- 运行时解密:Pod内使用时才解密为明文
Secret详情提供了元数据信息,但出于安全考虑不显示敏感数据内容。
Secret 数据(Base64 编码)
1 | # 查看 Secret 数据(Base64 编码) |

查看Secret完整数据(YAML格式):
Secret 的完整YAML结构包含以下内容:
资源元数据 (metadata):
- name:Secret名称 (goatvault)
- namespace:所属命名空间 (default)
- annotations:注解信息,包括kubectl的应用配置历史
- creationTimestamp:创建时间戳
- resourceVersion:资源版本号
- uid:全局唯一标识符
规范信息 (spec):
- type:Secret类型 (Opaque - 通用类型)
- data:Base64编码的敏感数据
k8sgoatvaultkey:azhzLWdvYXQtY2QyZGEyNzIyNDU5MWRhMmI0OGVmODM4MjZhOGE2YzM=
解码后的实际值:
1 | echo "azhzLWdvYXQtY2QyZGEyNzIyNDU5MWRhMmI0OGVmODM4MjZhOGE2YzM=" | base64 -d |
当前环境的关键Secret:
- goatvault:存储k8s-goat-cd2da27224591da2b48ef83826a8a6c3密钥
- vaultapikey:API访问密钥
- webhookapikey:Webhook认证密钥
8.2.11 Volume(卷)与持久化
Volume:Pod 内的存储抽象。
PV/PVC:持久化存储资源。
持久卷声明
1 | # 查看持久卷声明 |

PVC (PersistentVolumeClaim) 不存在。
PVC 全称:PersistentVolumeClaim(持久卷声明)
PVC 的作用:
- 存储请求:Pod向Kubernetes请求持久化存储空间
- 自动绑定:根据请求条件自动绑定合适的PersistentVolume(PV)
- 抽象层:为Pod提供存储抽象,屏蔽底层存储细节
- 生命周期管理:独立于Pod生命周期,数据持久保存
为什么 Goat 环境中没有 PVC?
-
应用特性:大部分服务是无状态应用,无需持久化存储
-
数据存储方式:
- 内存存储:数据存储在Pod内存中,随Pod重启而丢失
- 数据库服务:数据存储在metadata-db容器中(但未配置外部持久卷)
- 临时存储:可能使用emptyDir卷提供容器内临时存储
-
环境设计:作为安全靶场环境,重点在于安全漏洞演示而非数据持久化
-
存储策略:使用local-path-provisioner但未创建实际的PVC请求
PVC 使用示例:
1 | apiVersion: v1 |
PVC 是 Kubernetes 持久化存储的核心抽象,但在 Goat 环境中被有意省略以简化架构。
持久卷
1 | # 查看持久卷 |

PV (PersistentVolume) 为空。
PV 全称:PersistentVolume(持久卷)
PV 的作用:
- 存储资源:集群级别的存储卷,代表实际的物理存储
- 生命周期管理:独立于Pod存在,可被多个PVC绑定和释放
- 存储抽象:屏蔽底层存储实现的差异(NFS、本地磁盘、云存储等)
- 容量管理:定义存储容量、访问模式和回收策略
为什么 Goat 环境中 PV 为空?
- 没有PVC请求:PV是由PVC动态创建或静态预创建的,没有PVC就不会有PV
- 应用无需持久化:大部分服务是无状态的,不需要持久卷
- 存储策略:虽然配置了local-path-provisioner,但没有实际的PVC来触发PV创建
PV 创建方式:
- 动态创建:通过StorageClass + PVC自动创建
- 静态创建:管理员预先创建PV供PVC绑定
PV 状态:
- Available:可用,等待PVC绑定
- Bound:已绑定到PVC
- Released:PVC删除后进入释放状态
- Failed:创建或绑定失败
PV 是 Kubernetes 存储系统的物理存储层,在 Goat 环境中被省略以简化架构。
存储类
1 | # 查看存储类 |

StorageClass 详解:
StorageClass 是什么?
StorageClass 是 Kubernetes 的存储类,定义了如何自动创建存储卷的"模板"。
核心作用:
- 存储供应:定义存储卷的创建方式和参数
- 动态供应:PVC请求时自动创建对应的PV
- 存储抽象:屏蔽不同存储系统的差异
- 策略控制:定义回收策略、绑定模式等行为
当前环境StorageClass配置:
| 属性 | 值 | 说明 |
|---|---|---|
| 名称 | standard (default) | 默认存储类,标有(default)标识 |
| 供应器 | rancher.io/local-path | 使用本地路径供应器 |
| 回收策略 | Delete | PVC删除时自动删除PV和数据 |
| 绑定模式 | WaitForFirstConsumer | 延迟绑定,等待Pod使用时再绑定 |
| 卷扩展 | false | 不支持动态扩展存储容量 |
工作原理:
- PVC请求存储时指定storageClassName
- StorageClass根据配置自动创建PV
- PV与PVC绑定,Pod即可使用存储
StorageClass 让存储管理变得声明式和自动化。
存储配置:
- StorageClass:standard (local-path) - 已配置但未使用
- PVC:0个 - Goat环境中没有持久卷声明
- PV:0个 - 没有PVC请求,自然没有持久卷
存储设计决策:
- 采用无状态架构设计,大部分应用无需持久化存储
- 数据存储在容器内存或服务抽象层中
- 虽然配置了local-path-provisioner,但没有实际PVC触发PV创建
- 这种设计有利于快速重建和环境简化,但数据在Pod重启后会丢失
8.3 控制平面组件(Control Plane)
控制平面负责集群的全局决策与协调。
8.3.1 kube-apiserver(API 服务器)
作用:K8s 集群的唯一入口,所有组件都通过 REST API 与 apiserver 交互。
API Server状态
1 | # 查看 API Server状态 |

API Server 运行状态:正常运行
API Server 详解:
API Server 是什么?
kube-apiserver 是 Kubernetes 控制平面的核心组件,是整个集群的"大脑"和统一入口。
核心功能:
- 统一入口:所有集群操作的唯一入口点
- API 提供:提供RESTful API供kubectl、控制器、调度器等访问
- 认证授权:验证请求身份和权限
- 数据校验:验证和处理API请求的数据合法性
- 状态存储:将资源状态写入etcd并提供读取服务
- Watch机制:支持实时监听资源变化
当前状态:
- Pod名称:kube-apiserver-my-k8s-lab-control-plane
- 状态:1/1 Running(1个容器,正常运行)
- 重启次数:0(运行稳定)
- 运行时间:32小时
工作原理:
- 接收kubectl或其他客户端的请求
- 进行身份认证和权限检查
- 验证请求数据的合法性
- 将资源状态写入etcd
- 通过Watch机制通知相关组件
API Server 是 Kubernetes 集群的控制中枢,所有操作都要通过它进行。
测试API连接
1 | # 测试 API 连接 |

查看 API Server 端点
1 | # 查看 API Server 端点 |

API Server 端点详解:
端点是什么?
API Server端点是kubernetes服务的实际访问地址,记录了API Server Pod的IP和端口。
端点的作用:
- 服务发现:告诉集群内部组件如何访问API Server
- 负载均衡:支持多个API Server实例时的负载分发
- 网络连接:提供稳定的网络访问点
- 健康检查:Endpoints会自动更新,确保只指向健康的Pod
当前端点信息:
- 服务名称:kubernetes
- 端点地址:172.19.0.3:6443
- 协议:HTTPS (6443是标准Kubernetes API端口)
- 运行时间:32小时
访问方式对比:
- 内部访问:通过端点IP (172.19.0.3:6443)
- 外部访问:通过kubectl proxy或端口转发 (https://127.0.0.1:64040)
重要性:
Endpoints确保了集群组件能够可靠地找到并连接到API Server,是集群通信的基础设施。
8.3.2 etcd
作用:分布式键值存储,保存集群的全部状态数据。
etcd状态
1 | # 查看 etcd 状态 |

etcd 运行状态:正常运行
etcd 详解:
etcd 是什么?
etcd 是 Kubernetes 的分布式键值存储系统,是集群的"记忆数据库"。
核心功能:
- 数据存储:保存集群的所有状态信息(Pod、Service、ConfigMap等)
- 高可用:支持多节点复制,确保数据不丢失
- 一致性保证:使用Raft算法确保数据一致性
- Watch机制:支持实时监听数据变化
- 原子操作:支持事务和条件更新
当前状态:
- Pod名称:etcd-my-k8s-lab-control-plane
- 状态:1/1 Running(正常运行)
- 重启次数:0(运行稳定)
- 运行时间:42小时
etcd 的作用机制:
- API Server写入:所有集群状态变更都通过API Server写入etcd
- 数据持久化:etcd将数据写入磁盘,确保重启后数据不丢失
- 数据复制:在多节点etcd集群中同步数据
- 读取服务:API Server从etcd读取集群状态
- 变更通知:通过Watch API通知控制器和调度器状态变化
为什么重要?
- 单一数据源:集群状态的唯一权威来源
- 故障恢复:支持集群重启后状态恢复
- 性能保障:高效的读写性能支撑大规模集群
- 安全存储:支持数据加密存储
etcd 是 Kubernetes 集群状态的"中央大脑",没有etcd集群就无法正常工作。
etcd端点
1 | # 查看 etcd 端点 |

etcd 容器配置详解:
容器信息:
- 镜像:registry.k8s.io/etcd:3.6.6-0
- 端口:2381/TCP(etcd客户端端口,用于集群内部通信)
- 探针端口:2381(用于健康检查)
存储配置:
- 证书卷:etcd-certs (HostPath类型)
- 挂载路径:/etc/kubernetes/pki/etcd
- 用途:存储etcd的TLS证书和密钥
工作机制:
- 数据存储:etcd将集群状态以键值对形式存储
- 证书认证:使用TLS证书保证通信安全
- 集群通信:通过2381端口与其他etcd节点通信
- API访问:API Server通过本地连接访问etcd
安全特性:
- TLS加密:所有通信都经过TLS加密
- 证书验证:双向证书认证确保通信安全
- 访问控制:只有API Server能直接访问etcd
etcd 是集群状态的加密、安全存储后端。
8.3.3 kube-scheduler(调度器)
作用:为未调度的 Pod 选择合适的 Node 并完成绑定。
调度器状态
1 | # 查看调度器状态 |

调度策略
1 | # 查看调度决策 |

调度器状态:正常运行
Kubernetes 调度策略详解:
调度器是什么?
kube-scheduler 是 Kubernetes 的调度组件,负责将Pod分配到合适的节点上运行。
调度流程:
- 过滤阶段(Predicate):筛选出满足Pod要求的节点
- 打分阶段(Priority):对候选节点进行打分排序
- 选择阶段:选择得分最高的节点进行绑定
主要调度策略:
1. 资源调度:
- CPU/内存请求:确保节点有足够资源
- 资源限制:考虑Pod的资源上限
- QoS等级:Guaranteed > Burstable > BestEffort
2. 亲和性调度:
- 节点亲和性:Pod偏好某些节点特征
- Pod亲和性:Pod间相互吸引或排斥
- Pod反亲和性:避免Pod在同一节点
3. 污点与容忍:
- 污点:节点拒绝某些Pod调度
- 容忍:Pod声明能接受的污点
4. 其他策略:
- 拓扑约束:跨区域/可用区的分布
- 优先级:高优先级Pod优先调度
- 抢占:为高优先级Pod释放资源
当前调度结果分析:
- Pod状态:PodScheduled=True(已成功调度)
- 调度节点:my-k8s-lab-worker(工作节点)
- 控制关系:通过ReplicaSet间接调度
- 网络分配:自动分配Pod IP (10.244.1.9)
调度器确保了Pod被分配到满足所有要求的节点上,实现集群资源的合理利用。
8.3.4 kube-controller-manager(控制器管理器)
作用:运行多种内置控制器,驱动"当前状态"向"期望状态"收敛。
控制器管理器是实现Kubernetes声明式API和自愈能力的关键组件。
控制器管理器状态
1 | # 查看控制器管理器状态 |

控制器管理的资源
1 | # 查看控制器管理的资源(修正后的命令) |
控制器管理器状态:正常运行
控制器管理器详解:
kube-controller-manager 是什么?
它是 Kubernetes 控制平面的核心组件,运行多个内置控制器来维护集群状态。
核心功能:
- 状态调谐:持续监控当前状态与期望状态的差异
- 自动修复:发现偏差时自动执行操作纠正状态
- 多控制器集成:在一个进程中运行多种控制器
包含的主要控制器:
- Deployment Controller:管理Deployment和ReplicaSet
- ReplicaSet Controller:管理Pod副本
- Service Controller:维护Service和Endpoints
- Node Controller:管理节点状态
- PV Controller:管理持久卷绑定
- Job Controller:管理一次性任务
当前状态:
- Pod名称:kube-controller-manager-my-k8s-lab-control-plane
- 状态:1/1 Running(正常运行)
- 重启次数:0(运行稳定)
- 运行时间:42小时
工作机制:
控制器管理器通过API Server的Watch机制监听资源变化,当检测到当前状态偏离期望状态时,自动执行修正操作,确保集群始终处于期望状态。
8.4 节点组件(Node Components)
运行在每个工作节点上,负责维护 Pod 生命周期与网络。
8.4.1 kubelet
作用:节点上的代理,负责 Pod 生命周期管理。
1 | # 查看 kubelet 进程(需要在节点上执行) |

1 | # 查看节点状态 |


工作节点状态详解:
节点基本信息:
- 名称:my-k8s-lab-worker
- 角色:
(纯工作节点) - 污点:无(可正常调度Pod)
- 状态:Ready(节点正常运行)
资源容量:
- CPU:10核
- 内存:8GB (8024852Ki)
- 存储:60GB (ephemeral-storage)
- Pod容量:最多110个Pod
当前资源使用:
- CPU分配:320m 请求 / 340m 限制 (3% 使用率)
- 内存分配:490Mi 请求 / 520Mi 限制 (6% 使用率)
- 运行Pod数:13个
网络配置:
- Pod网络段:10.244.1.0/24
- 节点IP:172.19.0.2 (内部)
健康状态:
- MemoryPressure:False(内存充足)
- DiskPressure:False(磁盘空间充足)
- PIDPressure:False(进程数正常)
- Ready:True(节点就绪)
系统信息:
- OS:Debian GNU/Linux 12 (bookworm)
- 架构:ARM64
- 内核:6.12.54-linuxkit
- 容器运行时:containerd 2.2.0
- Kubelet版本:v1.35.0
节点运行正常,资源充足,可继续调度新的Pod。
1 | # 查看 Pod 状态 |
**当前状态:**每个节点都有 kubelet 运行,负责管理该节点的 Pod
8.4.2 kube-proxy
作用:在节点上实现 Service 的负载均衡与转发。
在 Goat 环境中的体现:
1 | # 查看 kube-proxy 状态 |

1 | # 查看 Service 网络规则 |

1 | # 测试服务访问 |
kube-proxy 详解:
当前状态:
- 工作节点:kube-proxy-462gh (1/1 Running)
- 控制平面:kube-proxy-hmzh6 (1/1 Running)
- 职责:每个节点都有kube-proxy,负责该节点的Service流量转发
kube-proxy 的核心作用:
- Service实现:将Service的虚拟IP/端口映射到实际Pod
- 负载均衡:在多个Pod间分发请求,实现高可用
- 网络规则管理:维护iptables/ipvs规则进行流量转发
与Service的关系:
Service定义网络抽象:
1 | apiVersion: v1 |
kube-proxy实现具体转发:
- 监听Service和Endpoints变化
- 创建本地网络规则(iptables/ipvs)
- 将到达Service IP:Port的流量转发到Pod IP:targetPort
流量路径:
1 | 客户端 → Service ClusterIP:Port → kube-proxy规则 → 选择Pod → Pod IP:targetPort |
kube-proxy 是Service网络功能的实际执行者,确保了服务的可靠访问。
8.4.3 容器运行时(Container Runtime)
作用:真正拉取镜像、创建/运行容器。
在 Goat 环境中的体现:
1 | # 进入 Kind 节点容器检查容器运行时 |

1 | # 4. 查看容器镜像 |

为什么选择控制平面节点?
- 运行 API Server、etcd、scheduler 等核心组件
- 容器数量更多,代表性更强
- 可以同时观察系统组件和业务容器的运行时状态
命令详解:
crictl ps:
- 显示当前正在运行的容器(包括pause容器和业务容器)
- 显示容器ID、镜像、状态、创建时间、Pod归属等
crictl images:
- 显示节点本地缓存的所有容器镜像
- 显示镜像仓库、标签、ID、大小等信息
crictl inspect <container-id>:
- 显示容器的完整配置和运行时信息
- 包含环境变量、挂载卷、网络配置、资源限制等
**当前状态:**使用 containerd 作为容器运行时,支持 CRI 接口
8.5 附加组件(Add-ons)
常以 Pod 形式部署在集群内,提供扩展能力。
8.5.1 DNS 服务
作用:为 Service/Pod 提供集群内 DNS 解析。
在 Goat 环境中的体现:
1 | # 查看 DNS 服务 |
**当前状态:**CoreDNS 正常运行,提供集群内 DNS 服务
8.5.2 网络插件
作用:实现 Pod 间通信和网络策略。
在 Goat 环境中的体现:
1 | # 查看网络插件(实际使用的是 kindnet) |

当前网络通信详解:
使用的网络插件:kindnet
- kindnet:Kind 集群默认的简单网络插件
- 运行位置:每个节点都有一个 kindnet Pod
- 功能:提供基本的 Pod 间通信能力
- 特点:轻量级,适合开发测试环境
网络架构:
- Pod 网络段:10.244.1.0/24(工作节点)
- Pod 网络段:10.244.0.0/24(控制平面)
- Service 网络:10.96.0.0/12
- 通信方式:通过 CNI (Container Network Interface) 实现
8.5.3 存储插件
作用:提供持久化存储能力。
在 Goat 环境中的体现:
1 | # 查看存储插件 |

**当前状态:**配置了 local-path-provisioner 但未实际使用。
存储配置详情:
- 供应器Pod:
local-path-provisioner-67b8995b4b-24xtc(运行中) - StorageClass:
standard (default)使用rancher.io/local-path供应器 - 回收策略:Delete(PVC删除时自动清理PV)
- 绑定模式:WaitForFirstConsumer(延迟绑定,等待Pod使用时再分配)
- 卷扩展:false(不支持运行时扩容)
- 实际使用:0个PV,0个PVC(Goat环境的所有应用都是无状态的,无需持久存储)
8.6 环境安全分析
8.6.1 RBAC 权限检查
查看角色定义
1 | # 查看角色定义 |

Goat环境的RBAC角色配置:
Role(命名空间级别角色):
- big-monolith/secret-reader:允许读取big-monolith命名空间的Secret
- kube-public/kubeadm:bootstrap-signer-clusterinfo:kubeadm引导签名角色
- local-path-storage/local-path-provisioner-role:本地存储供应器角色
ClusterRole(集群级别角色):
- admin:管理员角色,具有命名空间内大部分资源的管理权限
- cluster-admin:集群管理员,拥有集群级别的完全权限
- edit:编辑者角色,可以修改大部分资源但不能管理角色
- view:查看者角色,只读权限
- kindnet:网络插件kindnet的角色
- kubeadm:get-nodes:kubeadm获取节点信息的角色
- local-path-provisioner-role:本地存储供应器的集群角色
RBAC配置分析:
- Goat环境配置了基本的RBAC角色,但主要是为系统组件和存储供应器服务
- 没有看到专门为Goat业务应用配置的自定义角色
- 安全检查时需要验证是否有过度权限的角色绑定
查看角色绑定
1 | # 查看角色绑定 |

查看服务账户
1 | # 查看服务账户 |

Goat环境的角色绑定配置:
RoleBinding(命名空间级别绑定):
-
big-monolith/secret-reader-binding → Role/secret-reader
- 绑定对象:big-monolith命名空间
- 权限范围:读取该命名空间的Secret
-
kube-public/kubeadm:bootstrap-signer-clusterinfo → Role/kubeadm:bootstrap-signer-clusterinfo
- 绑定对象:kube-public命名空间
- 权限范围:kubeadm引导签名权限
-
local-path-storage/local-path-provisioner-bind → Role/local-path-provisioner-role
- 绑定对象:local-path-storage命名空间
- 权限范围:本地存储供应权限
ClusterRoleBinding(集群级别绑定):
-
cluster-admin → ClusterRole/cluster-admin (多个绑定)
- 绑定对象:集群管理员权限
- 权限范围:集群完全控制权限
-
kindnet → ClusterRole/kindnet
- 绑定对象:网络插件kindnet
- 权限范围:网络配置和管理权限
-
kubeadm:get-nodes → ClusterRole/kubeadm:get-nodes
- 绑定对象:kubeadm工具
- 权限范围:获取节点信息权限
-
local-path-provisioner-bind → ClusterRole/local-path-provisioner-role
- 绑定对象:本地存储供应器
- 权限范围:集群级存储供应权限
安全分析:
- Goat环境主要为系统组件和服务配置了必要的权限
- cluster-admin权限被多个对象绑定,可能存在权限过大的风险
- 业务应用(如big-monolith)的权限相对受限,符合安全原则
Goat环境的服务账户配置:
服务账户分类:
系统服务账户 (kube-system):
- 控制器相关:deployment-controller, replicaset-controller, job-controller等(41个)
- 网络相关:kindnet, kube-proxy
- 存储相关:persistent-volume-binder, pvc-protection-controller
- 安全相关:service-account-controller, token-cleaner
- DNS相关:coredns
业务应用服务账户:
- big-monolith/big-monolith-sa:big-monolith命名空间的专用服务账户
- big-monolith/default:big-monolith命名空间的默认服务账户
- secure-middleware/default:secure-middleware命名空间的默认服务账户
默认服务账户:
- 每个命名空间都有一个default服务账户,供未指定serviceAccount的Pod使用
服务账户作用:
- 身份认证:Pod使用服务账户身份访问Kubernetes API
- 权限控制:通过RBAC绑定角色获得特定权限
- Secret管理:自动关联API访问令牌和CA证书
- 安全隔离:不同应用使用不同服务账户实现权限隔离
安全检查要点:
- 检查default服务账户是否绑定了过多权限
- 验证专用服务账户是否遵循最小权限原则
- 监控服务账户令牌的使用情况
8.6.2 安全上下文审计
查找特权容器
1 | # 查找特权容器 |

命令解析:
- 数据提取:使用JSONPath从Pod spec中提取privileged字段
- 格式化输出:Pod名称 → 命名空间 → 特权状态
- 条件筛选:只显示privileged=true或null的容器
安全分析:
- 系统组件特权(合理):kube-proxy需要配置iptables规则,必需的网络权限
- 业务应用特权(潜在风险):health-check和system-monitor作为Goat靶场应用,可能故意设置为特权以演示安全漏洞
- 安全影响:特权容器可以访问宿主机文件系统、内核功能,可能导致容器逃逸
查找主机路径挂载
1 | kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.namespace}{"\t"}{.spec.volumes[*].hostPath.path}{"\n"}{end}' | grep -v "^\s*$" |

主机路径挂载检查结果:
发现以下Pod使用了hostPath卷挂载(存在安全风险):
高风险挂载:
-
system-monitor-deployment (default): 挂载整个根目录
/- 安全风险:可以访问所有宿主机文件,潜在的容器逃逸风险
- 可能用途:作为Goat靶场故意设置的安全漏洞演示
-
health-check-deployment (default): 挂载containerd socket
/run/containerd/containerd.sock- 安全风险:可以通过containerd API控制容器运行时
- 可能用途:健康检查功能需要访问容器运行时状态
系统组件挂载(合理):
- etcd:
/etc/kubernetes/pki/etcd /var/lib/etcd- 证书和数据存储 - kube-apiserver: 多个证书和配置路径 - API服务所需
- kube-proxy:
/run/xtables.lock /lib/modules- 网络规则配置 - kindnet: CNI配置和内核模块 - 网络插件所需
安全分析:
- hostPath卷允许Pod访问宿主机文件系统
- 过度挂载可能导致容器逃逸或数据泄露
- 应遵循最小权限原则,只挂载必需的路径
查找未设置资源限制的容器
1 | # 查找未设置资源限制的容器 |

未设置资源限制的容器分析
从输出可以看到以下容器未设置资源限制(resources字段为空 {}):
发现的未设置资源限制容器:
hunger-check-deployment-5488f8b86c-6tkmh(big-monolith命名空间)batch-check-job-5hbfj(default命名空间)hidden-in-layers-rh6pp(default命名空间)kube-proxy-*(kube-system命名空间)local-path-provisioner-*(local-path-storage命名空间)cache-store-deployment-*(secure-middleware命名空间)
安全风险分析:
- 资源耗尽攻击:恶意容器可能消耗大量CPU/内存,导致节点资源耗尽
- DoS攻击:单个容器可能影响整个节点的稳定性
- 服务质量下降:其他正常Pod因资源竞争而性能下降
- 成本控制缺失:无法限制资源使用,可能导致云资源费用超支
推荐防护措施:
- 为所有容器设置
resources.limits和resources.requests - 使用ResourceQuota限制命名空间总资源使用
- 实施LimitRange设置默认资源限制
- 监控资源使用情况,及时发现异常消耗
8.6.3 网络安全检查
查看网络策略
1 | # 查看网络策略 |

原因解释:
No resources found表示集群中没有配置任何网络策略(Network Policies)- 这是Kubernetes的默认行为:默认允许所有Pod间通信
安全风险:
- 横向移动攻击:攻击者可以从受感染的Pod访问其他所有服务
- 数据泄露:Pod之间没有任何网络边界限制
- 服务枚举:攻击者可以轻松发现和访问内部服务
配置建议:
- 为敏感应用配置网络策略,只允许必要的通信
- 使用
default deny策略作为安全基线 - 考虑结合服务网格实现更细粒度的流量控制
这个检查结果实际上暴露了一个重要的安全问题:在没有网络策略的情况下,整个集群的Pod网络是完全开放的,这为攻击者提供了极大的活动空间。
分析服务暴露情况
1 | kubectl get svc -A | grep -E "(NodePort|LoadBalancer)" |

从输出可见,当前集群发现了一个通过 NodePort 类型暴露的服务:
internal-proxy-info-app-service(default命名空间)- Service 类型为
NodePort - 集群内服务端口为
5000 - 对外暴露的节点端口为
30003
这说明该服务不仅可以被集群内部访问,还可以通过任意工作节点的 IP 加上端口 30003 进行访问(前提是节点网络和防火墙规则允许该端口连通)。例如,外部用户可能通过 http://<节点IP>:30003 访问到该服务。
安全含义:
NodePort会把服务暴露到每个节点的指定端口上,扩大服务可达范围- 如果该服务本应仅供集群内部调用,那么这种暴露方式会增加被扫描、探测和攻击的可能性
- 一旦服务本身存在认证缺陷、信息泄露或命令执行类漏洞,攻击者就可能直接从节点入口发起利用
风险分析:
- 攻击面扩大:服务从“仅集群内部可见”变成“可能被外部网络直接访问”
- 敏感接口暴露:如果这是内部代理、信息查询或管理类服务,暴露后更容易泄露内部结构和业务信息
- 横向渗透入口:攻击者可将该服务作为进入集群业务面的初始落点
检查 Pod间网络隔离
1 | # 检查 Pod 间网络隔离 |
8.6.4 配置安全审计
检查Secret内容
1 | # 检查 Secret 内容 |

从输出可以看到,当前集群中发现了以下 Secret:
vaultapikey(big-monolith命名空间),类型为Opaquewebhookapikey(big-monolith命名空间),类型为Opaquegoatvault(default命名空间),类型为Opaquesh.helm.release.v1.metadata-db.v1(default命名空间),类型为helm.sh/release.v1
这说明集群里既存在业务相关的敏感数据,也存在 Helm 发布过程自动生成的元数据。
类型说明:
Opaque是最常见的通用类型Secret,通常用于保存 API Key、密码、Token、证书片段等自定义敏感信息helm.sh/release.v1是 Helm 在安装或升级 Chart 时自动创建的发布记录,里面主要保存 Helm Release 的元数据,不一定直接是业务凭据,但同样不应被随意暴露
结合名称进行分析:
vaultapikey和webhookapikey这类名称明显带有apikey,说明其中很可能保存的是访问外部系统或内部服务所需的认证凭据goatvault名称表明它也可能保存了某类机密配置或凭据- 这些对象虽然叫做
Secret,但 Kubernetes 默认只是以 Base64 编码存储,并不是强加密;如果拥有足够权限,仍然可以被读取和解码
安全含义:
- 一旦攻击者获得读取
Secret的 RBAC 权限,就可能直接获取 API Key、Token 或密码 - 如果应用把这些
Secret挂载进环境变量或文件系统,容器被入侵后也可能进一步导致凭据泄露 - 命名清晰的
Secret往往会帮助攻击者快速定位高价值目标
审计建议:
- 继续检查这些
Secret是否被业务 Pod 使用,以及以什么方式挂载 - 审查哪些 ServiceAccount、用户或角色具备读取
Secret的权限 - 对高敏感
Secret启用更严格的访问控制,并考虑结合外部密钥管理系统 - 避免在日志、镜像、ConfigMap 或环境变量中重复暴露同一份敏感信息
分析 ConfigMap内容
1 | # 分析 ConfigMap 内容 |

从输出可以看到,当前集群中的 ConfigMap 主要以 Kubernetes 系统组件自动生成的配置为主,暂时没有看到明显的业务自定义配置项大量暴露出来。
主要发现如下:
- 多个命名空间中都存在
kube-root-ca.crt,如big-monolith、default、kube-system、local-path-storage、secure-middleware等 kube-public命名空间中存在cluster-infokube-system命名空间中存在coredns、extension-apiserver-authentication、kube-proxy、kubeadm-config、kubelet-config等系统级配置local-path-storage命名空间中存在local-path-config
内容说明:
kube-root-ca.crt通常用于向 Pod 提供集群 CA 证书,属于正常的系统配置cluster-info一般保存集群访问信息,常用于集群初始化或公开发现coredns、kube-proxy、kubeadm-config、kubelet-config等都属于 Kubernetes 控制面或基础设施组件依赖的配置local-path-config则与本地存储供应器的工作方式有关,也属于基础设施配置
安全审计意义:
- 这类
ConfigMap大多不是直接的凭据存储位置,但它们可能泄露集群架构、网络配置、DNS 规则、代理行为或节点参数 - 攻击者在获得读取权限后,可以利用这些配置信息更快理解集群内部结构,辅助后续横向移动或权限提升
- 尤其像
kubeadm-config、kubelet-config、coredns这类对象,往往可以帮助攻击者了解控制面部署方式、DNS 解析策略和节点运行参数
需要注意的一点:
ConfigMap适合保存普通配置,不适合存放密码、Token、API Key 等敏感数据- 如果在审计中发现业务把密钥、口令或证书私钥放进
ConfigMap,应视为高风险问题,应该迁移到Secret或外部密钥管理系统
检查环境变量中的敏感信息
1 | # 检查环境变量中的敏感信息 |

从输出可以看到,当前命中了一个疑似敏感环境变量:
- Pod:
system-monitor-deployment-866f697c75-2wzd4 - 命名空间:
default - 环境变量名:
K8S_GOAT_VAULT_KEY
这个变量名中包含 KEY,并且带有 VAULT 字样,说明它很可能用于保存访问某个密钥库、保险库服务或内部敏感资源所需的认证信息。即使这里只看到了变量名,没有直接看到变量值,也已经足以说明该 Pod 中存在高价值凭据或敏感配置入口。
安全含义:
- 把密钥类信息放入环境变量是常见做法,但如果容器被入侵,攻击者往往可以直接读取进程环境变量
- 某些调试命令、错误日志、崩溃转储或应用配置输出,也可能意外泄露环境变量内容
- 如果该变量实际对应的是 API Key、访问令牌或解密密钥,那么泄露后可能进一步导致数据访问、横向移动或权限提升
为什么要重点关注:
- 环境变量名本身已经暴露了用途,攻击者可以据此快速定位关键配置
- 与挂载文件相比,环境变量更容易在运行时被应用、脚本或诊断工具直接读取
- 如果该变量来源于
Secret,还需要继续确认其挂载方式是否合理;如果它是明文直接写在 Pod 配置中,则风险更高
8.7 授权安全评估常用审计命令
这一节主要面向 Kubernetes 安全学习和授权测试场景,重点不是“如何利用”,而是当某个工作负载已经失陷时,如何从防守和评估角度快速判断风险会不会进一步扩大到命名空间、节点甚至整个集群。
建议按以下几个方向进行检查:
- 当前
Pod或命名空间具备什么身份和权限 - 是否暴露了
Secret、环境变量、挂载文件等敏感信息 - 是否存在
privileged、hostPath、容器运行时socket等高危配置 - 网络策略、服务暴露、RBAC 是否会导致横向风险扩大
1 | # 1. 环境快速概览:查看所有工作负载和服务分布 |
风险判断思路:
- 如果业务
Pod暴露了Secret、敏感环境变量或ServiceAccount Token,说明已经具备进一步信息收集的基础 - 如果该身份对应的
RBAC权限过大,例如可以读取secrets、创建pods、修改deployments,风险就可能从单个Pod扩大到整个命名空间 - 如果同时存在
privileged、hostPath、hostNetwork、运行时socket挂载等问题,则需要重点关注是否会扩大到节点层面 - 如果集群中没有
NetworkPolicy,并且存在不必要的NodePort/LoadBalancer,那么东西向和南北向的攻击面都会明显增加
审计建议:
- 先识别“身份材料”与“权限边界”,再看运行时配置和网络暴露
- 重点关注系统命名空间、基础设施组件、监控组件和中间件命名空间
- 把发现的问题按“凭据暴露、权限过大、运行时高危配置、网络暴露”四类进行整理,便于后续复盘和加固