Build, Ship, and Run Any App, Anywhere
可見容器技術(shù)的使用給我們帶來了效率上的提升,將一個(gè)應(yīng)用直接打包成一個(gè)容器就能在各種平臺(tái)運(yùn)行践樱,但是废封,當(dāng)一個(gè)應(yīng)用帶有狀態(tài)屬性的話倚搬,使用的時(shí)候肯定也需要將狀態(tài)數(shù)據(jù)帶上防泵。
出于對(duì)應(yīng)用數(shù)據(jù)對(duì)安全尿瞭,可用性闽烙,共享,性能等方面的要求和Root Image的要求完全不一樣声搁,所以Docker并不推薦采用Root Image的存儲(chǔ)方式來存儲(chǔ)應(yīng)用數(shù)據(jù)黑竞,而是采用了Volume這樣一個(gè)獨(dú)立的數(shù)據(jù)訪問接口。通過Volume機(jī)制疏旨,Docker可以輕易地將主機(jī)目錄掛載到容器中很魂;通過Docker的Volume Plugin機(jī)制,使Docker能夠方便地整合第三方存儲(chǔ)充石,為Docker提供Volume莫换。
volume是如何被使用的呢?
Volume是個(gè)interface骤铃,docker daemon通過調(diào)用這個(gè)接口完成volume的操作拉岁;Docker實(shí)現(xiàn)兩種Volume:基于主機(jī)文件系統(tǒng)《枧溃基于Volume Plugin喊暖。
-
基于本地文件系統(tǒng)的Volume
可以在執(zhí)行Docker create或Docker run時(shí),通過-v參數(shù)將主機(jī)的目錄作為容器的數(shù)據(jù)卷撕瞧。這部分功能便是基于本地文件系統(tǒng)的volume管理陵叽。
-
基于Plugin的Volume
Docker為了支持第三方存儲(chǔ)方案狞尔,在1.8版本引入Volume Plugin機(jī)制。
如何去編寫一個(gè)docker volume plugin呢巩掺?
官方文檔中給我們列取了許多第三發(fā)的編寫的plugin:
docker plugin其實(shí)就是一個(gè)RPC/JSON的接口偏序,docker daemon直接通過HTTP協(xié)議直接與該接口通訊;
- docker daemon如何發(fā)現(xiàn)這個(gè)接口:
- 接口生成通訊的sock文件
- 在/etc/docker/plugins/目錄下新建一個(gè)spec文件胖替,spec文件內(nèi)描述了接口的sock文件的地址
{
"Name": "plugin-example",
"Addr": "https://example.com/docker/plugin",
"TLSConfig": {
"InsecureSkipVerify": false,
"CAFile": "/usr/shared/docker/certs/example-ca.pem",
"CertFile": "/usr/shared/docker/certs/example-cert.pem",
"KeyFile": "/usr/shared/docker/certs/example-key.pem"
}
}
-
這個(gè)接口需要實(shí)現(xiàn)如下一些方法:
可參見:https://docs.docker.com/engine/extend/plugins_volume/#volumedriver
- /VolumeDriver.Create: 創(chuàng)建一個(gè)卷研儒,Docker會(huì)發(fā)送卷名稱和參數(shù)發(fā)送給插件,卷插件會(huì)根據(jù)Docker發(fā)送過來的參數(shù)創(chuàng)建一個(gè)卷独令,并和這個(gè)卷名稱關(guān)聯(lián)端朵。
- /VolumeDriver.Remove:刪掉特定的卷時(shí)調(diào)用,當(dāng)運(yùn)行”docker rm -v”命令時(shí)燃箭,Docker會(huì)調(diào)用該API發(fā)送請(qǐng)求給插件冲呢。
- /VolumeDriver.Mount: 掛載一個(gè)卷到本機(jī),Docker會(huì)把卷名稱和參數(shù)發(fā)送給參數(shù)招狸。插件會(huì)返回一個(gè)本地路徑給Docker敬拓,這個(gè)路徑就是卷所在的位置。Docker在創(chuàng)建容器的時(shí)候裙戏,會(huì)將這個(gè)路徑掛載到容器中恩尾。
- /VolumeDriver.Path:一個(gè)卷創(chuàng)建成功后,Docker會(huì)調(diào)用Path API來獲取這個(gè)卷的路徑挽懦,隨后Docker通過調(diào)用Mount API翰意,讓插件將這個(gè)卷掛載到本機(jī)。
- /VolumeDriver.Unmount:當(dāng)容器退出時(shí)信柿,Docker daemon會(huì)發(fā)送Umount API給插件冀偶,通知插件這個(gè)卷不再被使用,插件可以對(duì)該卷做些清理工作(比如引用計(jì)數(shù)減一渔嚷,不同的插件行為不同)进鸠。
- /VolumeDriver.Get: 獲取Plugin Volume的詳細(xì)信息。
- /VolumeDriver.List: 執(zhí)行docker volume ls命令時(shí)形病,會(huì)向plugin發(fā)送該請(qǐng)求客年,獲取volume list。
- /VolumeDriver.Capabilities
docker官方提供了一個(gè)編寫接口的SDK漠吻,docker/go-plugins-helpers, 在編寫volume plugin的時(shí)候量瓜,我們只需要實(shí)現(xiàn)Driver interface中的方法就可以了。
image -
下面我們一起來看一個(gè)第三方的plugin, docker-volume-glusterfs
其中一個(gè)Mount方法
WX20170706-154238@2x.png其實(shí)就是在先在容器的宿主機(jī)將gluster存儲(chǔ)掛載至本地途乃,然后再提供給容器使用
WX20170706-154303@2x.png
總結(jié)
從上面可以看出绍傲,無論使用volume還是volume plugin來實(shí)現(xiàn)容器的持久化存儲(chǔ),本質(zhì)上都是將容器所在宿主機(jī)上都文件系統(tǒng)掛在至容器內(nèi)使用,使用volume plugin就是完成了兩個(gè)動(dòng)作:1. 首先將存儲(chǔ)掛在至本地文件系統(tǒng)烫饼;2. 在將本地文件系統(tǒng)掛載至容器使用猎塞,完成了容器與共享存儲(chǔ)的解耦合,在大型的容器使用環(huán)境還是非常有必要的杠纵!