Kubernetes中YAML文件编写
1、YAML格式基本规范(复习)
YAML(YAML Ain't Markup Language)是一种用于数据序列化的格式,常用于配置文件、数据交换等场景。YAML的目标是易于阅读和书写,同时也易于与编程语言交互。YAML文件通常以.yaml或.yml作为文件扩展名。
YAML格式基本规范:
结构表示:
- 使用缩进表示层级关系,通常使用两个或四个空格的缩进,但必须在同一文档中保持一致。
- 不使用制表符(Tab)进行缩进。
键值对:
- 使用冒号加空格: 来分隔键和值。
- 键是唯一的,通常是字符串。
列表(数组):
- 使用短横线加空格- 来表示列表项。
- 列表项通常会缩进,表示属于上一级的列表。
字典(映射):
- 字典是一组键值对的集合。
- 字典的每个键值对都会缩进,表示属于上一级的字典。
数据类型:
- 支持字符串、布尔值、整数、浮点数、null、时间、日期等数据类型。
- 字符串通常不需要引号,但如果包含特殊字符,则需要用单引号或双引号括起来。
- 使用true/false表示布尔值。
- 使用null表示空值。
注释:
- 使用井号 # 开头表示注释,注释内容不会被解析。
多文档支持:
- 使用三个短横线---来分隔文件中的多个文档。
复杂结构:
- 字典和列表可以嵌套使用,形成复杂的结构。
这是一个简单的YAML示例,展示了一些基本的格式:
# 这是一个注释
person: # 字典的开始
name: John Doe # 字符串
age: 30 # 整数
married: true # 布尔值
children: # 列表的开始
- name: Jane Doe
age: 10
- name: Doe Junior
age: 5
# 它对应的JSON文件如下:
{
"person": {
"name": "John Doe",
"age": 30,
"married": true,
"children": [
{
"name": "Jane Doe",
"age": 10
},
{
"name": "Doe Junior",
"age": 5
}
]
}
}
2、K8S中YAML文件编写
YAML文件通常用于配置管理系统、部署工具、持续集成和持续部署(CI/CD)等场景,它们易于阅读和编辑。在Kubernetes中,YAML文件被广泛用于定义资源对象,如Deployments、Services、Pods等。
通过定义Deployment资源对象的过程,看下YAML文件编写的思路。
YAML文件的组成
YAML文件由apiVersion、kind、metadata、spec、status五部分组成,前四部分较常用。
基本语法规则
在Kubernetes中,YAML文件遵循特定的结构:
--- # YAML文件起始标志(可选)
apiVersion: v1 # API版本
kind: Pod # 资源类型
metadata: # 元数据
name: myapp # 资源名称
labels: # 标签
app: webapp # 标签键值对
spec: # 详细配置
containers: # 容器定义
- name: web # 容器名称
image: nginx:1.17 # 容器镜像
关键字段解析
- apiVersion: 指定使用的Kubernetes API版本,不同资源类型使用不同版本
- kind: 定义资源类型,如Pod、Deployment、Service等
- metadata: 包含资源的标识信息(名称、标签、注释等)
- spec: 描述资源的期望状态,这是最复杂的部分
- status: 记录资源的实际状态,由Kubernetes自动生成,使用清单时通常省略
# 查看K8S自带的资源管理帮助文档
root@k8s-master01:~# kubectl explain deployment
KIND: Deployment
VERSION: apps/v1
DESCRIPTION:
Deployment enables declarative updates for Pods and ReplicaSets.
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
spec <Object>
Specification of the desired behavior of the Deployment.
status <Object>
Most recently observed status of the Deployment.
--dry-run生成YAML文件框架
快速生成YAML模板
Kubernetes提供了强大的模板生成功能,无需手动编写YAML。
# 生成Pod模板
kubectl run myapp --image=nginx:1.17 --dry-run=client -o yaml > pod.yaml
# 生成Namespace模板
kubectl create namespace work --dry-run=client -o yaml > namespace.yaml
# 生成Deployment模板
kubectl create deployment myapp --image=dbimg:1.35 --dry-run=client -o yaml > deployment.yaml
实际生成的Deployment示例:
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: myapp
name: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: myapp
spec:
containers:
- image: dbimg:1.35
name: dbimg
resources: {}
status: {}
案例:通过--dry-run生成YAML文件框架
root@k8s-master01:~# kubectl create deployment jumpoint-web --image=nginx:latest --port=80 --replicas=2 --namespace=jumpoint-ns --dry-run=client --output=yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: jumpoint-web
name: jumpoint-web
namespace: jumpoint-ns
spec:
replicas: 2
selector:
matchLabels:
app: jumpoint-web
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: jumpoint-web
spec:
containers:
- image: nginx:latest
name: nginx
ports:
- containerPort: 80
resources: {}
status: {}
通过explain获取YAML文件字段含义
# 若要查看metadata.labels字段的含义:
root@k8s-master01:~# kubectl explain deployment.metadata.labels
KIND: Deployment
VERSION: apps/v1
FIELD: labels <map[string]string>
DESCRIPTION:
Map of string keys and values that can be used to organize and categorize
(scope and select) objects. May match selectors of replication controllers
and services. More info: http://kubernetes.io/docs/user-guide/labels
# 若要查看deployment.spec.template.spec.containers字段下还有哪些字段可用
root@k8s-master01:~# kubectl explain deployment.spec.template.spec.containers
KIND: Deployment
VERSION: apps/v1
RESOURCE: containers <[]Object>
DESCRIPTION:
List of containers belonging to the pod. Containers cannot currently be
added or removed. There must be at least one container in a Pod. Cannot be
updated.
A single application container that you want to run within a pod.
FIELDS:
...
imagePullPolicy <string>
Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always
if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated.
More info:
https://kubernetes.io/docs/concepts/containers/images#updating-images
Possible enum values:
- `"Always"` means that kubelet always attempts to pull the latest image.
Container will fail If the pull fails.
- `"IfNotPresent"` means that kubelet pulls if the image isn't present on
disk. Container will fail if the image isn't present and the pull fails.
- `"Never"` means that kubelet never pulls an image, but only uses a local
image. Container will fail if the image isn't present
...
调整YAML文件内容
精简不用的字段、修改字段的内容、添加镜像的拉取策略等,将其保存到nginx-deployment.yaml文件中。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: jumpoint-web-deployment-label
name: jumpoint-web
namespace: jumpoint-ns
spec:
replicas: 2
selector:
matchLabels:
app: jumpoint-web-pod-label
template:
metadata:
labels:
app: jumpoint-web-pod-label
spec:
containers:
- image: nginx:latest
name: jumpoint-web-container-name
imagePullPolicy: Always
ports:
- containerPort: 80
protocol: TCP
name: http
使用nginx-deployment.yaml文件创建Deployment资源对象。
root@k8s-master01:~/yaml-resources# kubectl create namespace jumpoint-ns
namespace/jumpoint-ns created
root@k8s-master01:~/yaml-resources# kubectl apply -f nginx-deployment.yaml
deployment.apps/jumpoint-web created
root@k8s-master01:~/yaml-resources# kubectl get deployments -n jumpoint-ns
NAME READY UP-TO-DATE AVAILABLE AGE
jumpoint-web 2/2 2 2 95s
root@k8s-master01:~/yaml-resources# kubectl get pods -n jumpoint-ns -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
jumpoint-web-66c66b4db4-f5dw4 1/1 Running 0 3m49s 10.200.2.14 k8s-node02-237 <none> <none>
jumpoint-web-66c66b4db4-x8jqj 1/1 Running 0 3m49s 10.200.1.13 k8s-node01-236 <none> <none>
root@k8s-master01-235:~/yaml-resources# kubectl describe deployment -n jumpoint-ns jumpoint-web
Name: jumpoint-web
Namespace: jumpoint-ns
CreationTimestamp: Tue, 30 Apr 2024 13:13:50 +0800
Labels: app=jumpoint-web-deployment-label
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=jumpoint-web-pod-label
Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=jumpoint-web-pod-label
Containers:
jumpoint-web-container-name:
Image: nginx:latest
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: jumpoint-web-66c66b4db4 (2/2 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 3m19s deployment-controller Scaled up replica set jumpoint-web-66c66b4db4 to 2
3、资源操作命令详解
1.创建资源
# 从YAML文件创建资源
kubectl create -f myapp.yaml
# 创建多个资源
kubectl create -f directory/ # 目录下所有YAML文件
kubectl create -f file1.yaml -f file2.yaml
2.应用声明式配置
# 创建或更新某个资源(推荐方式)
kubectl apply -f myapp.yaml
# 查看将要应用的变更
kubectl apply -f myapp.yaml --dry-run=client
# 强制替换配置
kubectl replace --force -f myapp.yaml
3.删除资源
# 删除指定资源
kubectl delete -f myapp.yaml
# 删除多个资源
kubectl delete -f directory/
# 基于标签删除(可能的多个pod)
kubectl delete pod -l app=webapp
4、高级操作技巧
1. 部分更新资源(打补丁)
# 使用merge混合策略(默认是strategic策略性合并)更新标签,适用于简单字段更新
cat > patch.yaml << EOF
metadata:
labels:
key: myapp-value
EOF
kubectl patch pod myapp --type=merge --patch-file patch.yaml
# 使用JSON patch删除标签
cat > remove-label.yaml << EOF
- op: remove
path: /metadata/labels/key
EOF
kubectl patch pod myapp --type=json --patch-file remove-label.yaml
2. 添加注解
# 添加或更新注解
kubectl annotate pod myapp webapp="nginx.1.17" description="前端Web服务器"
# 查看注解信息
kubectl describe pod myapp | grep Annotations
3. 实时编辑资源(对于改动不大的情况,使用edit更快速)
# 编辑运行中的资源
kubectl edit pod myapp
# 编辑Deployment配置(编辑时会打开默认文本编辑器,修改保存后会立即生效)
kubectl edit deployment/myapp
5、常见问题排查
1. YAML格式错误
# 常见的格式错误
error: error parsing pod.yaml: error converting YAML to JSON: yaml: line 10: did not find expected key
# 解决方法:使用YAML验证工具或在线校验器
2. 资源已存在错误
# 使用create时如果资源已存在会报错
Error from server (AlreadyExists): error when creating "myapp.yaml": pods "myapp" already exists
# 解决方法:使用apply代替create,或者先删除再创建
3. 字段验证错误
# API服务器会验证字段合法性
The Deployment "myapp" is invalid: spec.template.spec.containers[0].name: Required value
# 解决方法:使用kubectl explain查看字段要求
掌握Kubernetes资源清单文件的使用是容器编排的基础技能。记住,实践是最好的学习方式。尝试从简单的Pod开始,逐步扩展到复杂的Deployment和Service配置,慢慢你就会发现Kubernetes资源管理的强大之处。