1. 初识Kubernetes资源清单
第一次接触Kubernetes时,最让我困惑的就是那些YAML文件。它们看起来结构复杂,却又像是Kubernetes世界的"源代码"。这些文件在Kubernetes中被称为资源清单(Manifest),是定义和配置Kubernetes对象的标准方式。
资源清单本质上是一种声明式配置文件,它告诉Kubernetes你希望集群达到什么样的状态,而不是如何达到这个状态。这与传统运维中编写脚本一步步执行操作的方式完全不同。举个例子,当你想部署一个Nginx服务时,你不需要写"先创建容器,再配置网络,最后暴露端口"这样的指令,而是直接声明"我需要一个运行Nginx的Pod,它应该监听80端口"。
注意:Kubernetes采用声明式API设计,你只需要告诉系统"想要什么",而不是"如何做"。系统会自动计算并执行必要的操作使当前状态匹配期望状态。
资源清单最常见的格式是YAML(也可以使用JSON),它比传统的配置文件更易读和编写。一个典型的资源清单包含以下几个关键部分:
- apiVersion:定义使用的Kubernetes API版本
- kind:指定要创建的资源类型(如Pod、Deployment、Service等)
- metadata:包含资源的元数据,如名称、标签等
- spec:详细描述资源的期望状态
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 资源清单核心结构解析
2.1 基础字段详解
让我们通过一个实际的例子来理解资源清单的结构。下面是一个最简单的Pod定义:
yaml复制apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: nginx:1.14.2
ports:
- containerPort: 80
在这个例子中:
-
apiVersion字段指定了我们使用的Kubernetes API版本。不同资源类型可能属于不同的API组,比如Pod属于核心API组(v1),而Deployment属于apps/v1。
-
kind字段定义了我们要创建的资源类型。Kubernetes中有几十种内置资源类型,常见的有Pod、Deployment、Service、ConfigMap等。
-
metadata部分包含了资源的元信息,其中name是必填项,它必须是命名空间内唯一的。labels是键值对,用于标识和组织资源,在后续的资源选择和调度中非常有用。
-
spec部分是最重要的,它定义了资源的期望状态。对于Pod来说,spec.containers定义了Pod中运行的容器列表,每个容器需要指定名称和镜像。
2.2 标签与选择器机制
标签(Labels)是Kubernetes中一个简单但强大的概念。它们是附加到对象上的键值对,用于标识对象的特性。标签选择器(Label Selector)则是用于筛选具有特定标签的对象的机制。
yaml复制metadata:
labels:
app: frontend
tier: web
environment: production
标签的常见用途包括:
- 标识应用程序组件(如前端/后端)
- 区分环境(开发/测试/生产)
- 标记版本信息
- 组织团队拥有的资源
在Deployment等控制器中,会使用选择器(selector)来匹配它管理的Pod:
yaml复制selector:
matchLabels:
app: nginx
3. 常用资源类型及其清单
3.1 Pod资源清单
Pod是Kubernetes中最小的可部署单元,代表集群中运行的一个或多个容器。以下是一个更完整的Pod定义示例:
yaml复制apiVersion: v1
kind: Pod
metadata:
name: my-app-pod
labels:
app: my-app
environment: staging
spec:
containers:
- name: main-container
image: my-app:1.0.0
ports:
- containerPort: 8080
env:
- name: DB_HOST
value: "db-service"
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1"
memory: "1Gi"
- name: sidecar-container
image: log-collector:2.1
volumeMounts:
- name: log-volume
mountPath: /var/log
volumes:
- name: log-volume
emptyDir: {}
这个例子展示了Pod的几个高级特性:
- 多容器配置(主应用容器和sidecar日志收集容器)
- 环境变量注入
- 资源请求和限制
- 卷挂载
3.2 Deployment资源清单
Deployment是管理Pod副本的控制器,它提供了声明式更新、滚动升级和回滚等功能。以下是典型的Deployment定义:
yaml复制apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
Deployment的关键特性包括:
- replicas:指定Pod副本数量
- selector:匹配要管理的Pod
- template:定义Pod模板
- 健康检查(livenessProbe和readinessProbe)
3.3 Service资源清单
Service定义了访问Pod的逻辑方式,为Pod提供稳定的IP和DNS名称。以下是ClusterIP类型的Service示例:
yaml复制apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP
Service的主要配置项:
- selector:选择要暴露的Pod
- ports:定义端口映射(Service端口到Pod端口的映射)
- type:服务类型(ClusterIP、NodePort、LoadBalancer等)
4. 资源清单高级特性
4.1 配置注入:ConfigMap和Secret
在实际应用中,我们通常需要将配置信息与容器镜像分离。Kubernetes提供了ConfigMap和Secret来实现这一目的。
ConfigMap示例:
yaml复制apiVersion: v1
kind: ConfigMap
metadata:
name: game-config
data:
game.properties: |
enemy.types=aliens,monsters
player.maximum-lives=5
ui.properties: |
color.good=purple
color.bad=yellow
在Pod中引用ConfigMap:
yaml复制spec:
containers:
- name: game-container
image: game-image
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: game-config
Secret示例(用于敏感数据):
yaml复制apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
username: YWRtaW4= # base64编码的"admin"
password: MWYyZDFlMmU2N2Rm # base64编码的"1f2d1e2e67df"
4.2 资源配额与限制
Kubernetes允许为容器指定资源请求和限制,这对于集群资源管理和应用稳定性至关重要。
yaml复制resources:
requests:
cpu: "500m" # 0.5个CPU核心
memory: "512Mi" # 512兆字节
limits:
cpu: "1" # 1个CPU核心
memory: "1Gi" # 1GB
资源配额的关键点:
- requests:调度器使用此值决定将Pod放在哪个节点
- limits:容器运行时使用此值限制容器资源使用
- CPU以毫核(m)为单位,1000m=1个CPU核心
- 内存可以使用Ki/Mi/Gi/Ti或K/M/G/T为单位
4.3 健康检查机制
健康检查是生产环境中必不可少的配置,Kubernetes提供了三种探针:
- livenessProbe:检测容器是否正常运行。如果失败,kubelet会杀死容器并重启它。
- readinessProbe:检测容器是否准备好接收流量。如果失败,端点控制器会从Service的端点中移除该Pod的IP地址。
- startupProbe:检测容器应用是否已启动。如果提供了启动探针,则禁用所有其他探针,直到它成功为止。
yaml复制livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Custom-Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
startupProbe:
tcpSocket:
port: 8080
failureThreshold: 30
periodSeconds: 10
5. 资源清单最佳实践
5.1 编写可维护的资源清单
在实际工作中,资源清单会变得越来越复杂。以下是一些保持清单可维护性的技巧:
-
使用注释:为复杂的配置添加注释说明
yaml复制# 这个注解用于启用Istio自动注入 metadata: annotations: sidecar.istio.io/inject: "true" -
多文件组织:将不同资源类型分开存放,例如:
code复制manifests/ ├── deployment.yaml ├── service.yaml └── configmap.yaml -
使用kustomize或helm:当清单变得复杂时,考虑使用这些工具来管理
-
验证清单:在应用前使用
kubectl apply --dry-run=client -f file.yaml验证
5.2 常见错误与排查
在编写资源清单时,经常会遇到以下问题:
-
缩进错误:YAML对缩进非常敏感,建议使用支持YAML的编辑器
提示:使用VS Code等编辑器并安装YAML插件,可以实时检查语法错误
-
字段拼写错误:比如将
containerPort写成container_port -
选择器不匹配:Deployment的selector必须匹配Pod模板的labels
-
API版本不兼容:不同Kubernetes版本支持的API版本可能不同
当资源创建失败时,可以使用以下命令排查:
bash复制kubectl describe <resource-type> <resource-name> # 查看详细事件
kubectl get events --sort-by=.metadata.creationTimestamp # 查看集群事件
kubectl logs <pod-name> # 查看Pod日志
5.3 资源清单管理进阶
随着应用规模扩大,需要考虑更高级的资源清单管理策略:
-
命名空间隔离:使用命名空间分隔不同环境或团队
yaml复制apiVersion: v1 kind: Namespace metadata: name: production -
资源配额:限制命名空间的资源使用
yaml复制apiVersion: v1 kind: ResourceQuota metadata: name: mem-cpu-quota spec: hard: requests.cpu: "2" requests.memory: 2Gi limits.cpu: "4" limits.memory: 4Gi -
网络策略:控制Pod间的网络通信
yaml复制apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: db-access-policy spec: podSelector: matchLabels: role: db ingress: - from: - podSelector: matchLabels: role: api ports: - protocol: TCP port: 5432
在实际操作中,我发现将资源清单纳入版本控制系统(如Git)并建立完善的评审流程,可以显著减少配置错误。同时,使用CI/CD管道自动化部署过程,可以确保环境一致性并提高部署效率。
