天天看點

Docker MySQL持久性

Java開發人員的9個Docker食譜中的食譜之一是将MySQL容器與WildFly結合使用。 Docker容器是臨時性的,是以終止和删除它們後,存儲在其中的任何狀态都将消失。 是以,即使可以按照本食譜中的說明使用MySQL容器,也可以使用DDL / DML指令來持久化資料,但是在終止和删除容器之後,該狀态将丢失,或者至少不可通路。

該部落格展示了Docker MySQL Persistence的不同方法-跨容器重新開機并可以從多個容器通路。

MySQL Docker容器的預設資料位置

讓我們檢視MySQL Docker容器存儲資料的預設位置。

以以下方式啟動MySQL容器:

docker run --name mysqldb -e MYSQL_USER=mysql -e MYSQL_PASSWORD=mysql -e MYSQL_DATABASE=sample -e MYSQL_ROOT_PASSWORD=supersecret -d mysql
           

并檢查為:

docker inspect -f {{.Volumes}} <CONTAINER_ID>
           

然後顯示匿名卷:

map[/var/lib/mysql:/mnt/sda1/var/lib/docker/vfs/dir/78f079dae09bf052cf900951b6d71a611fcf7c72f3460a2013e6f4d941a2b256]
           

如果使用的是Boot2Docker,則

/mnt/sda1

目錄用于存儲映像,容器和資料。 該目錄來自Boot2Docker虛拟機檔案系統。 Docker文檔中也對此做了澄清,值得在這裡重複:

注意:如果使用的是Boot2Docker,則Docker守護程式僅對OSX / Windows檔案系統具有有限的通路權限。 Boot2Docker嘗試自動共享您的

/Users

(OSX)或

C:\Users

(Windows)目錄,是以您可以使用

docker run -v /Users/<path>:/<container path> ...

挂載檔案或目錄

docker run -v /Users/<path>:/<container path> ...

(OSX)或

docker run -v /c/Users/<path>:/<container path ...

(Windows)。 所有其他路徑都來自Boot2Docker虛拟機的檔案系統。

您可以通過以下方式登入到VM,進而在Boot2Docker上檢視此已安裝目錄:

boot2docker ssh
           

然後檢視目錄清單為:

[email protected]:~$ ls -la /mnt/sda1/var/lib/docker/
total 72
drwxr-xr-x   11 root     root          4096 Apr  9 19:45 ./
drwxr-xr-x    4 root     root          4096 Mar 27 13:58 ../
drwxr-xr-x    5 root     root          4096 Mar 27 13:59 aufs/
drwx------   10 root     root          4096 Apr  9 19:45 containers/
drwx------    3 root     root          4096 Mar 27 13:59 execdriver/
drwx------  128 root     root         20480 Apr  9 19:45 graph/
drwx------    2 root     root          4096 Apr  7 23:34 init/
-rw-r--r--    1 root     root          7168 Apr  9 19:45 linkgraph.db
-rw-------    1 root     root          2229 Apr  9 19:45 repositories-aufs
drwx------    2 root     root          4096 Apr  9 19:14 tmp/
drwx------    2 root     root          4096 Mar 27 17:56 trust/
drwx------    3 root     root          4096 Apr  9 19:45 vfs/
drwx------    4 root     root          4096 Apr  9 19:45 volumes/
           

跨容器重新開機的MySQL資料–匿名卷

匿名卷(即,由容器建立且未顯式安裝的卷)是特定于容器的。 除非使用

docker remove -v

指令明确删除它們,否則它們會一直存在。 這意味着即使可能不會删除先前的卷,也會為新容器安裝新的匿名卷。 即使在終止并删除容器後,該卷仍駐留在Docker主機上。 一個MySQL容器建立的匿名卷不能被另一個MySQL容器通路。 這意味着不能在不同的資料容器之間共享資料。

讓我們使用代碼來了解這一點。

以以下方式啟動MySQL容器:

docker run --name mysqldb -e MYSQL_USER=mysql -e MYSQL_PASSWORD=mysql -e MYSQL_DATABASE=sample -e MYSQL_ROOT_PASSWORD=supersecret -it -p 3306:3306 mysql
           

登入到容器:

docker exec -it <CONTAINER_ID> bash
           

