注:自從開始使用docker,部署方面的事情就簡單多了。使用docker構建的數據庫容器不用直接安裝,開啟后就可以使用,也比以前方便很多。下面將一些要點記錄下來。
下面的例子使用以下環境:
- 系統(即host):CentOS Linux release 7.4.1708
- docker:Docker version 17.12.0-ce, build c97c6d6
- 數據庫:MariaDB 5.5
啟動數據庫
MariaDB是MySQL的一個分支,使用起來基本上沒有什么差別。在docker hub中有該數據庫的官方鏡像,使用下面的簡單命令就可以開啟一個數據庫容器,開啟后可以利用IP+端口號的方式訪問該數據庫。
1 [belter@localhost ~]$ docker run -d -p 3301:3306 -v ~/mdbdata/mdb55:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=admin --name mdb55 mariadb:5.5 2 c7f2cd8ed93de8ab8ab58171c375e83fb2659c2a1cdab2ec79c264cb78b1e131 3 [belter@localhost ~]$ docker ps 4 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5 c7f2cd8ed93d mariadb:5.5 "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:3301->3306/tcp mdb55
- 使用第1行的命令,就可以開啟一個數據庫容器,主要參數:
-d: 表示detach,后台運行並打印container ID;
-p: 端口,3301:3306表示將容器中的3306端口公開給host的3301端口;
-v: 表示volume,用來設置數據文件存放的位置,~/mdbdata/mdb55:/var/lib/mysql表示將host中當前用戶home目錄下的文件夾"mdbdata/mdb55"掛載於容器中的/var/lib/mysql目錄,這樣即使容器被刪除,數據文件還是可以保留;
-e: 表示environment,用來設置用戶及密碼等環境變量,MYSQL_ROOT_PASSWORD=admin表示將root的密碼設置為admin(只在第一次登陸數據庫時使用);
--name: 表示容器的名稱,例如現在這個數據庫容器的名稱為mdb55
命令的最后是鏡像的名稱,mariadb:5.5表示MariaDB-5.5
- 第2行是返回的容器編號
- 第3行的命令用來查看當前運行的容器列表,第4-5行可以看到剛剛啟動的數據庫容器的基本信息
此外可以使用下面的命令查看全部容器的狀態(包括已經停止運行的容器),以及刪除容器
1 [belter@localhost ~]$ docker ps -a # 查看所有的容器 2 [belter@localhost ~]$ docker rm 92a1bcd89578 # 刪除ID為92a1bcd89578的容器
Mariadb在docker hub中的官方網站,以及build鏡像mariadb:5.5的Dockerfile文件。
下面測試一下剛啟動的數據庫容器的連接:
1 [belter@localhost ~]$ mysql -u root -padmin -h 127.0.0.1 -P3301 2 Welcome to the MariaDB monitor. Commands end with ; or \g. 3 Your MariaDB connection id is 3 4 Server version: 5.5.60-MariaDB-1~trusty mariadb.org binary distribution 5 6 Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others. 7 8 Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. 9 10 MariaDB [(none)]>
現在已經可以正常連接該數據庫了(由於這里使用了host中的mysql命令,因此需要先安裝mysql才能使用)。
- 注意-padmin和-P3301之間沒有空格,一個表示user的密碼,另一個表示連接的端口號;
- -h: 表示需要連接的數據庫的IP地址,這里連接的是本地IP+3301端口,host中的3301端口是訪問數據庫容器中3306端口的入口;
上面使用host中的mysql來連接容器中的數據庫,需要先在本地安裝mysql(或MariaDB)。此外也可以直接進入容器內部連接該數據庫:
1 [belter@localhost ~]$ docker exec -it c7f2cd8ed93d /bin/bash 2 root@c7f2cd8ed93d:/# mysql -u root -padmin -h 127.0.0.1 -P3306 3 Welcome to the MariaDB monitor. Commands end with ; or \g. 4 Your MariaDB connection id is 4 5 Server version: 5.5.60-MariaDB-1~trusty mariadb.org binary distribution 6 7 Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. 8 9 Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. 10 11 MariaDB [(none)]>
- 使用第1行命令,進入剛才啟動的數據庫容器(ID為c7f2cd8ed93d)的bash;
- 進入容器后,使用第2行命令連接容器內部的數據庫,此時使用的端口號是3306.
注:退出數據庫和容器都可以使用"exit;"
為了測試修改密碼以及數據文件的重用,在數據庫中做了以下修改:修改root的密碼,創建一個新的數據庫"test"並在該數據庫中創建一個表"table1"
1 # 修改root的密碼為admin1,並更新權限列表 2 SET PASSWORD FOR 'root'@'%' = PASSWORD('admin1'); 3 FLUSH PRIVILEGES; 4 5 # 創建數據庫test,並在該數據庫中創建表table1 6 CREATE DATABASE test; 7 CREATE TABLE table1( 8 col1 VARCHAR(50), 9 col2 VARCHAR(50) 10 ); 11 12 # 在表table1中插入兩行記錄 13 INSERT INTO table1(col1, col2) VALUES(1, 'Belter'), (2, 'Merry Christmas');
數據文件可以直接復制到另一個文件夾來備份(所有者修改為ods:ssh_keys,與原數據文件相同)
使用docker-compose配置數據庫
利用上面的方法可以快速開啟一個數據庫容器,連接后就可以使用。但是配置的參數都寫在命令行中不利於后面的維護。此時可以使用docker-compose來保存配置文件:
對於數據庫來說,主要需要以下幾方面的配置:用戶及密碼,數據文件存放的位置,端口,字符集。
下面是我的配置文件:
1 version: '2.2' 2 3 services: 4 db: 5 image: mariadb:5.5 6 restart: always 7 environment: 8 - MYSQL_HOST=localhost 9 - MYSQL_PORT=3306 # port in container 10 - MYSQL_ROOT_HOST=% 11 - MYSQL_DATABASE=test 12 - MYSQL_USER=belter 13 - TZ=Asia/Shanghai 14 volumes: 15 - ~/mdbdata/mdb55:/var/lib/mysql 16 ports: 17 - 3303:3306 18 command: 19 - --character-set-server=utf8mb4 20 - --collation-server=utf8mb4_unicode_ci 21 - --skip-character-set-client-handshake
更多關於docker-compose.yml文件的介紹,可參考我的上一篇博客:使用docker搭建數據分析環境
- environment是對容器內部來說的,第10行設置為"%"表示允許使用root遠程連接數據庫,第11行指定了MYSQL_USER直接訪問的數據庫,MYSQL_USER需要手動添加;
- 修改完root密碼后,就不需要在environment中指定MYSQL_ROOT_PASSWORD這一參數了,該參數相當於指定了數據庫初始化時的root密碼;
- 第19-21行,配置了數據庫的字符集,更多可參考link1, link2
- host的端口換成3303
停止之前運行的容器,並使用docker-compose啟動上面配置好的容器:
1 [belter@localhost mariadb]$ docker stop c7f2cd8ed93d 2 c7f2cd8ed93d 3 [belter@localhost mariadb]$ docker-compose up -d 4 Creating network "mariadb_default" with the default driver 5 Creating mariadb_db_1 ... done 6 [belter@localhost mariadb]$ docker-compose logs 7 Attaching to mariadb_db_1 8 db_1 | 181225 18:04:11 [Note] mysqld (mysqld 5.5.60-MariaDB-1~trusty) starting as process 1 ... 9 db_1 | 181225 18:04:11 InnoDB: The InnoDB memory heap is disabled 10 db_1 | 181225 18:04:11 InnoDB: Mutexes and rw_locks use GCC atomic builtins 11 db_1 | 181225 18:04:11 InnoDB: Compressed tables use zlib 1.2.8 12 db_1 | 181225 18:04:11 InnoDB: Using Linux native AIO 13 db_1 | 181225 18:04:11 InnoDB: Initializing buffer pool, size = 256.0M 14 db_1 | 181225 18:04:11 InnoDB: Completed initialization of buffer pool 15 db_1 | 181225 18:04:11 InnoDB: highest supported file format is Barracuda. 16 db_1 | 181225 18:04:11 InnoDB: Waiting for the background threads to start 17 db_1 | 181225 18:04:12 Percona XtraDB (http://www.percona.com) 5.5.59-MariaDB-38.11 started; log sequence number 1601918 18 db_1 | 181225 18:04:12 [Note] Plugin 'FEEDBACK' is disabled. 19 db_1 | 181225 18:04:12 [Note] Server socket created on IP: '0.0.0.0'. 20 db_1 | 181225 18:04:12 [Warning] 'proxies_priv' entry '@ root@c7f2cd8ed93d' ignored in --skip-name-resolve mode. 21 db_1 | 181225 18:04:12 [Note] Event Scheduler: Loaded 0 events 22 db_1 | 181225 18:04:12 [Note] mysqld: ready for connections. 23 db_1 | Version: '5.5.60-MariaDB-1~trusty' socket: '/var/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
- 第1行停止了之前的容器(停止后3301端口就無法訪問了);
- 第3行從docker-compose啟動了新的數據庫容器;
- 第6行查看容器開啟之后的日志,第22行顯示數據庫已經可以正常連接.
使用上面的方法,連接host的3303端口:
1 [xiongxin@localhost mariadb]$ mysql -u root -padmin1 -h 127.0.0.1 -P3303 2 Welcome to the MariaDB monitor. Commands end with ; or \g. 3 Your MariaDB connection id is 2 4 Server version: 5.5.60-MariaDB-1~trusty mariadb.org binary distribution 5 6 Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others. 7 8 Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. 9 10 MariaDB [(none)]> show databases; 11 +--------------------+ 12 | Database | 13 +--------------------+ 14 | information_schema | 15 | mysql | 16 | performance_schema | 17 | test | 18 +--------------------+ 19 4 rows in set (0.00 sec) 20 21 MariaDB [(none)]> select * from test.table1; 22 +------+-----------------+ 23 | col1 | col2 | 24 +------+-----------------+ 25 | 1 | Belter | 26 | 2 | Merry Christmas | 27 +------+-----------------+ 28 2 rows in set (0.00 sec) 29 30 MariaDB [(none)]>
可以正常連接,且之前的數據還可以查詢到。
在另一個容器中連接數據庫
創建另一個文件夾"query-db",從另外一個鏡像上開啟一個新的容器,如果這個容器需要連接上面的數據庫容器該怎么辦呢?
下面使用的鏡像可以在我的docker hub中下載到:django_py35_new,更多關於這個問題的討論可以參考Stack OverFlow。
直接使用host的IP(127.0.0.1)和本地的端口(3303)無法連接。這時候需要使用docker內部自己建立的網絡將這兩個容器連接起來。
在該文件夾下創建如下docker-compose.yml文件:
1 version: '2.2' 2 3 services: 4 djangoApp: 5 image: onlybelter/django_py35_new 6 # restart: on-failure 7 command: python3 query_db.py 8 working_dir: /code 9 volumes: 10 - ./code:/code 11 - /etc/localtime:/etc/localtime:ro 12 environment: 13 - PYTHONUNBUFFERED=1 14 15 networks: 16 default: 17 external: 18 name: mariadb_default
並且在該文件夾下創建新的文件夾"code",並將名為query_db.py的文件放到code文件夾,該文件內的代碼如下:
import MySQLdb import time def q_db(): db = MySQLdb.connect(host='db', port=3306, user='root', passwd='admin1', db='test') try: q_queue = """SELECT a.col2 FROM table1 AS a;""" with db.cursor() as cursor: cursor.execute(query=q_queue) one_queue = cursor.fetchall() print(one_queue[0], one_queue[1], '\n') except Exception as e: print(e) finally: db.close() while 1: q_db() time.sleep(5)
- 在上面的docker配置文件中的第7行,會執行code文件夾中名為"query_db.py"的Python腳本,即上面所示的Python代碼;
- 配置文件的第15-18行,添加了數據庫容器中默認網絡的名稱"mariadb_default"作為自己的一個擴展網絡(一般由文件夾的名稱+"_default");
整體的目錄結構如下:
mariadb # 數據庫容器所在的文件夾
docker-compose.yml
query-db # 查詢數據庫的另一個容器所在的文件夾
docker-compose.yml
code # code文件夾
query_db.py
可以使用下面的命令來查看當前正在運行的容器所屬的網絡(通常名稱為外部的文件夾名稱加一個"_default"后綴):
1 [belter@localhost query-db]$ docker network ls 2 NETWORK ID NAME DRIVER SCOPE 3 1d35e7fb797c bridge bridge local 4 8a2336ca7bcc djangopy35_default bridge local 5 8d044b04d49f mariadb_default bridge local
由於擴展網絡的連接,上面的Python代碼會查詢之前建立的數據庫容器(名稱為db,配置文件中service的名稱)的3306端口(docker的內網),然后輸出數據庫中的內容:
1 [belter@localhost query-db]$ docker-compose up 2 Starting querydb_djangoApp_1 ... done 3 Attaching to querydb_djangoApp_1 4 djangoApp_1 | ('Belter',) ('Merry Christmas',) 5 djangoApp_1 | 6 djangoApp_1 | ('Belter',) ('Merry Christmas',) 7 djangoApp_1 | 8 djangoApp_1 | ('Belter',) ('Merry Christmas',) 9 djangoApp_1 |
Merry Christmas!
Reference
https://mariadb.com/resources/blog/mariadb-and-docker-use-cases-part-1/
https://stackoverflow.com/a/47980388/2803344
