写在前面
本文一起看下如何通过声明式的yaml文件来创建pod。
1:命令式和声明式
命令式就是具体告诉计算机做什么,比如我们写的Java代码,Dockerfile定义FROM,COPY,CMD,RUN,Expose等语句,这都是命令式。那么什么是声明式呢,声明式与命令式刚好相反,不需要具体每一步怎么做怎么做,只需要告知要什么就行了。以打车作为例子,你要到东单逛街,但是出租车师傅不熟悉路况,告知目的地后,其就要跟着导航,导航让他左拐他左拐,导航让他右拐,他右拐,这就是命令式的,导航一直在命令出租车师傅,但是如果是出租车师傅是一个本地通,我们只需要告知目的地,这个过程就变成了,司机自己一路走小道,走红灯最少的路,用最少的时间把我们送到东单,这对应的就是声明式,我们只是声明了目的地
,具体的执行就完全交给出租车师傅了。
2:yaml
因为k8s的声明文件是通过yaml来定义的,所以我们简单来看下yaml的基础内容。yaml 是2001创建的,比xml晚了3年,但是其要比xml更加简单清晰,不管是对人类还是对于计算机都更加友好。支持常见的数据类型,如整数,浮点数,布尔,数组等,简单说明如下:
使用空白与缩进表示层次(有点类似 Python),可以不使用花括号和方括号。
可以使用 # 书写注释,比起 JSON 是很大的改进。
对象(字典)的格式与 JSON 基本相同,但 Key 不需要使用双引号。
数组(列表)是使用 - 开头的清单形式(有点类似 MarkDown)。
表示对象的 : 和表示数组的 - 后面都必须要有空格。
可以使用 --- 在一个文件里分隔多个 YAML 对象。
下面看些实际的例子。
- 数组
# YAML数组(列表)
OS:
- linux
- macOS
- Windows
转换为json如下图:
- 对象
声明了1个master node,3个worker node:
# YAML对象(字典)
Kubernetes:
master: 1
worker: 3
转换为json如下图:
- 数组和对象
# 复杂的例子,组合数组和对象
Kubernetes:
master:
- apiserver: running
- etcd: running
node:
- kubelet: running
- kube-proxy: down
- container-runtime: [docker, containerd, cri-o]
转换 为json如下图:
关于yaml详细可参考下图:
3:k8s的yaml中都可以定义哪些内容
我们知道可通过在yaml配置文件中以声明式的方式来定义一些内容,从而让k8s执行某些工作(其中创建Pod就是其中的一个,也可通过kubectl run ngx --image=nginx:alpine)
,那么都能声明哪些内容呢?可以声明的内容我们可以通过命令kubectl api-resources
来查看,如下:
这一行一行的内容都是啥?这些是k8s提供给我对其进行运维的资源,比如Pod,就是来创建Pod的资源,而因为这些信息最终都需要通过apiserver来发送到k8s集群中,所以k8s给这些项目起了一个名字,叫做API 对象
,即要在apiserver接口中用到的对象。
4:基于yaml启动Pod
接下来我们就以启动Pod为例来看下如何定义yaml,比如定义如下文件:
apiVersion: v1
kind: Pod
metadata:
name: ngx-pod
labels:
env: demo
owner: chrono
spec:
containers:
- image: nginx:alpine
name: ngx1111
ports:
- containerPort: 80
其对应的json如下图:
我们先来看apiVersion
,kind
,metadata
,apiVersion定义当前API的版本,kind定义API的类型,metadata定义元信息,这些信息也可以在kubectl api-resources
命令的结果中获取,如下图:
接着看下spec
部分,这部分定义了要启动的容器数组,都定义完毕之后,我们就可以通过kubectl apply -f fielname.yml
命令来启动容器了,如下:
到这里基于yaml定义Pod我们就成功了,但是我想此时你肯定有一个疑问,我已经知道了我要定义的API对象类型是Pod,我怎么知道可以定义什么呢?我怎么知道要定义spec
,又怎么知道spec下要定义什么呢?接下来我们就一起看下这部分内容。
5:如何确定可以定义的内容
我们依然还是以定义Pod为例来看下。
5.1:通过官方文档
在这里 有管理API对象的详细内容,比如定义Pod,我们就可以点击下图位置:
进入之后就可以看Pod中可以定义的内容,与我们前面已经完成的yaml对比如下图:
如果想要继续查看metadata可以定义的内容,则可点击其右侧的(ObjectMeta)
超链接,同样对比yaml如下:
其他的API对象也都可按照这种方式来查找。
5.2:kubectl explain
这是k8s提供的命令行方式API对象使用说明,比如要查看Pod,则执行如下命令:
如果想要继续查看metadata可以定义的内容,则执行kubectl explain po.spec
,同样对比yaml如下:
5.3:生成模板
通过kubectl run ngx --image=nginx:alpine --dry-run=client -o yaml
直接生成模板,--dry-run=client
代表空执行,只生成yaml结果但是不发送到apiserver,如下:
dongyunqi@dongyunqi-virtual-machine:~$ kubectl run ngx --image=nginx:alpine --dry-run=client -o 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,并在此基础上看了使用yaml如何定义k8s提供的各种API对象,并重点通过Pod API对象进行了详细的说明,最后分析了编写k8s yaml文件可以参考的方法。由于在k8s的实际使用中,一般都是通过yaml的方式来对k8s进行各种运维工作的,所以这部分内容是我们必须要重点进行掌握的。
多知道一点
查看kubectl和apiserver的交互过程
通过增加--v=9
,如下: