K8S微服务部署完之后自动修改RC并重启微服务

好久没更新过了,今天把这个习惯拾起来吧。

背景

之前自己在公司做了一个平台,可以实现自动部署微服务到测试环境,但RC文件的配置还是按照生产环境来的,所以有同事提了个需求,就是自动部署完之后自动修改RC文件并重启。

开始实施

在自己完成测试工作之后开始分析、设计、实施的,大概花了多半天的时间,大部分时间还是在前期分析上,知道怎么弄了后,代码还是很好写出来的。
鉴于自己之前对K8S的操作仅在一些命令行上,以这个操作为例,更改RC:kubectl edit rc xxx-rc,删除微服务:kubectl delete pod xxx;这种方式去自动化实现其实是不可行的,python可以与后台进行交互,但自动进入到vim里面去操作就似乎是不可实现的。
百度了一堆资料后,发现了一个切入点:官方API
果然有对应的API操作:

# prefix为k8s api的前缀,各公司的应该不尽相同吧
# 获取指定的RC文件信息(Json格式):
rc_by_name = ['GET', prefix + '/api/v1/namespaces/{namespace}/replicationcontrollers/{name}']  # read the specified ReplicationController
# 替换RC
rc_replace_by_name = ['PUT', prefix + '/api/v1/namespaces/{namespace}/replicationcontrollers/{name}']  # replace the specified ReplicationController
# 获取所有Pod列表信息
pod_list = ['GET', prefix + '/api/v1/pods']  # list or watch objects of kind Pod
# 删除指定Pod
pod_delete_by_name = ['DELETE', prefix + '/api/v1/namespaces/{namespace}/pods/{name}']  # delete a Pod

看到这几个API,使这个修改RC并重启Pod的大致思路想必大家都知道了。

  1. 获取指定RC的信息;
  2. 根据RC信息修改部分字段;
  3. 调用replace rc接口;
  4. 查找所有pod,删除所有与RC文件想匹配的Pod。

步骤1不用介绍;
步骤2需要提示下,接口获取到的RC信息是比较多的,不过大多数是去改环境变量,也就是如下部分中的字段:

# resp为获取到的RC的信息,dict格式
# containers一般为1个,也有多个的情况
# env_index为环境变量的索引,获取到RC信息后看到Json文件就知道什么含义了
resp['spec']['template']['spec']['containers'][0]['env'][env_index]['value']

步骤3中有个小坑,如果不注意的话会报错的,那就是得去除resourceVersion的信息:

resp['metadata'].pop('resourceVersion')

步骤4就不多说了。

光说无码假把式,整体的执行流程见下面的代码:

import requests

from *** import K8SAPI  # 将K8S API集中写到单独的一个python文件中了


class K8sOperations:

    def __init__(self, master_ip, namespace='default'):
        self.master_ip = master_ip
        self.namespace = namespace

    def replace_rc(self, rc, env_index, name, value):
        method, url = K8SAPI.rc_by_name
        url = url.format(MASTER_IP=self.master_ip, namespace=self.namespace, name=rc)
        resp = requests.request(method, url).json()
        resp['metadata'].pop('resourceVersion')
        if resp['spec']['template']['spec']['containers'][0]['env'][env_index]['name'] == name:
            resp['spec']['template']['spec']['containers'][0]['env'][env_index]['value'] = value
            response = requests.put(url=url, json=resp)
            if response.status_code == 200:
                return True
            else:
                return False
        else:
            return 'Index or Name Error'

    def get_pods_via_rc(self, rc):
        method, url = K8SAPI.pod_list
        url = url.format(MASTER_IP=self.master_ip)
        pods = requests.request(method, url).json()['items']
        pod_list = []
        for each in pods:
            if rc in each['metadata']['name']:
                pod_list.append(each['metadata']['name'])
        return pod_list

    def delete_pods(self, pod_list):
        method, url = K8SAPI.pod_delete_by_name
        code_sum = 0
        for each in pod_list:
            url = url.format(MASTER_IP=self.master_ip, namespace=self.namespace, name=each)
            resp = requests.request(method, url)
            code_sum += resp.status_code
        if code_sum == 200*len(pod_list):
            return True
        else:
            return False

    def modify_rc_streamline(self, rc, env_index, name, value):
        result = self.replace_rc(rc, env_index, name, value)
        if not result:
            return result
        elif result is not True:
            return result
        pod_list = self.get_pods_via_rc(rc)
        result = self.delete_pods(pod_list)
        if result:
            return True
        else:
            return 'RC修改完成但重启Pod异常'

实现功能的代码如上,至于怎么写API,各位看官自有各自的一套风格,这儿就不再赘述了。

成品

确切的说是半成品,将功能完成并可以自由去使用了,但还没有去做自动部署完后自动执行改RC,做的话也很容易,就是需要调研一下详细的需求,因为不同的项目组行为不一样,可能有的项目组一个RC需要改几个地方,有的项目组一次性改多个RC,需要对所有的项目组做调查。当然把所有的可能性都编写出来最好,但不会用到的可能性不就是无用功嘛。
直接上图:


完成

后端是Vue.js,虽不精通,但能造东西,我觉得作为测试工程师这就够了,至少目前够了。庞大的技术体系面前,哪能样样精通。如果后期有需要,那就学它丫的

后记

今晚有点失眠。。

你可能感兴趣的:(K8S微服务部署完之后自动修改RC并重启微服务)