K8S(五)—— K8s中YAML文件全方位解析:语法、案例、Port详解与快速编写技巧
文章目录
- 前言
- 一、K8s配置文件格式对比:YAML与JSON
- 二、YAML语法格式详解
- 2.1 核心语法规则
- 2.2 语法示例(简单YAML结构)
- 三、查看K8s API版本(资源清单基础)
- 3.1 查看集群支持的API版本
- 3.2 API版本选择原则
- 四、K8s资源清单实战:Deployment与Service
- 4.1 案例1:Deployment资源(管理Pod副本)
- 4.1.1 编写Deployment YAML文件
- 4.1.2 创建与验证Deployment
- 4.2 案例2:Service资源(对外暴露访问)
- 4.2.1 编写Service YAML文件
- 4.2.2 创建与验证Service
- 五、K8s中4类Port详解:port、nodePort、targetPort、containerPort
- 5.1 核心Port定义与用途
- 5.2 流量转发流程
- 六、快速编写YAML文件的3种实用技巧
- 6.1 技巧1:用`--dry-run`生成模板
- 6.1.1 生成Pod模板
- 6.1.2 生成Deployment模板
- 6.1.3 优化模板(删除无用字段)
- 6.2 技巧2:导出现有资源的YAML
- 6.2.1 导出Service的YAML
- 6.2.2 导出Deployment的YAML
- 6.3 技巧3:用`kubectl explain`查询字段帮助
- 6.3.1 查看Deployment的字段帮助
- 6.3.2 逐层查询字段
- 七、YAML文件学习方法(从入门到熟练)
- 7.1 阶段1:读懂现有YAML(输入)
- 7.2 阶段2:修改现有YAML(实践)
- 7.3 阶段3:独立编写+查帮助(输出)
- 总结
前言
在Kubernetes(简称K8s)的日常运维与资源管理中,配置文件是连接用户需求与集群执行逻辑的核心载体。K8s支持JSON和YAML两种格式的资源配置文件,其中JSON因结构严谨性更适合API接口间的消息传递,而YAML凭借其简洁无标记、人性化可读性强的特点,成为K8s资源定义、配置与管理的首选格式。
本文将从YAML语法基础切入,结合实战案例讲解K8s资源清单(Deployment、Service)的编写逻辑,深入解析K8s中4类核心Port的区别,并分享快速生成与优化YAML文件的实用技巧,帮助读者从“读懂”到“会写”,逐步掌握K8s配置文件的核心能力。
一、K8s配置文件格式对比:YAML与JSON
K8s作为容器编排平台,需通过配置文件定义资源对象(如Pod、Deployment、Service)的属性与行为。其支持的两种主流格式各有侧重,需明确适用场景:
格式 | 核心用途 | 优势 | 劣势 |
---|---|---|---|
JSON | API接口消息传递(如K8s组件间通信) | 结构严谨、机器易解析、无歧义 | 语法繁琐、可读性差、不适合人工编写 |
YAML | 资源配置与管理(人工编写/维护) | 语法简洁、格式人性化、易读易改 | 对缩进敏感、机器解析需处理格式校验 |
结论:日常运维中,优先选择YAML格式编写K8s资源清单,仅在API开发或自动化脚本中考虑JSON格式。
二、YAML语法格式详解
YAML的语法规则是编写正确配置文件的基础,需严格遵循以下规范,否则会导致K8s解析失败:
2.1 核心语法规则
- 大小写敏感:例如
Name
与name
代表不同字段,需与K8s资源定义的字段严格匹配(如apiVersion
而非apiversion
)。 - 缩进表示层级:通过空格缩进体现字段间的父子关系(如
metadata
下的name
需缩进),不支持Tab键(不同编辑器Tab宽度可能不一致,导致格式错乱)。 - 缩进空格数灵活:相同层级的字段左侧对齐即可,推荐统一使用“2个空格”作为基础缩进(K8s社区通用习惯)。
- 符号后需空格:特殊符号(冒号
:
、逗号,
、短横杆-
)后必须跟1个空格,例如name: nginx
(冒号后空格)、- image: nginx
(短横杆后空格)。 - 文件分隔符:
---
表示YAML文件的开始,若一个文件中定义多个资源(如同时定义Deployment和Service),可通过---
分隔不同资源块。 - 注释语法:
#
开头的内容为注释,注释仅作用于单行,K8s解析时会忽略注释内容(推荐为关键字段添加注释,提升可维护性)。
2.2 语法示例(简单YAML结构)
# 注释:示例YAML结构,体现层级与符号规范
apiVersion: v1
kind: Pod
metadata:name: my-pod # Pod名称(同一Namespace唯一)labels: # 标签(用于K8s资源关联,如Service匹配Pod)app: my-app
spec:containers: # 容器列表(一个Pod可包含多个容器,用短横杆分隔)- name: my-container # 第一个容器名称image: nginx:1.15.4 # 容器镜像(需指定版本,避免拉取latest镜像)ports:- containerPort: 80 # 容器内部端口
三、查看K8s API版本(资源清单基础)
K8s的资源(如Deployment、Service)需通过apiVersion
字段指定对应的API版本,不同版本代表资源的特性阶段(稳定版/测试版),直接影响生产环境的可用性。
3.1 查看集群支持的API版本
通过kubectl api-versions
命令可列出当前K8s集群支持的所有API版本,示例输出如下:
kubectl api-versions
# 部分输出如下
admissionregistration.k8s.io/v1beta1
apps/v1 # 稳定版(生产环境首选,如Deployment属于此类)
apps/v1beta1 # Beta版(测试特性,不建议生产使用,可能被废弃)
apps/v1beta2
v1 # 核心API组(如Pod、Service属于此类)
3.2 API版本选择原则
- 稳定版(无Beta字样):如
apps/v1
、v1
,特性成熟、兼容性有保障,生产环境必须使用。 - Beta版(含beta字样):如
apps/v1beta1
,代表特性处于测试阶段,可能存在bug或后续版本不兼容,仅用于测试环境验证新特性。 - Alpha版(含alpha字样):特性未稳定,默认不启用,不建议日常使用。
四、K8s资源清单实战:Deployment与Service
资源清单是YAML文件的核心应用场景,下面通过“Nginx Deployment(副本管理)”和“Nginx Service(对外访问)”两个案例,讲解资源清单的编写逻辑与操作流程。
4.1 案例1:Deployment资源(管理Pod副本)
Deployment是K8s中用于管理Pod副本的核心资源,可实现Pod的创建、扩容、滚动更新等功能。
4.1.1 编写Deployment YAML文件
1、创建目录并新建YAML文件:
mkdir -p /opt/demo && cd /opt/demo
vim nginx-deployment.yaml
2、编写YAML内容(关键字段已加注释):
apiVersion: apps/v1 #指定api版本标签
kind: Deployment #定义资源的类型/角色,deployment为副本控制器,此处资源类型可以是Deployment、Job、Ingress、Service等
metadata: #定义资源的元数据信息,比如资源的名称、namespace、标签等信息name: nginx-deployment #定义资源的名称,在同一个namespace空间中必须是唯一的labels: #定义Deployment资源标签app: nginx
spec: #定义deployment资源需要的参数属性,诸如是否在容器失败时重新启动容器的属性replicas: 3 #定义副本数量selector: #定义标签选择器matchLabels: #定义匹配标签app: nginx #需与 .spec.template.metadata.labels 定义的标签保持一致template: #定义业务模板,如果有多个副本,所有副本的属性会按照模板的相关配置进行匹配metadata:labels: #定义Pod副本将使用的标签,需与 .spec.selector.matchLabels 定义的标签保持一致app: nginxspec:containers: #定义容器属性- name: nginx #定义一个容器名,一个 - name: 定义一个容器image: nginx:1.15.4 #定义容器使用的镜像以及版本ports:- containerPort: 80 #定义容器的对外的端口
4.1.2 创建与验证Deployment
1、执行YAML文件创建Deployment:
kubectl create -f nginx-deployment.yaml
# 输出:deployment.apps/nginx-deployment created
2、查看创建的Pod副本(验证是否正常运行):
kubectl get pods -o wide
# 输出示例(3个Pod均为Running状态,分布在不同Node)
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-746ccc65d8-hdrp7 1/1 Running 0 21s 10.244.1.28 node01 <none> <none>
nginx-deployment-746ccc65d8-vjthp 1/1 Running 0 21s 10.244.2.23 node02 <none> <none>
nginx-deployment-746ccc65d8-zj99c 1/1 Running 0 21s 10.244.2.24 node02 <none> <none>
READY
:1/1
表示Pod内1个容器正常运行。STATUS
:Running
表示Pod已就绪。IP
:Pod的内部IP(仅集群内可访问)。
4.2 案例2:Service资源(对外暴露访问)
Deployment创建的Pod仅能在K8s集群内部访问,需通过Service资源对外暴露端口,实现外部流量访问Pod。
4.2.1 编写Service YAML文件
1、新建Service YAML文件:
vim nginx-service.yaml
2、编写YAML内容(选择NodePort
类型,支持外部访问):
apiVersion: v1 # API版本(Service属于核心组v1)
kind: Service # 资源类型(此处为Service)
metadata:name: nginx-service # Service名称labels:app: nginx
spec:type: NodePort # Service类型(NodePort:通过NodeIP+NodePort访问)ports:- port: 80 # Service集群内端口(集群内通过ClusterIP:port访问)targetPort: 80 # 目标Pod端口(流量转发到Pod的80端口)selector:app: nginx # 标签选择器(匹配带有app: nginx的Pod)
4.2.2 创建与验证Service
1、执行YAML文件创建Service:
kubectl create -f nginx-service.yaml
# 输出:service/nginx-service created
2、查看Service信息(获取NodePort端口):
kubectl get svc
# 输出示例
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 18h
nginx-service NodePort 10.96.157.209 <none> 80:30947/TCP 16s
PORT(S)
:80:30947
表示“Service集群内端口:NodePort外部端口”,其中30947
是K8s自动分配的外部访问端口。
3、外部访问测试:
在浏览器或终端中通过“NodeIP:NodePort”访问Nginx,例如:
# 终端访问示例(NodeIP为192.168.10.15或192.168.10.16)
curl http://192.168.10.15:30947
# 输出Nginx默认首页HTML内容,说明访问成功
五、K8s中4类Port详解:port、nodePort、targetPort、containerPort
在K8s的Service与Pod配置中,4类Port容易混淆,需明确其定义、用途及流量转发关系。
5.1 核心Port定义与用途
Port类型 | 定义 | 用途 | 访问方式 | 备注 |
---|---|---|---|---|
port | Service的集群内端口 | 集群内部Pod访问Service的端口 | ClusterIP:port | 仅集群内可见,由用户指定(如80) |
nodePort | Service的外部访问端口 | 外部客户端访问Service的端口 | NodeIP:nodePort | 由K8s自动分配(默认范围30000-32767),也可手动指定 |
targetPort | 目标Pod的端口 | Service将从 port 或 nodePort 来的流量经过 kube-proxy 反向代理负载均衡转发到后端 Pod 的 targetPort | 无直接访问方式(仅Service内部转发) | 一般与Pod的containerPort 一致 |
containerPort | 容器内部的端口 | 容器监听的端口(如Nginx监听80) | 无直接访问方式(仅Pod内部可见) | 需与容器实际运行的端口匹配(如镜像内Nginx的端口) |
5.2 流量转发流程
外部客户端访问Pod的完整流量路径如下:
外部客户端 → NodeIP:nodePort(Service外部入口)
→ ClusterIP:port(Service集群内入口)
→ PodIP:targetPort(Service转发到Pod)
→ 容器:containerPort(Pod内容器监听端口)
例如本文案例中的流量路径:
curl http://192.168.80.11:30947
→ Service(30947→80) → Pod(80) → 容器(80)
六、快速编写YAML文件的3种实用技巧
手动编写YAML文件易出错且效率低,推荐以下3种技巧快速生成符合规范的YAML模板。
6.1 技巧1:用--dry-run
生成模板
--dry-run=client
参数可模拟创建资源,仅输出YAML/JSON格式的资源定义,不实际创建资源,适合生成基础模板。
6.1.1 生成Pod模板
# 生成Nginx Pod的YAML模板,输出到文件
kubectl run nginx-test --image=nginx --port=80 --dry-run=client -o yaml > nginx-test.yaml
6.1.2 生成Deployment模板
# 生成3个副本的Nginx Deployment模板
kubectl create deployment nginx-deploy --image=nginx --port=80 --replicas=3 --dry-run=client -o yaml > nginx-deploy.yaml
6.1.3 优化模板(删除无用字段)
生成的模板中会包含creationTimestamp: null
、resources: {}
、status: {}
等无用字段,需手动删除,优化后示例:
vim nginx-test.yaml
apiVersion: v1
kind: Pod
metadata:labels:run: nginx-testname: nginx-test
spec:containers:- image: nginxname: nginx-testports:- containerPort: 80dnsPolicy: ClusterFirstrestartPolicy: Always
6.2 技巧2:导出现有资源的YAML
若集群中已存在同类资源,可通过kubectl get
命令导出其YAML,修改后复用(适合复杂资源的快速复制)。
6.2.1 导出Service的YAML
# 导出名为nginx-service的Service YAML,保存到文件
kubectl get svc nginx-service -o yaml > my-svc.yaml
6.2.2 导出Deployment的YAML
kubectl get deployment nginx-deployment -o yaml > my-deploy.yaml
6.3 技巧3:用kubectl explain
查询字段帮助
遇到不熟悉的字段时,通过kubectl explain
可逐层查看字段的定义、类型及说明,避免语法错误。
6.3.1 查看Deployment的字段帮助
# 查看Deployment的spec.template.spec.containers字段(容器配置相关)
kubectl explain deployments.spec.template.spec.containers
6.3.2 逐层查询字段
若需更细致的帮助,可逐层深入字段,例如:
# 1. 查看Deployment的spec字段
kubectl explain deployments.spec
# 2. 查看spec下的template字段
kubectl explain deployments.spec.template
# 3. 查看template下的spec字段
kubectl explain deployments.spec.template.spec
七、YAML文件学习方法(从入门到熟练)
掌握YAML的核心在于“理解+实践”,推荐以下3个阶段的学习路径:
7.1 阶段1:读懂现有YAML(输入)
- 优先阅读K8s官方文档的示例(如K8s官方Deployment示例),理解每个字段的用途。
- 分析集群中现有资源的YAML(如
kubectl get pod xxx -o yaml
),对比字段与实际资源的对应关系(如replicas
与Pod数量)。
7.2 阶段2:修改现有YAML(实践)
- 基于导出的模板修改字段(如调整
replicas
数量、更换image
版本、修改nodePort
),执行后观察资源变化(如kubectl get pods
查看副本数是否变化)。 - 重点关注关联字段的一致性(如
selector.matchLabels
与template.metadata.labels
必须一致,否则Service无法匹配Pod)。
7.3 阶段3:独立编写+查帮助(输出)
- 从简单资源(如Pod、Service)开始独立编写YAML,遇到未知字段时用
kubectl explain
查询。 - 积累常用资源模板(如带资源限制的Deployment、带Ingress的Service),形成个人模板库,提升后续效率。
总结
YAML作为K8s资源配置的“通用语言”,其语法规范性、字段正确性直接决定了资源的正常运行。本文从语法基础到实战案例,再到Port详解与快速编写技巧,覆盖了YAML在K8s中的核心应用场景。
学习YAML的关键在于“多练+多查”:通过实战案例熟悉字段逻辑,用--dry-run
和导出模板提升效率,遇到问题时借助kubectl explain
获取权威帮助。随着实践深入,你会逐渐掌握YAML的编写规律,进而更高效地管理K8s集群资源。