基于docker部署mysql的數(shù)據(jù)持久化問題

本人最近在使用docker部署mysql時(shí),在持久化mysql數(shù)據(jù)時(shí)遇到了一個(gè)有趣的問題锻狗,將排查過程及思考記錄在這里满力,以備后查。

先簡(jiǎn)單描述下我遇到的問題:在mysql容器中創(chuàng)建了兩個(gè)數(shù)據(jù)庫轻纪,然后使用docker commit想要保存容器的修改為新的鏡像油额,發(fā)現(xiàn)只保存下來了新建的一個(gè)數(shù)據(jù)庫,而另一個(gè)并沒有被保存下來刻帚。最終通過查看docker文檔和自己的實(shí)驗(yàn)潦嘶,發(fā)現(xiàn)是mysql鏡像中指定了volume為mysql數(shù)據(jù)路徑所致。

具體講一下我遇到的問題及排查過程:首先我從dockerHub里拉取了最新的mysql鏡像來部署
docker pull mysql

然后基于這個(gè)鏡像創(chuàng)建一個(gè)容器
docker run --name mysqldock -e MYSQL_ROOT_PASSWORD=admin -e MYSQL_DATABASE=inst1 -d -p 3066:3066 mysql

這里的MYSQL_ROOT_PASSWORD指定了root賬號(hào)的密碼崇众,MYSQL_DATABASE指定了在容器創(chuàng)建時(shí)同時(shí)創(chuàng)建的數(shù)據(jù)庫命掂僵。MYSQL_DATABASE可以不提供,這樣不會(huì)預(yù)創(chuàng)建數(shù)據(jù)庫顷歌。創(chuàng)建好名為mysqldock的容器后锰蓬,使用
docker exec -it mysqldock bash

進(jìn)入容器,執(zhí)行mysql客戶端命令眯漩,查看mysql的庫芹扭,發(fā)現(xiàn)inst1已經(jīng)建好:
inst1在容器初始化的時(shí)候已經(jīng)創(chuàng)建

然后手動(dòng)創(chuàng)建數(shù)據(jù)庫inst2,并且在兩個(gè)庫中創(chuàng)建一些表:
手動(dòng)創(chuàng)建inst2及兩個(gè)庫中的表

這時(shí)赦抖,我想把目前為止對(duì)mysqldock容器做的變更保存下來舱卡,所以就想到了使用docker commit指令
docker commit mysqldock

docker commit 命令會(huì)將docker容器的變更保存下來,并且生成新的鏡像摹芙。生成新的鏡像后灼狰,我想看看之前創(chuàng)建的庫和表還在不在宛瞄,就使用新的鏡像創(chuàng)建了新的容器mysqlnew浮禾,并且進(jìn)入容器查看mysql情況,神奇的現(xiàn)象出現(xiàn)了份汗,mysql中竟然只有inst1庫盈电,而沒有inst2,同時(shí)inst1里面是空的杯活,我們創(chuàng)建的表也消失了:
消失了的inst2和表

這就讓我疑惑了匆帚,查看了下docker commit命令的說明:
docker commit 說明

沒毛病啊,基于容器的變化創(chuàng)建一個(gè)新的鏡像旁钧。為了驗(yàn)證docker commit 命令的可用性吸重,我在mysqldock中創(chuàng)建一個(gè)新的文件互拾,再commit成新鏡像,再創(chuàng)建容器嚎幸,查看發(fā)現(xiàn)新的容器的確是包含了新創(chuàng)建的文件颜矿,也就是說docker commit的確能夠基于容器的變化創(chuàng)建新的鏡像:
新建文件出現(xiàn)在了新的鏡像中

那我就丈二和尚摸不著頭腦了,為啥新建的文件可以保存下來嫉晶,新建的庫就不行呢骑疆,新建的庫不也是在mysql數(shù)據(jù)文件路徑下新建的文件么?是時(shí)候求助官方文檔了替废,查閱了docker commit的官方文檔說明后箍铭,發(fā)現(xiàn)了在擴(kuò)展說明中有這么一句話:

The commit operation will not include any data contained in volumes mounted inside the container.

意思是commit操作并不會(huì)包含容器內(nèi)掛載數(shù)據(jù)卷中的數(shù)據(jù)變化。難道是因?yàn)閙ysql容器的掛載數(shù)據(jù)卷引起的椎镣?(這里我就要吐槽一下了诈火,docker --help好歹詳細(xì)點(diǎn)啊,這么重要的信息竟然都沒有顯示衣陶。)通過
docker inspect mysqlsock

