04 YAML kubetnetes世界里的通用语

news2025/1/20 13:23:58

文章目录

  • 1. 前言
  • 2. 声明式和命令式是怎么回事?
  • 3. 什么是YAML?
  • 4. 什么是API对象?
    • 4.1 k8s都有哪些资源对象
    • 4.2 列出kubectl 命令详细执行过程
  • 5. 如何描述 API 对象
    • 5.1 命令式
    • 5.2 声明式
      • 5.2.1 声明式YAML语法详解
        • 5.2.1.1 header部分详解
        • 5.2.1.2 body部分详解
        • 5.2.1.3 创建或删除对象
        • 5.2.1.4 创建或删除对象原理
  • 6. 如何编写YAML及技巧
    • 6.1 kubectl api-resources 命令
    • 6.2 kubectl explain 命令
    • 6.3 -o yaml 参数生成YAML 文件
  • 7. YAML 小结
  • 8 思考
    • 8.1 你是如何理解“命令式”和“声明式”的?为什么说空调是“声明式”的?
    • 8.2 使用 --v=9 参数,试着解释一下 YAML 是如何被 kubectl 转换成 HTTP 请求的

1. 前言

我们一起研究了 Kubernetes 的内部架构和组成,知道它分为控制面和数据面。控制面管理集群,数据面跑业务应用,节点内部又有 apiserver、etcd、scheduler、kubelet、kube-proxy 等组件,它们互相协作来维护整个集群的稳定运行。

这套独特的 Master/Node 架构是 Kubernetes 得以安身立命的根本,但仅依靠这套“内功心法”是不是就能够随意仗剑走天涯了呢?

显然不行。就像许多武侠、玄幻作品里的人物一样,Kubernetes 也需要一份“招式秘籍”才能把自己的“内功”完全发挥出来,只有内外兼修才能够达到笑傲江湖的境界。

而这份“招式秘籍”,就是 Kubernetes 世界里的标准工作语言 YAML,所以今天,我就来讲讲为什么要有 YAML、它是个什么样子、该怎么使用。

2. 声明式和命令式是怎么回事?

Kubernetes 使用的 YAML 语言有一个非常关键的特性,叫“声明式”(Declarative),对应的有另外一个词:“命令式”(Imperative)。

  • 命令式
    大多数编程语言也属于命令式,它的特点是交互性强,注重顺序和过程,你必须“告诉”计算机每步该做什么,所有的步骤都列清楚,这样程序才能够一步步走下去,最后完成任务,显得计算机有点“笨”。
  • 声明式
    在 Kubernetes 出现之前比较少见,它与“命令式”完全相反,不关心具体的过程,更注重结果。我们不需要“教”计算机该怎么做,只要告诉它一个目标状态,它自己就会想办法去完成任务,相比起来自动化、智能化程度更高。

举个栗子:

假设你要打车去高铁站,但司机不熟悉路况,你就只好不厌其烦地告诉他该走哪条路、
在哪个路口转向、在哪里进出主路、停哪个站口。虽然最后到达了目的地,但这一
路上也费了很多口舌,发出了无数的“命令”。很显然,这段路程就属于“命令式”。

现在我们来换一种方式,同样是去高铁站,但司机经验丰富,他知道哪里有拥堵
、哪条路的红绿灯多、哪段路有临时管控、哪里可以抄小道,此时你再多嘴无疑
会干扰他的正常驾驶,所以,你只要给他一个“声明”:我要去高铁站,接下来
就可以舒舒服服地躺在后座上休息,顺利到达目的地了。

在这里插入图片描述
在这个“打车”的例子里,Kubernetes 就是这样的一位熟练的司机,Master/Node 架构让它对整个集群的状态了如指掌,内部的众多组件和插件也能够自动监控管理应用。

