原文做者:春哥php
初識春哥時,春哥是美術設計大咖。後不久,創業並致力於遊戲開發,已有3年。從Unity3D到IOS(Swift)開發,從前端開發到後端以及容器技術,從設計開發測試到產品經理以及CEO,已經是爬坑累累,可是還是奮勇前行。前端
春哥仍在奮鬥,遊戲也即將上線,而咱們也需砥礪前行啊!mysql
使用 Docker 時,容器(Container)會自動建立一個數據卷(Data Volume)來單獨儲存數據。數據卷有獨立的本地目錄,不跟着容器走,你在不一樣地方使用同一個容器,數據是不同的。自動建立的數據卷不便於管理,Docker 官方建議咱們用 Named Volume 來負責容器的數據持久化,Named Volume 就是本身取名字手動建立一個數據卷。sql
本文使用 MySQL 數據庫作例子。數據卷對數據庫容器來講是很是重要的。docker
這裏咱們隨便取個數據卷名字叫 my-data
吧。建立命令很簡單:數據庫
docker volume create --name my-data
容器在建立時,除了自動建立數據卷外,也會自動建立它的專用網絡(Network)。這個網絡咱們也要用本身建立的(Defined Network),本身建立的方便管理。這裏給網絡取名叫 my-network
:後端
docker network create my-network
爲何建立這個網絡呢?是爲了在容器間共享網絡,看下去就會明白。centos
如今利用前面建立的數據卷和網絡建立一個 MySQL 容器:瀏覽器
docker run -d --rm --name mysql-a -v my-data:/var/lib/mysql --network my-network -p 33061:3306 -e MYSQL_ROOT_PASSWORD=abcd1234 mysql:latest
詳細解釋一下各參數:bash
mysql-a
。3306
,你能夠換一個以避免和本地的衝突。這個例子中我映射到 33061
。-d
是後臺運行。 --rm
是讓容器在中止運行時自動刪除。數據在外部的卷裏,能夠放心刪。-v
就是使用數據卷。/var/lib/mysql
是 MySQL 存放數據的目錄,如今咱們要把裏面的東西都映射到數據卷裏:-v my-data:/var/lib/mysql
--network my-network
使用咱們剛纔建立的網絡。-e
設定 MySQL 的環境變量。在這裏咱們設定 root 密碼爲 abcd1234
mysql:latest
是映像(Image)。具體 tag 可看 Docker Hub: MySQL管理 MySQL 數據庫的客戶端有不少,其中 PhpMyAdmin 是比較常見的一種。因此如今咱們要建立 PhpMyAdmin 的容器,而後去管理 MySQL 容器,也就是鏈接兩種容器。
如何鏈接?之前能夠用 --link
的方式,但官方已經不推薦了,將來版本會棄用的,這裏就不寫了。官方推薦的是 Defined Network,以前建立 my-network
就是爲了用在這裏。若是你不用 PhpMyAdmin 管理,那麼 Network 也能夠不單首創建。
建立容器:
docker run -d --rm --name my-pma --network my-network -p 8080:80 -e PMA_HOST=mysql-a phpmyadmin/phpmyadmin
參數中 PMA_HOST=mysql-a
指定了 MySQL 容器。端口隨便映射了一個 8080
。建立好後,PhpMyAdmin 容器和 MySQL 容器就在同一個網絡裏了,而後 PhpMyAdmin 就能夠管理 MySQL 數據庫了。
如今打開瀏覽器,進 http://localhost:8080
,輸入 root 帳戶密碼就能夠進去管理了——若是你的 MySQL 版本 >= 5.7,那可能登陸不進去,須要改一下 MySQL 帳號所用的密碼插件(identified with mysql_native_password
)。
使用數據卷的一大好處,是能夠在不一樣機器和環境中使用同一套數據。所以,必須掌握如何備份和還原數據卷。
備份的操做思路:
命令行操做:
docker run --rm --volumes-from mysql-a -v $(pwd):/backup busybox tar cvf /backup/mysql-backup.tar /var/lib/mysql
參數說明:
--volumes-from mysql-a
,就是從 mysql-a
直接拿它的數據卷(my-data
)過來用。-v $(pwd):/backup
:將本地當前目錄做爲數據卷目錄映射到容器系統的 /backup
目錄,$(pwd)
就是輸出當前目錄,注意在 PowerShell 裏是 ${pwd}
。你用別的目錄也能夠。busybox
是用到的 Image,它的容量很小,但重要工具基本都有。tar cvf /backup/mysql-backup.tar /var/lib/mysql
是在容器裏執行的備份命令:將 /var/lib/mysql
(mysql-a
數據卷內容)打包到 /backup
目錄下的 mysql-backup.tar 中。因爲本地當前目錄和 /backup
有映射關係,因此本地當前目錄下也會有 mysql-backup.tar 文件。mysql-backup.tar 就是咱們建立的數據卷備份文件,你能夠帶着它處處跑了。有些人會作一個專門存放各類數據卷的容器做爲備份,我感受有點麻煩和多餘。
還原的思路和備份同樣,也是先要搞一個臨時容器,而後執行一些命令去解壓 tar 文件。
假設咱們在別的地方建立了一個新的 MySQL 容器 mysql-b
,咱們該怎麼把 my-data
數據卷的數據還原到它裏面去呢?
先把 mysql-backup.tar 拷貝到當前目錄。而後:
docker run --rm --volumes-from mysql-b -v $(pwd):/backup centos bash -c "cd /var/lib && rm -rf mysql/* && tar xvf /backup/mysql-backup.tar --strip 2"
這裏重點解釋一下在容器 bash 裏執行的命令:
cd /var/lib
: 進入 /var/lib
目錄。rm -rf mysql/*
: 刪除目錄 mysql 下的全部文件,爲的是等會將數據卷的備份文件放進去。刪除再解壓進去比直接覆蓋更乾淨穩妥一些。tar xvf /backup/mysql-backup.tar --strip 2
: 將 mysql-backup.tar 文件中 mysql 的文件解壓到 /var/lib/mysql
目錄中去,由於咱們在 /var/lib
中,而打包文件包括了 /var/lib/mysql
多層目錄,因此加了參數 --strip 2
。關於打包解壓目錄這種事你能夠本身規劃,只要確保 mysql
裏的文件能正確的備份和還原就行。文件解壓完後,重啓當前的 MySQL 容器:
docker restart mysql-b
還原工做到此結束,如今 mysql-b
的數據和 mysql-a
是同樣的了。
數據卷對數據庫容器很是重要。Named Volume 可使咱們管理數據卷更爲方便,應多加利用。其餘數據庫的文件結構和 MySQL 可能不同,但只要掌握了 MySQL 數據卷備份還原的原理以後,其餘數據庫應該也不難操做。