查看mysqldock的屬性柄瑰,發(fā)現(xiàn)Mounts里有這樣的信息:
Mounts

這說明了這個(gè)容器將容器內(nèi)的/var/lib/mysql路徑作為volume掛載。查看容器內(nèi)的該路徑發(fā)現(xiàn)的確是mysql數(shù)據(jù)庫的數(shù)據(jù)文件剪况,這點(diǎn)在mysql的dockerHub主頁也能發(fā)現(xiàn):
/var/lib/mysql下的數(shù)據(jù)

我馬上試了一下在該文件下新建一個(gè)文件教沾,并且docker commit,然后用新的鏡像創(chuàng)建新容器译断,文件果然不見了授翻!

那么問題來了,學(xué)習(xí)挖掘機(jī)到底哪家強(qiáng)?為何commit之后inst2沒有了孙咪,但inst1還在堪唐?深究起來,連mysql root密碼也沒有變翎蹈,還是之前設(shè)置的admin淮菠。發(fā)現(xiàn)沒有?數(shù)據(jù)庫inst1及root密碼都是我在創(chuàng)建mysqldock容器時(shí)通過-e參數(shù)指定的荤堪,莫非是在容器創(chuàng)建時(shí)通過-e創(chuàng)建的合陵,就算是在volume里的也可以保存么?繼續(xù)研究docker commit命令的官方文檔澄阳,在擴(kuò)展說明里發(fā)現(xiàn)了這么一句:

It can be useful to commit a container’s file changes or settings into a new image.

看到了么拥知,file changes or settings。文件變更和設(shè)置碎赢,-e的不就是設(shè)置么低剔,這點(diǎn)也可以通過docker inspect發(fā)現(xiàn),在Config下的Env參數(shù)中:
mysqldock和mysqlnew有一樣的env參數(shù)

這么說就說得通了,雖然文件的確是發(fā)生了變化襟齿,但是由于文件是在容器掛載的數(shù)據(jù)卷中姻锁,所以這些變化沒有被commit,然而由于在創(chuàng)建mysqldock容器的時(shí)候設(shè)置了-e參數(shù)猜欺,這些設(shè)置被容器保留了下來屋摔,commit命令使用這些設(shè)置構(gòu)建了新的鏡像。排查到這里替梨,我們的問題是找到原因了钓试,可怎么解決呢?我們?cè)撊绾螌ysql docker中修改的數(shù)據(jù)保存下來呢副瀑?通過查看mysql dockerHub主頁Where to Store Data一節(jié)中的說明弓熏,我們可以通過docker提供的數(shù)據(jù)掛載來實(shí)現(xiàn)。

docker的數(shù)據(jù)掛載分為三種糠睡,volume, bind mount和tmpfs挽鞠,關(guān)于三種的具體說明,強(qiáng)烈推薦大家看一下官網(wǎng)的文檔狈孔。這邊簡(jiǎn)單說明一下:
volume是由docker默認(rèn)及推薦的掛載方式信认,volume由docker直接管理,同一個(gè)volume可以共享給多個(gè)容器使用均抽,volume和容器的生命周期完全獨(dú)立嫁赏,容器刪除時(shí)volume仍然存在,除非使用docker volume相應(yīng)命令刪除volume油挥;缺點(diǎn)是volume在宿主機(jī)上比較難定位潦蝇,在宿主機(jī)上直接操作volume比較困難。
bind mount是直接將宿主機(jī)文件系統(tǒng)上的文件路徑映射到容器中深寥,兩邊雙向同步攘乒,顯而易見,有缺點(diǎn)也有優(yōu)點(diǎn)惋鹅,優(yōu)點(diǎn)是可以直接訪問则酝,也可以被別的程序使用,比如我們打包一個(gè)本地應(yīng)用到本地/target路徑闰集,我們就可以把這個(gè)路徑使用bind mount的方式掛在到依賴他的應(yīng)用的docker容器中沽讹,這樣本地應(yīng)用打包后,docker里的數(shù)據(jù)卷也會(huì)同時(shí)更新返十;缺點(diǎn)也是顯而易見的妥泉,因?yàn)槟憧梢园讶魏挝募窂绞褂胋ind mount的方式綁定到容器中椭微,這樣有可能一些安全問題洞坑,比如把宿主機(jī)的系統(tǒng)文件綁定到容器中。
tmpfs這種方式是使用宿主機(jī)的內(nèi)存作為存儲(chǔ)蝇率,不會(huì)寫到宿主機(jī)的文件系統(tǒng)中迟杂,和前兩種區(qū)別較大刽沾。