这个时候我们再用“命令式”跟它打交道就不太合适了,因为它知道的信息比我们更多更全面,不需要我们这个外行去指导它这个内行,所以我们最好是做一个“甩手掌柜”,用“声明式”把任务的目标告诉它,比如使用哪个镜像、什么时候运行,让它自己去处理执行过程中的细节。

3. 什么是YAML?

你需要知道,YAML 是 JSON 的超集,支持整数、浮点数、布尔、字符串、数组和对象等数据类型。也就是说,任何合法的 JSON 文档也都是 YAML 文档,如果你了解 JSON,那么学习 YAML 会容易很多。
但和 JSON 比起来,YAML 的语法更简单,形式也更清晰紧凑,比如:

  • 使用空白与缩进表示层次(有点类似 Python),可以不使用花括号和方括号。
  • 可以使用 # 书写注释,比起 JSON 是很大的改进。
  • 对象(字典)的格式与 JSON 基本相同,但 Key 不需要使用双引号。
  • 数组(列表)是使用 - 开头的清单形式(有点类似 MarkDown)。
  • 表示对象的 : 和表示数组的 - 后面都必须要有空格。
  • 可以使用 — 在一个文件里分隔多个 YAML 对象。
    下面我们来看几个 YAML 的简单示例。
    首先是数组,它使用 - 列出了三种操作系统:

# YAML数组(列表)
OS:
  - linux
  - macOS
  - Windows
#这段 YAML 对应的 JSON 如下:

{
  "OS": ["linux", "macOS", "Windows"]
}

对比可以看到 YAML 形式上很简单,没有闭合花括号、方括号的麻烦,每个元素后面也不需要逗号。YAML 里的 Key 都不需要使用双引号,看起来更舒服。

4. 什么是API对象?

作为一个集群操作系统,Kubernetes 归纳总结了 Google 多年的经验,在理论层面抽象出了很多个概念,用来描述系统的管理运维工作,这些概念就叫做“API 对象”。说到这个名字,你也许会联想到 Kubernetes 组件 apiserver。没错,它正是来源于此。

因为 apiserver 是 Kubernetes 系统的唯一入口,外部用户和内部组件都必须和它通信,而它采用了 HTTP 协议的 URL 资源理念,API 风格也用 RESTful 的 GET/POST/DELETE 等等,所以,这些概念很自然地就被称为是“API 对象”了。

4.1 k8s都有哪些资源对象

kubectl api-resources 来查看当前 Kubernetes 版本支持的所有对象:

kubectl api-resources

在输出的“NAME”一栏,就是对象的名字,比如 ConfigMap、Pod、Service 等等。
第二栏“SHORTNAMES”则是这种资源的简写,在我们使用 kubectl 命令的时候很有用,可以少敲几次键盘,比如 Pod 可以简写成 po,Service 可以简写成 svc。

目前的 Kubernetes 1.23 版本有 50 多种 API 对象,全面地描述了集群的节点、应用、配置、服务、账号等等信息,apiserver 会把它们都存储在数据库 etcd 里,然后 kubelet、scheduler、controller-manager 等组件通过 apiserver 来操作它们,就在 API 对象这个抽象层次实现了对整个集群的管理。
在这里插入图片描述

4.2 列出kubectl 命令详细执行过程

从截图里可以看到,kubectl 客户端等价于调用了 curl,向 8443 端口发送了 HTTP GET 请求,URL 是 /api/v1/namespaces/default/pods。

kubectl get pod --v=9

在这里插入图片描述

5. 如何描述 API 对象

5.1 命令式

现在我们就来看看如何以 YAML 语言,使用“声明式”在 Kubernetes 里描述并创建 API 对象。
之前我们运行 Nginx 的命令你还记得吗?使用的是 kubectl run,和 Docker 一样是“命令式”的:

kubectl run ngx --image=nginx:alpine

5.2 声明式

把命令式 它改写成“声明式”的 YAML,说清楚我们想要的 Nginx 应用是个什么样子,也就是“目标状态”,让 Kubernetes 自己去决定如何拉取镜像运行:

