Docker映像與資料備份與還原:以cassandra為例
今天開發的時候遇到一個情況,就是我的測試程式依賴了我本機起的一個nosql cassandra服務,是建立在docker上的
因此我把程式提供給同事以後,發現他沒有環境,因此程式功能無法展示,當然一部份也要展示cassandra的使用方式
一時間還不會docker的備份與移轉,因此早上就急著先把vmware的images(約略15GB)複製給同事,光複製的時間就花了快二十分鐘,當下覺得這種環境移轉的方式太過於笨重,想到若我還要再把我本機的另一個安裝hadoop的vm也要copy過去的話,那這樣來來回回的時間就不知耗費掉多少,而且我的私人開發環境其實是我自己常用的密碼,所以分享起來也是挺麻煩的。
有上述念頭後,我開始嘗試著在我兩台不同的vm(都是ubuntu)上面,試著把docker備份流程做一次
docker images備份(起手式:連結)
首先,我們需要先將目前的container狀態commit,先docker -ps列出所有container的id
我們很快的就看到dev-cassandra就是我們要備份的目標,接著輸入以下的指令:docker commit -p {{container id}} {{repository-name}}
sudo docker commit -p 3b5 cassandra-devenv
接著回到docker images列表,我們就會看到我們的新commit的images已經被建立出來了(圖中第一個)
container已經被commit了以後,那我們要怎麼轉成實體檔案呢?
指令很簡單:
docker save -o ~/cassandra-devenv.tar cassandra-devenv
這個指令要跑一下子,跑完以後,我們可以看到tar檔已經產生,看起來要400mb左右,著實比vm動輒1x gb來得輕量許多
這裡有一個小陷阱,就是要先去chown給paul與chmod 給檔案合適的權限
備份docker的資料卷資料
images既然被備份出來以後,那我們的資料呢?
還記得dockers要怎麼看資料卷的現實綁定的位置呀?就要靠docker inspect 指令了
sudo docker inspect 3b5
看到container的環境資訊後,會發現幸好這個dockerfile有將資料獨立出來,在mount的字段下,我們可以看到/var/lib/cassandra的根目錄,被指派在我們本機(ubuntu)的/var/lib/docker/volumes/31a88f59c57b5a75b98f9c4e6a539e4140cb226760fc540b15b930d96010a84c/_data下。
(註:這邊不同系統的資料或設定目錄要視系統而定,不見得每個系統都有必要這樣做切割,但大部分有這樣切割設定的images佈署的彈性才會更好,也才會有更好使用率)
既然知道了cassandra相關檔案的實體位置,我們先將它備份壓縮起來吧。我已經可以想像等下要連同docker image的檔案與data要壓縮複製過去另一台主機。
先備份到個人目錄:
sudo cp -r /var/lib/docker/volumes/31a88f59c57b5a75b98f9c4e6a539e4140cb226760fc540b15b930d96010a84c /home/paul
記得要下-r,才會recursive的複製所有子目錄、檔案
這時/home/paul的目錄下就有了31a88f59c57b5a75b98f9c4e6a539e4140cb226760fc540b15b930d96010a84c
接著我們來進行打包成tar檔,tar的壓縮指令請參考:連結
tar -zcvf ./cassandra-data.tar ./31a88f59c57b5a75b98f9c4e6a539e4140cb226760fc540b15b930d96010a84c
建議可以使用加上-z的參數,代表,透過gzip的方式壓縮,若沒有-z或-j的話,是代表僅打包,不壓縮
ls -l看看壓完以後只剩下33MB,看起來效果不錯
既然都已經備份出來了,包含docker與資料的壓縮檔
那我們要怎麼從vm複製檔案到另一個vm呀?在我還沒學會scp指令前,我還真的只知道vm的linux開分享samba,然後透過windows去copy到另一台分享出來的目錄
以上動作,真的只需要1行指令就做的到了,那就是scp,我們先ssh到另一台目標移置的vm去!!
輸入scp指令看看使用方式:
usage: scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
[-l limit] [-o ssh_option] [-P port] [-S program]
[[user@]host1:]file1 … [[user@]host2:]file2
scp是secure copy的簡寫,因此我們可以從首n台主機host 1 ~host n的檔案,複製到local來,以我們的例子來說,我們只要切到目標主機的指令目錄以後,照著以下輸入
同意建立ecdsa以後,接著輸入遠端的密碼,就會發現他開始copy了:
scp [email protected]:/home/paul/cassandra-data.tar ./ [email protected]:/home/paul/cassandra-devenv.tar ./
restore docker的image
都搞定以後,我們輸入以下指令,就可以將這個備份load到這台vm的docker的images
sudo docker load -i ./cassandra-devenv.tar
不過怪異的是,不知有沒有參數可以指令輸入的repository name與tag,我load進來以後,預設是none。接著考慮本機的環境,我希望將cassandra的data目錄換一個位置:就到my/own/datadir吧,這邊沒有絕對名稱,只需要自己分的清楚,解壓縮以後,按照當初打包的相對位置先放置好:
tar -zxvf cassandra-data.tar
註:這邊我後來想想若在壓縮時,有透過-z的參數進行壓縮的話,建議命名就要是tar.gz,否則解壓端應該很難知道需不需要加上-z的參數,這邊因為都是我幹的,所以我當然知道要這樣搞。通通都解到目標目錄,接著看看目錄內容是不是都有了
(註:這邊我還省略了一些解壓目錄以後,再從目錄把檔案cp或mv到my/own/datadir的過程)
接著只要輸入神奇的docker run指令,就會發現
sudo docker run –name cassandra-dev -p 9042:9042 -v /my/own/datadir:/var/lib/cassandra -d e86
檢查一下,sudo docker ps,已經正常跑起來了,這邊其實我有發現,cassandra的服務通常都要跑三分鐘左右,有時initialize掛掉都是發生在2~3分之間,通常超過3分鐘,應該就是起來了
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2cf14dc1d4d0 e86 “/docker-entrypoint.s” 6 hours ago Up 6 hours 7000-7001/tcp, 7199/tcp, 9160/tcp, 0.0.0.0:9042->9042/tcp cassandra-dev
實際連到192.168.65.130(剛剛是從136備份過來)的cassandra來看看囉!嗯~資料看起來都有被複製過來~暫時大功告成!特此記錄一番
後記:每次要寫這種過程重現真的是很耗費時間(也整理了差不多1個多小時),我發現,最佳的記錄方式,其實就是當我們在試著學習與除錯的時候(若有那個餘裕啦)
就定期把相關的畫面與做過的事情,記錄到evernote或其他方便的地方,事後的整理事實上真的事半功倍…若下次有機會遇到的話…希望有機會想到…