1 CustomResourceDefinition1

Tip
  1. k8s 在发展过程中, 肯定是不断的增加某种类型的资源, 比如 deployment, 我们会创建一个 类型是kind: Deployment的yaml文件
  2. k8s 系统里肯定有相关的代码来实现 这个类型的东西所具有的功能
  3. 增加这样一个功能, 可能就需要很多的代码, k8s 代码更新的周期 可能就比较长, 新功能等待时间可能就比较长
  4. 而自定义资源 的出现 ,就是让用户可以自己来简单的做这样一个扩展,增加了一个自己需要的功能.

1.我们现在来创建一个yaml文件来表示我们的资源

crontab.yaml
apiVersion: "stable.example.com/v1"
kind: CronTab
metadata:
  name: my-new-cron-object
spec:
  cronSpec: "* * * * */5"
  image: my-awesome-cron-image
我们apply看看,肯定报错了
k apply -f crontab.yaml
error: unable to recognize "crontab.yaml": no matches for kind "CronTab" in version "stable.example.com/v1"

2.我们得让系统知道你yaml里的东西是啥玩意,我们定义一个CustomResourceDefinition让系统知道你yaml里的东西是啥意思

crontab-resource-definition.yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  # 名字必需与下面的 spec 字段匹配,并且格式为 '<名称的复数形式>.<组名>'
  name: crontabs.stable.example.com
spec:
  # 组名称,用于 REST API: /apis/<组>/<版本>
  group: stable.example.com
  # 列举此 CustomResourceDefinition 所支持的版本
  versions: # 可设置多个版本
    - name: v1
      # 每个版本都可以通过 served 标志来独立启用或禁止
      served: true
      # 其中一个且只有一个版本必需被标记为存储版本
      storage: true
      schema:
1        openAPIV3Schema: #openAPIV3Schema 是验证自定义对象的模式
          type: object
          properties:
            spec:
              type: object
              properties:
                cronSpec:
                  type: string
                image:
                  type: string
                replicas:
                  type: integer
2      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
  # 范围 可以是 Namespaced 或 Cluster
  # 就像pod ,是有 ns 范围的
  scope: Namespaced
  names:
    # 名称的复数形式,用于 URL:/apis/<组>/<版本>/<名称的复数形式>
    plural: crontabs
    # 名称的单数形式,作为命令行使用时和显示时的别名
    singular: crontab
    # kind 通常是单数形式的驼峰命名(CamelCased)形式。你的资源清单会使用这一形式。
    kind: CronTab
    # shortNames 允许你在命令行使用较短的字符串来匹配资源, 比如 k get po 中的po 是pod
    shortNames:
    - ct
1
合法性验证
2
额外的打印列
k get ct #可以看到更多的列
NAME                 SPEC        REPLICAS   AGE
my-new-cron-object   * * * * *   1          7s
k apply -f crontab-resource-definition.yaml
#查看创建了哪些 资源定义
k get crd
NAME                          CREATED AT
crontabs.stable.example.com   2023-08-07T02:35:01Z
k api-resources # 这个时候能看到这个类型crontab的资源

# 创建完成后,我们就可以有 通过http 来查询这类资源了
curl localhost:8001/apis/stable.example.com/v1/namespaces/default/crontabs/
{
  "apiVersion": "stable.example.com/v1",
  "items": [],
  "kind": "CronTabList",
  "metadata": {
    "continue": "",
    "resourceVersion": "2608555"
  }
}
# 这个时候我们再创建这个自定义类型的对象
k apply -f crontab.yaml
# 和我们使用 k get po  一样
# 可以用上面crd里定义的ct这个shortName
k get ct

curl localhost:8001/apis/stable.example.com/v1/namespaces/default/crontabs/my-new-cron-object

3.现在创建的CronTab 类型的对象 和我们POD 类似, 只是pod对象创建完后,系统会给创建真正的pod,而CronTab系统可没做啥实质性的动作, 这需要我们写一些代码(自定义控制器,就是operator), 让系统看到这样的对象被写入后,做些什么事情,完全由用户来设计. 详见operator

2 Finalizers23

2.1 介绍

如果给对象设置了metadata.finalizers字段, 那么删除k8s对象前会触发对应的钩子函数
可以使用 Finalizers 控制资源的垃圾收集, 或阻止删除未被管理的资源

Diagram
Tip
  • 一个常见的 Finalizer 的例子是 kubernetes.io/pv-protection, 它用来防止意外删除 PersistentVolume 对象
  • 当一个 PersistentVolume 对象被 Pod 使用时, Kubernetes 会添加 pv-protection Finalizer. 如果你试图删除 PersistentVolume,它将进入 Terminating 状态, 但是控制器因为该 Finalizer 存在而无法删除该资源.当 Pod 停止使用 PersistentVolume 时, Kubernetes 清除 pv-protection Finalizer,控制器就会删除该卷
k get pv pv-nfs-0001 -o yaml |grep finalizers -A 3 -B 10
    apiVersion: v1
    kind: PersistentVolume
    metadata:
    annotations:
        pv.kubernetes.io/bound-by-controller: "yes"
    creationTimestamp: "2023-07-18T12:44:00Z"
    finalizers:
    - kubernetes.io/pv-protection

2.2 模拟一下

pod-finalizers.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-nginx
  labels:
    app: pod-nginx
  finalizers:
  - abc/protect-xyz # 随便写一个
spec:
  containers:
  - name: c-main
    image: nginx:1.14.2
k apply -f pod-finalizers.yaml
k delete -f pod-finalizers.yaml # 会看到卡着, 等待..
# 我们手动将 finalizers 字段删除

k edit pod  pod-nginx # 删除finalizers
# 可以看到 ok了
Back to top