首页 > 其他分享 >如何编写Kubernetes的YAML(一)

如何编写Kubernetes的YAML(一)

时间:2023-03-05 22:22:05浏览次数:62  
标签:kubectl Kubernetes v1 对象 YAML API 编写 Pod metadata

什么是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”包含的是 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 applykubectl 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

标签:kubectl,Kubernetes,v1,对象,YAML,API,编写,Pod,metadata
From: https://www.cnblogs.com/niuben/p/17180056.html

相关文章

  • Kubernetes(k8s)权限管理RBAC详解
    一、简介kubernetes集群相关所有的交互都通过apiserver来完成,对于这样集中式管理的系统来说,权限管理尤其重要,在1.5版的时候引入了RBAC(RoleBaseAccessControl)的权限......
  • Kubernetes的工作机制
    云计算时代的操作系统Kubernetes是一个生产级别的容器编排平台和集群管理系统,能够创建、调度容器,监控、管理服务器。Kubernetes的基本架构操作系统的一个重要功能就是......
  • K8S CKA 1.26 模拟环境 实验环境(一键导入) Kubernetest v1.26题库
    K8SCKA1.26考试环境,按照CKA最新原题搭建的,模拟环境已集成考题,可直接模拟练习,做题实操。资料包含:2023年3月最新题库+答案解析+考试笔记+模拟环境+技术支持+在线辅导答疑......
  • minikube搭建Kubernetes环境
    前言Kubernetes一般都运行在大规模的计算集群上,管理很严格,Kubernetes充分考虑到了这方面的需求,提供了一些快速搭建Kubernetes环境的工具。minikube它是一个“迷你”......
  • 如何编写正确高效的Dockerfile
    Dockerfile是什么Dockerfile非常普通,它就是一个纯文本,里面记录了一系列的构建指令,比如选择基础镜像、拷贝文件、运行脚本等等,RUN,COPY,ADD指令都会生成一个Layer,而Do......
  • 在c开发环境下,编写、编译、运行一个简单程序,实现在屏幕上打印一个字符小人
    实验1:源代码#include<stdio.h>intmain(){printf("O\n");printf("<H>\n");printf("II\n");return0;} 运行实验1.2:源代码#i......
  • KCL 语言和 YAML 字符串的区别是什么?一文完全解答
    什么是YAMLYAML是一种数据序列化语言,通常用于编写配置文件。YAML代表另一种标记语言或YAML不是标记语言(递归首字母缩写词),YAML通常用于数据,而不是文档。YAML还是一种......
  • 有什么很好的软件是用 Qt 编写的?
    作者:闫有尽意无琼链接:https://www.zhihu.com/question/19630324/answer/2541042064来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。再补......
  • 使用sealos工具安装kubernetes集群
    一、安装前准备1.1、主机规划IP系统角色主机名192.168.80.7CentOS7.6masterk8s-master-1192.168.80.17CentOS7.6nodek8s-master-2192.168.80.27......
  • python 在编写库需要调用自己内部的文件
    ChatGPT回答:如果你的库需要调用自己内部的文件,可以使用相对路径来引用这些文件。假设你的库名为mylib,它的文件结构如下:mylib/__init__.pymodule1.pydata......