整理Kubernetes的CRD周围

整合Kubernetes自定义资源(CRD)。

Kubernetes中有一个名为Custom Resource Definitions(CRD)的功能。CRD可以扩展Kubernetes API以定义自己的资源。Kubernetes资源指的是像Deployment或Pod这样的东西,但是使用CRD,我们可以自己定义和实现与Deployment或Pod同等级的资源。

在本文中,我们将整理CRD的概念和工具(基于2018/12/24的信息)。

资源和对象

在进入CRD之前,我们需要整理一下Kubernetes的资源和对象。

image.png

资源

资源是指任何类型的对象的概念。例如,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生成客户端库。

client-go

Kubernetes API、Custom Controller、client-go之间的关系如下所示。

kcc

通过client-go,Custom Controller操作Kubernetes API。通过将运行Custom Controller的Docker Image部署为CRD的控制器,并作为Deployment部署,可以使CRD的Custom Controller在Kubernetes上运行。

image.png

使用自定义资源和自定义控制器,可以自定义定义资源和Kubernetes API,但有两种实现方式。

    1. 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
广告
将在 10 秒后关闭
bannerAds