【Kubernetes 021】Python客户端自动创建和销毁Kubernetes资源详解

学会了k8s的基本使用,下面就可以开始一些进阶的学习了,例如二次开发。想象有一个网页管理工具,管理人员只需要点击一个按钮,后台就会自动按照预先设定好的参数创建资源。当资源使用完毕,又可以点击另一个按钮自动删除资源。这一节我们就一起来学习如何用python来完成这一目的。

我是T型人小付,一位坚持终身学习的互联网从业者。喜欢我的博客欢迎在csdn上关注我,如果有问题欢迎在底下的评论区交流,谢谢。

客户端

之前我们一直用的kubectl这个客户端去连接的API server,其通过~/.kube/config文件内的信息完成验证,进而进行API交互。所以其实理论上,只要有程序能获得同样的认证信息,就可以和kubectl一样完成这样的交互。于是官方用各种语言写了这样的一个客户端,并开源在了Github上,见这里。其中星标最多的当属python客户端了,于是我们就来试一试这款官方推出的python客户端。

对于用户config文件内容感兴趣的可以参考我的另一篇博客《【Kubernetes 018】cfssl创建证书并结合RBAC的RoleBinding配置新用户config文件操作详解》

操作思路

官方的Readme里面已经给出了各种代码示例,从这些示例里面大概能总结出操作的一些基本步骤,我这里按照我自己的理解总结如下

  1. 首先是获取认证信息,直接通过用户的config文件导入即可
  2. 查阅k8s的API Reference获取资源对应的API分支,例如deployment就是Deployment v1 apps,而对应到客户端的API类列表中的apps_v1_api.py。如果是service就是Service v1 core,对应到客户端的core_v1_api.py
  3. 然后对API的各个字段进行设置,可以单独设置,也可以直接用之前配置好的yaml文件
  4. 利用客户端类的各种方法去对资源进行创建更新或者删除

注意,因为k8s中的API分支多大几十种,在选择的时候要仔细点,不然会出现API版本不匹配的报错。

实际操作

我这里操作使用的环境如下

  • python 3.7.1
  • pycharm 2019.3 professional
  • kubernetes集群 1.15
  • kubernetes库 11.0.0

还是以创建《部署Rasa框架到Kubernetes集群并分配GPU资源》同样的资源来作为操作演示。

安装kubernetes库

直接利用pip安装即可,或者在pycharm里面安装,如下

1-package.png

之后就可以在项目中引入了

from kubernetes import client, config

获取认证信息

我这里创建了一个叫k8s_client的项目,然后将config文件拷贝到项目的根目录,用下面的方法从文件导入认证信息

BASE_URL = '/home/fuhx/python_projects/k8s/k8s_client/'
cf = config.load_kube_config(path.join(BASE_URL, 'config'))

创建API实例

如果要创建Deployment,创建一个apps_v1_api.py的API实例如下

apps_v1_api = client.AppsV1Api()

如果要创建Service,创建一个core_v1_api.py的API实例如下

core_v1_api = client.CoreV1Api()

导入yaml文件

我这里在项目根目录下创建了yaml目录,里面放了两个yaml文件rasa-deployment.yamlrasa-service.yaml分别创建Deployment和Service。这里的两个文件是上一篇博客《部署Rasa框架到Kubernetes集群并分配GPU资源》中用到的文件,但是添加了一些字段,如下

apiVersion: apps/v1
kind: Deployment
metadata:
  name: rasa-deployment-2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: rasa-2
  template:
    metadata:
      labels:
        app: rasa-2
    spec:
      containers:
        - name: myrasa
          image: myrasa:v2
          ports:
            - containerPort: 5005
          command: ["/bin/sh","-c","rasa init --no-prompt;rasa run --enable-api"]
          livenessProbe:
            httpGet:
              port: 5005
              path: /
            initialDelaySeconds: 1
            periodSeconds: 3
          resources:
            limits:
              aliyun.com/gpu-mem: 1
          volumeMounts:
            - mountPath: /app
              name: rasa-app
            - mountPath: /tmp
              name: rasa-tmp
      volumes:
        - name: rasa-app
          emptyDir: {}
        - name: rasa-tmp
          emptyDir: {}

需要注意,这里除了修改了下名字以与现有资源不冲突以外,还添加了下面这一段

  selector:
    matchLabels:
      app: rasa-2

直接用kubectl的时候不用添加但是这里必须要添加,或许是因为这里的规范比较严格,不然在执行的时候会出现如下报错

...
...
kubernetes.client.rest.ApiException: (422)
Reason: Unprocessable Entity
HTTP response headers: HTTPHeaderDict({'Content-Type': 'application/json', 'Date': 'Fri, 22 May 2020 08:04:23 GMT', 'Content-Length': '672'})
HTTP response body: {"kind":"Status","apiVersion":"v1","metadata":{},"status":"Failure","message":"Deployment.apps \"rasa-deployment-2\" is invalid: [spec.selector: Required value, spec.template.metadata.labels: Invalid value: map[string]string{\"app\":\"rasa-2\"}: `selector` does not match template `labels`]","reason":"Invalid","details":{"name":"rasa-deployment-2","group":"apps","kind":"Deployment","causes":[{"reason":"FieldValueRequired","message":"Required value","field":"spec.selector"},{"reason":"FieldValueInvalid","message":"Invalid value: map[string]string{\"app\":\"rasa-2\"}: `selector` does not match template `labels`","field":"spec.template.metadata.labels"}]},"code":422}



