k8s在线和离线批量修改镜像地址的两种方式
Posted dogfei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了k8s在线和离线批量修改镜像地址的两种方式相关的知识,希望对你有一定的参考价值。
背景介绍
有时往k8s集群里部署一堆服务的时候,需要拷贝一堆yaml文件,当然还有其他方式部署,例如通过建立一个一个的流水线等方式,但是这太慢了,虽然是一劳永逸,但是如果说仅仅是部署一次那就可太费劲了,那么直接拷贝一堆yaml文件就简单了许多,但是如果之前的环境中镜像地址是走的内网,而现在放到另一个环境中,网络不通时,就需要更改其中的镜像地址了
假如之前的网络环境到阿里云内网镜像地址是通的,也就是长这样:registry-vpc.cn-beijing.aliyuncs.com/xxxx/xxxxx
然后现在要部署到华为云上时,直接启动yaml文件肯定是起不来的,需要修改下此镜像地址,改为:registry.cn-beijing.aliyuncs.com/xxxx/xxxx
,改成这样就可以拉了。
那么该如何实现呢?
调用k8s接口完成镜像替换
下面这段代码是通过k8s的接口,先去查当前命名空间下都有哪些服务,然后把这些服务都写道一个数组里,然后再去迭代这个数组,然后去修改整个命名空间下的所有pod的镜像地址
import re
from kubernetes import client, config
class deployServer:
def __init__(self, kubeconfig):
self.kubeconfig = kubeconfig
config.kube_config.load_kube_config(config_file=self.kubeconfig)
self._AppsV1Api = client.AppsV1Api()
# 这俩暂时用不到
# self._CoreV1Api = client.CoreV1Api()
# self._ExtensionsV1beta1Api = client.ExtensionsV1beta1Api()
def list_deploy(self, namespace_name):
\'\'\'
:param namespace_name: 指定命名空间
:return: 返回一个deployment的列表
\'\'\'
deploySubj = self._AppsV1Api.list_namespaced_deployment(namespace_name)
return [ subj.metadata.name for subj in deploySubj.items ]
def patchMultiDeploy(self, namespace_name, newimgdomain):
for i in self.list_deploy(namespace_name):
self.patchDeploy(namespace_name, i, newimgdomain)
print("{}: {} patch success.".format(namespace_name, i))
def patchDeploy(self, deploy_namespace, deploy_name, newimgdomain, keyword=\'vpc\'):
img_addr_rule = r"[^?]{1,}\\.[^?]{1,}\\.com(\\/.*\\:.*)"
img_domain_rule = r"([^?]{1,}\\.[^?]{1,}\\.com).*\\:.*"
old_deploy = self._AppsV1Api.read_namespaced_deployment(
name=deploy_name,
namespace=deploy_namespace,
)
old_deploy_container = old_deploy.spec.template.spec.containers
# 迭代deployment的列表,获取deployment的名称以及它所在索引位置
for i, k in enumerate(old_deploy_container):
# 捕获处域名之外的镜像地址
oldImgAddr = re.findall(img_addr_rule, old_deploy_container[i].image)[0]
# 捕获镜像地址的域名,也可以不获取,但是获取会更准确些
oldImgDoamin = re.findall(img_domain_rule, old_deploy_container[i].image)[0]
# 符合条件的才会进行替换
if keyword in oldImgDoamin:
old_deploy_container[i].image = newimgdomain + oldImgAddr
self._AppsV1Api.patch_namespaced_deployment(
name=deploy_name,
namespace=deploy_namespace,
body=old_deploy
)
return
if __name__ == \'__main__\':
kubeconfig = r\'kubeconfig/config\'
k8s = deployServer(kubeconfig)
# 指定服务所在命名空间
namespace = \'ops-logging\'
# 指定要替换的镜像的域名
img = \'docker.elastic.co\'
k8s.patchMultiDeploy(namespace, img)
注意这里需要指定kubeconfig
文件
修改文件里的镜像地址
上面那个是直接调接口,通过patch来进行修改,下面是直接修改yaml文件
import os
import re
def modifyImagesFromFile(originpath, src_img, dst_img):
_re_rule = r".*image: ([^?]{1,}\\.[^?]{1,}\\.com).*\\:.*"
if os.path.isdir(originpath):
filesubj = os.walk(originpath)
filename = []
# 迭代指定路径下的所有文件
for path, _, file in filesubj:
# 把所有的文件拼成一个完整的路径,并写道一个列表里
filename = [os.path.join(path, f) for f in file]
if filename:
for f in filename:
with open(f, \'r+\', encoding=\'utf-8\') as fr:
fr_data = fr.read()
replace_list = re.findall(_re_rule, fr_data)
if replace_list:
for pattern in replace_list:
if src_img in pattern:
# 把匹配到的内容进行替换
fr_data = fr_data.replace(pattern, dst_img)
fr.seek(0)
fr.write(fr_data)
print("{} replace success".format(f))
else:
print("Unknown")
else:
print("{} not a directory".format(originpath))
if __name__ == \'__main__\':
originpath = r"E:\\项目\\DEV环境\\sg-saas-pro-hbali\\gldsg-gvs\\deployments"
dst_img = \'registry.cn-beijing.aliyuncs.com\'
src_img = \'registry-vpc.cn-beijing.aliyuncs.com\'
modifyImagesFromFile(originpath)
注意: 需要把所有的deployment文件都放到一个目录里
总结一哈
如果是在线修改的话,就用上面调k8s接口通过patch来修改,直接粘贴复制,指定好命名空间,指定好kubeconfig
的文件位置即可
如果是把所有的yaml文件都down下来了,那么就直接迭代目录下的所有文件,通过正则去捕获镜像地址,然后进行替换,再写入源文件就可以了。
本文由博客群发一文多发等运营工具平台 OpenWrite 发布
以上是关于k8s在线和离线批量修改镜像地址的两种方式的主要内容,如果未能解决你的问题,请参考以下文章
如何在线保存/加载数据(使用 AJAX 和 JSON 存储数据)和离线(本地)