Openstack+novadockerでストレージ機能付きdockerを作成

2861 ワード

一.実装された機能


ストレージ機能付きdockerを作成します.「ストレージ」とは、docker内のあるディレクトリをhost上のあるディレクトリの下に掛けることです.本実験ではdockerルートディレクトリの下のフォルダをhostに掛けた.
具体的には、novaコードを変更することで、通常のdocker(ストレージなし)を作成したり、ストレージ付きdockerを作成したりすることができます.
本実験ではdockerを作成する方法によってdockerが格納する必要があるかどうかを区別し,dashboardでInstanceの作成をクリックしたときにBoot From Imageを選択すると,作成したdockerは格納されず,Boot from Image(create a new volume)を選択すると作成したdockerは格納される.

二.具体的なやり方.


novaセクション:


ページ上で仮想マシンの作成要求が発行されると、この要求は最後にcomputeノード上のnova/manageに送信されます.pyの_build_Instance関数は、ここの論理を変えるだけでいいです.
コード(nova/manage.py):
device_type = request_spec['block_device_mapping'][0]['device_type']
if device_type: #  docker  
    block_device_info = {}
else:#   docker  
    block_device_info = {'need-storage':request_spec['block_device_mapping'][0]['device_name'],
                         #need-storage   device name
                         'storage-size':request_spec['block_device_mapping'][0]['volume_size']}
                         #storage-size   volume size

novadockerセクション:


コード(driver.py):
# Does the docker wanted storage?
if block_device_info.get('need-storage', None):
    # 
    self._start_storage_container(instance, block_device_info)
    # _start_storage_container  
else:
    # 
    self._start_container(instance, network_info)
    _start_storage_container   ( driver.py )
def _start_storage_container(self, instance, block_device_info):
    container_id = self._find_container_by_name(instance['name']).get('id')
    #  container_id(   )
    if not container_id:
    return
    self.docker.start_storage_container(container_id, block_device_info)


コード(client.py):
def start_storage_container(self, container_id, block_device_info):
    host_dir = '/mnt/docker-volumes/' + container_id
    utils.execute('mkdir', '-p', host_dir)
    docker_dir = '/' + block_device_info.get('need-storage', 'data')
    dir_param = host_dir + ':' + docker_dir + ':rw'
    data = {
        'Binds': [ dir_param ]
    }
    resp = self.make_request(
    'POST',
    'containers/{0}/start'.format(container_id),
    body=jsonutils.dumps(data))
    return (resp.code == 200 or resp.code == 204)


特筆すべきは、docker startの場合、Bindsパラメータを送信することでhost上のフォルダをdocker内部に掛け、例えばBinds=['/test:/data:rw']では、/testはhost上のdirであり、dataはdockerに掛けられたdirであり、rwは権限である
これで作成したdockerには「ストレージ」が付いていますが、実は「ストレージ」とは、docker内部のフォルダ内で行われるIO操作がHOSTに反映されることを理解しています.そうすれば、dockerが閉じたり削除されたりしても、そのデータは存在します.