<python模块>kubernetes

时间:Jan. 17, 2019 分类:

目录:

下载方式

pip install kubernetes

官方例子

用法参考官方的例子

from kubernetes import client, config

config.load_kube_config()

v1 = client.CoreV1Api()

print("Listing pods with their IPs:")

ret = v1.list_pod_for_all_namespaces(watch=False)

for i in ret.items:
    print("%s\t%s\t%s" %
    (i.status.pod_ip, i.metadata.namespace, i.metadata.name))

可以在文档里找到对应的Class和method,可以看下相信的方法介绍

Deployment资源操作

create

自动化功能更多就是就通过获取元数据来创建需要的资源

示例AppsV1Api下的create_namespaced_deployment方法

Name Type Description Notes
namespace str object name and auth scope, such as for teams and projects
body V1Deployment
include_uninitialized bool If true, partially initialized resources are included in the response. [optional]
pretty str If 'true', then the output is pretty printed. [optional]
dry_run str When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed [optional]
  • include_uninitialized为是否在response中包含initialized的容器信息
  • pretty是否添加tty终端
  • dry_run未知

官方示例简化一下就是

from kubernetes import client, config

config.load_kube_config()

DEPLOYMENT_NAME = "nginx-deployment"

def create_deployment_object():
    # Configureate Pod template container
    container = client.V1Container(
        name="nginx",
        image="nginx:1.7.9",
        ports=[client.V1ContainerPort(container_port=80)])
    # Create and configurate a spec section
    template = client.V1PodTemplateSpec(
        metadata=client.V1ObjectMeta(labels={"app": "nginx"}),
        spec=client.V1PodSpec(containers=[container]))
    # Create the specification of deployment
    spec = client.ExtensionsV1beta1DeploymentSpec(
        replicas=3,
        template=template)
    # Instantiate the deployment object
    deployment = client.ExtensionsV1beta1Deployment(
        api_version="extensions/v1beta1",
        kind="Deployment",
        metadata=client.V1ObjectMeta(name=DEPLOYMENT_NAME),
        spec=spec)
    return deployment

extensions_v1beta1 = client.ExtensionsV1beta1Api()

deployment = create_deployment_object()

extensions_v1beta1.create_namespaced_deployment(namespace="default", body=deployment)

执行结果

$ kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           90s

更多的配置还需要去V1Deployment获取,这边也可以直接以yaml或者json的方式

$ kubectl get deployments nginx-deployment  -o json
$ kubectl delete deployments nginx-deployment  
deployment.extensions "nginx-deployment" deleted

然后将一些需要kubernetes自动生成的配置和一些无用的配置删除,直接将Deployment定义为一个json

deployment = {
    "apiVersion": "extensions/v1beta1",
    "kind": "Deployment",
    "metadata": {
        "labels": {
            "app": "nginx"
        },
        "name": "nginx-deployment",
        "namespace": "default",
    },
    "spec": {
        "replicas": 3,
        "selector": {
            "matchLabels": {
                "app": "nginx"
            }
        },
        "template": {
            "metadata": {
                "labels": {
                    "app": "nginx"
                }
            },
            "spec": {
                "containers": [
                    {
                        "image": "nginx:1.7.9",
                        "name": "nginx",
                        "ports": [
                            {
                                "containerPort": 80,
                                "protocol": "TCP"
                            }
                        ],
                    }
                ],
                "restartPolicy": "Always",
            }
        }
    }
}

直接通过字典的方式可以,构建起来非常方便,也可以通过open的方式打开一个yaml作为body

这样也是可以的,create_namespaced_deployment方法的返回结果是一个kubernetes.client.models.extensions_v1beta1_deployment.ExtensionsV1beta1Deployment对象

Delete

官方文档上是说只需要namespace和namespace,但是如果只传这两个参数会报错TypeError: delete_namespaced_deployment() takes exactly 4 arguments (3 given)

当设置body为None的时候也是报错,不过报出相关的代码路径和行数了,这边查看了一下

$ /usr/lib/python2.7/site-packages/kubernetes/client/apis/extensions_v1beta1_api.py +1783
        ...
        if kwargs.get('async_req'):
            return self.delete_namespaced_deployment_with_http_info(name, namespace, body, **kwargs)
        else:
            (data) = self.delete_namespaced_deployment_with_http_info(name, namespace, body, **kwargs)
            return data
        ...

可以看到这里需要body参数的,这边我传了个空字典

extensions_v1beta1.delete_namespaced_deployment(namespace="default",name=DEPLOYMENT_NAME, body={})

Read

c = extensions_v1beta1.read_namespaced_deployment(namespace="default", name=DEPLOYMENT_NAME)
print type(c.api_version)
print type(c.spec)
print type(c.spec.replicas)
print type(c.spec.template)

执行结果

<type 'str'>
<class 'kubernetes.client.models.extensions_v1beta1_deployment_spec.ExtensionsV1beta1DeploymentSpec'>
<type 'int'>
<class 'kubernetes.client.models.v1_pod_template_spec.V1PodTemplateSpec'>

可以到返回的有些是对象,有些则是值了,更多参考V1Deployment对象的定义

Patch

先获取原来的deployment对象,修改对应的值

