docker中的數據庫

 

 

注:自從開始使用docker,部署方面的事情就簡單多了。使用docker構建的數據庫容器不用直接安裝,開啓後就可使用,也比之前方便不少。下面將一些要點記錄下來。html

下面的例子使用如下環境:python

- 系統(即host):CentOS Linux release 7.4.1708mysql

- docker:Docker version 17.12.0-ce, build c97c6d6git

- 數據庫:MariaDB 5.5github

 

啓動數據庫


MariaDB是MySQL的一個分支,使用起來基本上沒有什麼差異。在docker hub中有該數據庫的官方鏡像,使用下面的簡單命令就能夠開啓一個數據庫容器,開啓後能夠利用IP+端口號的方式訪問該數據庫。sql

複製代碼
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;docker

-p: 端口,3301:3306表示將容器中的3306端口公開給host的3301端口;數據庫

-v: 表示volume,用來設置數據文件存放的位置,~/mdbdata/mdb55:/var/lib/mysql表示將host中當前用戶home目錄下的文件夾"mdbdata/mdb55"掛載於容器中的/var/lib/mysql目錄,這樣即便容器被刪除,數據文件仍是能夠保留;django

-e: 表示environment,用來設置用戶及密碼等環境變量,MYSQL_ROOT_PASSWORD=admin表示將root的密碼設置爲admin(只在第一次登錄數據庫時使用);bash

--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行,配置了數據庫的字符集,更多可參考link1link2
  • 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  | 
複製代碼

 

 

Reference


https://mariadb.com/resources/blog/mariadb-and-docker-use-cases-part-1/

https://stackoverflow.com/a/47980388/2803344

相關文章
相關標籤/搜索