標籤: Linux

Docker映像與資料備份與還原:以cassandra為例

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或其他方便的地方,事後的整理事實上真的事半功倍…若下次有機會遇到的話…希望有機會想到…

 

透過Docker安裝mysql + phpmyadmin + nginx + php7 + wordpress

透過Docker安裝mysql + phpmyadmin + nginx + php7 + wordpress

最近開始熟悉使用Docker建置環境,索性希望透過一個平台可以記錄自己曾經待過的坑。原本是存在Evernote,但我希望一半程度可以透過公開平台來展現自己的經歷,這是一部分私心,但記錄下來總是對於自己曾經參與過的一個重新組織與整理的機會。

話不多說…立刻來指令安裝,這次的虛擬環境:從Azure上租了一個新台幣$800元左右/月的小小vm,只有單核,0.75G,但只用ssh,沒有什麼影像處理、大量運算的需求,先硬著頭皮用下去了吧,至於Linux Ubuntu Server版本,好像是16版的,一開始若沒安裝Docker的,可以透過以下指令安裝Linux上的Docker

sudo apt-get install docker.io

這次安裝過程中需要3個Containner,一個放db,二個放web server

安裝Mariadb

MariaDB是Mysql的Opensoure分支,最大的好處就是免費授權。不過mysql是否會遇到什麼授權問題其實我也不是太清楚,日後有機會再來研究。
有許多官網公司出的Docker/Images其實都很方便,wiki都建的好好的,單一無腦啟用或是微調設定上,資訊已經很足夠用了。

sudo docker pull mariadb:latest

sudo docker run --name mariadb \
-p 3306:3306 \
-v /mnt/mariadb/data:/var/lib/mysql \
-v /mnt/mariadb/config:/etc/mysql/conf.d \
 -e MYSQL_ROOT_PASSWORD=123456 \
  -d mariadb

-p代表port的對外開放。通常用:隔開,前者是使用端的port,後者是容器內port,因此假如你起了一個80的Docker Containner,但你希望綁到你對外主機domain 8080 port的話,就設定成-p 8080:80, 也可以給一樣的

-v代表volumns,代表要從外部掛載資料卷,外部資料卷會直接同步containner的內容。因此當你指定的位置內檔案有異動,containner會即時讀取到最新的檔案。

-e代表環境變數,通常是dockerfile內定義,預先初始化可以帶入的參數。這邊的例子是預設定root的密碼

這邊我就不註記所有的參數用途了,有興趣請到docker從入門到實踐

安裝好DataBase,接著來順便安裝一下PhpMyadmin,這個是我從大學時期就很愛用的Mysql管理介面,最棒的是他有web版本,方便至上

sudo docker pull phpmyadmin/phpmyadmin:latest
sudo docker run -d -P –name mariadbMyAdmin –link mariadb:db phpmyadmin/phpmyadmin

-d代表在background執行

–link代表containner之間建立連線,透過:隔開,前者為來源containner名稱,後者為別名,其原理其實為在此Containner的環境的/etc/hosts下建立ip別名,透過這樣,才能讓設定檔保持一致,不用因為每次取得新的虛擬ip後,程式相關的檔案又要再度調整。

這樣設定以後,就可以直接連到該畫面了,預設的port是32768

http://xxx.xxx.xxx.xxx:32768

可以使用一開始對mariadb設定的ip進行

下載Wordpress

wget https://tw.wordpress.org/wordpress-4.7.4-zh_TW.tar.gz

複製到指定的Application目錄

tar -xzpvf wordpress-4.7.4-zh_TW.tar.gz

將該解壓縮後的檔案目錄,直接複製到一個Application的目錄,這個目錄下再切一個Wordpress目錄放置所有解壓的內容。

wordpress設定檔位置:

wordpress/we-config.php

// ** MySQL 設定 – 您可以從主機服務提供商獲取相關資訊。 ** //
/** WordPress 的資料庫名稱,請更改 “database_name_here” */
define(‘DB_NAME’, ‘wordpress’);

/** MySQL 資料庫使用者名稱,請更改 “username_here” */
define(‘DB_USER’, ‘wordpressuser’);

/** MySQL 資料庫密碼,請更改 “password_here” */
define(‘DB_PASSWORD’, ‘Abc123’);

/** MySQL 主機位址 */
define(‘DB_HOST’, ‘mariadb’);

/** 建立資料表時預設的文字編碼 */
define(‘DB_CHARSET’, ‘utf8’);

/** 資料庫對照型態。如果不確定請勿更改。 */
define(‘DB_COLLATE’, ‘utf8_unicode_ci’);

我這邊我先將db的路徑先直接改成我等下預計要建立link的名稱:mariadb,然後帳密先設定一下就好,另外我有設一個,認證金鑰,相關取得方式config都有說明,一併複製到config檔裡面就好

安裝nginx+php+php_mysql模組

特別說一下,這次使用的docker組合是已經有大神Docker連結,將php7+NGINX打包好,我將剛剛下載解壓的wordpress放到application目錄中,然後一樣透過-v配置到容器中,同時指定link到mariadb。(我自己試著裝php7,可以正常使用php,偏偏少了mysql的extension,卡了半天,先投降,日後再努力orz)

sudo docker run –name nginx -p 80:80 -v /home/paul/nginx-php/application:/data/www –link mariadb:mariadb -d skiychan/nginx-php7

建立起來以後,直接連到ip的80 port,記得vm的firewall要開,不然怎樣都連不進去

苦手坑談

曾經想自已分別安裝nginx與php-fpm模組。會這樣想純粹是因為好像有了Docker任何安裝問題都解決了,想裝什麼就裝什麼…所以我透過Docker-Compose.yml玩了一個上午,透過配置的方式,驅動Docker建置,但當環境愈來愈複雜時,包含DB跟App的分離,Php模組需要做調整設定,不同Containner之間要Link,還分為外部link跟內部link,事實上我苦腦於Compose的配置如何跟已存在的containner作link,這段也還沒研究出來,看來還有很長的路要走,但至少現在有一個開始,所以才有辦法發這篇文章呀XD