K8S 的核心概念
K8S 的核心概念
简介
Kubernetes(简称 K8s)是 Google 开源的容器编排和管理平台,用于自动化部署、扩展和管理容器化应用程序。它构建在 Docker 等容器技术之上,提供了一整套完整的基础设施抽象,包括服务发现、负载均衡、存储编排、自动部署、滚动更新、自我修复等能力。
K8s 的核心设计理念是声明式配置(Declarative Configuration)和 reconciliation loop(协调循环)。用户通过 YAML 或 JSON 文件描述期望的集群状态,K8s 的各种 Controller 会持续监控实际状态并与期望状态进行对比,自动执行必要的操作来使两者保持一致。
特点
优点
缺点
一、Cluster(集群)
Cluster 是计算、存储和网络资源的集合,Kubernetes 利用这些资源运行各种基于容器的应用。一个 Cluster 由一个或多个 Master 节点和多个 Node 节点组成。
| 组件 | 说明 |
|---|---|
| Master | 集群控制面,负责调度和管理整个集群 |
| Node | 工作节点,负责运行容器应用 |
| etcd | 分布式键值存储,保存集群所有状态数据 |
| Pod | 最小工作单元,包含一个或多个容器 |
二、Master(主节点)
Master 是 Cluster 的大脑,它的主要职责是调度,即决定将应用放在哪里运行。Master 运行在 Linux 操作系统上,可以是物理机或者虚拟机。为了实现高可用,可以运行多个 Master。
Master 节点上运行的核心组件包括:
| 组件 | 说明 |
|---|---|
| API Server | 集群入口,提供 RESTful API |
| Scheduler | 负责 Pod 的调度和节点选择 |
| Controller Manager | 运行各种控制器,维护集群状态 |
| etcd | 分布式数据存储,保存集群配置 |
三、Node(工作节点)
Node 的职责是运行容器应用。Node 由 Master 管理,Node 负责监控并汇报容器的状态,并根据 Master 的要求管理容器的生命周期。Node 运行在 Linux 操作系统上,可以是物理机或者是虚拟机。
Node 节点上运行的核心组件:
| 组件 | 说明 |
|---|---|
| kubelet | 接收 Pod 创建请求,管理容器生命周期 |
| kube-proxy | 维护网络规则,实现 Service 的负载均衡 |
| Container Runtime | 容器运行时(如 Docker、containerd) |
四、Pod
Pod 是 Kubernetes 的最小工作单元。每个 Pod 包含一个或多个容器。Pod 中的容器会作为一个整体被 Master 调度到一个 Node 上运行。
Pod 核心特性
- Pod 中的所有容器共享同一个网络 namespace(相同 IP 和端口空间)
- Pod 中的容器可以直接通过 localhost 通信
- Pod 中的容器可以共享存储卷(Volume)
- Pod 有自己的生命周期:Pending -> Running -> Succeeded/Failed
- Pod 的 IP 地址是临时的,重启后可能变化
Pod 的两种使用方式
Pod 示例 YAML
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp
image: myregistry/myapp:1.0.0
ports:
- containerPort: 5000
env:
- name: ASPNETCORE_ENVIRONMENT
value: "Production"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 5000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health/ready
port: 5000
initialDelaySeconds: 5
periodSeconds: 5多容器 Pod 示例(Sidecar 模式)
apiVersion: v1
kind: Pod
metadata:
name: myapp-with-sidecar
spec:
containers:
- name: myapp
image: myregistry/myapp:1.0.0
ports:
- containerPort: 5000
volumeMounts:
- name: shared-data
mountPath: /app/data
- name: log-collector
image: myregistry/log-collector:1.0.0
volumeMounts:
- name: shared-data
mountPath: /collector/input
volumes:
- name: shared-data
emptyDir: {}五、ReplicaSet(副本集)
ReplicaSet 是新一代的 Replication Controller,保证在任何时候都有指定数量的 Pod 副本在运行。ReplicaSet 通过 Label Selector 来匹配和管理 Pod。
ReplicaSet 示例 YAML
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myapp-replicaset
labels:
app: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myregistry/myapp:1.0.0
ports:
- containerPort: 5000| 字段 | 说明 |
|---|---|
| replicas | 期望的 Pod 副本数量 |
| selector.matchLabels | 用于匹配 Pod 的标签选择器 |
| template | Pod 模板,定义创建 Pod 的规格 |
六、Deployment(部署)
Deployment 是最常用的 Controller,用于管理 Pod 的多个副本,并确保 Pod 按照期望的状态运行。Deployment 通过 ReplicaSet 来管理 Pod 的多个副本,支持滚动更新和回滚。
Deployment 示例 YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
app: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myregistry/myapp:1.0.0
ports:
- containerPort: 5000
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
env:
- name: ASPNETCORE_ENVIRONMENT
value: "Production"Deployment 常用操作
# 创建 Deployment
kubectl apply -f deployment.yaml
# 查看 Deployment
kubectl get deployments
# 查看 Deployment 详情
kubectl describe deployment myapp-deployment
# 查看滚动更新状态
kubectl rollout status deployment/myapp-deployment
# 查看滚动更新历史
kubectl rollout history deployment/myapp-deployment
# 回滚到上一版本
kubectl rollout undo deployment/myapp-deployment
# 回滚到指定版本
kubectl rollout undo deployment/myapp-deployment --to-revision=2
# 水平扩缩容
kubectl scale deployment myapp-deployment --replicas=5
# 更新镜像(触发滚动更新)
kubectl set image deployment/myapp-deployment myapp=myregistry/myapp:2.0.0
# 暂停滚动更新
kubectl rollout pause deployment/myapp-deployment
# 恢复滚动更新
kubectl rollout resume deployment/myapp-deployment更新策略说明
| 策略 | 说明 |
|---|---|
| RollingUpdate | 默认策略,逐步替换旧 Pod,支持 maxSurge 和 maxUnavailable 配置 |
| Recreate | 先删除所有旧 Pod,再创建新 Pod,会有短暂不可用 |
七、Service(服务)
Service 定义了外界访问一组特定 Pod 的方式。Service 有自己的 IP(ClusterIP)和端口,为 Pod 提供了稳定的访问入口和负载均衡。
Service 类型
| 类型 | 说明 | 适用场景 |
|---|---|---|
| ClusterIP | 默认类型,分配集群内部 IP | 集群内部服务间通信 |
| NodePort | 在每个 Node 上开放端口 | 从集群外部访问服务 |
| LoadBalancer | 使用云厂商的负载均衡器 | 云环境下的外部访问 |
| ExternalName | 映射到外部 DNS 名称 | 引用集群外部的服务 |
ClusterIP Service 示例
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
type: ClusterIP
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 5000NodePort Service 示例
apiVersion: v1
kind: Service
metadata:
name: myapp-nodeport
spec:
type: NodePort
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 5000
nodePort: 30080LoadBalancer Service 示例
apiVersion: v1
kind: Service
metadata:
name: myapp-loadbalancer
spec:
type: LoadBalancer
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 5000八、ConfigMap(配置管理)
ConfigMap 用于将非敏感的配置数据与容器镜像解耦,可以在不重新构建镜像的情况下修改配置。
ConfigMap 示例 YAML
apiVersion: v1
kind: ConfigMap
metadata:
name: myapp-config
data:
# 键值对形式
appsettings.json: |
{
"Logging": {
"LogLevel": {
"Default": "Information"
}
},
"ConnectionStrings": {
"DefaultConnection": "Server=myserver;Database=mydb;"
},
"AllowedHosts": "*"
}
# 简单键值对
ASPNETCORE_ENVIRONMENT: "Production"
LOG_LEVEL: "Information"在 Pod 中使用 ConfigMap
apiVersion: v1
kind: Pod
metadata:
name: myapp-with-config
spec:
containers:
- name: myapp
image: myregistry/myapp:1.0.0
# 方式1:作为环境变量
envFrom:
- configMapRef:
name: myapp-config
# 方式2:作为文件挂载
volumeMounts:
- name: config-volume
mountPath: /app/appsettings.json
subPath: appsettings.json
volumes:
- name: config-volume
configMap:
name: myapp-config九、Secret(密钥管理)
Secret 用于存储敏感信息,如密码、OAuth token、SSH 密钥等。Secret 的数据以 Base64 编码存储,使用时自动解码。
Secret 示例 YAML
apiVersion: v1
kind: Secret
metadata:
name: myapp-secret
type: Opaque
data:
# Base64 编码的值
db-password: UGFzc3dvcmQxMjM=
api-key: YWJjZGVmZ2hpamtsbW5vcA==
stringData:
# 明文字符串(创建时自动编码)
connection-string: "Server=myserver;Database=mydb;User=sa;Password=Password123;"在 Pod 中使用 Secret
apiVersion: v1
kind: Pod
metadata:
name: myapp-with-secret
spec:
containers:
- name: myapp
image: myregistry/myapp:1.0.0
# 作为环境变量引用
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: myapp-secret
key: db-password
- name: CONNECTION_STRING
valueFrom:
secretKeyRef:
name: myapp-secret
key: connection-string
# 或者作为文件挂载
volumeMounts:
- name: secret-volume
mountPath: /app/secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: myapp-secret十、Namespace(命名空间)
Namespace 用于将一个物理 Cluster 逻辑上划分成多个虚拟 Cluster。不同 Namespace 里的资源是相互隔离的。Kubernetes 默认创建了两个 Namespace。
| Namespace | 说明 |
|---|---|
| default | 创建资源时如果不指定 Namespace,将被放到这里 |
| kube-system | Kubernetes 自己创建的系统资源 |
| kube-public | 所有用户可读的资源(如集群信息) |
| kube-node-lease | 节点心跳检测相关的 Lease 对象 |
Namespace 常用操作
# 查看所有 Namespace
kubectl get namespaces
# 创建 Namespace
kubectl create namespace myproject
# 使用 YAML 创建apiVersion: v1
kind: Namespace
metadata:
name: myproject
labels:
name: myproject# 在指定 Namespace 中创建资源
kubectl apply -f deployment.yaml -n myproject
# 查看指定 Namespace 的资源
kubectl get pods -n myproject
# 切换默认 Namespace(使用 kubens 工具)
kubens myproject
# 删除 Namespace(会删除其中所有资源)
kubectl delete namespace myproject十一、Labels 和 Selectors(标签与选择器)
Labels 是附加到 K8s 对象(如 Pod、Service 等)上的键值对,用于标识和组织资源。Selectors 用于根据 Labels 筛选资源。
Labels 使用示例
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
tier: frontend
environment: production
version: v1.0.0
spec:
containers:
- name: myapp
image: myregistry/myapp:1.0.0Selectors 查询语法
# 等值匹配
kubectl get pods -l app=myapp
# 不等于匹配
kubectl get pods -l environment!=staging
# 集合匹配
kubectl get pods -l 'tier in (frontend,backend)'
# 不在集合中
kubectl get pods -l 'tier notin (frontend)'
# 存在性检查
kubectl get pods -l environment
# 不存在
kubectl get pods -l '!canary'
# 多标签组合
kubectl get pods -l 'app=myapp,tier=frontend,environment=production'Label 在 Service 中的使用
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
tier: frontend
ports:
- protocol: TCP
port: 80
targetPort: 5000十二、其他重要 Controller
DaemonSet
DaemonSet 确保每个(或指定)Node 上运行一个 Pod 副本,常用于日志收集、监控代理等。
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: log-collector
spec:
selector:
matchLabels:
app: log-collector
template:
metadata:
labels:
app: log-collector
spec:
containers:
- name: log-collector
image: myregistry/log-collector:1.0.0
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
hostPath:
path: /var/logStatefulSet
StatefulSet 用于管理有状态应用,保证 Pod 的启动/停止顺序和稳定的网络标识。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: mysql-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10GiJob 和 CronJob
Job 用于运行一次性任务,CronJob 用于定时任务。
# Job 示例
apiVersion: batch/v1
kind: Job
metadata:
name: data-migration
spec:
template:
spec:
containers:
- name: migration
image: myregistry/migration-tool:1.0.0
restartPolicy: Never
backoffLimit: 3# CronJob 示例
apiVersion: batch/v1
kind: CronJob
metadata:
name: daily-backup
spec:
schedule: "0 2 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: myregistry/backup-tool:1.0.0
restartPolicy: OnFailure十三、Controller 类型对比
| Controller | 适用场景 | Pod 标识 | 数据持久化 |
|---|---|---|---|
| Deployment | 无状态应用(Web API、前端) | 随机名称,可替换 | 通常不需要 |
| StatefulSet | 有状态应用(数据库、MQ) | 稳定的有序名称 | 需要 PVC |
| DaemonSet | 每个 Node 运行一个副本 | 每个 Node 一个 | 通常使用 HostPath |
| Job | 一次性任务 | 随机名称 | 可选 |
| CronJob | 定时任务 | 随机名称 | 可选 |
| ReplicaSet | 通常不直接使用 | 随机名称 | 通常不需要 |
十四、完整的 .NET 应用部署示例
以下是一个完整的 .NET Web API 应用的 K8s 部署配置,包含 Deployment、Service、ConfigMap 和 Secret。
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myapi-config
data:
ASPNETCORE_ENVIRONMENT: "Production"
appsettings.json: |
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
---
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: myapi-secret
type: Opaque
stringData:
ConnectionStrings__DefaultConnection: "Server=sqlserver-service;Database=MyDb;User=sa;Password=StrongPassword123!"
---
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapi-deployment
labels:
app: myapi
spec:
replicas: 3
selector:
matchLabels:
app: myapi
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: myapi
spec:
containers:
- name: myapi
image: myregistry/myapi:1.0.0
ports:
- containerPort: 5000
envFrom:
- configMapRef:
name: myapi-config
env:
- name: ConnectionStrings__DefaultConnection
valueFrom:
secretKeyRef:
name: myapi-secret
key: ConnectionStrings__DefaultConnection
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 5000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health/ready
port: 5000
initialDelaySeconds: 5
periodSeconds: 5
volumeMounts:
- name: config-volume
mountPath: /app/appsettings.json
subPath: appsettings.json
volumes:
- name: config-volume
configMap:
name: myapi-config
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: myapi-service
spec:
type: ClusterIP
selector:
app: myapi
ports:
- protocol: TCP
port: 80
targetPort: 5000总结
K8S 核心概念包括 Pod、Deployment、Service、ConfigMap、Secret 等。掌握这些概念后可以进行应用的容器化部署、弹性伸缩和配置管理。
关键知识点
- 部署类主题的核心不是“装成功”,而是“稳定运行、可排障、可回滚”。
- 同一个服务通常至少要关注版本、目录、端口、权限、数据、日志和备份。
- Linux 问题经常跨越系统层、网络层、服务层和应用层。
- Kubernetes 主题必须同时看资源对象、调度行为、网络暴露和配置分发。
项目落地视角
- 把安装步骤补成可重复执行的清单,必要时写成脚本或配置文件。
- 把配置目录、数据目录、日志目录和挂载点明确拆开。
- 上线前检查防火墙、SELinux、时区、磁盘、系统服务和健康检查。
- 上线前检查镜像、命名空间、探针、资源限制、Service/Ingress 和配置来源。
常见误区
- 使用 latest 或未固定版本,导致环境不可复现。
- 只验证启动成功,不验证持久化、开机自启和故障恢复。
- 遇到问题先改配置而不是先看日志和依赖链路。
- 只会 apply YAML,不理解对象之间的依赖关系。
进阶路线
- 继续补齐 systemd、性能监控、安全加固和备份恢复。
- 把单机操作升级成 Docker、Kubernetes 或 IaC 方案。
- 建立标准化运维手册,包括巡检、扩容、回滚和灾备演练。
- 继续补齐调度、网络策略、存储、GitOps 和平台工程能力。
适用场景
- 当你准备把《K8S 的核心概念》真正落到项目里时,最适合先在一个独立模块或最小样例里验证关键路径。
- 适合单机环境初始化、中间件快速搭建、测试环境验证和生产部署前准备。
- 当服务稳定性依赖端口、权限、目录、网络和系统参数时,这类主题会直接影响成败。
落地建议
- 固定版本号与镜像标签,避免“latest”带来的不可预期变化。
- 把配置、数据、日志目录拆开管理,并记录恢复步骤。
- 上线前确认端口、防火墙、SELinux、时区和磁盘空间。
排错清单
- 先查 systemctl、容器日志和应用日志,确认失败发生在哪一层。
- 检查端口占用、目录权限、挂载路径和网络连通性。
- 如果是新环境问题,优先对比与已知正常环境的差异。
复盘问题
- 如果把《K8S 的核心概念》放进你的当前项目,最先要验证的输入、输出和失败路径分别是什么?
- 《K8S 的核心概念》最容易在什么规模、什么边界条件下暴露问题?你会用什么指标或日志去确认?
- 相比默认实现或替代方案,采用《K8S 的核心概念》最大的收益和代价分别是什么?