連接配接到MySQL執行個體,并建立一個表,如下所示:

[email protected]:/# mysql --user=mysql --password=mysql
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.6.24 MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| sample             |
+--------------------+
2 rows in set (0.00 sec)

mysql> connect sample;
Connection id:    3
Current database: sample

mysql> show tables;
Empty set (0.00 sec)

mysql> create table user(name varchar(50));
Query OK, 0 rows affected (0.00 sec)

mysql> show tables;
+------------------+
| Tables_in_sample |
+------------------+
| user             |
+------------------+
1 row in set (0.00 sec)
           

停止容器:

docker stop <CONTAINER_ID>
           

重新啟動容器:

docker start <CONTAINER_ID>
           

現在,當您連接配接到MySQL容器時,資料庫表将正确顯示。 這表明匿名卷可以在容器重新啟動後保持狀态。

檢查容器:

~> docker inspect -f {{.Volumes}} ea7b1eff9714
map[/var/lib/mysql:/mnt/sda1/var/lib/docker/vfs/dir/78f079dae09bf052cf900951b6d71a611fcf7c72f3460a2013e6f4d941a2b256]
           

并且它可以正确顯示

/mnt/sda1

目錄中的相同匿名卷。

現在,讓我們删除該容器,然後啟動一個新的MySQL容器。 首先取出容器:

docker rm -f <CONTAINER_ID>
           

并使用與先前相同的指令啟動新容器:

docker run --name mysqldb -e MYSQL_USER=mysql -e MYSQL_PASSWORD=mysql -e MYSQL_DATABASE=sample -e MYSQL_ROOT_PASSWORD=supersecret -it -p 3306:3306 mysql
           

現在,當您嘗試檢視表清單時,其顯示為空:

mysql> connect sample;
Connection id:    3
Current database: sample

mysql> show tables;
Empty set (0.00 sec)
           

這是因為匿名卷在容器重新啟動時可見,但對其他容器不可見。 将安裝新卷以用于容器的新運作。 還可以通過再次檢查容器來驗證:

~> docker inspect -f {{.Volumes}} bde73c930275
map[/var/lib/mysql:/mnt/sda1/var/lib/docker/vfs/dir/4d0ab6d1412bfbe79541b2d87d632cf12e70044201665f859a6a678132fb323f]
           

使用另一個目錄來裝入匿名卷。

如此有效地,由一個容器存儲在MySQL資料庫中的任何資料都不可用于另一個MySQL容器。

用于存儲MySQL資料的Docker卷

在不同的MySQL容器之間共享資料的一種選擇是在運作Docker映像時使用

-v

開關将Docker主機上的目錄作為卷裝入容器中。 如果使用的是Boot2Docker,則有兩種選擇:

  • 從Boot2Docker VM檔案系統挂載目錄。 如果該目錄不存在,則需要建立。
  • 從Mac主機挂載目錄。 為了友善起見,此目錄必須存在于

    /Users/arungupta

    或您對應的目錄中。

第一種方法與特定的Boot2Docker VM映像相關,第二種方法與特定的Mac主機相關。 稍後我們将讨論如何解決此問題。

我們僅在這裡讨論第一種方法。 以以下方式啟動MySQL容器:

docker run --name mysqldb -v /mnt/sda1/var/mysql_data:/var/lib/mysql -e MYSQL_USER=mysql -e MYSQL_PASSWORD=mysql -e MYSQL_DATABASE=sample -e MYSQL_ROOT_PASSWORD=supersecret -it -p 3306:3306 mysql
           

/var/lib/mysql

是MySQL容器寫入其檔案的預設目錄。 Boot2Docker重新開機後,該目錄不會保留。 是以,建議的選項是在

/mnt/sda1

建立一個目錄并映射該目錄。 確定像上面一樣建立目錄

/mnt/sda1/var/mysql_data

現在檢查容器為:

~> docker inspect -f {{.Volumes}} cd7deacc9d18
map[/var/lib/mysql:/mnt/sda1/var/mysql_data]
           

現在,容器的所有其他運作都可以安裝相同的卷,并且可以通路資料。

請記住,多個MySQL容器不能一起通路此共享安裝,而是會出現錯誤:

