添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Kubernetes 是什么

Kubernetes 是一个全新的基于容器技术的分布式架构解决方案,是 Google 开源的一个容器集群管理系统,Kubernetes 简称 K8S。

Kubernetes 是一个一站式的完备的分布式系统开发和支撑平台,更是一个开放平台,对现有的编程语言、编程框架、中间件没有任何侵入性。

Kubernetes 提供了完善的管理工具,这些工具涵盖了开发、部署测试、运维监控在内的各个环节。

Kubernetes 具有完备的集群管理能力,包括多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和服务发现机制、内建智能负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制、多粒度的资源配额管理能力。

Kubernetes 特性

在节点故障时,重新启动失败的容器,替换和重新部署,保证预期的副本数量;杀死健康检查失败的容器,并且在未准备好之前不会处理用户的请求,确保线上服务不中断。 使用命令、UI或者基于CPU使用情况自动快速扩容和缩容应用程序实例,保证应用业务高峰并发时的高可用性;业务低峰时回收资源,以最小成本运行服务。
  • 自动部署和回滚
    K8S采用滚动更新策略更新应用,一次更新一个Pod,而不是同时删除所有Pod,如果更新过程中出现问题,将回滚更改,确保升级不影响业务。
  • 服务发现和负载均衡
    K8S为多个容器提供一个统一访问入口(内部IP地址和一个DNS名称),并且负载均衡关联的所有容器,使得用户无需考虑容器IP问题。
  • 机密和配置管理
    管理机密数据和应用程序配置,而不需要把敏感数据暴露在镜像里,提高敏感数据安全性。并可以将一些常用的配置存储在K8S中,方便应用程序使用。
  • 挂载外部存储系统,无论是来自本地存储,公有云,还是网络存储,都作为集群资源的一部分使用,极大提高存储使用灵活性。 提供一次性任务,定时任务;满足批量数据处理和分析的场景。

    k8s官网

    官网: https://kubernetes.io/zh-cn/

    文档: https://kubernetes.io/zh-cn/docs/home/

    k8s集群怎么安装可以看之前的博客,有讲怎么部署了,这里就不做赘述了

    客户端库: https://kubernetes.io/zh-cn/docs/reference/using-api/client-libraries/

    python库: https://github.com/kubernetes-client/python/

    支持的客户端版本的兼容性列表

  • client 9.y.z : Kubernetes 1.12 or below (+-), Kubernetes 1.13 (✓), Kubernetes 1.14 or above (+-)
  • client 10.y.z : Kubernetes 1.13 or below (+-), Kubernetes 1.14 (✓), Kubernetes 1.14 or above (+-)
  • client 11.y.z : Kubernetes 1.14 or below (+-), Kubernetes 1.15 (✓), Kubernetes 1.16 or above (+-)
  • client 12.y.z : Kubernetes 1.15 or below (+-), Kubernetes 1.16 (✓), Kubernetes 1.17 or above (+-)
  • client 17.y.z : Kubernetes 1.16 or below (+-), Kubernetes 1.17 (✓), Kubernetes 1.18 or above (+-)
  • client 18.y.z : Kubernetes 1.17 or below (+-), Kubernetes 1.18 (✓), Kubernetes 1.19 or above (+-)
  • client 19.y.z : Kubernetes 1.18 or below (+-), Kubernetes 1.19 (✓), Kubernetes 1.20 or above (+-)
  • client 20.y.z : Kubernetes 1.19 or below (+-), Kubernetes 1.20 (✓), Kubernetes 1.21 or above (+-)
  • client 21.y.z : Kubernetes 1.20 or below (+-), Kubernetes 1.21 (✓), Kubernetes 1.22 or above (+-)
  • client 22.y.z : Kubernetes 1.21 or below (+-), Kubernetes 1.22 (✓), Kubernetes 1.23 or above (+-)
  • client 23.y.z : Kubernetes 1.22 or below (+-), Kubernetes 1.23 (✓), Kubernetes 1.24 or above (+-)
  • client 24.y.z : Kubernetes 1.23 or below (+-), Kubernetes 1.24 (✓), Kubernetes 1.25 or above (+-)
  • client 25.y.z : Kubernetes 1.24 or below (+-), Kubernetes 1.25 (✓), Kubernetes 1.26 or above (+-)
  • client 26.y.z : Kubernetes 1.25 or below (+-), Kubernetes 1.26 (✓), Kubernetes 1.27 or above (+-)
  • client 27.y.z : Kubernetes 1.26 or below (+-), Kubernetes 1.27 (✓), Kubernetes 1.28 or above (+-)
  • client 28.y.z : Kubernetes 1.27 or below (+-), Kubernetes 1.28 (✓), Kubernetes 1.29 or above (+-)
  • client 29.y.z : Kubernetes 1.28 or below (+-), Kubernetes 1.29 (✓), Kubernetes 1.30 or above (+-)
  • client 30.y.z : Kubernetes 1.29 or below (+-), Kubernetes 1.30 (✓), Kubernetes 1.31 or above (+-)
  • 测试环境k8s版本

    $ kubectl version
    Client Version: v1.30.1
    Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
    Server Version: v1.30.0
    

    所以安装最新版本就可以

    pip install kubernetes
    
    poetry add kubernetes
    
    from kubernetes import client, config
    # 加载配置文件
    config.load_kube_config(config_file="examples/k8s/admin.conf")
    # 如果在k8s的本机上,或者配置文件是~/.kube/config,则可以直接加载配置
    # config.load_kube_config()
    # 创建API对象
    api_instance = client.CoreV1Api()
    # 使用API对象执行操作,例如列出所有命名空间
    namespace_list = api_instance.list_namespace()
    for namespace in namespace_list.items:
        print(namespace.metadata.name)
    

    使用config.load_kube_config()方法来连接k8s集群

    配置文件的获取方式有两种

  • 显式通过 config_file 参数来指定
  • 不指定 config_file 参数,会先检查环境变量
  • 如果找到环境变量 KUBECONFIG ,那么就直接使用 KUBECONFIG 的值
  • 如果找不到环境变量,那就会找 ~/.kube/config
  • 操作k8s

    参考 https://github.com/kubernetes-client/python/tree/master/examples

    获取POD相关信息

    from prettytable import PrettyTable
    from kubernetes import client, config
    from common.k8s_format import get_age
    # 加载配置文件
    config.load_kube_config(config_file="examples/k8s/admin.conf")
    # 创建API对象
    api_instance = client.CoreV1Api()
    # 列出所有pod
    table = PrettyTable()
    table.align = "l"
    table.field_names = ["NAME", "NAMESPACE", "READY", "STATUS", "RESTARTS", "AGE", "IP", "NODE"]
    table.title = "所有名称空间下的POD"
    pod_list = api_instance.list_pod_for_all_namespaces()
    for pod in pod_list.items:
        ready = 0
        restarts = 0
        for s in pod.status.container_statuses:
            if s.ready:
                ready += 1
            restarts += s.restart_count
        table.add_row([pod.metadata.name, pod.metadata.namespace,
                       f"{ready}/{len(pod.status.container_statuses)}", pod.status.phase, restarts,
                       get_age(pod.status.start_time), pod.status.pod_ip, pod.spec.node_name])
    print(table)
    +-----------------------------------------------------------------------------------------------------------------------+
    |                                                  所有名称空间下的POD                                                  |
    +------------------------------------------+-------------+-------+---------+----------+--------+----------------+-------+
    | NAME                                     | NAMESPACE   | READY | STATUS  | RESTARTS | AGE    | IP             | NODE  |
    +------------------------------------------+-------------+-------+---------+----------+--------+----------------+-------+
    | nginx-deployment-68c885dc79-6g8cr        | default     | 1/1   | Running | 0        | 2m19s  | 10.244.166.178 | node1 |
    | nginx-deployment-68c885dc79-k66gf        | default     | 1/1   | Running | 0        | 2m19s  | 10.244.166.180 | node1 |
    | nginx-deployment-68c885dc79-qtkvs        | default     | 1/1   | Running | 0        | 2m19s  | 10.244.166.179 | node1 |
    | calico-kube-controllers-776b58cfc5-dd8s4 | kube-system | 1/1   | Running | 2        | 18d23h | 10.244.166.139 | node1 |
    | calico-node-8ssd6                        | kube-system | 1/1   | Running | 2        | 18d23h | 192.168.140.76 | node1 |
    | calico-node-nkckv                        | kube-system | 1/1   | Running | 2        | 18d23h | 192.168.140.75 | node  |
    | coredns-7b5944fdcf-qrm6v                 | kube-system | 1/1   | Running | 2        | 18d23h | 10.244.166.142 | node1 |
    | coredns-7b5944fdcf-tm2gx                 | kube-system | 1/1   | Running | 2        | 18d23h | 10.244.166.141 | node1 |
    | etcd-node                                | kube-system | 1/1   | Running | 2        | 18d22h | 192.168.140.75 | node  |
    | kube-apiserver-node                      | kube-system | 1/1   | Running | 2        | 18d22h | 192.168.140.75 | node  |
    | kube-controller-manager-node             | kube-system | 1/1   | Running | 2        | 18d22h | 192.168.140.75 | node  |
    | kube-proxy-2cndq                         | kube-system | 1/1   | Running | 2        | 18d23h | 192.168.140.75 | node  |
    | kube-proxy-5mdhc                         | kube-system | 1/1   | Running | 2        | 18d23h | 192.168.140.76 | node1 |
    | kube-scheduler-node                      | kube-system | 1/1   | Running | 2        | 18d22h | 192.168.140.75 | node  |
    +------------------------------------------+-------------+-------+---------+----------+--------+----------------+-------+
    # 列出指定名称空间下的所有pod
    table = PrettyTable()
    table.align = "l"
    table.field_names = ["NAME", "NAMESPACE", "READY", "STATUS", "RESTARTS", "AGE", "IP", "NODE"]
    namespace = "default"
    table.title = "{}名称空间下的POD".format(namespace)
    pod_list = api_instance.list_namespaced_pod(namespace=namespace)
    for pod in pod_list.items:
        ready = 0
        restarts = 0
        for s in pod.status.container_statuses:
            if s.ready:
                ready += 1
            restarts += s.restart_count
        table.add_row([pod.metadata.name, pod.metadata.namespace,
                       f"{ready}/{len(pod.status.container_statuses)}", pod.status.phase, restarts,
                       get_age(pod.status.start_time), pod.status.pod_ip, pod.spec.node_name])
    print(table)
    +--------------------------------------------------------------------------------------------------------------+
    |                                            default名称空间下的POD                                            |
    +-----------------------------------+-----------+-------+---------+----------+--------+----------------+-------+
    | NAME                              | NAMESPACE | READY | STATUS  | RESTARTS | AGE    | IP             | NODE  |
    +-----------------------------------+-----------+-------+---------+----------+--------+----------------+-------+
    | nginx-deployment-68c885dc79-6g8cr | default   | 1/1   | Running | 0        | 23m46s | 10.244.166.178 | node1 |
    | nginx-deployment-68c885dc79-k66gf | default   | 1/1   | Running | 0        | 23m46s | 10.244.166.180 | node1 |
    | nginx-deployment-68c885dc79-qtkvs | default   | 1/1   | Running | 0        | 23m46s | 10.244.166.179 | node1 |
    +-----------------------------------+-----------+-------+---------+----------+--------+----------------+-------+
    # 读取指定pod的信息
    table = PrettyTable()
    table.align = "l"
    table.field_names = ["NAME", "NAMESPACE", "READY", "STATUS", "RESTARTS", "AGE", "IP", "NODE"]
    namespace = "default"
    name="nginx-deployment-68c885dc79-6g8cr"
    pod = api_instance.read_namespaced_pod(name, namespace)
    ready = 0
    restarts = 0
    for s in pod.status.container_statuses:
        if s.ready:
            ready += 1
        restarts += s.restart_count
    table.add_row([pod.metadata.name, pod.metadata.namespace,
                   f"{ready}/{len(pod.status.container_statuses)}", pod.status.phase, restarts,
                   get_age(pod.status.start_time), pod.status.pod_ip, pod.spec.node_name])
    print(table)
    +-----------------------------------+-----------+-------+---------+----------+--------+----------------+-------+
    | NAME                              | NAMESPACE | READY | STATUS  | RESTARTS | AGE    | IP             | NODE  |
    +-----------------------------------+-----------+-------+---------+----------+--------+----------------+-------+
    | nginx-deployment-68c885dc79-6g8cr | default   | 1/1   | Running | 0        | 25m33s | 10.244.166.178 | node1 |
    +-----------------------------------+-----------+-------+---------+----------+--------+----------------+-------+
    

    获取api-resources

    from kubernetes import client, config
    from prettytable import PrettyTable
    # 加载配置文件
    config.load_kube_config(config_file="examples/k8s/admin.conf")
    t = PrettyTable()
    # 设置表头
    t.field_names = ["name", "short_names", "api_version", "namespaced", "kind"]
    # 设置左对其
    t.align = "l"
    # 创建v1的API对象
    # 列出v1所有资源
    api_instance = client.CoreV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建admissionregistration.k8s.io/v1的API对象
    # 列出admissionregistration.k8s.io/v1所有资源
    api_instance = client.AdmissionregistrationV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建apiextensions.k8s.io/v1的API对象
    # 列出apiextensions.k8s.io/v1所有资源
    api_instance = client.ApiextensionsV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建apiregistration.k8s.io/v1的API对象
    # 列出apiregistration.k8s.io/v1所有资源
    api_instance = client.ApiregistrationV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建apps/v1的API对象
    # 列出apps/v1所有资源
    api_instance = client.AppsV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建authentication.k8s.io/v1的API对象
    # 列出authentication.k8s.io/v1所有资源
    api_instance = client.AuthenticationV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建authorization.k8s.io/v1的API对象
    # 列出authorization.k8s.io/v1所有资源
    api_instance = client.AuthorizationV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建autoscaling/v2的API对象
    # 列出autoscaling/v2所有资源
    api_instance = client.AutoscalingV2Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建batch/v1的API对象
    # 列出batch/v1所有资源
    api_instance = client.BatchV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建certificates.k8s.io/v1的API对象
    # 列出certificates.k8s.io/v1所有资源
    api_instance = client.CertificatesV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建coordination.k8s.io/v1的API对象
    # 列出coordination.k8s.io/v1所有资源
    api_instance = client.CoordinationV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建discovery.k8s.io/v1的API对象
    # 列出discovery.k8s.io/v1所有资源
    api_instance = client.DiscoveryV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建events.k8s.io/v1的API对象
    # 列出events.k8s.io/v1所有资源
    api_instance = client.EventsV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建flowcontrol.apiserver.k8s.io/v1的API对象
    # 列出flowcontrol.apiserver.k8s.io/v1所有资源
    api_instance = client.FlowcontrolApiserverV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建networking.k8s.io/v1的API对象
    # 列出networking.k8s.io/v1所有资源
    api_instance = client.NetworkingV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建node.k8s.io/v1的API对象
    # 列出node.k8s.io/v1所有资源
    api_instance = client.NodeV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建policy/v1的API对象
    # 列出policy/v1所有资源
    api_instance = client.PolicyV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建rbac.authorization.k8s.io/v1的API对象
    # 列出rbac.authorization.k8s.io/v1所有资源
    api_instance = client.RbacAuthorizationV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建scheduling.k8s.io/v1的API对象
    # 列出scheduling.k8s.io/v1所有资源
    api_instance = client.SchedulingV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    # 创建storage.k8s.io/v1的API对象
    # 列出storage.k8s.io/v1所有资源
    api_instance = client.StorageV1Api()
    for resource in api_instance.get_api_resources().resources:
        row = [resource.name, ",".join(resource.short_names) if resource.short_names else " ",
               api_instance.get_api_resources().group_version, resource.namespaced, resource.kind]
        t.add_row(row)
    print(t)
    如命令行 kubectl api-resources 结果
    +-------------------------------------+-------------+---------------------------------+------------+----------------------------------+
    | name                                | short_names | api_version                     | namespaced | kind                             |
    +-------------------------------------+-------------+---------------------------------+------------+----------------------------------+
    | bindings                            |             | v1                              | True       | Binding                          |
    | componentstatuses                   | cs          | v1                              | False      | ComponentStatus                  |
    | configmaps                          | cm          | v1                              | True       | ConfigMap                        |
    | endpoints                           | ep          | v1                              | True       | Endpoints                        |
    | events                              | ev          | v1                              | True       | Event                            |
    | limitranges                         | limits      | v1                              | True       | LimitRange                       |
    | namespaces                          | ns          | v1                              | False      | Namespace                        |
    | namespaces/finalize                 |             | v1                              | False      | Namespace                        |
    | namespaces/status                   |             | v1                              | False      | Namespace                        |
    | nodes                               | no          | v1                              | False      | Node                             |
    | nodes/proxy                         |             | v1                              | False      | NodeProxyOptions                 |
    | nodes/status                        |             | v1                              | False      | Node                             |
    | persistentvolumeclaims              | pvc         | v1                              | True       | PersistentVolumeClaim            |
    | persistentvolumeclaims/status       |             | v1                              | True       | PersistentVolumeClaim            |
    | persistentvolumes                   | pv          | v1                              | False      | PersistentVolume                 |
    | persistentvolumes/status            |             | v1                              | False      | PersistentVolume                 |
    | pods                                | po          | v1                              | True       | Pod                              |
    | pods/attach                         |             | v1                              | True       | PodAttachOptions                 |
    | pods/binding                        |             | v1                              | True       | Binding                          |
    | pods/ephemeralcontainers            |             | v1                              | True       | Pod                              |
    | pods/eviction                       |             | v1                              | True       | Eviction                         |
    | pods/exec                           |             | v1                              | True       | PodExecOptions                   |
    | pods/log                            |             | v1                              | True       | Pod                              |
    | pods/portforward                    |             | v1                              | True       | PodPortForwardOptions            |
    | pods/proxy                          |             | v1                              | True       | PodProxyOptions                  |
    | pods/status                         |             | v1                              | True       | Pod                              |
    | podtemplates                        |             | v1                              | True       | PodTemplate                      |
    | replicationcontrollers              | rc          | v1                              | True       | ReplicationController            |
    | replicationcontrollers/scale        |             | v1                              | True       | Scale                            |
    | replicationcontrollers/status       |             | v1                              | True       | ReplicationController            |
    | resourcequotas                      | quota       | v1                              | True       | ResourceQuota                    |
    | resourcequotas/status               |             | v1                              | True       | ResourceQuota                    |
    | secrets                             |             | v1                              | True       | Secret                           |
    | serviceaccounts                     | sa          | v1                              | True       | ServiceAccount                   |
    | serviceaccounts/token               |             | v1                              | True       | TokenRequest                     |
    | services                            | svc         | v1                              | True       | Service                          |
    | services/proxy                      |             | v1                              | True       | ServiceProxyOptions              |
    | services/status                     |             | v1                              | True       | Service                          |
    | mutatingwebhookconfigurations       |             | admissionregistration.k8s.io/v1 | False      | MutatingWebhookConfiguration     |
    | validatingadmissionpolicies         |             | admissionregistration.k8s.io/v1 | False      | ValidatingAdmissionPolicy        |
    | validatingadmissionpolicies/status  |             | admissionregistration.k8s.io/v1 | False      | ValidatingAdmissionPolicy        |
    | validatingadmissionpolicybindings   |             | admissionregistration.k8s.io/v1 | False      | ValidatingAdmissionPolicyBinding |
    | validatingwebhookconfigurations     |             | admissionregistration.k8s.io/v1 | False      | ValidatingWebhookConfiguration   |
    | customresourcedefinitions           | crd,crds    | apiextensions.k8s.io/v1         | False      | CustomResourceDefinition         |
    | customresourcedefinitions/status    |             | apiextensions.k8s.io/v1         | False      | CustomResourceDefinition         |
    | apiservices                         |             | apiregistration.k8s.io/v1       | False      | APIService                       |
    | apiservices/status                  |             | apiregistration.k8s.io/v1       | False      | APIService                       |
    | controllerrevisions                 |             | apps/v1                         | True       | ControllerRevision               |
    | daemonsets                          | ds          | apps/v1                         | True       | DaemonSet                        |
    | daemonsets/status                   |             | apps/v1                         | True       | DaemonSet                        |
    | deployments                         | deploy      | apps/v1                         | True       | Deployment                       |
    | deployments/scale                   |             | apps/v1                         | True       | Scale                            |
    | deployments/status                  |             | apps/v1                         | True       | Deployment                       |
    | replicasets                         | rs          | apps/v1                         | True       | ReplicaSet                       |
    | replicasets/scale                   |             | apps/v1                         | True       | Scale                            |
    | replicasets/status                  |             | apps/v1                         | True       | ReplicaSet                       |
    | statefulsets                        | sts         | apps/v1                         | True       | StatefulSet                      |
    | statefulsets/scale                  |             | apps/v1                         | True       | Scale                            |
    | statefulsets/status                 |             | apps/v1                         | True       | StatefulSet                      |
    | selfsubjectreviews                  |             | authentication.k8s.io/v1        | False      | SelfSubjectReview                |
    | tokenreviews                        |             | authentication.k8s.io/v1        | False      | TokenReview                      |
    | localsubjectaccessreviews           |             | authorization.k8s.io/v1         | True       | LocalSubjectAccessReview         |
    | selfsubjectaccessreviews            |             | authorization.k8s.io/v1         | False      | SelfSubjectAccessReview          |
    | selfsubjectrulesreviews             |             | authorization.k8s.io/v1         | False      | SelfSubjectRulesReview           |
    | subjectaccessreviews                |             | authorization.k8s.io/v1         | False      | SubjectAccessReview              |
    | horizontalpodautoscalers            | hpa         | autoscaling/v2                  | True       | HorizontalPodAutoscaler          |
    | horizontalpodautoscalers/status     |             | autoscaling/v2                  | True       | HorizontalPodAutoscaler          |
    | cronjobs                            | cj          | batch/v1                        | True       | CronJob                          |
    | cronjobs/status                     |             | batch/v1                        | True       | CronJob                          |
    | jobs                                |             | batch/v1                        | True       | Job                              |
    | jobs/status                         |             | batch/v1                        | True       | Job                              |
    | certificatesigningrequests          | csr         | certificates.k8s.io/v1          | False      | CertificateSigningRequest        |
    | certificatesigningrequests/approval |             | certificates.k8s.io/v1          | False      | CertificateSigningRequest        |
    | certificatesigningrequests/status   |             | certificates.k8s.io/v1          | False      | CertificateSigningRequest        |
    | leases                              |             | coordination.k8s.io/v1          | True       | Lease                            |
    | endpointslices                      |             | discovery.k8s.io/v1             | True       | EndpointSlice                    |
    | events                              | ev          | events.k8s.io/v1                | True       | Event                            |
    | flowschemas                         |             | flowcontrol.apiserver.k8s.io/v1 | False      | FlowSchema                       |
    | flowschemas/status                  |             | flowcontrol.apiserver.k8s.io/v1 | False      | FlowSchema                       |
    | prioritylevelconfigurations         |             | flowcontrol.apiserver.k8s.io/v1 | False      | PriorityLevelConfiguration       |
    | prioritylevelconfigurations/status  |             | flowcontrol.apiserver.k8s.io/v1 | False      | PriorityLevelConfiguration       |
    | ingressclasses                      |             | networking.k8s.io/v1            | False      | IngressClass                     |
    | ingresses                           | ing         | networking.k8s.io/v1            | True       | Ingress                          |
    | ingresses/status                    |             | networking.k8s.io/v1            | True       | Ingress                          |
    | networkpolicies                     | netpol      | networking.k8s.io/v1            | True       | NetworkPolicy                    |
    | runtimeclasses                      |             | node.k8s.io/v1                  | False      | RuntimeClass                     |
    | poddisruptionbudgets                | pdb         | policy/v1                       | True       | PodDisruptionBudget              |
    | poddisruptionbudgets/status         |             | policy/v1                       | True       | PodDisruptionBudget              |
    | clusterrolebindings                 |             | rbac.authorization.k8s.io/v1    | False      | ClusterRoleBinding               |
    | clusterroles                        |             | rbac.authorization.k8s.io/v1    | False      | ClusterRole                      |
    | rolebindings                        |             | rbac.authorization.k8s.io/v1    | True       | RoleBinding                      |
    | roles                               |             | rbac.authorization.k8s.io/v1    | True       | Role                             |
    | priorityclasses                     | pc          | scheduling.k8s.io/v1            | False      | PriorityClass                    |
    | csidrivers                          |             | storage.k8s.io/v1               | False      | CSIDriver                        |
    | csinodes                            |             | storage.k8s.io/v1               | False      | CSINode                          |
    | csistoragecapacities                |             | storage.k8s.io/v1               | True       | CSIStorageCapacity               |
    | storageclasses                      | sc          | storage.k8s.io/v1               | False      | StorageClass                     |
    | volumeattachments                   |             | storage.k8s.io/v1               | False      | VolumeAttachment                 |
    | volumeattachments/status            |             | storage.k8s.io/v1               | False      | VolumeAttachment                 |
    +-------------------------------------+-------------+---------------------------------+------------+----------------------------------+
    

    获取deploy相关信息

    from kubernetes import client, config
    from prettytable import PrettyTable
    from common.k8s_format import get_age
    # 加载配置文件
    config.load_kube_config(config_file="examples/k8s/admin.conf")
    # 创建API对象
    api_instance = client.AppsV1Api()
    # 获取所有Deployment
    table = PrettyTable()
    table.align = "l"
    table.field_names = ["NAMESPACE", "NAME", "READY", "UP-TO-DATE", "AVAILABLE", "AGE", "CONTAINERS",
                         "SELECTOR"]
    table.title = "所有名称空间下的Deployment"
    deploy_list = api_instance.list_deployment_for_all_namespaces()
    for deploy in deploy_list.items:
        containers = []
        for container in deploy.spec.template.spec.containers:
            containers.append(container.name)
        if len(containers) == 1:
            containers = containers[0]
        selector = None
        if deploy.spec.selector.match_labels:
            selector = deploy.spec.selector.match_labels
        else:
            selector = deploy.spec.selector.match_expressions
        table.add_row([deploy.metadata.namespace, deploy.metadata.name,
                       f"{deploy.status.ready_replicas}/{deploy.status.replicas}",
                       deploy.status.updated_replicas, deploy.status.available_replicas,
                       get_age(deploy.metadata.creation_timestamp),
                       containers if containers else "<none>",
                       selector if selector else "<none>"])
    print(table)
    +----------------------------------------------------------------------------------------------------------------------------------------------------+
    |                                                             所有名称空间下的Deployment                                                              |
    +-------------+-------------------------+-------+------------+-----------+--------+-------------------------+----------------------------------------+
    | NAMESPACE   | NAME                    | READY | UP-TO-DATE | AVAILABLE | AGE    | CONTAINERS              | SELECTOR                               |
    +-------------+-------------------------+-------+------------+-----------+--------+-------------------------+----------------------------------------+
    | default     | nginx-deployment        | 3/3   | 3          | 3         | 30m12s | nginx-http              | {'app': 'http-server'}                 |
    | kube-system | calico-kube-controllers | 1/1   | 1          | 1         | 18d23h | calico-kube-controllers | {'k8s-app': 'calico-kube-controllers'} |
    | kube-system | coredns                 | 2/2   | 2          | 2         | 19d0h  | coredns                 | {'k8s-app': 'kube-dns'}                |
    +-------------+-------------------------+-------+------------+-----------+--------+-------------------------+----------------------------------------+
    # 获取指定命名空间下的Deployment
    namespace = "default"
    table = PrettyTable()
    table.align = "l"
    table.field_names = ["NAMESPACE", "NAME", "READY", "UP-TO-DATE", "AVAILABLE", "AGE", "CONTAINERS",
                         "SELECTOR"]
    table.title = f"{namespace}名称空间下的Deployment"
    deploy_list = api_instance.list_namespaced_deployment(namespace=namespace)
    for deploy in deploy_list.items:
        containers = []
        for container in deploy.spec.template.spec.containers:
            containers.append(container.name)
        if len(containers) == 1:
            containers = containers[0]
        selector = None
        if deploy.spec.selector.match_labels:
            selector = deploy.spec.selector.match_labels
        else:
            selector = deploy.spec.selector.match_expressions
        table.add_row([deploy.metadata.namespace, deploy.metadata.name,
                       f"{deploy.status.ready_replicas}/{deploy.status.replicas}",
                       deploy.status.updated_replicas, deploy.status.available_replicas,
                       get_age(deploy.metadata.creation_timestamp),
                       containers if containers else "<none>",
                       selector if selector else "<none>"])
    print(table)
    +--------------------------------------------------------------------------------------------------------------+
    |                                        default名称空间下的Deployment                                         |
    +-----------+------------------+-------+------------+-----------+--------+------------+------------------------+
    | NAMESPACE | NAME             | READY | UP-TO-DATE | AVAILABLE | AGE    | CONTAINERS | SELECTOR               |
    +-----------+------------------+-------+------------+-----------+--------+------------+------------------------+
    | default   | nginx-deployment | 3/3   | 3          | 3         | 33m59s | nginx-http | {'app': 'http-server'} |
    +-----------+------------------+-------+------------+-----------+--------+------------+------------------------+
    # 获取指定deploy的相关信息
    name = "nginx-deployment"
    namespace = "default"
    table = PrettyTable()
    table.align = "l"
    table.field_names = ["NAMESPACE", "NAME", "READY", "UP-TO-DATE", "AVAILABLE", "AGE", "CONTAINERS",
                         "SELECTOR"]
    deploy = api_instance.read_namespaced_deployment(name=name, namespace=namespace)
    containers = []
    for container in deploy.spec.template.spec.containers:
        containers.append(container.name)
    if len(containers) == 1:
        containers = containers[0]
    selector = None
    if deploy.spec.selector.match_labels:
        selector = deploy.spec.selector.match_labels
    else:
        selector = deploy.spec.selector.match_expressions
    table.add_row([deploy.metadata.namespace, deploy.metadata.name,
                   f"{deploy.status.ready_replicas}/{deploy.status.replicas}",
                   deploy.status.updated_replicas, deploy.status.available_replicas,
                   get_age(deploy.metadata.creation_timestamp),
                   containers if containers else "<none>",
                   selector if selector else "<none>"])
    print(table)
    +-----------+------------------+-------+------------+-----------+--------+------------+------------------------+
    | NAMESPACE | NAME             | READY | UP-TO-DATE | AVAILABLE | AGE    | CONTAINERS | SELECTOR               |
    +-----------+------------------+-------+------------+-----------+--------+------------+------------------------+
    | default   | nginx-deployment | 3/3   | 3          | 3         | 35m21s | nginx-http | {'app': 'http-server'} |
    +-----------+------------------+-------+------------+-----------+--------+------------+------------------------+
    

    获取service的相关信息

    from kubernetes import client, config
    from prettytable import PrettyTable
    from common.k8s_format import get_age
    # 加载配置文件
    config.load_kube_config(config_file="examples/k8s/admin.conf")
    # 创建API对象
    api_instance = client.CoreV1Api()
    table = PrettyTable()
    table.align = "l"
    table.field_names = ["NAMESPACE", "NAME", "TYPE", "CLUSTER-IP", "EXTERNAL-IP", "PORT(S)", "AGE",
                         "SELECTOR"]
    table.title = "所有名称空间下的Service"
    svc_list = api_instance.list_service_for_all_namespaces()
    for svc in svc_list.items:
        table.add_row([svc.metadata.namespace, svc.metadata.name, svc.spec.type,
                       ",".join(svc.spec.cluster_i_ps),
                       ",".join(svc.spec.external_i_ps) if svc.spec.external_i_ps else "<none>",
                       ",".join(map(lambda x: str(x.port) + "/" + x.protocol, svc.spec.ports)),
                       get_age(svc.metadata.creation_timestamp),
                       svc.spec.selector if svc.spec.selector else "<none>"])
    print(table)
    +----------------------------------------------------------------------------------------------------------------------------+
    |                                                  所有名称空间下的Service                                                    |
    +-------------+------------+-----------+------------+-------------+------------------------+-------+-------------------------+
    | NAMESPACE   | NAME       | TYPE      | CLUSTER-IP | EXTERNAL-IP | PORT(S)                | AGE   | SELECTOR                |
    +-------------+------------+-----------+------------+-------------+------------------------+-------+-------------------------+
    | default     | kubernetes | ClusterIP | 10.96.0.1  | <none>      | 443/TCP                | 19d0h | <none>                  |
    | kube-system | kube-dns   | ClusterIP | 10.96.0.10 | <none>      | 53/UDP,53/TCP,9153/TCP | 19d0h | {'k8s-app': 'kube-dns'} |
    +-------------+------------+-----------+------------+-------------+------------------------+-------+-------------------------+
    # 获取指定名称空间下的所有service
    table = PrettyTable()
    table.align = "l"
    table.field_names = ["NAMESPACE", "NAME", "TYPE", "CLUSTER-IP", "EXTERNAL-IP", "PORT(S)", "AGE",
                         "SELECTOR"]
    namespace = "default"
    table.title = f"{namespace}名称空间下的Service"
    svc_list = api_instance.list_namespaced_service(namespace=namespace)
    for svc in svc_list.items:
        table.add_row([svc.metadata.namespace, svc.metadata.name, svc.spec.type,
                       ",".join(svc.spec.cluster_i_ps),
                       ",".join(svc.spec.external_i_ps) if svc.spec.external_i_ps else "<none>",
                       ",".join(map(lambda x: str(x.port) + "/" + x.protocol, svc.spec.ports)),
                       get_age(svc.metadata.creation_timestamp),
                       svc.spec.selector if svc.spec.selector else "<none>"])
    print(table)
    +--------------------------------------------------------------------------------------------+
    |                                 default名称空间下的Service                                  |
    +-----------+------------+-----------+------------+-------------+---------+-------+----------+
    | NAMESPACE | NAME       | TYPE      | CLUSTER-IP | EXTERNAL-IP | PORT(S) | AGE   | SELECTOR |
    +-----------+------------+-----------+------------+-------------+---------+-------+----------+
    | default   | kubernetes | ClusterIP | 10.96.0.1  | <none>      | 443/TCP | 19d0h | <none>   |
    +-----------+------------+-----------+------------+-------------+---------+-------+----------+
    # 获取指定service的信息
    table = PrettyTable()
    table.align = "l"
    table.field_names = ["NAMESPACE", "NAME", "TYPE", "CLUSTER-IP", "EXTERNAL-IP", "PORT(S)", "AGE",
                         "SELECTOR"]
    namespace = "default"
    name="kubernetes"
    svc = api_instance.read_namespaced_service(name=name, namespace=namespace)
    table.add_row([svc.metadata.namespace, svc.metadata.name, svc.spec.type,
                   ",".join(svc.spec.cluster_i_ps),
                   ",".join(svc.spec.external_i_ps) if svc.spec.external_i_ps else "<none>",
                   ",".join(map(lambda x: str(x.port) + "/" + x.protocol, svc.spec.ports)),
                   get_age(svc.metadata.creation_timestamp),
                   svc.spec.selector if svc.spec.selector else "<none>"])
    print(table)
    +-----------+------------+-----------+------------+-------------+---------+-------+----------+
    | NAMESPACE | NAME       | TYPE      | CLUSTER-IP | EXTERNAL-IP | PORT(S) | AGE   | SELECTOR |
    +-----------+------------+-----------+------------+-------------+---------+-------+----------+
    | default   | kubernetes | ClusterIP | 10.96.0.1  | <none>      | 443/TCP | 19d0h | <none>   |
    +-----------+------------+-----------+------------+-------------+---------+-------+----------+
    

    大概分两类:

  • 不需要指定什么类型的资源,根据给出的资源清单创建文件
  • 创建什么资源就用什么特定的接口
  • 通过yaml文件创建

    yaml文件

    # nginx.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: http-server
      strategy:
        type: Recreate
      template:
        metadata:
          labels:
            app: http-server
        spec:
          containers:
          - name: nginx-http
            image: nginx:latest
            imagePullPolicy: IfNotPresent
            ports:
            - protocol: TCP
              containerPort: 80
    
    from kubernetes import client, config, utils
    # 加载配置文件
    config.load_kube_config(config_file="examples/k8s/admin.conf")
    k8s_client = client.ApiClient()
    utils.create_from_yaml(k8s_client, "examples/k8s/nginx/nginx.yaml",verbose=True)
    

    通过文件夹创建资源

    from kubernetes import client, config, utils
    # 加载配置文件
    config.load_kube_config(config_file="examples/k8s/admin.conf")
    k8s_client = client.ApiClient()
    utils.create_from_directory(k8s_client, yaml_dir="examples/k8s/nginx", verbose=True)
    

    通过字典创建资源

    from kubernetes import client, config, utils
    # 加载配置文件
    config.load_kube_config(config_file="examples/k8s/admin.conf")
    k8s_client = client.ApiClient()
    data = {
        'apiVersion': 'apps/v1',
        'kind'      : 'Deployment',
        'metadata'  : { 'name': 'nginx-deployment' },
        'spec'      : {
            'replicas': 3,
            'selector': {
                'matchLabels': { 'app': 'http-server' }
            'strategy': { 'type': 'Recreate' },
            'template': {
                'metadata': {
                    'labels': {
                        'app': 'http-server'
                'spec'    : {
                    'containers': [
                            'name'           : 'nginx-http',
                            'image'          : 'nginx:latest',
                            'imagePullPolicy': 'IfNotPresent',
                            'ports'          : [
                                    'protocol'     : 'TCP',
                                    'containerPort': 80
    utils.create_from_dict(k8s_client, data=data, verbose=True)
    

    通过专门的接口来创建资源

    这里以 创建deploy举例

    from kubernetes import client, config, utils
    from kubernetes.client import exceptions
    import yaml
    # 加载配置文件
    config.load_kube_config(config_file="examples/k8s/admin.conf")
    api_instance = client.AppsV1Api()
    with open("examples/k8s/nginx/nginx.yaml") as f:
        nginx = yaml.safe_load(f)
        res = api_instance.create_namespaced_deployment(namespace="default", body=nginx)
        print(res)
    except exceptions.ApiException as e:
        print("状态码:", e.status)
        print("错误信息:", e.body)
    

    以上基本都是通过读取yaml文件或者类似的资源清单来创建的

    其实也可以通过接口一步步新建一个资源,只是比较复杂而已

    通过接口创建资源

    from kubernetes import client, config
    # 加载配置文件
    config.load_kube_config(config_file="examples/k8s/admin.conf")
    DEPLOYMENT_NAME = "nginx-deployment"
    # 配置Pod容器
    container = client.V1Container(
            name="nginx",
            image="nginx:latest",
            ports=[client.V1ContainerPort(container_port=80)],
            resources=client.V1ResourceRequirements(
                    requests={ "cpu": "100m", "memory": "200Mi" },
                    limits={ "cpu": "500m", "memory": "500Mi" },
    # 创建容器模板
    template = client.V1PodTemplateSpec(
            metadata=client.V1ObjectMeta(labels={ "app": "nginx" }),
            spec=client.V1PodSpec(containers=[container]),
    # 创建spec
    spec = client.V1DeploymentSpec(
            replicas=3, template=template, selector={
                "matchLabels":
                    { "app": "nginx" } })
    # 创建deploy对象
    deployment = client.V1Deployment(
            api_version="apps/v1",
            kind="Deployment",
            metadata=client.V1ObjectMeta(name=DEPLOYMENT_NAME),
            spec=spec,
    api = client.AppsV1Api()
    # 运行部署
    resp = api.create_namespaced_deployment(
            body=deployment, namespace="default"
    print("\n[INFO] deployment `nginx-deployment` created.\n")
    print("%s\t%s\t\t\t%s\t%s" % ("NAMESPACE", "NAME", "REVISION", "IMAGE"))
    print(
            "%s\t\t%s\t%s\t\t%s\n"
                resp.metadata.namespace,
                resp.metadata.name,
                resp.metadata.generation,
                resp.spec.template.spec.containers[0].image,
    

    对资源的CRUD

    这里以deployment为例

    from kubernetes import client, config
    import yaml
    from kubernetes.client import exceptions
    # 加载配置文件
    config.load_kube_config(config_file="examples/k8s/admin.conf")
    api_instance = client.AppsV1Api()
    with open("examples/k8s/nginx/nginx.yaml") as f:
        nginx = yaml.safe_load(f)
        res = api_instance.create_namespaced_deployment(body=nginx)
        print(res)
    except exceptions.ApiException as e:
        print("状态码:", e.status)
        print("错误信息:", e.body)
    
    from kubernetes import client, config
    # 加载配置文件
    config.load_kube_config(config_file="examples/k8s/admin.conf")
    name = "nginx-deployment"
    namespace = "default"
    api_instance = client.AppsV1Api()
    res = api_instance.delete_namespaced_deployment(namespace=ns, name=deploy_name)
    print(res)
    
    from kubernetes import client, config
    # 加载配置文件
    config.load_kube_config(config_file="examples/k8s/admin.conf")
    name = "nginx-deployment"
    namespace = "default"
    api_instance = client.AppsV1Api()
    res = api_instance.read_namespaced_deployment(namespace=ns, name=deploy_name)
    print(res)
    
    from kubernetes import client, config
    # 加载配置文件
    config.load_kube_config(config_file="examples/k8s/admin.conf")
    # 先查找
    name = "nginx-deployment"
    namespace = "default"
    api_instance = client.AppsV1Api()
    deploy = api_instance.read_namespaced_deployment(namespace=namespace, name=name)
    # 再修改
    deploy.spec.replicas = 1
    res = api_instance.patch_namespaced_deployment(
            namespace=deploy.metadata.namespace,
            name=deploy.metadata.name,
            body=deploy
    print(res)
    

    重启deploy

    from kubernetes import client, config
    import datetime
    import pytz
    # 加载配置文件
    config.load_kube_config(config_file="examples/k8s/admin.conf")
    # 先查找
    name = "nginx-deployment"
    namespace = "default"
    api_instance = client.AppsV1Api()
    deploy = api_instance.read_namespaced_deployment(namespace=namespace, name=name)
    # 再重启
    # update `spec.template.metadata` section
    # to add `kubectl.kubernetes.io/restartedAt` annotation
    deploy.spec.template.metadata.annotations = {
        "kubectl.kubernetes.io/restartedAt": datetime.datetime.now(tz=pytz.UTC)
        .isoformat()
    api_instance = client.AppsV1Api()
    # patch the deployment
    resp = api_instance.patch_namespaced_deployment(
            name=name, namespace=namespace, body=deploy
    print("\n[INFO] deployment `nginx-deployment` restarted.\n")
    print("%s\t\t\t%s\t%s" % ("NAME", "REVISION", "RESTARTED-AT"))
    print(
            "%s\t%s\t\t%s\n"
                resp.metadata.name,
                resp.metadata.generation,
                resp.spec.template.metadata.annotations,