最新消息:

如何获取到Kubernetes中的版本发布信息

IT技术 ipcpu 796浏览 0评论

一、背景介绍

我司使用的是阿里云的Kubernetes容器服务,也没有什么版本发布系统,测试人员测试完毕以后,直接更新了阿里云的服务镜像地址,如下

虽然,阿里云在界面中也提供了历史版本的查看功能,但是我们想把这部分信息集中存放起来并提供查询功能,该怎么处理呢?

二、实现思路

我们优先想到的是阿里云可以提供相关的API接口,给我们获取到这些信息,奈何阿里云对于Kubernetes容器服务都没有API接口,让我们自行对接原生Kubernetes服务的API。

与此同时,我的另外一位同事对prometheus的监控项和k8s event进行了整理和查找,k8sevent里面并没有发现相关的信息,但是prometheus中是有相关监控项的。

三、简单实现,通过Prometheus

Prometheus的实现如下方语句

changes(kube_deployment_status_observed_generation[5m])!=0 

但是上面的监控项存在一个致命缺点,当deployment自动扩容缩容时也会变化,因此需要使用如下语句

changes(kube_deployment_status_observed_generation[5m])!=0 and changes(kube_deployment_status_replicas_available[5m]) == 0

通过以上语句,我们基本实现了获取是哪个namespace的哪个deployment发布了新版本,通过prometheus报警发出的时间,也可以大致判断出发版的时间(相差两三分钟)。可是在我们实际的生产应用中发现会出现不少误报的情况。

四、更加精确详细,K8S API

prometheus的监控数据中没有版本信息,并且时间上有些偏差,因此我们决定使用Kubernetes原生API,经过一番查找,用google搜索kubernetes deployment history 等信息也没有相关的发现,最后在github里发现一个issue[参考资料1], list_namespaced_replica_set 或者 list_replica_set_for_all_namespaces 中存储了相关信息,终于有所收获。

接下来就是分析下接口返回内容,并对有效数据进行提取了,我们的代码如下,供大家参考:

from kubernetes import client, config

config.load_kube_config(config_file='./config')
api_instance = client.AppsV1Api()


def get_images_from_namespace( namespace: str) -> dict:
    output = dict()

    repl = api_instance.list_namespaced_replica_set(namespace=namespace)
    for replica_set in repl.items:
        if 'app' not in replica_set.metadata.labels:
            app_name = f'{replica_set.spec.template.spec.service_account}'
        else:
            app_name = f'{replica_set.metadata.labels["app"]}'
        if app_name not in output:
            output[app_name] = []
        app_record = dict()
        if 'deployment.kubernetes.io/revision' in replica_set.metadata.annotations:
            app_record['revision'] = replica_set.metadata.annotations['deployment.kubernetes.io/revision']
            app_record['creation_timestamp'] = replica_set.metadata.creation_timestamp
        app_record['containers'] = list()
        for container in replica_set.spec.template.spec.containers:
            app_record['containers'].append(container.image)
        output[app_name].append(app_record)
    return output


print(get_images_from_namespace(namespace='default'))

代码运行效果:

{
    'gitlab-aliyun-deploy': [{
        'revision': '1',
        'creation_timestamp': datetime.datetime(2020, 7, 16, 6, 17, 23, tzinfo = tzutc()),
        'containers': ['reg.ipcpu.com/juestest/my-deploy:1131-5d6f0278']
    }, {
        'revision': '3',
        'creation_timestamp': datetime.datetime(2020, 7, 16, 8, 40, 37, tzinfo = tzutc()),
        'containers': ['reg.ipcpu.com/juestest/my-deploy:1139-3a5695af']
    }, {
        'revision': '2',
        'creation_timestamp': datetime.datetime(2020, 7, 16, 8, 25, 51, tzinfo = tzutc()),
        'containers': ['reg.ipcpu.com/juestest/my-deploy:1139-3a5695af']
    }]
}

五、更科学,使用watch接口

在生产环境中,由于每天发版的次数都在数十上百次,采集上面这个接口每次返回海量的日志,一是对带宽,二是对API接口造成比较大的压力。好在K8S本身就有watch接口,来监听变化内容。

from kubernetes import client, config, watch
import json

config.load_kube_config(config_file='./config')
v1 = client.AppsV1Api()
w = watch.Watch()

for event in w.stream(func=v1.list_replica_set_for_all_namespaces):
    print('=======')
    print(event['type'])
    print(event['object'])

六、参考资料

https://github.com/kubernetes-client/python/issues/694

来自为知笔记(Wiz)

转载请注明:IPCPU-网络之路 » 如何获取到Kubernetes中的版本发布信息

发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址