一. 实现的功能
创建带存储功能的 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关闭或者删除了,它的数据还是存在的。