old_deployment_obj = extensions_v1beta1.read_namespaced_deployment(namespace="default", name=DEPLOYMENT_NAME)
print old_deployment_obj.spec.template.spec.containers[0].image
old_deployment_obj.spec.template.spec.containers[0].image = "nginx:1.9.1"
new_deployment_obj = extensions_v1beta1.patch_namespaced_deployment(namespace="default",name=DEPLOYMENT_NAME, body=old_deployment_obj)
print new_deployment_obj.spec.template.spec.containers[0].image

Replace

Replace和Patch在参数上看起来是一样的

Rollback

回滚的deployment可以使用create_namespaced_deployment_rollback

通过api创建的默认是使用了--record参数的

extensions_v1beta1.create_namespaced_deployment_rollback(namespace="default",name=DEPLOYMENT_NAME, body={ "name" : DEPLOYMENT_NAME, "rollback_to" : { "revision" : 3} })

详细的信息可以通过kubectl rollout history进行回滚

$ kubectl rollout history deployment/nginx-deployment --revision 2

部署版本等信息最好还是自行保存或者调控一下会比较好

创建自定义对象

参考官方示例

from __future__ import print_function

from pprint import pprint

import kubernetes
from kubernetes import config
from kubernetes.rest import ApiException

config.load_kube_config()
api_instance = kubernetes.ThirdPartyResources()

namespace = 'default'
resource = 'repos'
fqdn = 'git.k8s.com'

body = {}
body['apiVersion'] = "git.k8s.com/v1"
body['kind'] = "RePo"
body['metadata'] = {}
body['metadata']['name'] = "blog-repo"
body['repo'] = "github.com/user/my-blog"
body['username'] = "username"
body['password'] = "password"
body['branch'] = "branch"



try: 
    # Create a Resource
    api_response = api_instance.apis_fqdn_v1_namespaces_namespace_resource_post(
        namespace, fqdn, resource, body)
    pprint(api_response)
except ApiException as e:
    print(
        "Exception when calling DefaultApi->apis_fqdn_v1_namespaces_namespace_resource_post: %s\n" % 
        e)

watch

https://github.com/kubernetes-client/python/blob/master/kubernetes/docs/V1WatchEvent.md

from kubernetes import client,config,watch

config.load_kube_config()

v1=client.CoreV1Api()

def main():
    w = watch.Watch()
    for event in w.stream(v1.list_namespaced_pod,"default"):
        try:
            print("Event: %s, Status: %s, PodName: %s" % (event['type'], event['object'].status.phase, event['object'].metadata.name))
        except:
            print("Event: %s, Status: %s, PodName: %s" % (event['type'], None, event['object'].metadata.name))

if __name__ == '__main__':
    main()

获取Pod

$ kubectl get pod
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-76bf4969df-7gmcp   1/1     Running   0          43m
nginx-deployment-76bf4969df-cmv66   1/1     Running   0          4m37s
nginx-deployment-76bf4969df-djnwj   1/1     Running   0          8m40s

执行脚本

$ python watchk8s.py
Event: ADDED, Status: Running, PodName: nginx-deployment-76bf4969df-cmv66
Event: ADDED, Status: Running, PodName: nginx-deployment-76bf4969df-djnwj
Event: ADDED, Status: Running, PodName: nginx-deployment-76bf4969df-7gmcp

删除掉一个Pod

$ kubectl delete pod nginx-deployment-76bf4969df-djnwj
pod "nginx-deployment-76bf4969df-djnwj" deleted
$ python watchk8s.py
Event: ADDED, Status: Running, PodName: nginx-deployment-76bf4969df-cmv66
Event: ADDED, Status: Running, PodName: nginx-deployment-76bf4969df-djnwj
Event: ADDED, Status: Running, PodName: nginx-deployment-76bf4969df-7gmcp


Event: MODIFIED, Status: Running, PodName: nginx-deployment-76bf4969df-djnwj
Event: ADDED, Status: Pending, PodName: nginx-deployment-76bf4969df-hw4v5
Event: MODIFIED, Status: Pending, PodName: nginx-deployment-76bf4969df-hw4v5
Event: MODIFIED, Status: Pending, PodName: nginx-deployment-76bf4969df-hw4v5
Event: MODIFIED, Status: Running, PodName: nginx-deployment-76bf4969df-djnwj
Event: MODIFIED, Status: Running, PodName: nginx-deployment-76bf4969df-hw4v5
Event: MODIFIED, Status: Running, PodName: nginx-deployment-76bf4969df-djnwj
Event: DELETED, Status: Running, PodName: nginx-deployment-76bf4969df-djnwj

可以看到有四个新创建的nginx-deployment-76bf4969df-hw4v5的Event,分别对应的就是描述的四个Reason

$ kubectl describe pod nginx-deployment-76bf4969df-hw4v5
...
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  40s   default-scheduler  Successfully assigned default/nginx-deployment-76bf4969df-hw4v5 to node-01
  Normal  Pulled     39s   kubelet, node-01   Container image "nginx:1.7.9" already present on machine
  Normal  Created    39s   kubelet, node-01   Created container
  Normal  Started    39s   kubelet, node-01   Started container

可以在Pod,Deployment或者Service创建或者删除的时候进行一些自定义的操作