Process finished with exit code 1

Service需要注意修改端口避免跟现有资源冲突

apiVersion: v1
kind: Service
metadata:
  name: rasa-service-2
spec:
  type: NodePort
  selector:
    app: rasa-2
  ports:
    - name: http
      port: 5005
      targetPort: 5005
      nodePort: 31112

这里因为两个资源属于不同API分支,要用不同的类实例去创建,所以不能放在同一个文件用用---隔开。

之后就可以分别导入备用了

with open(path.join(BASE_URL, 'yaml/rasa_deployment.yaml')) as f:
    dep = yaml.safe_load(f)
with open(path.join(BASE_URL, 'yaml/rasa_service.yaml')) as f:
    svc = yaml.safe_load(f)

yaml和json一样用直接load进来变为字典格式,不过yaml为了安全起见有一个safe_load命令,只会去解析一些基本yaml语法,一般情况下用safe得就可以了

创建和删除

分别调用API实例得方法即可,这里单独创建了4个函数用来处理

def create_deployment(api_instance, body):
    api_response = api_instance.create_namespaced_deployment(
        body=body,
        namespace='default')
    print(api_response)
    # print("Deployment created. status='%s'" % str(api_response.status))


def delete_deployment(api_instance, name):
    api_response = api_instance.delete_namespaced_deployment(
        name=name,
        namespace='default'
    )
    print(api_response)


def create_service(api_instance, body):
    api_response = api_instance.create_namespaced_service(
        body=body,
        namespace='default'
    )
    print(api_response)


def delete_service(api_instance, name):
    api_response = api_instance.delete_namespaced_service(
        name=name,
        namespace='default'
    )
    print(api_response)

最后在main函数中去调用即可,我这里就不写复杂得逻辑判断了

BASE_URL = '/home/fuhx/python_projects/k8s/k8s_client/'
cf = config.load_kube_config(path.join(BASE_URL, 'config'))
core_v1_api = client.CoreV1Api()
apps_v1_api = client.AppsV1Api()
with open(path.join(BASE_URL, 'yaml/rasa_deployment.yaml')) as f:
	dep = yaml.safe_load(f)
with open(path.join(BASE_URL, 'yaml/rasa_service.yaml')) as f:
	svc = yaml.safe_load(f)
create_deployment(apps_v1_api, dep)
# create_service(core_v1_api, svc)
# delete_deployment(apps_v1_api, 'rasa-deployment-2')
# delete_service(core_v1_api, 'rasa-service-2')

检查效果

如果API方法没有报错就可以认为资源的操作没有问题,这时候就可以去集群内部检查下资源状况,当然安装了ELK或者Prometheus的就直接图形界面查看了。

root@control-plane-1:~# kubectl get pod -o wide
NAME                                 READY   STATUS    RESTARTS   AGE    IP            NODE       NOMINATED NODE   READINESS GATES
curl-6bf6db5c4f-fr2xv                1/1     Running   0          2d3h   10.244.2.2    gpu-node   <none>           <none>
nvidia-deployment-5f4bbd9457-2rj7r   1/1     Running   1          2d3h   10.244.2.4    gpu-node   <none>           <none>
nvidia-deployment-5f4bbd9457-hfxqh   1/1     Running   1          2d3h   10.244.2.3    gpu-node   <none>           <none>
rasa-deployment-2-6446bc5d4d-dp229   1/1     Running   0          19s    10.244.2.12   gpu-node   <none>           <none>
rasa-deployment-586ff4666-hf6xm      1/1     Running   0          2d2h   10.244.2.8    gpu-node   <none>           <none>
root@control-plane-1:~# kubectl get svc
NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes       ClusterIP   10.96.0.1        <none>        443/TCP          2d23h
rasa-service     NodePort    10.108.95.50     <none>        5005:31111/TCP   43h
rasa-service-2   NodePort    10.102.214.112   <none>        5005:31112/TCP   31s

从另外一台机器上试一下Service的端口服务

[root@ai-asterisk ~]# curl -X POST 172.29.57.202:31112/webhooks/rest/webhook -d '{"sender":"xiaofu","message":"How are you?"}'
[{"recipient_id":"xiaofu","text":"I am a bot, powered by Rasa."}]

总结

这里只是抛砖引玉,简单找了两个资源尝试了一下添加和删除,更多的API等着我们在实际项目中慢慢探索。有了python客户端我们就可以将k8s的自动化操作融入到一些运维平台中了,如果有机会我们以后再分享更多这方面的内容。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值