K8S(五)—— K8s中YAML文件全方位解析:语法、案例、Port详解与快速编写技巧

文章目录

  • 前言
  • 一、K8s配置文件格式对比:YAML与JSON
  • 二、YAML语法格式详解
    • [2.1 核心语法规则](#2.1 核心语法规则)
    • [2.2 语法示例(简单YAML结构)](#2.2 语法示例(简单YAML结构))
  • [三、查看K8s API版本(资源清单基础)](#三、查看K8s API版本(资源清单基础))
    • [3.1 查看集群支持的API版本](#3.1 查看集群支持的API版本)
    • [3.2 API版本选择原则](#3.2 API版本选择原则)
  • 四、K8s资源清单实战:Deployment与Service
    • [4.1 案例1:Deployment资源(管理Pod副本)](#4.1 案例1:Deployment资源(管理Pod副本))
      • [4.1.1 编写Deployment YAML文件](#4.1.1 编写Deployment YAML文件)
      • [4.1.2 创建与验证Deployment](#4.1.2 创建与验证Deployment)
    • [4.2 案例2:Service资源(对外暴露访问)](#4.2 案例2:Service资源(对外暴露访问))
      • [4.2.1 编写Service YAML文件](#4.2.1 编写Service YAML文件)
      • [4.2.2 创建与验证Service](#4.2.2 创建与验证Service)
  • 五、K8s中4类Port详解:port、nodePort、targetPort、containerPort
    • [5.1 核心Port定义与用途](#5.1 核心Port定义与用途)
    • [5.2 流量转发流程](#5.2 流量转发流程)
  • 六、快速编写YAML文件的3种实用技巧
    • [6.1 技巧1:用`--dry-run`生成模板](#6.1 技巧1:用--dry-run生成模板)
      • [6.1.1 生成Pod模板](#6.1.1 生成Pod模板)
      • [6.1.2 生成Deployment模板](#6.1.2 生成Deployment模板)
      • [6.1.3 优化模板(删除无用字段)](#6.1.3 优化模板(删除无用字段))
    • [6.2 技巧2:导出现有资源的YAML](#6.2 技巧2:导出现有资源的YAML)
      • [6.2.1 导出Service的YAML](#6.2.1 导出Service的YAML)
      • [6.2.2 导出Deployment的YAML](#6.2.2 导出Deployment的YAML)
    • [6.3 技巧3:用`kubectl explain`查询字段帮助](#6.3 技巧3:用kubectl explain查询字段帮助)
      • [6.3.1 查看Deployment的字段帮助](#6.3.1 查看Deployment的字段帮助)
      • [6.3.2 逐层查询字段](#6.3.2 逐层查询字段)
  • 七、YAML文件学习方法(从入门到熟练)
    • [7.1 阶段1:读懂现有YAML(输入)](#7.1 阶段1:读懂现有YAML(输入))
    • [7.2 阶段2:修改现有YAML(实践)](#7.2 阶段2:修改现有YAML(实践))
    • [7.3 阶段3:独立编写+查帮助(输出)](#7.3 阶段3:独立编写+查帮助(输出))
  • 总结

前言

在Kubernetes(简称K8s)的日常运维与资源管理中,配置文件是连接用户需求与集群执行逻辑的核心载体。K8s支持JSONYAML两种格式的资源配置文件,其中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 核心语法规则

  1. 大小写敏感 :例如Namename代表不同字段,需与K8s资源定义的字段严格匹配(如apiVersion而非apiversion)。
  2. 缩进表示层级 :通过空格缩进体现字段间的父子关系(如metadata下的name需缩进),不支持Tab键(不同编辑器Tab宽度可能不一致,导致格式错乱)。
  3. 缩进空格数灵活:相同层级的字段左侧对齐即可,推荐统一使用"2个空格"作为基础缩进(K8s社区通用习惯)。
  4. 符号后需空格 :特殊符号(冒号:、逗号,、短横杆-)后必须跟1个空格,例如name: nginx(冒号后空格)、- image: nginx(短横杆后空格)。
  5. 文件分隔符---表示YAML文件的开始,若一个文件中定义多个资源(如同时定义Deployment和Service),可通过---分隔不同资源块。
  6. 注释语法#开头的内容为注释,注释仅作用于单行,K8s解析时会忽略注释内容(推荐为关键字段添加注释,提升可维护性)。

2.2 语法示例(简单YAML结构)

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版本,示例输出如下:

bash 复制代码
kubectl api-versions
# 部分输出如下
admissionregistration.k8s.io/v1beta1
apps/v1                # 稳定版(生产环境首选,如Deployment属于此类)
apps/v1beta1           # Beta版(测试特性,不建议生产使用,可能被废弃)
apps/v1beta2
v1                     # 核心API组(如Pod、Service属于此类)

3.2 API版本选择原则

  • 稳定版(无Beta字样) :如apps/v1v1,特性成熟、兼容性有保障,生产环境必须使用
  • 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文件:

bash 复制代码
mkdir -p /opt/demo && cd /opt/demo
vim nginx-deployment.yaml

2、编写YAML内容(关键字段已加注释):

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: nginx
    spec:
      containers:				#定义容器属性
      - name: nginx				#定义一个容器名,一个 - name: 定义一个容器
        image: nginx:1.15.4		#定义容器使用的镜像以及版本
        ports:
        - containerPort: 80		#定义容器的对外的端口

4.1.2 创建与验证Deployment

1、执行YAML文件创建Deployment:

bash 复制代码
kubectl create -f nginx-deployment.yaml
# 输出:deployment.apps/nginx-deployment created

2、查看创建的Pod副本(验证是否正常运行):

bash 复制代码
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>
  • READY1/1表示Pod内1个容器正常运行。
  • STATUSRunning表示Pod已就绪。
  • IP:Pod的内部IP(仅集群内可访问)。

4.2 案例2:Service资源(对外暴露访问)

Deployment创建的Pod仅能在K8s集群内部访问,需通过Service资源对外暴露端口,实现外部流量访问Pod。

4.2.1 编写Service YAML文件

1、新建Service YAML文件:

bash 复制代码
vim nginx-service.yaml

2、编写YAML内容(选择NodePort类型,支持外部访问):

yaml 复制代码
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:

bash 复制代码
kubectl create -f nginx-service.yaml
# 输出:service/nginx-service created

2、查看Service信息(获取NodePort端口):

bash 复制代码
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,例如:

bash 复制代码
# 终端访问示例(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模板

bash 复制代码
# 生成Nginx Pod的YAML模板,输出到文件
kubectl run nginx-test --image=nginx --port=80 --dry-run=client -o yaml > nginx-test.yaml

6.1.2 生成Deployment模板

bash 复制代码
# 生成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: nullresources: {}status: {}等无用字段,需手动删除,优化后示例:

yaml 复制代码
vim nginx-test.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: nginx-test
  name: nginx-test
spec:
  containers:
  - image: nginx
    name: nginx-test
    ports:
    - containerPort: 80
  dnsPolicy: ClusterFirst
  restartPolicy: Always

6.2 技巧2:导出现有资源的YAML

若集群中已存在同类资源,可通过kubectl get命令导出其YAML,修改后复用(适合复杂资源的快速复制)。

6.2.1 导出Service的YAML

bash 复制代码
# 导出名为nginx-service的Service YAML,保存到文件
kubectl get svc nginx-service -o yaml > my-svc.yaml

6.2.2 导出Deployment的YAML

bash 复制代码
kubectl get deployment nginx-deployment -o yaml > my-deploy.yaml

6.3 技巧3:用kubectl explain查询字段帮助

遇到不熟悉的字段时,通过kubectl explain可逐层查看字段的定义、类型及说明,避免语法错误。

6.3.1 查看Deployment的字段帮助

bash 复制代码
# 查看Deployment的spec.template.spec.containers字段(容器配置相关)
kubectl explain deployments.spec.template.spec.containers

6.3.2 逐层查询字段

若需更细致的帮助,可逐层深入字段,例如:

bash 复制代码
# 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.matchLabelstemplate.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集群资源。

相关推荐
小诸葛的博客3 小时前
详解istio mtls双向身份认证
云原生·istio
2301_787328496 小时前
24.集群及高可用-Keepalived
linux·运维·云原生
java_logo6 小时前
n8n Docker 部署手册
运维·docker·容器
张忠琳6 小时前
volcano scheduler v1.3.0源码分析之启动流程
云原生·kubernetes·volcano
東雪蓮☆8 小时前
K8S 概念、安装与核心工作机制详解
linux·运维·云原生·容器·kubernetes
安安csdn9 小时前
k8s存储juicefs简介
docker·容器·kubernetes
张忠琳9 小时前
【kubernetes/k8s源码分析】kube-controller-manager之node controller源码分析
云原生·容器·kubernetes
bxlj_jcj9 小时前
K8S原理刨析
云原生·容器·kubernetes
筑梦之路10 小时前
etcd节点噶了导致的k8s集群瘫痪处理参考——筑梦之路
docker·kubernetes·etcd