2. Kubernetes 核心概念回顾:Pod、Service、Deployment、Namespace、ConfigMap、Secret 基础
在深入 GitOps 调度优化之前,必须重新夯实 Kubernetes 的六大核心抽象。这些对象构成了所有工作负载声明式管理的基石。本章从调度与配置视角出发,梳理每个原语的关键属性、生命周期与常见误区。
2.1 核心对象速览表
| 对象 | API 版本 (稳定) | 作用域 | 是否可调度 | 核心字段 |
|---|---|---|---|---|
| Pod | v1 | Namespace | 是(最小调度单元) | containers, volumes, nodeName |
| Service | v1 | Namespace | 否(网络抽象) | selector, ports, type |
| Deployment | apps/v1 | Namespace | 间接(通过 ReplicaSet) | replicas, template, strategy |
| Namespace | v1 | 集群 | 否(逻辑隔离) | name, labels, finalizers |
| ConfigMap | v1 | Namespace | 否(配置注入) | data, binaryData |
| Secret | v1 | Namespace | 否(敏感数据) | type, data (base64) |
2.2 Pod:不可变调度的原子单位
Pod 是 Kubernetes 中可创建和调度的最小计算单元。一个 Pod 封装一个或多个容器、共享存储卷和网络栈。在 GitOps 实践中,Pod 模板通常由 Deployment 等高层控制器管理,不建议直接创建裸 Pod,因为裸 Pod 不会在节点故障时自动重建。
关键调度属性: nodeSelector、affinity/anti-affinity、toleration、resource requests/limits。这些字段直接影响调度器决策,也是 GitOps 调度优化中需要声明式管控的核心参数。
apiVersion: v1
kind: Pod
metadata:
name: example-pod
labels:
app: myapp
spec:
containers:
- name: app
image: nginx:1.25
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
restartPolicy: Always
2.3 Service:稳定的网络端点抽象
Service 为一组动态变化的 Pod 提供稳定的虚拟 IP(ClusterIP)和 DNS 名称。它通过标签选择器(selector)匹配后端 Pod。在 GitOps 工作流中,Service 通常与 Deployment 一同声明,确保流量入口与工作负载版本同步。
- ClusterIP:默认类型,集群内可访问。
- NodePort:在每个节点上开放静态端口,适合开发调试。
- LoadBalancer:云厂商集成,对外暴露服务。
- Headless Service:设置 clusterIP: None,用于 StatefulSet 的有状态发现。
GitOps 注意点: Service 的 selector 必须与 Pod 标签精确匹配。如果 Deployment 更新了标签(不推荐),Service 流量会中断。建议将标签作为 GitOps 仓库中的不变标识。
2.4 Deployment:声明式滚动更新引擎
Deployment 管理 ReplicaSet,进而控制 Pod 的期望副本数与更新策略。它是 GitOps 中最常被同步的工作负载对象。核心策略包括:
| 策略字段 | 默认值 | 说明 |
|---|---|---|
| strategy.type | RollingUpdate | 滚动更新;可选 Recreate(先删后建) |
| strategy.rollingUpdate.maxUnavailable | 25% | 更新期间最多不可用 Pod 比例 |
| strategy.rollingUpdate.maxSurge | 25% | 更新期间最多超出期望副本数比例 |
| revisionHistoryLimit | 10 | 保留的历史 ReplicaSet 数量 |
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deploy
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
2.5 Namespace:多租户逻辑隔离边界
Namespace 将集群资源划分为逻辑组,常用于环境隔离(dev/staging/prod)或团队隔离。在 GitOps 中,每个 Namespace 通常对应一个应用环境目录。
- 资源配额:ResourceQuota 限制 Namespace 总资源消耗。
- 网络策略:NetworkPolicy 在 Namespace 级别控制流量。
- 默认对象:每个 Namespace 自动创建 default、kube-system、kube-public。
- 删除行为:删除 Namespace 会级联删除其下所有资源。
常见陷阱: 不要将 ConfigMap/Secret 跨 Namespace 引用。Pod 只能挂载同 Namespace 下的配置对象。GitOps 仓库应保持每个 Namespace 的配置自包含。
2.6 ConfigMap & Secret:配置与敏感数据注入
ConfigMap 存储非机密配置(键值对或文件),Secret 存储敏感数据(密码、、证书)。两者都可以通过环境变量或卷挂载注入 Pod。
| 特性 | ConfigMap | Secret |
|---|---|---|
| 数据编码 | 明文 UTF-8 | Base64(etcd 中默认未加密) |
| 大小限制 | 1 MiB(etcd 限制) | 1 MiB |
| 更新传播 | 环境变量方式需重启 Pod;卷挂载方式自动同步(数分钟延迟) | 同 ConfigMap |
| GitOps 存储 | 直接存 Git 仓库 | 推荐使用 SealedSecret / External Secrets Operator |
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: production
LOG_LEVEL: info
---
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
DB_PASSWORD: cGFzc3dvcmQxMjM= # base64 编码的 "password123"
2.7 核心对象关系图
下图展示了 Deployment、ReplicaSet、Pod、Service、ConfigMap/Secret 之间的典型关联关系。箭头方向表示“管理”或“选择”关系。
2.8 调度与配置注入的常见误区
误区一: 认为 ConfigMap 更新后,通过环境变量注入的 Pod 会自动获取新值。
事实: 环境变量只在 Pod 启动时注入一次。更新 ConfigMap 后,必须重建 Pod(如通过 Deployment 滚动更新)才能生效。卷挂载方式可以自动同步,但存在缓存延迟。
事实: 环境变量只在 Pod 启动时注入一次。更新 ConfigMap 后,必须重建 Pod(如通过 Deployment 滚动更新)才能生效。卷挂载方式可以自动同步,但存在缓存延迟。
误区二: 在 Git 仓库中明文存储 Secret 的 base64 值。
事实: Base64 不是加密。任何有 etcd 或 Git 访问权限的人都可以解码。GitOps 推荐使用 SealedSecret、External Secrets Operator 或 Vault 集成。
事实: Base64 不是加密。任何有 etcd 或 Git 访问权限的人都可以解码。GitOps 推荐使用 SealedSecret、External Secrets Operator 或 Vault 集成。
最佳实践: 在 GitOps 仓库中,每个环境(Namespace)使用独立的 Kustomize overlay 或 Helm values 文件。将 ConfigMap 和 Deployment 放在同一目录,确保配置变更触发工作负载滚动更新。