如何编写Kubernetes的YAML(一)
什么是API对象
作为一个集群操作系统,Kubernetes 归纳总结了 Google 多年的经验,在理论层面抽象出了很多个概念,用来描述系统的管理运维工作,这些概念就叫做“API 对象”。
因为 apiserver 是 Kubernetes 系统的唯一入口,外部用户和内部组件都必须和它通信,而它采用了 HTTP 协议的 URL 资源理念,API 风格也用 RESTful 的 GET/POST/DELETE 等等,所以,这些概念很自然地就被称为是“API 对象”了。
你可以使用 kubectl api-resources
来查看当前 Kubernetes 版本支持的所有对象:
$ kubectl api-resources
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings v1 true Binding
configmaps cm v1 true ConfigMap
namespaces ns v1 false Namespace
nodes no v1 false Node
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
persistentvolumes pv v1 false PersistentVolume
pods po v1 true Pod
services svc v1 true Service
...
在输出的“NAME”一栏,就是对象的名字,比如 ConfigMap、Pod、Service 等等,第二栏“SHORTNAMES”则是这种资源的简写,在我们使用 kubectl 命令的时候很有用,可以少敲几次键盘,比如 Pod 可以简写成 po,Service 可以简写成 svc。
在使用 kubectl 命令的时候,你还可以加上一个参数 --v=9
,它会显示出详细的命令执行过程,清楚地看到发出的 HTTP 请求,比如:
$ kubectl get pod --v=9
I0305 10:09:13.170728 14747 loader.go:372] Config loaded from file: /Users/niuben/.kube/config
I0305 10:09:13.174187 14747 cert_rotation.go:137] Starting client certificate rotation controller
I0305 10:09:13.185102 14747 round_trippers.go:435] curl -v -XGET -H "Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json" -H "User-Agent: kubectl/v1.22.5 (darwin/amd64) kubernetes/5c99e2a" 'https://127.0.0.1:60754/api/v1/namespaces/default/pods?limit=500'
I0305 10:09:13.202710 14747 round_trippers.go:454] GET https://127.0.0.1:60754/api/v1/namespaces/default/pods?limit=500 200 OK in 17 milliseconds
I0305 10:09:13.202729 14747 round_trippers.go:460] Response Headers:
I0305 10:09:13.202734 14747 round_trippers.go:463] Audit-Id: 44a71844-55c4-44e8-81cf-e2755f408d70
I0305 10:09:13.202738 14747 round_trippers.go:463] Cache-Control: no-cache, private
I0305 10:09:13.202741 14747 round_trippers.go:463] Content-Type: application/json
I0305 10:09:13.202744 14747 round_trippers.go:463] X-Kubernetes-Pf-Flowschema-Uid: c869356b-2a64-4f9b-b761-8648d9bf1512
I0305 10:09:13.202747 14747 round_trippers.go:463] X-Kubernetes-Pf-Prioritylevel-Uid: d3e9c83e-89b3-4f24-8253-c4267546be71
I0305 10:09:13.202751 14747 round_trippers.go:463] Date: Sun, 05 Mar 2023 02:09:13 GMT
...
可以看到,kubectl 客户端等价于调用了 curl,向 8443 端口发送了 HTTP GET 请求,URL 是 /api/v1/namespaces/default/pods。
目前的 Kubernetes 1.23 版本有 50 多种 API 对象,全面地描述了集群的节点、应用、配置、服务、账号等等信息,apiserver 会把它们都存储在数据库 etcd 里,然后 kubelet、scheduler、controller-manager 等组件通过 apiserver 来操作它们,就在 API 对象这个抽象层次实现了对整个集群的管理。
如何描述 API 对象
因为 API 对象采用标准的 HTTP 协议,为了方便理解,我们可以借鉴一下 HTTP 的报文格式,把 API 对象的描述分成“header”和“body”两部分。
header
“header”包含的是 API 对象的基本信息,有三个字段:apiVersion、kind、metadata。
- apiVersion 表示操作这种资源的 API 版本号,由于 Kubernetes 的迭代速度很快,不同的版本创建的对象会有差异,为了区分这些版本就需要使用 apiVersion 这个字段,比如 v1、v1alpha1、v1beta1 等等。
- kind 表示资源对象的类型,这个应该很好理解,比如 Pod、Node、Job、Service 等等。
- metadata 这个字段顾名思义,表示的是资源的一些“元信息”,也就是用来标记对象,方便 Kubernetes 管理的一些信息。
apiVersion: v1
kind: Pod
metadata:
name: ngx-pod
labels:
env: demo
owner: chrono
比如在这个 YAML 示例里 metadata 就有两个“元信息”,一个是 name,给 Pod 起了个名字叫 ngx-pod,另一个是 labels,给 Pod“贴”上了一些便于查找的标签,分别是 env 和 owner。
apiVersion、kind、metadata 都被 kubectl 用于生成 HTTP 请求发给 apiserver,你可以用 --v=9
参数在请求的 URL 里看到它们,比如:
https://192.168.49.2:8443/api/v1/namespaces/default/pods/ngx-pod
body
和 HTTP 协议一样,“header”里的 apiVersion、kind、metadata 这三个字段是任何对象都必须有的,而“body”部分则会与对象特定相关,每种对象会有不同的规格定义,在 YAML 里就表现为 spec 字段(即 specification),表示我们对对象的“期望状态”(desired status)。
举个例子:
apiVersion: v1
kind: Pod
metadata:
name: ngx-pod
labels:
env: demo
owner: chrono
spec:
containers:
- image: nginx:alpine
name: ngx
ports:
- containerPort: 80
这个 Pod,它的 spec 里就是一个 containers 数组,里面的每个元素又是一个对象,指定了名字、镜像、端口等信息。
现在把这些字段综合起来,我们就能够看出,这份 YAML 文档完整地描述了一个类型是 Pod 的 API 对象,要求使用 v1 版本的 API 接口去管理,其他更具体的名称、标签、状态等细节都记录在了 metadata 和 spec 字段等里。
YAML 创建删除对象
使用 kubectl apply
、kubectl delete
,再加上参数 -f
,你就可以使用这个 YAML 文件,创建或者删除对象了:
kubectl apply -f ngx-pod.yml
kubectl delete -f ngx-pod.yml
Kubernetes 收到这份“声明式”的数据,再根据 HTTP 请求里的 POST/DELETE 等方法,就会自动操作这个资源对象,至于对象在哪个节点上、怎么创建、怎么删除完全不用我们操心。
如何编写 YAML
这么多 API 对象,我们怎么知道该用什么 apiVersion、什么 kind?metadata、spec 里又该写哪些字段呢?还有,YAML 看起来简单,写起来却比较麻烦,缩进对齐很容易搞错,有没有什么简单的方法呢?
这些问题最权威的答案无疑是 Kubernetes 的官方参考文档(https://kubernetes.io/docs/reference/kubernetes-api/),API 对象的所有字段都可以在里面找到。不过官方文档内容太多太细,查阅起来有些费劲,所以介绍下面几个简单实用的小技巧。
第一个技巧
使用 kubectl api-resources
命令,它会显示出资源对象相应的 API 版本和类型,比如 Pod 的版本是“v1”,Ingress 的版本是“networking.k8s.io/v1”,照着它写绝对不会错。
第二个技巧
使用命令 kubectl explain
,它相当于是 Kubernetes 自带的 API 文档,会给出对象字段的详细说明,这样我们就不必去网上查找了。比如想要看 Pod 里的字段该怎么写,就可以这样:
$ kubectl explain pod
$ kubectl explain pod.metadata
$ kubectl explain pod.spec
$ kubectl explain pod.spec.containers
KIND: Pod
VERSION: v1
DESCRIPTION:
Pod is a collection of containers that can run on a host. This resource is
created by clients and scheduled onto hosts.
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 pod. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
status <Object>
Most recently observed status of the pod. This data may not be up to date.
Populated by the system. Read-only. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
...
第三个技巧
使用 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 文件:
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: {}
接下来你要做的,就是查阅对象的说明文档,添加或者删除字段来定制这个 YAML 了。
这个小技巧还可以再进化一下,把这段参数定义成 Shell 变量(名字任意,比如\(do/\)go,这里用的是$out),用起来会更省事,比如:
export out="--dry-run=client -o yaml"
kubectl run ngx --image=nginx:alpine $out
如何编写Kubernetes的YAML(一)的更多相关文章
- 新手学习FFmpeg - 如何编写Kubernetes资源文件
Kubernetes API的使用方式 Kubernetes API属于声明式API编程, 它和常用的命令式编程有一些区别. 通俗的说,命令式编程是第一人称,我要做什么,我要怎么做. 操作系统最喜欢这 ...
- Kubernetes之YAML文件
一.YAML 基础 YAML是专门用来写配置文件的语言,非常简洁和强大,使用比json更方便.它实质上是一种通用的数据串行化格式.后文会说明定义YAML文件创建Pod和创建Deployment. YA ...
- kubernetes创建yaml,pod服务一直处于 ContainerCreating状态的原因查找与解决
最近刚刚入手研究kubernetes,运行容器的时候,发现一直处于ContainerCreating状态,悲了个催,刚入手就遇到了点麻烦,下面来讲讲如何查找问题及解决的 运行容器命令: kubectl ...
- [docker]Kubernetes的yaml文件
yaml是一种专门用来写配置的语言,简洁强大 它的规则: 1.大小写敏感 2.使用缩进表示层级关系,但不支持tab缩进,只支持空格 3.缩进的数量不重要但至少一个空格,只要相同层级使用相同数量的空格即 ...
- kubernetes 简单yaml文件运行例子deployment
运行一个deployment: kubectl run nginx-deployment --image=nginx:1.7.9 --replicas=2 基本例子: nginx-test.y ...
- kubernetes内yaml格式
yaml格式的pod定义文件完整内容: apiVersion: v1 #必选,版本号,例如v1 可通过 kubectl api-versions 获取 kind: Pod #必选,Pod metada ...
- Kubernetes的YAML文件
deployments: - apiVersion: apps/v1beta1 kind: Deployment metadata: labels: system_serviceUnit: bas-b ...
- Kubernetes的yaml文件中command的使用
前面说了init容器initContainers,这主要是为应用容器做前期准备工作的,一般都会用到shell脚本,这就会用到command,这里写写command的用法. command就是将命令在创 ...
- K8s小白?应用部署太难?看这篇就够了!
在云原生趋势下,容器和 Kubernetes 可谓是家喻户晓,许多企业内部的研发团队都在使用 Kubernetes 打造 DevOps 平台.从最早的容器概念到 Kubernetes 再到 DevOp ...
- 如何不编写 YAML 管理 Kubernetes 应用?
Kubernetes 将自身边界内的事物都抽象为资源.其中的主要部分,是以 Deployment.StatefulSet 为代表的 workload 工作负载控制器,其他各类资源都围绕这些主要的资源工 ...
随机推荐
- Python__FLASK__MySQL基础
1.数据库的基本操作 创建数据库:使用"CREATE DATABASE 数据库名:"语句创建新的数据库 查看数据库:使用"SHOW DATABASES:"语句查 ...
- Qt音视频开发38-ffmpeg视频暂停录制的设计
一.前言 基本上各种播放器提供的录制视频接口,都是只有开始录制和结束录制两个,当然一般用的最多的也是这两个接口,但是实际使用过程中,还有一种可能需要中途暂停录制,暂停以后再次继续录制,将中间部分视频不 ...
- Windows 配置多版本JDK
@ 目录 前言 简介 一.下载并安装多个JDK版本 二.配置环境变量 2.1 点击高级系统设置 2.2 选择环境变量 2.3 配置CLASSPATH 2.4 配置JAVA_HOME 2.5 配置Pat ...
- Git Permission denied
问题现象 家里电脑 git pull 项目时,提示:Permission denied,ssh -T 测试又是正常的,如下图 同样配置和密钥,在公司电脑就可以正常 pull .push . 问题原因 ...
- KMS for Office 2021
I. 镜像下载 官方镜像下载地址: Office 2021 专业增强版: https://officecdn.microsoft.com/pr/492350f6-3a01-4f97-b9c0-c7c6 ...
- 视频分析框架VideoPipe完整介绍
(2024年4月编写) github地址 https://github.com/sherlockchou86/video_pipe_c 作者微信 zhzhi78(备注 videopipe),拉群交流( ...
- Note -「M. Analysis 24 Aut. Prev.」“有歌的地方,自有向往”
\[\textit{Litar!} \newcommand{\opn}[1]{\operatorname{#1}} \newcommand{\card}[0]{\opn{card}} \newcomm ...
- 连接Redis 错误的解决方法: It was not possible to connect to the redis server(s); to create a disconnected multiplexer
The error you are getting is usually a sign that you have not set abortConnect=false in your connect ...
- Spring Cloud认知学习(一)--Eureka使用、Ribbon使用
Spring Cloud是一个微服务架构,他有多种组件来管理微服务的方方面面.Spring Cloud是用于构建微服务开发和治理的框架的集合. Spring Cloud是最热门的Java技术毋庸置疑. ...
- Linux系统安全限制:禁用或限制用户ssh登录(sshd_config、hosts.allow、hosts.deny、nologin、passwd)
我们知道Linux系统安全性设置有很多方式.常见的有通过firewall防火墙.或者iptables规则实现放行.拦截屏蔽某些特征的网络请求.示例:iptables限制ssh链接服务器 还有一 ...