apiVersion: v1
kind: Pod
metadata:
  name: ngx-pod
  labels:
    env: demo
    owner: chrono

spec:
  containers:
  - image: nginx:alpine
    name: ngx
    ports:
    - containerPort: 80

5.2.1 声明式YAML语法详解

为了方便理解,我们可以借鉴一下 HTTP 的报文格式,把 API 对象的描述分成“header”和“body”两部分。

5.2.1.1 header部分详解

和 HTTP 协议一样,“header”里的 apiVersion、kind、metadata 这三个字段是任何对象都必须有的

“header”包含的是 API 对象的基本信息,有三个字段:apiVersion、kind、metadata。

  • apiVersion 表示操作这种资源的 API 版本号,由于 Kubernetes 的迭代速度很快,不同的版本创建的对象会有差异,为了区分这些版本就需要使用 apiVersion 这个字段,比如 v1、v1alpha1、v1beta1 等等。
  • kind 表示资源对象的类型,这个应该很好理解,比如 Pod、Node、Job、Service 等等。
  • metadata 这个字段顾名思义,表示的是资源的一些“元信息”,也就是用来标记对象,方便 Kubernetes 管理的一些信息。

比如在这个 YAML 示例里就有两个“元信息”,一个是 name,给 Pod 起了个名字叫 ngx-pod,另一个是 labels,给 Pod“贴”上了一些便于查找的标签,分别是 env 和 owner。

apiVersion、kind、metadata 都被 kubectl 用于生成 HTTP 请求发给 apiserver,你可以用 --v=9 参数在请求的 URL 里看到它们,比如:
在这里插入图片描述

5.2.1.2 body部分详解

body”部分则会与对象特定相关,每种对象会有不同的规格定义,在 YAML 里就表现为 spec 字段(即 specification),表示我们对对象的“期望状态”(desired status)。

spec:
  containers:
  - image: nginx:alpine
    name: ngx
    ports:
    - containerPort: 80

还是来看这个 Pod,它的 spec 里就是一个 containers 数组,里面的每个元素又是一个对象,指定了名字、镜像、端口等信息:

5.2.1.3 创建或删除对象

现在把这些字段综合起来,我们就能够看出,这份 YAML 文档完整地描述了一个类型是 Pod 的 API 对象,要求使用 v1 版本的 API 接口去管理,其他更具体的名称、标签、状态等细节都记录在了 metadata 和 spec 字段等里。

使用 kubectl apply、kubectl delete,再加上参数 -f,你就可以使用这个 YAML 文件,创建或者删除对象了:

kubectl apply -f ngx-pod.yml
kubectl delete -f ngx-pod.yml

5.2.1.4 创建或删除对象原理

Kubernetes 收到这份“声明式”的数据,再根据 HTTP 请求里的 POST/DELETE 等方法,就会自动操作这个资源对象,至于对象在哪个节点上、怎么创建、怎么删除完全不用我们操心。

6. 如何编写YAML及技巧

在实际情况中,这么多 API 对象,我们怎么知道该用什么 apiVersion、什么 kind?metadata、spec 里又该写哪些字段呢?还有,YAML 看起来简单,写起来却比较麻烦,缩进对齐很容易搞错,有没有什么简单的方法呢?

