作为容器编排领域的事实标准,Kubernetes通过声明式的资源清单(Manifest)来管理集群中的各种对象。这份看似简单的YAML文件背后,蕴含着Kubernetes设计哲学的核心——"期望状态"管理。当我在生产环境首次部署Go TodoList应用时,曾因对资源清单理解不透彻导致多次部署失败。本文将结合实战经验,带你深入理解Kubernetes资源清单的方方面面。
名称空间(Namespace)是Kubernetes实现资源隔离的核心机制。在我的TodoList项目部署中,90%的操作都集中在名称空间级别资源上。这些资源的特点是:
default名称空间下操作工作负载型资源是日常接触最频繁的类型。以Deployment为例,它通过控制器模式确保指定数量的Pod副本持续运行。在TodoList项目中,我使用以下配置创建了2个Pod副本:
yaml复制apiVersion: apps/v1
kind: Deployment
metadata:
name: todo-deploy
spec:
replicas: 2
selector:
matchLabels:
app: todo
template:
metadata:
labels:
app: todo
spec:
containers:
- name: todo-app
image: myrepo/todo:v1.2
关键经验:
selector.matchLabels必须与Pod模板中的labels完全匹配,否则Deployment将无法管理创建的Pod。这是我初期常犯的错误之一。
服务发现型资源为Pod提供网络访问入口。Service资源通过标签选择器动态关联后端Pod,当Pod发生扩缩容时,Service会自动更新Endpoint。以下是TodoList的NodePort类型Service配置:
yaml复制apiVersion: v1
kind: Service
metadata:
name: todo-svc
spec:
type: NodePort
ports:
- port: 80
targetPort: 8080
nodePort: 30080
selector:
app: todo
集群级别资源不受名称空间约束,通常由集群管理员管理。在TodoList项目中,我需要特别关注以下两类:
**节点资源(Node)**代表集群中的工作节点。通过kubectl describe node <node-name>可以查看节点资源详情,包括:
**持久卷(PersistentVolume)**为有状态应用提供存储。与名称空间级别的PVC(PersistentVolumeClaim)配合使用时,需要注意:
yaml复制# PV定义(集群级别)
apiVersion: v1
kind: PersistentVolume
metadata:
name: todo-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /data/todo
# PVC定义(名称空间级别)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: todo-pvc
namespace: default
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
这类资源往往被初学者忽视,但在故障排查时至关重要。在TodoList项目出现Pod频繁重启时,我通过以下命令发现了问题根源:
bash复制kubectl get events --sort-by='.metadata.creationTimestamp'
输出显示存活探针(livenessProbe)检测失败,原因是容器启动时间过长导致探针超时。调整initialDelaySeconds后问题解决。
Kubernetes资源清单严格遵循YAML1.2规范。在TodoList项目部署过程中,我总结了以下必须掌握的语法要点:
缩进规则:
常见错误示例:
yaml复制# 错误:使用Tab缩进
metadata:
name: todo-deploy # 这里使用了Tab
# 正确:使用空格缩进
metadata:
name: todo-deploy
字符串处理:
yaml复制env:
- name: CONFIG
value: |
{
"timeout": 30,
"retry": 3
}
**对象(字典)**是Kubernetes配置的主体结构。以Deployment的spec为例:
yaml复制spec:
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
**数组(列表)**常用于定义多个同类元素。容器端口定义就是典型示例:
yaml复制ports:
- name: http
containerPort: 8080
protocol: TCP
- name: metrics
containerPort: 9090
多级嵌套是复杂资源配置的常见模式。以下是Ingress资源的TLS配置示例:
yaml复制spec:
tls:
- hosts:
- todo.example.com
secretName: todo-tls
rules:
- host: todo.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: todo-svc
port:
number: 80
labels是Kubernetes的灵魂设计。在TodoList项目中,我建立了以下标签体系:
yaml复制metadata:
labels:
app: todo
tier: backend
version: v1.2
env: prod
annotations用于存储非识别性元数据。常用场景包括:
yaml复制metadata:
annotations:
buildTimestamp: "2023-07-20T14:30:00Z"
gitCommit: "a1b2c3d"
description: "TodoList production deployment"
容器定义是Pod的核心。以下配置展示了资源限制和健康检查的最佳实践:
yaml复制containers:
- name: todo-app
image: myrepo/todo:v1.2
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
初始化容器在业务容器前运行,适合执行预处理任务:
yaml复制initContainers:
- name: init-db
image: busybox
command: ['sh', '-c', 'until nslookup db-service; do echo waiting; sleep 2; done']
端口映射是Service的关键配置。在TodoList项目中,我采用了多端口方案:
yaml复制ports:
- name: http
port: 80
targetPort: 8080
- name: metrics
port: 9090
targetPort: 9090
会话保持配置示例:
yaml复制spec:
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 3600
ConfigMap实现配置与镜像分离。在TodoList项目中,我将应用配置外置:
yaml复制apiVersion: v1
kind: ConfigMap
metadata:
name: todo-config
data:
appsettings.json: |
{
"Logging": {
"Level": "Information"
},
"Database": {
"ConnectionString": "Server=db;Database=todo"
}
}
环境变量注入方式:
yaml复制envFrom:
- configMapRef:
name: todo-config
临时存储使用emptyDir:
yaml复制volumes:
- name: temp
emptyDir: {}
配置文件挂载:
yaml复制volumes:
- name: config
configMap:
name: todo-config
volumeMounts:
- name: config
mountPath: /etc/todo
问题现象:Pod处于CrashLoopBackOff状态
排查步骤:
kubectl logs <pod-name>kubectl describe pod <pod-name>kubectl exec -it <pod-name> -- sh问题现象:Service无法访问后端Pod
检查清单:
kubectl get endpoints <service-name>问题现象:Pod处于Pending状态
诊断方法:
bash复制kubectl describe pod <pod-name> | grep -A10 Events
kubectl get nodes -o=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.allocatable.cpu}{"\t"}{.status.allocatable.memory}{"\n"}{end}'
Pod资源请求设置建议:
yaml复制resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
节点选择器示例:
yaml复制spec:
nodeSelector:
disktype: ssd
gpu: "true"
亲和性配置:
yaml复制affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- todo
topologyKey: kubernetes.io/hostname
在TodoList项目演进过程中,我逐步将这些最佳实践应用到生产环境,显著提升了应用稳定性和运维效率。理解资源清单的每个细节,是掌握Kubernetes的关键一步。