• K8s python 实现 CRD 相关操作


    概述

    CRD 概述

    K8s 中内置了很多的资源类型, 包括 pod,svc,deploy 等等

    crd 是 K8s 允许用户自定义的一种资源格式.  定义好之后的使用体验如同 其他内置资源

    crd 本质上也是操作通过apiserver 去操作 etcd, 带有基本的增删改查概念, 如果需要更丰富的功能则需要自己手动实现 operator

    operator 目前官方未提供 python 相关的 sdk, 但是基础的 增删改查在官方的 sdk 中已实现

    CR 概述

    CRD 可以理解为 class 而 CR 则是 CRD 的实例化

    CRD 定义了 CR 的格式和属性, 而 CR 则可以对各属性进行定制和重载

    实现

    官方示例

    点击这里

    完整示例

    在 init 阶段链接集群(通过代码的字符串创建临时文件写入配置), 集群的配置文件在  ~/.kube/config  内, 将这个内容完全拿出来即可

    在 init 阶段创建CRD(CRD 只需要创建一次即可)

    通过API 调用 CR 的增删改查, 并启用 watch 监控 CR 的状态信息

    # -*- coding:utf-8 -*-
    import tempfile
    import time
    
    from kubernetes.client import api_client
    from kubernetes import config, dynamic, watch
    from kubernetes.dynamic.exceptions import ResourceNotFoundError
    
    
    class CRD(object):
        def __init__(self, name=None, res_id=None, phase=None, state=None):
            self.client = None
            self.crd_api = None
            self.flows_api = None
            self.ns = "default"
            self.cr_body = {
                "apiVersion": "flow.yangtuo.com/v1",
                "kind": "FlowPost",
                "metadata": {
                    "name": name,
                },
                "spec": {
                    "resourceid": res_id,
                },
                "status": {
                    "phase": phase,
                    "state": state
                }
            }
            self.init()
    
        def init(self):
            conf = self.get_conf()
            self.client = dynamic.DynamicClient(
                api_client.ApiClient(configuration=config.load_kube_config(config_file=conf)))
            self.crd_api = \
                self.client.resources.get(api_version="apiextensions.k8s.io/v1", kind="CustomResourceDefinition")
            try:
                self.flows_api = self.client.resources.get(api_version="flow.yangtuo.com/v1", kind="FlowPost")
            except ResourceNotFoundError as e:
                print(e)
                self.create_crd()
                time.sleep(2)
            finally:
                self.flows_api = self.client.resources.get(api_version="flow.yangtuo.com/v1", kind="FlowPost")
    
        @staticmethod
        def get_conf():
            conf = tempfile.mktemp()
            with open(conf, 'w') as f:
                f.write("""apiVersion: v1
    clusters:
    - cluster:
        certificate-authority-data: ...
        server: https://....:6443
      name: kubernetes
    contexts:
    - context:
        cluster: kubernetes
        user: kubernetes-admin
      name: kubernetes-admin@kubernetes
    current-context: kubernetes-admin@kubernetes
    kind: Config
    preferences: {}
    users:
    - name: kubernetes-admin
      user:
        client-certificate-data: ....
        client-key-data:....""")
            f.close()
            return conf
    
        # 创建 crd
        def create_crd(self):
            try:
                crd_res = self.crd_api.create({
                    "apiVersion": "apiextensions.k8s.io/v1",
                    "kind": "CustomResourceDefinition",
                    "metadata": {
                        "name": "flowposts.flow.yangtuo.com",
                    },
                    "spec": {
                        "group": "flow.yangtuo.com",
                        "scope": "Namespaced",
                        "names": {
                            "kind": "FlowPost",
                            "singular": "flowpost",
                            "plural": "flowposts",
                            "listKind": "FlowPostList",
                            "shortNames": ["fp"],
                        },
                        "versions": [
                            {
                                "name": "v1",
                                "served": True,
                                "storage": True,
                                "schema": {
                                    "openAPIV3Schema": {
                                        "type": "object",
                                        "properties": {
                                            "spec": {
                                                "type": "object",
                                                "properties": {
                                                    "resourceid": {"type": "string"},
                                                }
                                            },
                                            "status": {
                                                "type": "object",
                                                "properties": {
                                                    "phase": {"type": "string"},
                                                    "state": {"type": "string"},
                                                }
                                            },
                                        }
                                    },
                                }
                            }
                        ],
                    },
                })
                print(f"{crd_res.spec.scope} - {crd_res.metadata.name}")
                print("create_flows_crd success")
            except Exception as e:
                # print(e)
                return "create_crd  end ~~~~!"
    
        def get(self):
            res = self.flows_api.get()
            for item in res.items:
                print(f"name:{item.metadata.name}  "
                      f"res_id: {item.spec.resourceid}  "
                      f"state: {item.status.state}")
            return res
    
        def patch_cr(self, state):
            self.cr_body["status"]["state"] = state
            self.flows_api.patch(body=self.cr_body, content_type="application/merge-patch+json", namespace=self.ns)
    
        def create_cr(self):
            return self.flows_api.create(body=self.cr_body, namespace=self.ns)
    
        def delete_cr(self, name=None):
            self.flows_api.delete(name, namespace=self.ns)
    
        def watch(self):
            watcher = watch.Watch()
            for e in self.flows_api.watch(resource_version=0, namespace=self.ns, watcher=watcher):
                print("get new event !!! ", e['object'].metadata.name, e['type'], e['object'].status.phase)
                if e['object'].status.phase == "finished":
                    print(f"cr: {e['object'].metadata.name} is finished, over")
                    print("let start job (create cvm)....")
                    print("creating ... ")
                    print("job is done")
                    # watcher.stop()
    
    
    if __name__ == '__main__':
        c = CRD("No.xxxxxxx1234", "instance-dsdax20", "phase_1", "pending")
        c.create_cr() 
        c.patch_cr("finished")
        c.delete_cr()
        c.get()

    crd 的创建也可以通过 yaml 的形式 创建, 因为 CRD 是只需要创建一次的, 如果确认可部署集群的话可以提前在集群内导入

    apiVersion: apiextensions.k8s.io/v1
    kind: CustomResourceDefinition
    metadata:
      name: flowposts.flow.yangtuo.com
    spec:
      group: flow.linklogis.com
      scope: Namespaced
      names:
        kind: FlowPost
        singular: flowpost
        plural: flowposts
        listKind: FlowPostList
      versions:
      - name: v1
        served: true
        storage: true
        schema:
          openAPIV3Schema:
            type: object
            properties:
              spec:
                type: object
                properties:
                  resourceid:
                    type: string
              status:
                type: object
                properties:
                  phase:
                    type: string
    
  • 相关阅读:
    使用Spring RestTemplate 发送 List<MultipartFile>,上传多个文件
    二分查找的非递归实现
    图的深度优先遍历和广度优先遍历
    快速排序学习
    szwl面试记录
    Mycat对Mysql进行分库分表
    Java使用队列解决约瑟夫问题
    pa_hzzx面试总结
    Linux pam 后门纪录root用户密码以及自己设置root密码登录root
    JSP线程安全
  • 原文地址:https://www.cnblogs.com/shijieli/p/15878251.html
Copyright © 2020-2023  润新知