这些问题最权威的答案无疑是 Kubernetes 的官方参考文档(https://kubernetes.io/docs/reference/kubernetes-api/),API 对象的所有字段都可以在里面找到。不过官方文档内容太多太细,查阅起来有些费劲,所以下面我就介绍几个简单实用的小技巧。

6.1 kubectl api-resources 命令

它会显示出资源对象相应的 API 版本和类型,比如 Pod 的版本是“v1”,Ingress 的版本是“networking.k8s.io/v1”,照着它写绝对不会错。
在这里插入图片描述

6.2 kubectl explain 命令

它相当于是 Kubernetes 自带的 API 文档,会给出对象字段的详细说明,这样我们就不必去网上查找了。比如想要看 Pod 里的字段该怎么写,就可以这样:

kubectl explain pod
kubectl explain pod.metadata
kubectl explain pod.spec
kubectl explain pod.spec.containers

在这里插入图片描述
使用前两个技巧编写 YAML 就基本上没有难度了。

6.3 -o yaml 参数生成YAML 文件

我们还可以让 kubectl 为我们“代劳”,生成一份“文档样板”,免去我们打字和对齐格式的工作。
这第三个技巧就是 kubectl 的两个特殊参数 --dry-run=client 和 -o yaml,前者是空运行,后者是生成 YAML 格式,结合起来使用就会让 kubectl 不会有实际的创建动作,而只生成 YAML 文件。

例如,想要生成一个 Pod 的 YAML 样板示例,可以在 kubectl run 后面加上这两个参数:

kubectl run ngx --image=nginx:alpine --dry-run=client -o yaml

就会生成一个绝对正确的 YAML 文件:
接下来你要做的,就是查阅对象的说明文档,添加或者删除字段来定制这个 YAML 了

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: ngx
  name: ngx
spec:
  containers:
  - image: nginx:alpine
    name: ngx
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

7. YAML 小结

  1. YAML 是 JSON 的超集,支持数组和对象,能够描述复杂的状态,可读性也很好。
  2. Kubernetes 把集群里的一切资源都定义为 API 对象,通过 RESTful 接口来管理。描述 API 对象需要使用 YAML 语言,必须的字段是 apiVersion、kind、metadata。
  3. 命令 kubectl api-resources 可以查看对象的 apiVersion 和 kind,命令 kubectl explain 可以查看对象字段的说明文档。
  4. 命令 kubectl apply、kubectl delete 发送 HTTP 请求,管理 API 对象。
  5. 使用参数 --dry-run=client -o yaml 可以生成对象的 YAML 模板,简化编写工作

8 思考

8.1 你是如何理解“命令式”和“声明式”的?为什么说空调是“声明式”的?

  1. 命令式更像是自己驾驶车。需要打火启动,调整油门,调整方向盘。一步步对车发出命令,才能到目的地
    声明式像自动驾驶,只需要输入目的地,过程不需要操作。

  2. 空调只需要遥控器设置温度,而主机怎么运行降温,不需要我们关注

8.2 使用 --v=9 参数,试着解释一下 YAML 是如何被 kubectl 转换成 HTTP 请求的

因为YAML 类似HTTP 一样,有header,body部分。好吧,我不会,看下别人的答案

虽然yaml格式是json的超集,但在k8s中的yaml文件最终都是被转换为json格式字符串放在request body中提交到apiserver的.
从`kubectl -v=9`对各种操作的调试中可以看到。除此之外,还发现一些有规律的地方,
可见简单对象如下:(如pod, configmap, secret, serviceaccount等)
调用的接口形式如下:`/api/<apiVersion>/namespaces/<namespace>/kinds>[/<name>]`

其中对象类型为复数形式即`kubectl api-resources`中的name字段
修改、删除与查询具体对象时在URL中有`/<name>`部分,其它如创建、查询所有就没有。
对于复合对象(简单对象的包装对象,如replicaset, deployment, statefulset, cronjob等)的URL不同的是以`/apis`开头,说明是属于复合型的接口(组合服务)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/40957.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【教学类-19-01】20221127《ABAB式-规律排序-A4竖版2份》(中班)

展示效果&#xff1a; 单人使用样式&#xff1a; 单页打印样式 ​ 背景需求&#xff1a; 中班幼儿需要掌握ABAB规律排序&#xff0c;如下图所示&#xff0c;AB两个元素能外形不同、颜色不同。 ​ ​利用Python Word单元格填色功能&#xff0c;随机生成AB样式&#xff0c;引…

STM32模拟IIC与IIC四种实现数字光强采集模块GY30(标准库与HAL库)

目录 代码实现是的IIC通信&#xff0c;数据采集后在串口显示&#xff0c;方便大家实现二次开发 原件选择 GY-30 数字光强度介绍 BH1750芯片参数 引脚说明 BH1750指令集 接线表设计 通过四种方式实现GY-30数据采集 1.标准库模拟IIC实现GY-30采集并串口1显示 2.标准库IIC…

重构uniapp uni-ui coloerUI项目

重构uniapp uni-ui coloerUI项目这里写自定义目录标题重构uniappuni-uicoloerUI项目起源流程重构uniappuni-uicoloerUI项目 起源 从网上复制了若依移动端的代码,但是对里面的文件夹布局方式和第三方组件库引入方式不甚了解,就想着从头创建一个空白项目&#xff0c;然后一步一…

Linux中设置开机启动执行命令和普通用户配置环境变量开机启动生效

记录&#xff1a;343 场景&#xff1a;在CentOS 7.9操作系统上&#xff0c;开机启动就执行自定义的命令&#xff0c;配置rc.local文件达到需求&#xff1b;在普通用户中配置环境变量开机启动生效&#xff0c;使用profile实现。 版本&#xff1a; 操作系统&#xff1a;CentOS…

01、Docker入门

目录 1、Docker是什么 2、Docker与虚拟化 3、Docker虚拟化的好处 好处一&#xff1a;应用部署方便 好处二&#xff1a;服务器同等配置&#xff0c;性能更优&#xff0c;利用率更高 4、核心概念 5、CentOS7 安装docker(在线方式) 6、镜像 7、Docker容器 8、查看Docker容…

typescript 八叉树的简单实现

查了一些文章&#xff0c;准备自己用typescript写一个简单的八叉树场景管理。 所谓的简单&#xff0c;就是所有元素都是边长为1的立方体。 元素类和树节点类 //元素类&#xff0c;因为都是边长为1的立方体&#xff0c;所以就用cube命名 export class CubeData {public reado…

由于没有远程桌面授权服务器可以提供许可证,远程会话连接已断开

一、问题描述 在使用Windows的远程桌面工具连接WindowsServer2016服务器时&#xff0c;无法连接到服务器&#xff0c;并且提示【由于没有远程桌面授权服务器可以提供许可证&#xff0c;远程回来连接已经断开。请跟服务器管理员联系】。 二、解决办法 2.0、前提 Windows Serv…

黑胶歌曲没权限,看我python大展神通,一分钟一个歌单

前言 大家早好、午好、晚好吖 ❤ ~ 人之初&#xff0c;喜白嫖。 大家都喜欢白嫖&#xff0c;我也喜欢&#xff0c;那么今天就来试试怎么白嫖抑云~ 一、需要的准备 1、环境 Python3.6以上 pycharm2019以上 2、模块 requests # 发送请求模块 第三方模块 exec js # 调用JS的…

CocosCreater 教程(下)

1.物理系统 1.1 2D刚体 刚体是组成物理世界的基本对象。 1.2 2D 碰撞组件 目前引擎支持三种不同的碰撞组件&#xff1a; 盒碰撞组件&#xff08;BoxCollider2D&#xff09;、圆形碰撞组件&#xff08;CircleCollider2D&#xff09; 和 多边形碰撞组件&#xff08;PolygonCo…

Java中的抽象类和接口

java中的抽象类和接口抽象类什么是抽象类&#xff1f;抽象的使用场景抽象类的案例抽象类的特征、注意事项小结抽象类的应用知识&#xff1a;模版方法模式接口接口概述、特点接口的基本使用&#xff1a;被实现接口与接口的关系&#xff1a;多继承JDK8开始接口新增方法接口的注意…

AtCoder Beginner Contest 277 F. Sorting a Matrix(拓扑排序+虚点)

题目 n*m(2<n,m<1e6,n*m<1e6)的矩阵&#xff0c; 第i行第j列元素a[i][j](0<a[i][j]<n*m) 对于值为0的元素&#xff0c;你可以将其赋值为任意正整数&#xff0c; 不同位置的0元素&#xff0c;可以被赋值成不同的正整数 然后&#xff0c;你可以执行以下操作若…

firefly3399 移植linux5.15.80 - 2022-11-27

需要注意的是&#xff0c;虚拟机需要足够的硬盘空间&#xff0c;不小于15GB&#xff01;&#xff01; 一、内核源码下载 国内镜像地址 git clone https://kernel.source.codeaurora.cn/pub/scm/linux/kernel/git/stable/linux.git/ 基本达到了带宽的最大值。 国外地址&#…

Android使用AudioTrack播放WAV音频文件

目录 1、wav文件格式 2、wav文件解析 3、wav文件播放 QA&#xff1a; 开始播放wav的时候使用了系统的播放器mediaplayer进行播放&#xff0c;但是无奈mediaplayer支持的实在不好。 好些年前自己做过pcm播放使用的是audiotrack&#xff0c;参考&#xff1a;CSDN 其实两者之…

php 进程池设计与实现,phper必学!

php 进程池设计与实现phper 为什么要学习进程池池的概念为什么要有进程池?动态创建进程缺点进程池的优点选择子进程为新任务服务的方式进程池模型服务端客户端结语phper 为什么要学习进程池 在php开发过程中经常使用的 php-fpm 使用的进程模型就是进程池&#xff0c;学习进程…

如何基于FSM有限状态机实现Enemies AI

文章目录&#x1f35f; Preface&#x1f355; 巡逻状态&#x1f37f; 寻路状态&#x1f32d; 攻击状态&#x1f357; 完整代码&#x1f35f; Preface 本文简单介绍如何基于FSM有限状态机实现Enemies AI&#xff0c;首先定义敌人的AI逻辑&#xff1a;默认状态下Enemy为巡逻状态…

刷爆力扣之等价多米诺骨牌对的数量

刷爆力扣之等价多米诺骨牌对的数量 HELLO&#xff0c;各位看官大大好&#xff0c;我是阿呆 &#x1f648;&#x1f648;&#x1f648; 今天阿呆继续记录下力扣刷题过程&#xff0c;收录在专栏算法中 &#x1f61c;&#x1f61c;&#x1f61c; 该专栏按照不同类别标签进行刷题&…

使用 nlohmann 解析 json 文件

使用 nlohmann 解析 json 文件nlohmann/json的配置json基本数据结构json文件的读取、构造与输出C对象与nlohmann::json对象的转换C对象转换成nlohmann::json对象nlohmann::json对象转换成C对象序列化反序列化序列化nlohmann 是德国工程师&#xff0c;以其名字为工程名的 nlohm…

springboot项目的打包发布部署,jar和war的区别

简介&#xff1a; 1.Spring Boot使用了内嵌容器&#xff0c;因此它的部署方式也变得非常简单灵活&#xff0c;可以将Spring Boot项目打包成JAR包来独立运行&#xff0c;也可以打包成WAR包部署到Tomcat容器中运行&#xff0c;如果涉及大规模的部署&#xff0c;Jenkins成为最佳选…

【HCIP-Datacom】 IS-IS基础 ISIS动态路由协议配置(ISIS思维导图在底部)

目录 ISIS配置方法&#xff1a; 路由计算&#xff1a; ATT置位条件&#xff1a; 路由渗透&#xff1a; ISIS的认证&#xff1a; ISIS配置命令&#xff1a; ISIS的开销类型&#xff1a; ISIS配置方法&#xff1a; 进入ISIS进程 isis 1 //创建isis进程 设置实体名 network-entit…

.NET 升级发布后,IIS出现了System.IO.DirectoryNotFoundException

最近计划升级项目到.NET6, 在使用Release发布后发现IIS不能发现wwwroot目录,什么错误? 📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:无尽的折腾后,终于又回到了起点,工控,我来了 !1 发布的一…