整理Kubernetes的CRD周围
整合Kubernetes自定义资源(CRD)。
Kubernetes中有一个名为Custom Resource Definitions(CRD)的功能。CRD可以扩展Kubernetes API以定义自己的资源。Kubernetes资源指的是像Deployment或Pod这样的东西,但是使用CRD,我们可以自己定义和实现与Deployment或Pod同等级的资源。
在本文中,我们将整理CRD的概念和工具(基于2018/12/24的信息)。
资源和对象
在进入CRD之前,我们需要整理一下Kubernetes的资源和对象。
资源
资源是指任何类型的对象的概念。例如,Deployment和Pods都是资源。资源具有Kubernetes API,并且作为实际部署的对象,Pods作为资源存储在资源中。实际上类似于类和实例的概念(资源是类,对象是实例)。
以下是主要的资源类型:
-
- Nodes
-
- Namespaces
-
- Configmaps
-
- Secrets
-
- Roles
-
- Rolebindings
-
- Pods
-
- Replicasets
-
- Deployments
-
- Daemonsets
-
- Jobs
-
- Cronjobs
-
- Services
-
- Ingresses
-
- Persistentvolumes
- Persistentvolumeclaims
物品
对象是持续存在的实体,用于定义Kubernetes集群的状态。简单来说,它是指已部署的Pod和Service。对象的状态可以定义如下:
-
- 実行されているコンテナ・アプリケーション
-
- そのアプリケーションに提供されているリソース
- そのアプリケーションの稼働ポリシー(リスタート、アップグレード、フォールトトレランス)
当用户将Pods、Deployment和Service部署到Kubernetes时,通常会使用yaml文件向Kubernetes API定义所需的对象状态,并使用kubectl apply -f sample.yaml的方式实现所期望的状态。Kubernetes根据这个yaml文件部署对象,并通过操作对象来维护所需的状态。在这个过程中,kubectl访问和执行的是集群的Kubernetes API。
对象的所需状态在yaml中被定义为spec。Kubernetes的任务是维护指定在spec中定义的状态。
以下是Deployment对象的示例,首先在第一个spec下定义了Deployment的状态,然后在第二个spec中定义了Deployment内Pods的状态。
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
这个设置后,Kubernetes集群将使用nginx:1.7.9容器映像创建两个Pod,分别在80端口上发布。
定制资源
除了在Kubernetes中提供的標準資源,您還可以自行定義資源。這種自定義的資源被稱為Custom Resource,並通過擴展Kubernetes API來實現。Custom Resource只是一個用於存儲結構化數據的容器,實際操作需要實現Custom Controller。Custom Resource使用Kubernetes API(也可使用kubectl命令)通過管理對象來管理資源,與其他資源相同。
定制控制器
Custom Controller(自定义控制器)是用于控制自定义资源的声明式API。声明式API允许用户通过声明对象的desired state(期望状态)来进行部署和维护。实际操作和指令是由Custom Controller来执行的。Custom Controller会持续操作对象,使其状态与desired state保持一致。
Custom Controller本身是使用Golang在client-go中实现的,并通过code-generator生成客户端库。
Kubernetes API、Custom Controller、client-go之间的关系如下所示。
通过client-go,Custom Controller操作Kubernetes API。通过将运行Custom Controller的Docker Image部署为CRD的控制器,并作为Deployment部署,可以使CRD的Custom Controller在Kubernetes上运行。
使用自定义资源和自定义控制器,可以自定义定义资源和Kubernetes API,但有两种实现方式。
-
- CRD:可以无需编程定义API
- API Aggregation:需要编程,但可以定义更详细的API
API聚合(AA)
AA是Kubernetes API的扩展。AA是在Kubernetes 1.7版本之后添加的功能,kube-apiserver中已添加了AA的聚合层。用户可以通过实现APIService对象并注册到API中(通过设置自定义AA的URL),聚合层将请求作为代理转发到指定的URL。
AA作为PIServer的一部分进行功能扩展。要使用AA,需要向APIServer添加相应的扩展配置。
使用apiserver-builder或service-catalog进行开发将更加方便实用。
中国驻黎巴嫩大使馆
CRD是以比AA更便捷地添加自定义资源的方式。CRD可以在不向APIServer添加API的情况下进行实现。
CRD定义了自定义资源(正如其名称所示)。可以使用yaml对CRD进行定义。
以下是从CRD样本中获取的CRD定义示例。
# crd.yaml
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: foos.samplecontroller.k8s.io
spec:
group: samplecontroller.k8s.io
version: v1alpha1
names:
kind: Foo
plural: foos
scope: Namespaced
在这里,我们使用 foos.samplecontroller.k8s.io 作为终结点来定义一个名为 Foo 的CRD。只需要执行 kubectl apply -f crd.yaml,就可以生成一个新的 Kubernetes API 终结点。
由于CRD也是一种资源,所以上述操作将部署一个名为 Foo 的CRD对象到CRD资源中。
您可以使用 kubectl get crd 命令获取已部署的CRD列表。
在CRD对象Foo已部署的情况下,也可以创建Foo的自定义对象。
以下是一个示例。
# example-foo.yaml
apiVersion: samplecontroller.k8s.io/v1alpha1
kind: Foo
metadata:
name: example-foo
spec:
deploymentName: example-foo
replicas: 1
通过执行kubectl apply -f example-foo.yaml,将在Foo资源中部署一个名为example-foo的对象。
您可以使用”kubectl get foo”命令来获取已部署的 Foo 的列表。
CRD的扩展功能
在定义CRD时,我们会介绍一些有用的功能。
最终处理器
Finalizer定义了在自定义对象被删除之前执行的处理。通过定义Finalizer,可以定义在执行实际删除之前应该执行的操作,例如使用”kubectl delete”删除自定义对象时。例如,在Deployment中,删除Deployment会导致Pods和Replicaset被删除,但可以使用Finalizer来定义在删除Deployment之前删除Pods和Replicaset,从而实现相同的操作。
验证
你可以根据CRD的定义,以以下方式添加自定义对象的设置值验证。
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: foos.samplecontroller.k8s.io
spec:
group: samplecontroller.k8s.io
version: v1alpha1
names:
kind: Foo
plural: foos
scope: Namespaced
validation:
openAPIV3Schema:
properties:
spec:
properties:
replicas:
type: integer
minimum: 1
maximum: 10
在这里,可以将replicas的可设定值定义为整数,范围在1到10之间。如果使用其他值来应用kubectl的自定义对象,则会导致错误。
- OKな例:
# example-foo-ok.yaml
apiVersion: samplecontroller.k8s.io/v1alpha1
kind: Foo
metadata:
name: example-foo
spec:
deploymentName: example-foo
replicas: 1
- NGな例1:
# example-foo-ng-1.yaml
apiVersion: samplecontroller.k8s.io/v1alpha1
kind: Foo
metadata:
name: example-foo
spec:
deploymentName: example-foo
replicas: 1.1
- NGな例2:
# example-foo-ng-2.yaml
apiVersion: samplecontroller.k8s.io/v1alpha1
kind: Foo
metadata:
name: example-foo
spec:
deploymentName: example-foo
replicas: 111
打印机
从 Kubernetes 1.11 开始,您可以定义在使用 kubectl get 命令时要显示的自定义对象的参数。默认情况下,只显示 kubectl get 对象名称。为了显示其他参数,您需要在自定义资源定义(CRD)中定义显示目标参数,如下所示。
例如,通过设置 additionalPrinterColumns,您可以使 kubectl get 在标准输出中显示副本数和时间戳等信息。
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: foos.samplecontroller.k8s.io
spec:
group: samplecontroller.k8s.io
version: v1alpha1
names:
kind: Foo
plural: foos
scope: Namespaced
additionalPrinterColumns:
- name: Replicas
type: integer
description: The number of jobs launched by the Foo
JSONPath: .spec.replicas
- name: Age
type: date
JSONPath: .metadata.creationTimestamp
子资源
我們支援/status和/scale這兩個子資源。它們作為CRD API端點的子資源發揮作用。
/status表示對象的當前狀態(期望狀態在spec中)。/scale表示複製數量。
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: foos.samplecontroller.k8s.io
spec:
group: samplecontroller.k8s.io
version: v1alpha1
names:
kind: Foo
plural: foos
scope: Namespaced
subresources:
# status enables the status subresource.
status: {}
# scale enables the scale subresource.
scale:
# specReplicasPath defines the JSONPath inside of a custom resource that corresponds to Scale.Spec.Replicas.
specReplicasPath: .spec.replicas
# statusReplicasPath defines the JSONPath inside of a custom resource that corresponds to Scale.Status.Replicas.
statusReplicasPath: .status.replicas
# labelSelectorPath defines the JSONPath inside of a custom resource that corresponds to Scale.Status.Selector.
labelSelectorPath: .status.labelSelector
通过使用子资源,可以实现以下类型的端点公开。
# status
/apis/samplecontroller.k8s.io/v1alpha1/namespaces/default/foos/example-foo/status
# scale
/apis/samplecontroller.k8s.io/v1alpha1/namespaces/default/foos/example-foo/scale
请提供参考链接。
CRD的解释
-
- Custom Resource
- Extend the Kubernetes API with CustomResourceDefinitions
CRD例
-
- sample-controller
-
- KubernetesのCRD(Custom Resource Definition)とカスタムコントローラーの作成
- KubernetesのCustom Resource Definition(CRD)とCustom Controller
客户端-前往
-
- client-go
- Building stuff with the Kubernetes API (Part 4) — Using Go
代码生成器
-
- code-generator
- Kubernetes Deep Dive: Code Generation for CustomResources