2015-04-10 02:35:58 1 [ERROR] InnoDB: Unable to lock ./ibdata1, error: 11
2015-04-10 02:35:58 1 [Note] InnoDB: Check that you do not already have another mysqld process using the same InnoDB data or log files.
2015-04-10 02:35:58 1 [Note] InnoDB: Retrying to lock the first data file
           

是以,您需要確定停止現有的MySQL容器,使用相同的卷啟動新的MySQL容器,并且仍然可以通路資料。

這可以使用主/從配置進行配置,其中主伺服器和從伺服器可以通路相同的卷。 如果嘗試過該配置的人可以共享該配方,那将是很好的。

但是如前所述,這種方法是以主機為中心的。 它将MySQL限制為特定的Boot2Docker VM映像。 這意味着,您再次失去了Docker提供的可移植性的巨大好處。

認識Docker僅資料容器!

Docker僅資料容器

Docker很好地遵循了單一職責原則(SRP)。 Docker僅資料容器是NoOp容器,它們執行的指令實際上并不相關,而是裝載用于存儲資料的卷。 這些容器甚至不需要啟動或運作,是以該指令實際上是無關緊要的,僅建立它們就足夠了。

建立容器為:

docker create --name mysql_data -v /var/lib/mysql mysql
           

如果計劃以後使用MySQL容器,建議使用

mysql

映像來節省帶寬和空間,以免下載下傳另一個随機映像。 您可以針對所使用的任何資料庫容器調整此指令。

如果打算使用MySQL,則可以将以下僅資料容器建立為:

docker create --name mysql_data arungupta/mysql-data-container
           

該容器的Dockerfile非常簡單,可用于您選擇的資料庫伺服器。

由于此容器未運作,是以僅在

docker ps

中将不可見。 相反,您需要使用

docker ps -a

檢視容器:

~> docker ps -a | grep mysql
ec48ddda196e        mysql:5                      "/entrypoint.sh mysq   2 days ago                                                        mysql_data
           

Docker允許使用運作容器時指定的

--volumes-from

開關從其他容器安裝或拉入卷。

讓我們啟動MySQL容器以将此純資料容器用作:

docker run --name mysqldb --volumes-from mysql_data -v /var/lib/mysql:/var/lib/mysql -e MYSQL_USER=mysql -e MYSQL_PASSWORD=mysql -e MYSQL_DATABASE=sample -e MYSQL_ROOT_PASSWORD=supersecret -it -p 3306:3306 mysql
           

Boot2Docker VM現在已填充

/var/lib/mysql

目錄:

total 110596
drwxrwxrwx    5 999      999            180 Apr 10 05:05 ./
drwxrwxr-x    4 root     staff          120 Apr  9 21:11 ../
-rw-rw----    1 999      999             56 Apr 10 00:57 auto.cnf
-rw-rw----    1 999      999       50331648 Apr 10 05:05 ib_logfile0
-rw-rw----    1 999      999       50331648 Apr 10 00:57 ib_logfile1
-rw-rw----    1 999      999       12582912 Apr 10 05:05 ibdata1
drwx------    2 999      999           1620 Apr 10 00:57 mysql/
drwx------    2 999      999           1100 Apr 10 00:57 performance_schema/
drwx------    2 999      999            100 Apr 10 01:18 sample/
           

如果停止此容器,然後運作另一個容器,則可以在那裡通路資料。

Docker MySQL持久性

在一個簡單的場景中,應用程式伺服器,資料庫和僅資料容器都可以位于同一主機上。 另外,應用程式伺服器可以駐留在單獨的主機上,而資料庫伺服器和僅資料容器可以駐留在同一主機上。

希望當Docker卷可以跨多個主機工作時,它會更加廣泛。

如果所有這些操作(即建立僅資料容器并啟動使用僅資料容器中的卷的MySQL容器)都可以使用Docker Compose輕松完成,那将是很好的。 #1284應該解決此問題。

通常的

mysqldump

mysql

指令可用于從卷備份和還原。 這可以通過使用CLI為連接配接到MySQL實作這裡解釋 。

  • 您還可以檢視docker-volumes來管理主機上的卷。
  • 您還可以在#6496上閱讀有關将來可能發展的卷的更多資訊。

請享用!

翻譯自: https://www.javacodegeeks.com/2015/04/docker-mysql-persistence.html