mysql dockerHub主頁中的推薦方式是在宿主機(jī)中新建一個(gè)專門用來存放mysql docker數(shù)據(jù)的文件路徑,同時(shí)在新建容器的時(shí)候?qū)⒃撀窂接成涞饺萜髦信趴剑簿褪鞘褂胋ind mount的方式侧漓,之所以不使用volume的方式是因?yàn)関olume是由docker管理,在宿主機(jī)上比較難定位监氢。

那對(duì)于我的情況布蔗,既已經(jīng)有一個(gè)容器使用了volume,想把volume里的數(shù)據(jù)在新的容器中使用bind mount方式掛載該怎么辦呢浪腐?我們可以先把mysqldock容器中所需要的文件拷貝出來到本地的/var/own/mysqldata纵揍,通過
docker cp mysqldock:/var/lib/mysql /var/own/mysqldata

然后在創(chuàng)建新的mysql容器時(shí),掛載該文件即可
docker run -v /var/own/mysqldata:/var/lib/mysql --name mysqlnew -d mysql

這樣新的容器就可以保留mysqldock中的數(shù)據(jù)了议街,問題解決泽谨!當(dāng)然,我們也可以使用docker推薦的volume方式掛載特漩,首先找到mysqldock的volume吧雹,然后在運(yùn)行新容器時(shí)指定該volume進(jìn)行掛載就行了:
使用volume進(jìn)行掛載

這種方式繁瑣?別急涂身,還有更簡(jiǎn)單的雄卷,在創(chuàng)建容器的時(shí)候,可以指定使用其他容器的volume蛤售,也就是共享其他容器的volume龙亲,使用--volumes-from參數(shù)
docker run --name mysqlvolumn2 --volumes-from mysqldock -d mysql

其實(shí)volume還可以在創(chuàng)建的時(shí)候進(jìn)行命名,從而是查找起來不那么繁瑣悍抑,具體的參數(shù)就請(qǐng)大家參考官網(wǎng)或者--help了鳄炉,其實(shí)官方更加推薦的是使用--mount代替-v參數(shù),官網(wǎng)上有詳盡的例子搜骡,大家也可以自行進(jìn)行嘗試拂盯。

當(dāng)然啦,純粹把docker作成數(shù)據(jù)容器其實(shí)并沒有太大意義记靡,這里只是借這個(gè)問題窺探一下docker數(shù)據(jù)卷的一些用法贬养。

作者:SawyerZhou
鏈接:http://www.reibang.com/p/530d00f97cbf
來源:簡(jiǎn)書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)蕾羊,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處较解。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市寸痢,隨后出現(xiàn)的幾起案子呀洲,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件道逗,死亡現(xiàn)場(chǎng)離奇詭異兵罢,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)滓窍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門卖词,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吏夯,“玉大人,你說我怎么就攤上這事噪生。” “怎么了杠园?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵顾瞪,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我抛蚁,道長(zhǎng),這世上最難降的妖魔是什么瞧甩? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮肚逸,結(jié)果婚禮上爷辙,老公的妹妹穿的比我還像新娘。我一直安慰自己朦促,他們只是感情好膝晾,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布务冕。 她就那樣靜靜地躺著,像睡著了一般禀忆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上箩退,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音滋戳,去河邊找鬼钻蔑。 笑死胧瓜,一個(gè)胖子當(dāng)著我的面吹牛郑什,可吹牛的內(nèi)容都是我干的府喳。 我是一名探鬼主播蘑拯,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼弯蚜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起碎捺,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤贷洲,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后优构,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拧额,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年彪腔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片德挣。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖盲厌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情建芙,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布禁荸,位于F島的核電站,受9級(jí)特大地震影響赶熟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜映砖,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一邑退、第九天 我趴在偏房一處隱蔽的房頂上張望竹宋。 院中可真熱鬧地技,春花似錦、人聲如沸莫矗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽食磕。三九已至尽棕,卻和暖如春彬伦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背单绑。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留歉提,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓苔巨,卻偏偏與公主長(zhǎng)得像废离,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蜻韭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350