如何将卷移动到新的docker容器?

时间:2017-02-28 20:20:48

标签: docker docker-volume dockerpy

我正在努力实现一种升级容器基本映像的机制。为了做到这一点,我需要:

  1. 从当前容器中获取卷列表;
  2. 使用旧容器(卷,网络等)的配置创建一个新容器
  3. 创建新容器

    我试着这样做:

    docker_api.create_container(
            image=creation_data.get('image'),
            hostname=creation_data.get('hostname'),
            volumes=creation_data.get('volumes'),
            host_config=docker_api.create_host_config(
                binds=creation_data.get('volume_bindings'),
                port_bindings={80: 80},
                restart_policy={"MaximumRetryCount": 0, "Name": "always"}
            ))
    

    创建数据

    从旧容器中收集creation_data,如下所示:

     {
        'image': 'docker.akema.fr:5000/coaxis/coaxisopt_daemon:latest',
        'hostname': "test-01",
        'volumes': [
            "/home/mast/.ssh",
            "/etc/mast"
        ],
        'volumes_bindings': {
            "841d6a1709b365763c85fb4b7400c87f264d468eb1691a660fe81761da6e374f": {
                'bind': "/home/mast/.ssh",
                'mode': 'rw'
            },
            "002730cbb4dd9b37ad808915a60081508885d533fe003b529b8d0ab4fa46e92e": {
                'bind': "/etc/mast",
                'mode': 'rw'
            }
        },
        'networking_config': {
            'EndpointsConfig': {'opt_network_508be7': {'IPAMConfig': {'IPv4Address': '10.0.0.1'}}}
        }
    }
    

    问题

    检查新容器时,Mounts部分似乎没有正确的音量Source fields is a different path

    如何根据旧容器信息将卷装入新容器?

2 个答案:

答案 0 :(得分:2)

I don't know how much control you have on how the first container is started, but if you do :

docker run --name container1 --volume vol1:/my/vol1/dir --volume vol2:/my/vol2/dir image1

to run container1, you just need to do this to reuse container1 volumes for container2 :

docker run --name container2 --volume vol1:/my/vol1/dir --volume vol2:/my/vol2/dir image2

And then remove container1 which won't remove volumes (even if they were not already reused by an other container).

vol1 and vol2 data will be stored under /var/lib/docker/volumes/vol1/_data/ and /var/lib/docker/volumes/vol2/_data/ on your host.

So, the answer would be : don't use anonymous volumes for this need, use named volumes. And if u have a legacy container with anonymous volumes you need to reuse, I guess u can just copy them by hand into the named volumes of the new container for this time.

答案 1 :(得分:0)

Tristan回答帮助我进行工作设置,然后我拒绝了docker-py。解决方案是使用卷Name值(例如a87bdc07881fcf139a29…)作为挂载点的源。

N.B。:也有一个非常讨厌的错字:volumes_bindings vs volume_bindings

检查

$ docker inspect my_container  --format "{{ json .Mounts }}" | python -m json.tool
[
    {
        "Destination": "/etc/mast",
        "Driver": "local",
        "Mode": "",
        "Name": "a87bdc07881fcf139a29…",
        "Propagation": "",
        "RW": true,
        "Source": "/var/lib/docker/volumes/a87bdc07881fcf139a29…/_data",
        "Type": "volume"
    }
]

装载到新容器

docker create  \
    --name container \
    --volume a87bdc07881fcf139a29…:/etc/mast \
    docker.site.org:5000/coaxis/coaxisopt_daemon:latest

docker-py

new_container = docker_api.create_container(
    image=creation_data.get('image'),
    hostname=creation_data.get('hostname'),
    volumes=creation_data.get('volumes'),
    host_config=docker_api.create_host_config(
        binds=creation_data.get('volumes_bindings'),
        port_bindings={80: 80},
        restart_policy={"MaximumRetryCount": 0, "Name": "always"}
    ))

有数据:

{
            'image': 'docker.akema.fr:5000/coaxis/coaxisopt_daemon:latest',
            'hostname': "test-01",
            'volumes': ["/etc/mast"],
            'volumes_bindings': {
                "a87bdc07881fcf139a29…": {
                    'bind': "/etc/mast",
                    'mode': 'rw'
                }
            },
            'networking_config': {}
        }