Kubernetes 核心功能学习文档
涵盖:服务注册、服务发现、负载均衡、配置管理、存储管理、健康检查、自动扩缩容、RBAC、多命名空间隔离 每节包含:原理讲解、使用方式(含 YAML 示例)、典型场景/案例
0. 全局背景:为什么需要这些机制
Kubernetes(简称 k8s)是一个容器编排平台,核心目标是把一堆"随时可能死掉、随时可能漂移到别的机器上"的容器(Pod),管理成一个稳定、可自愈、可伸缩的分布式系统。
它要解决的根本问题是:Pod 是临时的、IP 会变、数量会变,但访问它的人不希望关心这些细节。下面的每一个功能,几乎都是围绕这个核心矛盾展开的。
1. 服务注册(Service Registration)
原理
在 k8s 里,"服务注册"不是一个独立动作,而是自动完成的:
- 每个 Pod 启动后,kubelet 会向 API Server 上报自己的状态(IP、所在节点、是否 Ready)。
- API Server 把这些信息写入 etcd(k8s 的分布式键值存储,相当于整个集群的"数据库")。
- 当你创建一个
Service资源,并用selector(标签选择器)指定它要代理哪些 Pod 时,控制平面里的 Endpoint Controller 会持续监听(watch)匹配该 selector 的 Pod,把它们的 IP:Port 写入一个叫Endpoints(或新版的EndpointSlice)的对象里。
也就是说:Pod 通过打标签"自动注册"到 Service 上,不需要像传统微服务架构(如 Eureka、Consul)那样,应用代码里手写"启动时向注册中心汇报"的逻辑。
怎么用
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
replicas: 3
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service # 关键:Pod 的标签
spec:
containers:
- name: order-service
image: myrepo/order-service:v1.2
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: order-service
spec:
selector:
app: order-service # Service 用同样的标签去"认领" Pod
ports:
- port: 80
targetPort: 8080
一旦这两个资源创建,Service 就会自动"注册"到当前所有匹配的 3 个 Pod,且后续 Pod 扩容/缩容/重启都会自动更新。
使用场景
- 案例:电商订单服务滚动升级。运维发布新版本时,新 Pod 起来、旧 Pod 被删,Endpoint 列表实时更新,前端调用方完全无感知,不需要手动去注册中心摘除/添加节点。
2. 服务发现(Service Discovery)
原理
"服务注册"解决了"谁在提供服务","服务发现"解决的是"调用方怎么找到它"。k8s 提供两种主流方式:
- DNS 方式(最常用):集群内置 CoreDNS,每个 Service 创建后会自动获得一个域名:
<service-name>.<namespace>.svc.cluster.localPod 内部的 DNS 解析会被自动配置指向 CoreDNS,调用方直接用服务名即可访问。 - 环境变量方式:Pod 启动时,kubelet 会把同 namespace 下已存在的 Service 信息注入为环境变量(如
ORDER_SERVICE_SERVICE_HOST),但这种方式有先后顺序限制(Service 必须先于 Pod 创建),生产环境很少用,了解即可。
怎么用
# 在同一 namespace 内的 Pod 中,直接用服务名访问
curl http://order-service/api/orders
# 跨 namespace 访问,需要带上 namespace
curl http://order-service.production.svc.cluster.local/api/orders
使用场景
- 案例:微服务之间调用。
user-service要调用order-service,代码里只需写死一个域名http://order-service,无论order-service扩容到 10 个副本还是缩到 1 个,调用方代码永远不用改。这比传统架构里维护一份"服务地址配置表"要简单得多。
3. 负载均衡(Load Balancing)
原理
k8s 的负载均衡分两个层次:
(1) 集群内负载均衡(Service 层面)
- 每个节点上运行 kube-proxy,它监听 API Server 中 Service/Endpoint 的变化,并在本机配置转发规则(早期用 iptables,规则较多时性能下降;新版本可用 IPVS 模式,基于哈希表,性能更好,支持更多负载均衡算法如轮询、最少连接等)。
- 客户端请求 Service 的虚拟 IP(ClusterIP)时,请求包在节点内核层面就被转发到某个真实 Pod,整个过程对客户端透明。
(2) 集群外负载均衡(Ingress / LoadBalancer 层面)
- Service 类型为 LoadBalancer 时,会向云厂商(如 AWS ELB、阿里云 SLB)申请一个外部负载均衡器。
- Ingress 资源则工作在七层(HTTP/HTTPS),通过 Ingress Controller(如 Nginx Ingress、Traefik)实现基于域名、路径的路由和负载均衡,功能比 Service 的四层转发更丰富(比如可以做灰度发布、路径重写)。
怎么用
# 四层负载均衡:ClusterIP(默认)
apiVersion: v1
kind: Service
metadata:
name: order-service
spec:
type: ClusterIP # 默认类型,集群内负载均衡
selector:
app: order-service
ports:
- port: 80
targetPort: 8080
---
# 七层负载均衡:Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: shop-ingress
spec:
rules:
- host: shop.example.com
http:
paths:
- path: /orders
pathType: Prefix
backend:
service:
name: order-service
port:
number: 80
- path: /users
pathType: Prefix
backend:
service:
name: user-service
port:
number: 80
使用场景
- 案例:大促流量分发。双十一大促期间,
order-service扩容到 50 个 Pod,通过 Ingress 统一入口按路径/orders分流到这些 Pod,同时 kube-proxy 保证请求均匀落到每个副本,避免单点过载。
4. 配置管理(Configuration Management)
原理
k8s 提倡"配置与镜像分离":同一个镜像,通过注入不同配置,就能跑在开发/测试/生产环境。核心对象有两个:
- ConfigMap:存储非敏感配置(如日志级别、feature flag、URL 地址等),本质是键值对集合。
- Secret:存储敏感信息(密码、Token、证书),内容以 Base64 编码存储在 etcd 中(注意:Base64 只是编码不是加密,生产环境建议开启 etcd 静态加密或使用外部密钥管理如 Vault)。
两者都可以通过环境变量或挂载为文件的方式注入 Pod。挂载为文件的好处是:修改 ConfigMap 后,文件内容会自动热更新(有一定延迟),而环境变量方式修改后必须重启 Pod 才能生效。
怎么用
apiVersion: v1
kind: ConfigMap
metadata:
name: order-config
data:
LOG_LEVEL: "info"
MAX_RETRY: "3"
---
apiVersion: v1
kind: Secret
metadata:
name: order-db-secret
type: Opaque
data:
DB_PASSWORD: cGFzc3dvcmQxMjM= # base64 编码后的值
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
template:
spec:
containers:
- name: order-service
image: myrepo/order-service:v1.2
envFrom:
- configMapRef:
name: order-config
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: order-db-secret
key: DB_PASSWORD
使用场景
- 案例:多环境部署。同一份
order-service镜像,在测试环境挂载order-config-test(连测试数据库),在生产环境挂载order-config-prod(连生产数据库),无需重新打镜像。
5. 存储管理(Storage Management)
原理
容器本身是无状态、易失的,重启后本地文件系统数据会丢失。k8s 用三层抽象解决持久化存储问题:
- PV(PersistentVolume):由集群管理员(或存储插件自动)创建的一块"实际存储资源",可以是云盘、NFS、Ceph 等。
- PVC(PersistentVolumeClaim):应用方"申请"存储的方式,类似"我需要 10GB、ReadWriteOnce 的存储",k8s 会自动找一个匹配的 PV 绑定(Bind)。
- StorageClass:定义"动态供应"规则,PVC 提交后,如果没有现成 PV 匹配,StorageClass 会调用对应的存储插件(CSI,Container Storage Interface)自动创建一块新的 PV,免去管理员手动创建的麻烦。
这种"申请-绑定"模式让应用和底层存储解耦:开发者只管写 PVC,不用关心底层是阿里云盘还是 AWS EBS。
怎么用
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard # 指定动态供应的 StorageClass
resources:
requests:
storage: 20Gi
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
volumeMounts:
- name: data
mountPath: /var/lib/mysql
volumes:
- name: data
persistentVolumeClaim:
claimName: mysql-pvc
使用场景
- 案例:数据库有状态服务迁移。用
StatefulSet+ PVC 部署 MySQL,即使 Pod 被重新调度到另一台物理机,只要底层是网络存储(如云盘),数据依然完整挂载回新 Pod,不丢数据。
6. 健康检查(Health Check)
原理
k8s 通过三种探针(Probe)持续检测容器的健康状态,由 kubelet 定期执行:
- Liveness Probe(存活探针):判断容器是否"活着"。失败达到阈值 → kubelet 重启该容器。用于解决"进程没崩但已经死锁/卡死"的问题。
- Readiness Probe(就绪探针):判断容器是否"准备好接收流量"。失败 → 该 Pod 被从 Service 的 Endpoint 列表中摘除,但不会被重启。常用于启动慢、需要预热的服务。
- Startup Probe(启动探针):用于启动特别慢的应用,在它成功前,Liveness/Readiness 探针都不会生效,避免"还没启动完就被当成死了重启"的死循环。
三种探针的检测方式都支持:httpGet(发 HTTP 请求看状态码)、tcpSocket(探测端口)、exec(执行命令看返回值)。
怎么用
apiVersion: v1
kind: Pod
metadata:
name: order-service
spec:
containers:
- name: order-service
image: myrepo/order-service:v1.2
ports:
- containerPort: 8080
startupProbe:
httpGet:
path: /healthz
port: 8080
failureThreshold: 30
periodSeconds: 2
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
periodSeconds: 5
使用场景
- 案例:Java 应用启动慢导致的误杀。Spring Boot 应用启动加载需要 60 秒,若只配 Liveness 探针且
initialDelaySeconds设太短,容器会在没启动完时被反复重启,形成死循环;加上startupProbe后,给足启动时间,问题解决。 - 案例:数据库连接池未就绪。应用进程已经启动(Liveness 通过),但数据库连接还没建立好,此时靠 Readiness 探针让 Service 暂时不转发流量过去,避免用户请求报错。
7. 自动扩缩容(Autoscaling)
原理
k8s 提供三个层面的自动扩缩容,通常配合使用:
- HPA(Horizontal Pod Autoscaler,水平扩缩容):根据 CPU/内存使用率或自定义指标(如 QPS、消息队列长度),自动增减 Pod 副本数。原理是 HPA Controller 每隔一段时间(默认 15 秒)向 Metrics Server(或 Prometheus Adapter)查询指标,与目标值比较后调整
Deployment的replicas字段。 - VPA(Vertical Pod Autoscaler,垂直扩缩容):自动调整单个 Pod 的 CPU/内存 request/limit,而不是增加副本数,适合资源需求波动大但不适合水平扩展的应用(一般需要重启 Pod 生效)。
- Cluster Autoscaler(集群扩缩容):当 Pod 因为节点资源不足而 Pending 时,自动向云厂商申请新的节点;反之节点长期空闲会被自动缩减,节省成本。
三者关系:HPA/VPA 解决"Pod 层面"资源不够用的问题,Cluster Autoscaler 解决"节点层面"资源不够用的问题——当 HPA 扩出很多 Pod 但节点装不下时,就会触发 Cluster Autoscaler 加节点。
怎么用
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: order-service-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: order-service
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # CPU 平均利用率超过 70% 就扩容
使用场景
- 案例:秒杀活动流量突增。平时
order-service保持 3 个副本,秒杀开始前 CPU 使用率飙升,HPA 在几分钟内自动扩容到 20 个副本;活动结束流量回落后再自动缩回 3 个,全程无需人工干预,也不必长期占用 20 个副本的资源(省钱)。
8. RBAC(基于角色的访问控制)
原理
RBAC 控制"谁(Subject)能对哪些资源(Resource)做什么操作(Verb)",四个核心对象:
- Role:定义一组权限规则,作用域限定在某个 namespace 内(比如"能读写 default 命名空间下的 Pod")。
- ClusterRole:和 Role 类似,但作用域是整个集群(可以跨 namespace,也可以用于非命名空间资源如 Node)。
- RoleBinding:把 Role(或 ClusterRole)绑定给某个用户/组/ServiceAccount,且绑定关系只在某个 namespace 内生效。
- ClusterRoleBinding:把 ClusterRole 绑定给用户,且全集群生效。
简单记忆:Role/ClusterRole 定义"能做什么",RoleBinding/ClusterRoleBinding 定义"谁能做,在哪个范围内做"。
怎么用
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"] # 只能查看 Pod,不能删除/修改
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods-binding
namespace: production
subjects:
- kind: User
name: alice # 也可以是 ServiceAccount
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
使用场景
- 案例:CI/CD 流水线权限最小化。给 Jenkins 的 ServiceAccount 只授予"在 staging 命名空间创建/更新 Deployment"的权限,而无权访问 production 命名空间或删除集群级资源,防止误操作或流水线被攻破后造成大范围破坏(最小权限原则)。
- 案例:只读监控账号。给运维新人一个只能
get/list所有资源但不能create/delete的 ClusterRole,方便他排查问题又不用担心手滑删除生产资源。
9. 多命名空间隔离(Namespace Isolation)
原理
Namespace 是 k8s 里的逻辑隔离单元,本质上是给资源加了一个"分组前缀"。它提供的隔离体现在几个层面:
- 资源命名隔离:不同 namespace 下可以有同名资源(比如
dev和prod都能有一个叫order-service的 Deployment)。 - 资源配额隔离(ResourceQuota):可以限制某个 namespace 总共能用多少 CPU/内存/Pod 数,防止一个团队把整个集群资源耗尽。
- 网络隔离(NetworkPolicy):默认情况下所有 Pod 可以互相访问,通过 NetworkPolicy 可以限制"只有同 namespace 或指定标签的 Pod 才能访问我"。
- 权限隔离(配合 RBAC):如上一节所说,Role/RoleBinding 天然是 namespace 级别的,可以做到"A 团队看不到 B 团队的资源"。
需要注意:Namespace 不是强安全边界(比如节点、内核层面并不隔离),它更多是一种管理和逻辑上的隔离,真正的强隔离通常还需要多集群方案。
怎么用
apiVersion: v1
kind: Namespace
metadata:
name: team-a
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-a-quota
namespace: team-a
spec:
hard:
requests.cpu: "10"
requests.memory: 20Gi
pods: "50"
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-from-other-namespaces
namespace: team-a
spec:
podSelector: {}
ingress:
- from:
- podSelector: {} # 只允许来自同 namespace 内 Pod 的流量
使用场景
- 案例:多团队共享集群。公司有
team-a、team-b两个业务团队共用一个 k8s 集群,通过 Namespace + ResourceQuota 划分资源边界(team-a 最多用 10 核 CPU),再通过 RBAC 限制彼此看不到对方的资源,实现"逻辑上的多租户",比给每个团队单独建一套集群成本低得多。
10. 综合案例:把这些功能串起来
以一个"电商订单服务"从开发到生产的完整链路为例:
- 配置管理:开发用 ConfigMap 挂载测试环境配置,生产切换成
order-config-prod。 - 服务注册/发现:Deployment 创建 Pod,Service 自动注册并生成 DNS 名
order-service,其他服务通过域名调用它。 - 健康检查:配置 Liveness + Readiness 探针,保证只有真正就绪的 Pod 才接收流量。
- 存储管理:订单数据落到通过 PVC 挂载的云数据库存储卷(如果自建 MySQL)。
- 负载均衡:外部通过 Ingress 按路径把
/orders流量转发到order-service,kube-proxy 负责集群内部的均衡分发。 - 自动扩缩容:大促期间 HPA 根据 CPU 自动把 Pod 从 3 扩到 20,Cluster Autoscaler 在节点不够时自动加机器。
- RBAC:CI/CD 系统的 ServiceAccount 只被授权在
production命名空间做部署,不能碰其他命名空间。 - 多命名空间隔离:
order-service部署在production命名空间,和team-b的服务(在team-b命名空间)互不干扰,各自有资源配额限制。
这九个功能不是孤立的,而是共同构成了 k8s "自愈、弹性、多租户、安全"的核心能力。
11. 学习建议
- 先动手用
minikube或kind搭一个单节点集群,把本文所有 YAML 依次跑一遍,比单纯看文档理解快得多。 - 用
kubectl explain <资源名>命令可以直接在命令行看到官方字段说明,比如kubectl explain deployment.spec。 - 遇到问题优先看
kubectl describe pod <name>的 Events 部分,90% 的排障线索都在这里。 - 推荐官方文档作为权威参考:https://kubernetes.io/zh-cn/docs/home/