Kuberneters(K8s)CRD简明及简用
########文章仅仅是对官网给出的文档做了一个不入流的翻译-_-以及实操后的个人理解所得,若有存在不足或者不同之处还望各位大神指点,临表涕零
1、K8S CRD简明及简用:
CustomResourceDefinition简介:
在 Kubernetes 中一切都可视为资源,Kubernetes 1.7 之后增加了对 CRD 自定义资源二次开发能力来扩展 Kubernetes API,通过 CRD 我们可以向 Kubernetes API 中增加新资源类型,而不需要修改 Kubernetes 源码或创建自定义的 API server,该功能大大提高了 Kubernetes 的扩展能力。
当你创建一个新的CustomResourceDefinition (CRD)时,Kubernetes API服务器将为你指定的每个版本创建一个新的RESTful资源路径,我们可以根据该api路径来创建一些我们自己定义的类型资源。CRD可以是命名空间的,也可以是集群范围的,由CRD的作用域(scpoe)字段中所指定的,与现有的内置对象一样,删除名称空间将删除该名称空间中的所有自定义对象。customresourcedefinition本身
没有名称空间,所有名称空间都可以使用。
1.1、通过crd资源创建自定义资源,即自定义一个Restful API:
$ vi resourcedefinition.yaml:
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
# 名称必须与下面的spec字段匹配,格式为: <plural>.<group>
name: crontabs.stable.example.com
spec:
# 用于REST API的组名称: /apis/<group>/<version>
group: stable.example.com
# 此CustomResourceDefinition支持的版本列表
versions:
- name: v1
# 每个版本都可以通过服务标志启用/禁用。
served: true
# 必须将一个且只有一个版本标记为存储版本。
storage: true
# 指定crd资源作用范围在命名空间或集群
scope: Namespaced
names:
# URL中使用的复数名称: /apis/<group>/<version>/<plural>
plural: crontabs
# 在CLI(shell界面输入的参数)上用作别名并用于显示的单数名称
singular: crontab
# kind字段使用驼峰命名规则. 资源清单使用如此
kind: CronTab
# 短名称允许短字符串匹配CLI上的资源,意识就是能通过kubectl 在查看资源的时候使用该资源的简名称来获取。
shortNames:
- ct
- 创建自定义contab资源
$ kubectl create -f resourcedefinition.yaml
然后在以下位置创建一个新的带有名称空间的RESTful API端点:
/apis/stable.example.com/v1/namespaces/*/crontabs/...然后我们可以使用该url来创建和管理自定义对象资源。 - 查看自定义contab资源的信息
$ kubectl get contab/ct
1.2、创建自定义资源的对象:
根据crd对象资源创建出来的RESTful API,来创建crontab类型资源对象
$ vi my-crontab.yaml:
apiVersion: "stable.example.com/v1"
kind: CronTab
metadata:
name: my-new-cron-object
spec:
cronSpec: "* * * * */5"
image: my-awesome-cron-image
在创建CustomResourceDefinition对象之后,我们可以创建定制资源的对象。自定义对象可以包含自定义字段。这些字段可以包含任意JSON。上面的例子中cronSpec和image自定义字段设置在CronTab类型的自定义对象中。CronTab类型来自您在上面创建的CustomResourceDefinition对象的规范。
- 创建自定义资源contab资源的对象
$ kubectl create -f my-crontab.yaml
1.3、为自定义资源添加验证:
validation这个验证是为了在创建好自定义资源后,通过该资源创建对象的时候,对象的字段中存在无效值,则创建该对象的请求将被拒绝,否则会被创建。我们可以在crd文件中添加“validation:”字段来添加相应的验证机制。
我们可以通过使用OpenAPI v3 模式来验证我们自定义的资源对象,使用该模式也应用了一些限制:
- default, nullable, discriminator, readOnly, writeOnly, xml, deprecated和$ref不能设置这些字段。
- 字段uniqueItem不能设置为true
- 字段additionalProperties不能设置为false
当然我们可以通过修改kube-apiserver.yml文件来去限制,将kube-apiserver.yml文件中的cusstomresourcevalidation设置为false(--feature-gates=CustomResourceValidation=false)
例子如下:
在crd资源中对自定义资源应用openapi v3模式验证,该自定义资源中对cronSpec和replicas两个字段做了验证,不符合规则的不给予创建该资源对象。
$ vi resourcedefinition.yaml:
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: crontabs.stable.example.com
spec:
group: stable.example.com
versions:
- name: v1
served: true
storage: true
version: v1
scope: Namespaced
names:
plural: crontabs
singular: crontab
kind: CronTab
shortNames:
- ct
validation:
# openAPIV3Schema is the schema for validating custom objects.
openAPIV3Schema:
properties:
spec:
properties:
cronSpec: #--必须是字符串,并且必须是正则表达式所描述的形式
type: string
pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$'
replicas: #----必须是整数,最小值必须为1,最大值必须为10
type: integer
minimum: 1
maximum: 10
- 创建含有验证的自定义资源(Contab)
$ kubectl create -f resourcedefinition.yaml
- 创建不符合验证规则的contab资源对象:
$ vi my-crontab.yaml:
apiVersion: "stable.example.com/v1"
kind: CronTab
metadata:
name: my-new-cron-object
spec:
cronSpec: "* * * *"
image: my-awesome-cron-image
replicas: 15
- 创建不符合验证规则的contab资源对象
$ kubectl create -f my-crontab.yaml
结果是该Contab资源对象创建失败
1.4、为自定义资源添加额外的打印列:
从Kubernetes 1.11开始,kubectl使用服务器端打印。服务器决定由kubectl get命令显示哪些列即在我们获取一个内置资源的时候会显示出一些列表信息(比如:kubectl get nodes)。这里我们可以使用CustomResourceDefinition自定义这些列,当我们在查看自定义资源信息的时候显示出我们需要的列表信息。通过在crd文件中添加“additionalPrinterColumns:”字段,在该字段下声明需要打印列的的信息。
例如:
这里我们在crd对象中为自定义资源添加要显示的列表信息:
$ vi resourcedefinition.yaml:
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: crontabs.stable.example.com
spec:
group: stable.example.com
version: v1
scope: Namespaced
names:
plural: crontabs
singular: crontab
kind: CronTab
shortNames:
- ct
additionalPrinterColumns:
- name: Spec
type: string
description: The cron spec defining the interval a CronJob is run
JSONPath: .spec.cronSpec
- name: Replicas
type: integer
description: The number of jobs launched by the CronJob
JSONPath: .spec.replicas
- name: Age
type: date
JSONPath: .metadata.creationTimestamp
- 创建含有显示列表信息的自定义资源
$ kubectl create -f resourcedefinition.yaml - 创建contab自定义资源对象
$ kubectl create -f my-crontab.yaml - 查看自定义资源对象基本信息
$ kubectl get crontab my-new-cron-object
NAME SPEC REPLICAS AGE
my-new-cron-object * * * * * 1 7s
注意:name列不需要定义默认会有的
1.5、为自定义的资源添加状态和伸缩配置:
一般我们要是没有在自定义资源当中配置关于资源对象的伸缩和状态信息的一些相关配置的话,那么在当我们通过该自定义资源创建对象后,又想通过“kubectl scale”来弹性的扩展该对象的容器的时候就会无能为力。而CRD可以允许我们添加该方面的相关配置声明,从而达到我们可以对自定义资源对象的伸缩处理。添加“ subresources:”字段来声明状态和伸缩信息。
在k8s中这个称为子资源,我们可以通过“kube-apiserver.yml”文件来关闭或启用该功能,“--feature-gates=CustomResourceSubresources=false”。
注意:在CRD OpenAPI验证模式的根目录中,只允许以下结构在crd文件中出现:
Description、Example、ExclusiveMaximum、ExclusiveMinimum、ExternalDocs、Format、Items、Maximum、MaxItems、MaxLength、Minimum、MinItems、MinLength、MultipleOf、Pattern、Properties、Required、Title、Type、UniqueItems
如下crd文件中同时申明status和scale子资源:
$ vi resourcedefinition.yaml
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: crontabs.stable.example.com
spec:
group: stable.example.com
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: crontabs
singular: crontab
kind: CronTab
shortNames:
- ct
# 自定义资源的子资源的描述
subresources:
# 启用状态子资源。
status: {}
# 启用scale子资源
scale:
specReplicasPath: .spec.replicas
statusReplicasPath: .status.replicas
labelSelectorPath: .status.labelSelector
- 创建含有子资源声明的自定义资源
$ kubectl create -f resourcedefinition.yaml - 创建自定义资源对象
$ kubectl create -f my-crontab.yaml
apiVersion: "stable.example.com/v1"
kind: CronTab
metadata:
name: my-new-cron-object
spec:
cronSpec: "* * * * */5"
image: my-awesome-cron-image
replicas: 3
- 扩充自定义资源对象副本数目
$ kubectl scale --replicas=5 crontabs/my-new-cron-object
1.6、为自定义资源分配所属组:
一般的我们在创建完自定义资源的时候该资源就是一个分组,为了减少分组信息,我们可以将自定义资源分配到对应已存在的组里面。通过“categories:”字段来定义我们自定义资源所属的组。在crd文件中添加”categories:“字段来声明所属组。
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: crontabs.stable.example.com
spec:
group: stable.example.com
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: crontabs
singular: crontab
kind: CronTab
shortNames:
- ct
# categories字段指定自定义资源所属的组
categories:
- all
- 创建完上面的crd资源以及资源对象my-crontab后我们就可以通过获取all组来获取该组下的信息
$ kubectl get all
2、Prometheus Operator:
k8s监控除了要监控Node和pod之外我们还需要监控集群的健康比如kube-api、Scheduler、Controller Manager等组件的是否正常。而 Weave Scope 和 Heapster,它们主要的监控对象是Node 和 Pod,而Prometheus Operator可以弥补两者的不足之处。
2.1、Prometheus operator设计原理:
Prometheus资源设计:
1)、operator会在Prometheus自定义资源对象的命名空间下创建一个statefulset资源对象名为“prometheus-k8s”该资源对象通过”volumes:“标签来选着secret资源中含有标签为“secretName: prometheus-k8s”的secret资源对象,然后通过该文件来配置或重载Prometheus server pod中的的配置文件(secret文件),简而言之就是由operator来生成Prometheus server的配置
文件以及后续的重载
2)、Prometheus server实例通过标签选择器(serviceMonitorSelector: {})来确定应该覆盖哪些ServiceMonitors。然后operator创建的statefulsets资源对象来依据Prometheus server选择的servicemonitor来生成Prometheus的配置文件然后再通过secret文件挂载进去。
ServiceMonitor资源设计:
1)、ServiceMonitor自定义资源定义(CRD)允许声明性地定义如何监视一组动态服务。使用标签选择来定义所需配置监视的服务。允许各组织通过约定的方式来暴露metrics,然后通过这个约定的方式来通过自发现所要监控的对象服务,从而无需从配置系统配置文件。
2)、Prometheus要监视Kubernetes内的任何应用程序,需要存在Endpoints对象。Endpoints对象本质上是IP地址列表。而这个Endpoints对象列表是由service对象来填充的,service对象通过标签选择器发现pod并将其添加到Endpoints对象。
3)、ServiceMonitor对象是通过 Prometheus Operator来发现并转化成Prometheus server的配置文件然后挂载到Prometheus server中最后由Prometheus server来监控这些对象目标。ServiceMonitor中通过(endpointt:)标签来指定Endpoint资源中那些端口将会被scraped。
Altermanager资源设计:
1)、operator会在Alertmanager自定义资源对象的命名空间下创建一个statefulset资源对象名为alertmanager-main该资源对象通过”volumes:“标签来选着secret资源中含有标签为“secretName: alertmanager-main”的secret资源对象,然后通过该文件来配置或重载alertmanager pod中的的配置文件(secret文件)。
简而言之:
- 首先就是pod在k8s中先通过service资源对象来将pod中的容器的IP添加到Endpoints资源对象中列表中,用于后期的查找使用。
- 其次就是ServiceMonitor资源对象通过标签选择器(serviceMonitorSelector: {})来选择service资源对象。
- 然后就是Prometheus server实例通过标签选择器(serviceMonitorSelector: {})来确定应该覆盖哪些ServiceMonitors。
- 最后就是operatoroperator创建的statefulsets资源对象依据Prometheus server选择的
servicemonitor来生成Prometheus的配置文件然后再通过secret文件挂载进去
2.2、Prometheus Operator 架构:
Prometheus Operator 的目标是尽可能简化在 Kubernetes 中部署和维护 Prometheus 的工作。其架构如下图所示:
architecture.png
1)、Operator:
Operator 即 Prometheus Operator,在 Kubernetes 中以 Deployment 运行。其职责是部署和管理 Prometheus Server,根据 ServiceMonitor 动态更新 Prometheus Server 的监控对象,这里的ServiceMonitor资源对象就是指一个需要监控的目标对象在Prometheus中的配置信息。operator会根据Kubernetes标签查询自动生成监控目标配置;不需要学习普罗米修斯特有的配置语言。(operator就是一个将应用的操作性知识以软件的形式表现出来,通过基于K8s的Resources 和 Controllers来创建、配置、管理有状态的pod,使有状态的应用在k8s中得到简化的运用)
2)、Prometheus Server:
Prometheus Server 会作为 Kubernetes 应用部署到集群中。为了更好地在 Kubernetes 中管理 Prometheus,CoreOS 的开发人员专门定义了一个命名为 Prometheus 类型的 Kubernetes 定制化资源。我们可以把 Prometheus 看作是一种特殊的 Deployment,它的用途就是专门部署 Prometheus Server。Prometheus的配置是通过yaml文件中serviceMonitorSelector标签来选择ServiceMonitor资源对象来自动创建配置,其告警规则文件是通过一个独立的prometheus-rules.yaml文件来创建一个“PrometheusRule”自定义的资源对象。
3)、Service:
这里的 Service 就是 Cluster 中的 Service 资源,也是 Prometheus 要监控的对象,在 Prometheus中叫做 Target。每个监控对象都有一个对应的 Service。比如要监控 Kubernetes Scheduler,就得有一个与 Scheduler 对应的 Service。当然,Kubernetes 集群默认是没有这个 Service 的,Prometheus Operator 会负责创建。
4)、ServiceMonitor:
Operator 能够动态更新 Prometheus 的 Target 列表,ServiceMonitor 就是 Target 的抽象。比如想监控 Kubernetes Scheduler,用户可以创建一个与 Scheduler Service 相映射的 ServiceMonitor对象。Operator 则会发现这个新的 ServiceMonitor,并将 Scheduler 的 Target 添加到 Prometheus 的监控列表中。ServiceMonitor 也是 Prometheus Operator 专门开发的一种 Kubernetes 定制化资源类型。
5)、Alertmanager:
除了 Prometheus 和 ServiceMonitor,Alertmanager 是 Operator 开发的第三种 Kubernetes 定制化资源。我们可以把 Alertmanager 看作是一种特殊的 Deployment,它的用途就是专门部署 Alertmanager 组件。
参考: