镜像迁移脚本

在日常的服务部署开发中,我们有时需要迁移环境,将服务器上的私有镜像从一个服务器迁移到另一个服务器中。在以微服务为架构的项目中,我们的一个项目可能存在大量的镜像,对每一个镜像单独进行导出打包迁移即重复又麻烦,针对这种情况,我们可以通过开发脚本来实现快速的迁移部署,减少重复工作。

镜像迁移流程

  • 导出镜像为打包文件
  • 迁移镜像到其他服务器
  • 导入镜像
  • [可选]根据需要修改镜像标签
  • [可选]推送镜像到镜像中心

Python脚本处理

获取镜像列表

table格式显示镜像列表

bash环境中,我们一般通过 [docker] image ls命令会以 table格式显示服务器中的镜像。

[docker] image ls

json格式显示镜像列表

table格式显示的镜像虽然直观,但是脚本以流的方式读取内容为 str类型数据,str类型针对 table格式转化出的数据处理相对比较麻烦。所以针对镜像列表的获取,我们可以采用 json格式进行读取。

[docker] image ls –help

调用 docker image ls --help命令可知,docker 输出镜像列表支持通过 --format参数指定输出格式内容。

json格式显示镜像列表

调用 docker image ls --format json以json格式显示镜像列表

[docker] image ls –format json

兼容旧版Docker显示json格式镜像列表

在旧版的docker中,没有默认的json模板,此时调用 docker image ls --format json命令将无法正确显示镜像列表,阅读 docker image ls --help的输出和docker go format官网文档。可以看到,docker是通过go template进行的格式化输出,针对这种情况,可以在输出时通过手动设置json模板 { {json .}}来显示json格式内容。

调用 docker image ls --format "{ {json .}}"以json格式显示镜像列表

[docker] image ls –format “{​{json .}}”

注意 --format string这里,以json模板进行输出时,""是可选项,但是在设置模板时,""是必选项,否则会导致输出错误。

Python获取shell输入流

bash环境中,我们一般通过管道 |获取上一步操作的输入流进行操作。在Python中,我们可以通过 os或者 subprocess库来执行shell命令。

subprocess获取输入流

在Python的subprocess依赖库中,可以通过 subprocess.getoutput(cmd)命令来获取输入流内容,将输入流转化为 str类型数据。

os获取输入流

在Python的os依赖库中,可以通过 os.popen(cmd).read()命令来获取输入流内容,将输入流转化为 str类型数据。

推荐使用os来获取输入流,具有更好的兼容性,即使在Python2版本上也支持使用

str转jsonl

以json格式输出的镜像列表,是每个镜像都以json格式进行输出,整体是以jsonl的格式,所以不可以通过 json.load()来解析转化json数据,针对该情况,可以编写函数来实现将输入流转化为列表进行处理。

def str2jsonl(string):
    """
    str类型数据转换为jsonl(列表)
    """
    jsonl = []
    lines = string.split('\n')
    for line in lines:
        if line.strip() != '':
            jsonl.append(json.loads(line))
    return jsonl

Python执行shell命令

在python中,可以通过 os.system(cmd)命令来执行shell命令。

导出镜像为打包文件

导出镜像并打包的命令为: docker save ${image_id} | gzip -c > ${filename}.tar.gz

def save_images():
    """
    导出镜像为.tar.gz文件到本地
    """
    # 执行shell命令,获取输入流
    images = os.popen('docker image ls --format "{
   {json .}}"').read()

    images = str2jsonl(images)

    for image in images:
        tag = ""
        for _tag in image['Tag'].split('.'):
            tag = tag + "_" + _tag
        # 导出镜像 | 将镜像打包为tar.gz文件
        os.system(f"docker save {
     image['Repository']}:{
     image['Tag']} | gzip -c > {
     image['Repository'].split('/')[-1]}_{
     tag}.tar.gz")

迁移镜像(网络互通)

导出镜像为 .tar.gz后,可以根据网络环境通过传输文件的方式将镜像传输到其他服务器中。

但是在网络互通的环境中,可以直接通过Python启动文件服务器的方式快速传输:

python3:python3 -m http.server 8000

python2: python -m SimpleHTTPServer 8080

在导出镜像服务器通过python命令快速启动一个文件服务器,其他服务器即可通过 IP:Port的方式访问获取文件。

在传输完文件后,尽快将文件服务器关闭,避免网络内其他人无授权访问主机内容。

导入镜像

导入镜像命令为: docker load -i ${filename}

def str2list(string):
    return string.split('\n')


def load_images():
    """
    导入镜像
    """
    # 执行shell命令,获取输入流
    images = os.popen('ls').read()

    images = str2list(images)

    for image in images:
        if '' != image:
            os.system(f"docker load -i {
     image}")

[可选]修改镜像标签

在进行服务迁移时,我们可能根据需要,需要修改镜像的标签,以便后续将镜像推送到指定镜像中心。一般这种情况下,修改镜像标签主要是修改镜像中心前缀和项目名,修改相对固定,可以通过脚本来实现统一修改。

修改镜像标签命令: docker tag ${old_image_tag} ${new_image_tag}

def fix_tags(image_center: str, project_name: str):
    # 执行shell命令,获取输入流
    images = os.popen('docker image ls --format "{
   {json .}}"').read()

    images = str2jsonl(images)

    for image in images:
        if len(image['Repository'].split("/")) >= 2:
            repository = f"{
     image['Repository'].split('/')[-2]}/{
     image['Repository'].split('/')[-1]}"
        else:
            repository = image['Repository'].split("/")[-1]
        os.system(f"docker tag {
     image['Repository']}:{
     image['Tag']}\t\t{
     image_center}/{
     project_name}/{
     repository}:{
     image['Tag']}")

[可选]推送镜像到镜像中心

登陆镜像中心命令: docker login -u ${username} ${image_center}

推送镜像标签命令: docker push ${image}

Docker会根据镜像名前缀推送到指定镜像中心。

def push_images():
    """
    推送镜像到镜像中心
    """
    # 执行shell命令,获取输入流
    images = os.popen('docker image ls --format "{
   {json .}}"').read()
   
    images = str2jsonl(images)

    for image in images:
        os.system(f"docker push -i {
     image['Repository']}:{
     image['Tag']}")

相关推荐

  1. harbor仓库镜像迁移脚本

    2024-01-16 12:52:03       24 阅读
  2. 迁移Docker镜像存放目录

    2024-01-16 12:52:03       17 阅读
  3. Windows Docker手动迁移镜像

    2024-01-16 12:52:03       8 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-16 12:52:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-16 12:52:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-16 12:52:03       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-16 12:52:03       20 阅读

热门阅读

  1. 每日算法打卡:地宫取宝 day 16

    2024-01-16 12:52:03       26 阅读
  2. 每日算法打卡:波动数列 day 16

    2024-01-16 12:52:03       37 阅读
  3. 云原生周刊:OpenTofu 宣布正式发布 | 2023.1.15

    2024-01-16 12:52:03       41 阅读
  4. [NOIP2009 普及组] 分数线划定#洛谷

    2024-01-16 12:52:03       31 阅读
  5. 做数据缓存,Map 比List更具有优势

    2024-01-16 12:52:03       38 阅读
  6. python多线程和多进程内存共享方式

    2024-01-16 12:52:03       34 阅读
  7. Linux新建文件详解

    2024-01-16 12:52:03       39 阅读
  8. Nginx虚拟主机配置

    2024-01-16 12:52:03       33 阅读
  9. 什么是本地IP?服务器本地IP有哪些优势?

    2024-01-16 12:52:03       36 阅读
  10. Pandas实战100例 | 案例 52: 重命名列

    2024-01-16 12:52:03       39 阅读
  11. HCIP-2

    2024-01-16 12:52:03       29 阅读
  12. Centos7安装python12+最新openssl

    2024-01-16 12:52:03       41 阅读