k8s

k8s-yaml配置文件

1、Redis Deployment部署示例yaml

先来看一个部署yaml示例文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# application/guestbook/redis-master-deployment.yaml 
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: redis-master
labels:
app: redis
spec:
selector:
matchLabels:
app: redis
role: master
tier: backend
replicas: 1
template:
metadata:
labels:
app: redis
role: master
tier: backend
spec:
containers:
- name: master
image: redis # or just image: redis
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 6379

通过执行命令kubectl create -f redis-master-deployment.yaml,可以创建1个Redis master Pod。如果我想通过yaml文件创建3个Pod,怎么办?

很简单,只需要将yaml文件中的spec.replicas设置为3即可,那么一个yaml文件可以控制什么呢?

我们通过四个模块简单的介绍一下k8s使用的yaml配置文件,当然了也可以使用json格式,毕竟kubectl是把yaml文件转换成json文件之后再发送给kube-apiServer的。

2、apiVersion模块

为啥要在这引入一个apiVersion?apiVersion跟软件版本有没有关系?…

一个简单的命令,能够引出很多问题,但是回答问题,需要一个一个来。

首先,k8s是master-node架构模式,master上一般不运行kubelet(要是机器牛逼也可以的哈),只负责资源的管理和调度等等工作。我们使用kubectl的时候,实际是在跟master节点上的kube-apiServer进行通信,所有的请求提交到kube-apiServer,而kubectl跟kube-apiServer的通信实际上是一次http请求,我们使用curl命令可以进行简单的测试就可以证实这一点。

其次,k8s整体版本已经升级到1.16,版本升级带来可以操控资源的变动,开发者期待增加新的资源,以面对不同场景的需求,但是已经存在的客户端怎么办了,武断的直接升级,会破坏兼容性,所以,引入apiVersion可以保证兼容性。

所以使用apiVersion既可以保证兼容性,又可以兼顾实现层面的问题。So,next one!

apiVersion跟软件的Version是没有直接关系的,apiVersion可能存在好几个版本中。不同级别的apiVersion,意味着不同的稳定性和支持度。apiVersion的级别如下:

序号 版本 备注
1 alpha 名称中包含alpha,可能存在bug,版本特性可能被丢弃,后续版本可能不兼容,测试环境使用
2 beta 名称中包含beta,代码经过测试,版本特性不会丢弃,实现层面可能变动,非商业环境使用
3 stable 名称中包含vX,X是一个整数

为了扩展k8s api方便,开发人员实现了API groups。API groups在rest路径中指定,而在apiVersion中是一个序列化的对象。目前使用的API groups包含:

1、核心组:rest路径是/api/v1,apiVersion中是v1

2、命名组:rest路径是/apis/$GROUP_NAME/$VERSION,apiVersion中是$GROUP_NAME/$VERSION

有老铁可能发现了,你这示例给的apps/v1,apps是啥了?apps就是一个命名组的名称,表示功能和k8s运行的应用有关联,比如说Deployments, RollingUpdates, and ReplicaSets。当然同一个路径下可能包含多种类型的资源,所以k8s为了区别具体的区别,使用了kind标识具体的资源类型。

3、kind模块

kind字段用于标识资源类型,那么k8s支持的资源类型有哪些了?

太多了,不一一列举了。提几个常用的,比如Deployment、ReplicaController、Pod和Service等等。现在我们创建了一个对象,我们想给她一个名字,怎么办?

4、metadata模块

显示,metadata模块可以满足我们的这个需求,metadata.name就是描述我们刚刚创建的对象的名称,当然k8s还有其他的metadata需要描述,比如metadata.namespace,默认为default,metadata.uid不需要手动填写,系统自动生成。这几个要么必须填写,要么系统生成,是必备硬货。为了方便用户组织资源,metadata提供labels字段,可以组织和分类对象。label是一个键值对,labels可以同时又多个label,逗号分隔。还有其他字段,就不细说了。

好,上面三个模块基本描述了我要创建一个什么样的对象,那具体咋实现了?假设我们有两个时间点,当前时间和最终时间。我们需要一个模块去描述最终时间点资源对象的状态,这就是spec模块的活。

5、spec模块

额,这个模块就是干脏活、累活的。

创建的对象牛不牛逼,就看在这咋写了。

既然spec是写最终时间点资源对象的状态,我们可以这样描述:我想要3个黄色的、标准大小的红双喜乒乓球。这里乒乓球我们要红双喜的,数量是三个,性质是黄色的、标准大小的。所以spec.selector就是选择哪个牌子的乒乓球,spec.replicas是乒乓球的数量,spec.template则描述乒乓球的具体属性信息。看来template还是实现最终状态的关键,模板template就是用来制作红双喜黄色、标准大小乒乓球的。每个被制造的乒乓球都具有相同的元信息、制作过程和功能,k8s用spec.template.metadata描述元信息,spec.template.spec描述制作过程。在k8s的底层使用的是容器技术,所以spec.template.spec实际描述怎么创建一个容器,如果kind是Service,是没有spec.template.spec字段的。当然,spec下面还有其他字段,需要根据apiVersion和kind进行适配,这里就不细说了。

所以,yaml文件描述了如何创建一个资源对象。apiVersion指定了创建资源对象使用的k8s API版本,kind指定了类型,metadata唯一的描述了资源对象,spec描述了最终时间点资源对象的状态。

嗯,看完这个,是可以照猫画虎了,但还是有点懵。为了不再懵圈,接下来,是时候好好研究研究k8s的架构和底层实现了。下次见!!!

分享到