k8s在线和离线批量修改镜像地址的两种方式

智极空间
• 阅读 1234

背景介绍

有时往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 发布
点赞
收藏
评论区
推荐文章
Easter79 Easter79
3年前
springcloud的配置文件的读取顺序
SpringBoot默认支持properties和YAML两种格式的配置文件。前者格式简单,但是只支持键值对。如果需要表达列表,最好使用YAML格式。SpringBoot支持自动加载约定名称的配置文件,例如application.yml。如果是自定义名称的配置文件,就要另找方法了。可惜的是,不像前者有@PropertySource这样方便的加载方式,
Stella981 Stella981
3年前
Kubernetes(三):k8s集群部署之kubeadm
k8s部署环境公有云环境:AWS、腾讯云、阿里云等等私有云:OpenStack、vSphere等Baremetal环境:物理服务器或独立虚拟机(底层没有云环境)。k8s部署方式Minikube:Kubernetes官网提供的微型分布式环境(ht
Easter79 Easter79
3年前
SpringBoot使用assembly进行项目打包教程1
一、基本介绍1.部署方式介绍目前来说,SpringBoot项目有如下两种常见的部署方式:一种是使用docker容器去部署。将SpringBoot的应用构建成一个dockerimage,然后通过容器去启动镜像,这种方式在需要部署大规模的应用、以及应用扩展时是非常方便的,属于目前工业级的部署方案,但是需要掌握
Stella981 Stella981
3年前
Ceph分布式存储部署过程
前言:  环境介绍:此次部署系统为Cenots7MON、OSD10.110.180.112AdminMON、OSD10.110.180.113Node1MON、OSD10.110.180.114Node2Ceph文件目录部署过程此部署过程是采用文件目录方式挂在激活OSD的方式部署Ceph集群。1.系统关闭
Stella981 Stella981
3年前
Istio技术与实践03:最佳实践之sidecar自动注入
Istio通过对serviceMesh中的每个pod注入sidecar,来实现无侵入式的服务治理能力。其中,sidecar的注入是其能力实现的重要一环(本文主要介绍在kubernetes集群中的注入方式)。sidecar注入有两种方式,一是通过创建webhook资源,利用k8s的webhook能力实现pod的自动注入,二是通过istioctl工具,对yaml
Stella981 Stella981
3年前
Flink从入门到真香(Flink环境部署
FlinkStandalone模式部署集群是最简单的一种部署方式,不依赖于其他的组件,另外还支持YARN/Mesos/K8S等模式下的部署Standalone执行架构图:!Flink从入门到真香(Flink环境部署集群standalone模式)(https://s4.51cto.com/images/blog/202011/05/8073eb
Easter79 Easter79
3年前
Springboot基于assembly的服务化打包方案
  在使用assembly来打包springboot微服务项目前,我想说一说,目前springboot项目的几种常见的部署方式。1. 使用docker容器去部署,将springboot的应用构建成一个dockerimage,然后通过容器去启动镜像,这种方式在需要部署大规模的应用和应用扩展时是非常方便的,属于目前工业级的部署方案,但是需要掌握d
Stella981 Stella981
3年前
SpringBoot使用assembly进行项目打包教程1
一、基本介绍1.部署方式介绍目前来说,SpringBoot项目有如下两种常见的部署方式:一种是使用docker容器去部署。将SpringBoot的应用构建成一个dockerimage,然后通过容器去启动镜像,这种方式在需要部署大规模的应用、以及应用扩展时是非常方便的,属于目前工业级的部署方案,但是需要掌握
Stella981 Stella981
3年前
Docker镜像瘦身
Docker是一个用于开发,交付和运行应用程序的开发平台。它能够将应用程序和基础架构分开,保证开发,测试,部署的环境完全一致,从而达到快速交付的目的。但是在实际项目中,会对项目中的模块或者服务进行细分,导致部署的镜像过多(50个),过大(打包压缩后的镜像达50G),这给部署带来了不小的隐患,特别是私有化部署(通过移动介质拷贝镜像进行部署)。
Wesley13 Wesley13
3年前
ActiveMQ集群部署
(摘自:http://www.openopen.com/lib/view/open1400126457817.html)        单点的ActiveMQ作为企业应用无法满足高可用和集群的需求,所以ActiveMQ提供了masterslave、brokercluster等多种部署方式,但通过分析多种部署方式之后我认为需要将两种部署方式相结合才能
DevOpSec DevOpSec
2年前
自建k8s集群之负载均衡使用
自建k8s而非云环境,组件mysql类(部分有状态服务)部署在虚机里也即集群外,业务服务部署在k8s集群内。需求:集群内、集群外,业务服务和组件相互间通过负载均衡、高可用的形式连通。此需求拆解成两个问题进行解决,接着往下看。集群内:k8s集群集群外:k8s集群外的应用部署在虚拟机或物理机环境