注: 自从开始使用 docker, 部署方面的事情就简单多了. 使用 docker 构建的数据库容器不用直接安装, 开启后就可以使用, 也比以前方便很多. 下面将一些要点记录下来.
下面的例子使用以下环境:
- 系统: CentOS Linux release 7.4.1708
- docker:Docker version 17.12.0-ce, build c97c6d6
- 数据库: MariaDB 5.5
启动数据库
MariaDB 是 MySQL 的一个分支, 使用起来基本上没有什么差别. 在 docker hub 中有该数据库的官方镜像, 使用下面的简单命令就可以开启一个数据库容器, 开启后可以利用端口 ip + 端口号的方式访问该数据库.
- [belter@localhost ~]$ docker run -d -p 3301:3306 -v ~/mdbdata/mdb55:/var/lib/MySQL -e MYSQL_ROOT_PASSWORD=admin --name mdb55 mariadb:5.5
- c7f2cd8ed93de8ab8ab58171c375e83fb2659c2a1cdab2ec79c264cb78b1e131
- [belter@localhost ~]$ docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 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: 后台运行;
-p: 端口, 3301:3306 表示 host 上的 3301 端口对于容器中 3306 端口;
-v: 表示 volumes, 用来设置数据文件存放的位置,~/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 行可以看到刚刚启动的数据库容器的基本信息
此外可以使用下面的命令查看全部容器的状态(包括已经停止运行的容器), 以及删除容器
- [belter@localhost ~]$ docker ps -a # 查看所有的容器
- [belter@localhost ~]$ docker rm 92a1bcd89578 # 删除 ID 为 92a1bcd89578 的容器
Mariadb 在 docker hub 中的官方网站 https://hub.docker.com/_/mariadb/ , 以及 build 镜像 mariadb:5.5 的 Dockerfile 文件.
下面测试一下刚启动的数据库容器的连接:
- [belter@localhost ~]$ MySQL -u root -padmin -h 127.0.0.1 -P3301
- Welcome to the MariaDB monitor. Commands end with ; or \g.
- Your MariaDB connection id is 3
- Server version: 5.5.60-MariaDB-1~trusty mariadb.org binary distribution
- Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
- Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
- MariaDB [(none)]>
现在已经可以正常连接该数据库了(由于这里使用了 host 中的 MySQL 命令, 因此需要先安装 MySQL 才能使用).
注意 - padmin 和 - P3301 之间没有空格, 一个表示 user 的密码, 另一个表示连接的端口号;
-h: 表示 host 的 IP 地址, 这里连接的是本地 IP+3301 端口, 该端口对应于容器中的 3306 端口;
上面使用 host 中的 MySQL 来连接容器中的数据库, 需要先在本地安装 MySQL(或 MariaDB). 此外也可以直接进入容器内部连接该数据库:
- [belter@localhost ~]$ docker exec -it c7f2cd8ed93d /bin/bash
- root@c7f2cd8ed93d:/# MySQL -u root -padmin -h 127.0.0.1 -P3306
- Welcome to the MariaDB monitor. Commands end with ; or \g.
- Your MariaDB connection id is 4
- Server version: 5.5.60-MariaDB-1~trusty mariadb.org binary distribution
- Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
- Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
- MariaDB [(none)]>
使用第 1 行命令, 进入刚才启动的数据库容器 (ID 为 c7f2cd8ed93d) 的 bash;
进入容器后, 使用第 2 行命令连接容器内部的数据库, 此时使用的端口号是 3306.
注: 退出数据库和容器都可以使用 "exit;"
为了测试修改密码以及数据文件的重用, 在数据库中做了以下修改: 修改 root 的密码, 创建了一个新的数据库以及表
- # 修改 root 的密码为 admin1, 并更新权限列表
- SET PASSWORD FOR 'root'@'%' = PASSWORD('admin1');
- FLUSH PRIVILEGES;
- # 创建数据库 test, 并在该数据库中创建表 table1
- CREATE DATABASE test;
- CREATE TABLE table1(
- col1 VARCHAR(50),
- col2 VARCHAR(50)
- );
- # 在表 table1 中插入两行记录
- INSERT INTO table1(col1, col2) VALUES(1, 'Belter'), (2, 'Merry Christmas');
数据文件可以直接复制到另一个文件夹来备份(所有者修改为 ods:ssh_keys, 与原数据文件相同)
使用 docker-compose 配置数据库
利用上面的方法可以快速开启一个数据库容器, 连接后就可以使用了. 但是配置的参数都写在命令行中不利于后面的维护. 此时可以使用 docker-compose 来保存配置文件:
对于数据库来说, 主要需要以下几方面的配置: 用户及密码, 数据文件存放的位置, 端口, 字符集.
下面是我的配置文件:
- version: '2.2'
- services:
- db:
- image: mariadb:5.5
- restart: always
- environment:
- - MYSQL_HOST=localhost
- - MYSQL_PORT=3306 # port in container
- - MYSQL_ROOT_HOST=%
- - MYSQL_DATABASE=test
- - MYSQL_USER=belter
- - TZ=Asia/Shanghai
- volumes:
- - ~/mdbdata/mdb55:/var/lib/MySQL
- ports:
- - 3303:3306
- command:
- - --character-set-server=utf8mb4
- - --collation-server=utf8mb4_unicode_ci
- - --skip-character-set-client-handshake
更多关于 docker-compose.YAML 文件的介绍, 可参考我的上一篇博客: 使用 docker 搭建数据分析环境
environment 是对容器内部来说的, 第 10 行设置为 "%" 表示允许使用 root 远程连接数据库, 第 11 行指定了 MYSQL_USER 直接访问的数据库, MYSQL_USER 需要手动添加;
修改完 root 密码后, 就不需要在 environment 中指定 MYSQL_ROOT_PASSWORD 这一参数了, 该参数相当于指定了数据库初始化时的 root 密码;
第 19-21 行, 配置了数据库的字符集, 更多可参考 link1 http://ourmysql.com/archives/1402 , link2
端口换成 3303
停止之前运行的容器, 并使用 docker-compose 启动上面配置好的容器:
- [belter@localhost mariadb]$ docker stop c7f2cd8ed93d
- c7f2cd8ed93d
- [belter@localhost mariadb]$ docker-compose up -d
- Creating network "mariadb_default" with the default driver
- Creating mariadb_db_1 ... done
- [belter@localhost mariadb]$ docker-compose logs
- Attaching to mariadb_db_1
- db_1 | 181225 18:04:11 [Note] mysqld (mysqld 5.5.60-MariaDB-1~trusty) starting as process 1 ...
- db_1 | 181225 18:04:11 InnoDB: The InnoDB memory heap is disabled
- db_1 | 181225 18:04:11 InnoDB: Mutexes and rw_locks use GCC atomic builtins
- db_1 | 181225 18:04:11 InnoDB: Compressed tables use zlib 1.2.8
- db_1 | 181225 18:04:11 InnoDB: Using Linux native AIO
- db_1 | 181225 18:04:11 InnoDB: Initializing buffer pool, size = 256.0M
- db_1 | 181225 18:04:11 InnoDB: Completed initialization of buffer pool
- db_1 | 181225 18:04:11 InnoDB: highest supported file format is Barracuda.
- db_1 | 181225 18:04:11 InnoDB: Waiting for the background threads to start
- db_1 | 181225 18:04:12 Percona XtraDB (http://www.percona.com) 5.5.59-MariaDB-38.11 started; log sequence number 1601918
- db_1 | 181225 18:04:12 [Note] Plugin 'FEEDBACK' is disabled.
- db_1 | 181225 18:04:12 [Note] Server socket created on IP: '0.0.0.0'.
- db_1 | 181225 18:04:12 [Warning] 'proxies_priv' entry '@ root@c7f2cd8ed93d' ignored in --skip-name-resolve mode.
- db_1 | 181225 18:04:12 [Note] Event Scheduler: Loaded 0 events
- db_1 | 181225 18:04:12 [Note] mysqld: ready for connections.
- 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 端口:
- [xiongxin@localhost mariadb]$ MySQL -u root -padmin1 -h 127.0.0.1 -P3303
- Welcome to the MariaDB monitor. Commands end with ; or \g.
- Your MariaDB connection id is 2
- Server version: 5.5.60-MariaDB-1~trusty mariadb.org binary distribution
- Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
- Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
- MariaDB [(none)]> show databases;
- +--------------------+
- | Database |
- +--------------------+
- | information_schema |
- | MySQL |
- | performance_schema |
- | test |
- +--------------------+
- 4 rows in set (0.00 sec)
- MariaDB [(none)]> select * from test.table1;
- +------+-----------------+
- | col1 | col2 |
- +------+-----------------+
- | 1 | Belter |
- | 2 | Merry Christmas |
- +------+-----------------+
- 2 rows in set (0.00 sec)
- MariaDB [(none)]>
可以正常连接, 且之前的数据还可以查询到.
在另一个容器中连接数据库
创建另一个文件夹 "query-db", 从另外一个镜像上开启一个新的容器, 如果这个容器需要连接上面的数据库容器该怎么办呢?
直接连接, 即使用 localhost 的 IP(127.0.0.1)和本地的端口 (3303) 无法连接. 这时候需要使用 docker 内部自己建立的网络将这两个容器连接起来.
在该文件下建立如下 docker-compose.YAML 文件:
- version: '2.2'
- services:
- djangoApp:
- image: onlybelter/django_py35_new
- # restart: on-failure
- command: python3 query_db.py
- working_dir: /code
- volumes:
- - ./code:/code
- - /etc/localtime:/etc/localtime:ro
- environment:
- - PYTHONUNBUFFERED=1
- networks:
- default:
- external:
- 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");
可以使用下面的命令来查看当前正在运行的容器的网络:
- [belter@localhost query-db]$ docker network ls
- NETWORK ID NAME DRIVER SCOPE
- 1d35e7fb797c bridge bridge local
- 8a2336ca7bcc djangopy35_default bridge local
- 8d044b04d49f mariadb_default bridge local
由于扩展网络的连接, 上面的 Python 代码会查询之前建立的数据库容器 (名称为 db) 的 3303 端口(docker 的内网), 然后输出数据库中的内容:
- [belter@localhost query-db]$ docker-compose up
- Starting querydb_djangoApp_1 ... done
- Attaching to querydb_djangoApp_1
- djangoApp_1 | ('Belter',) ('Merry Christmas',)
- djangoApp_1 |
- djangoApp_1 | ('Belter',) ('Merry Christmas',)
- djangoApp_1 |
- djangoApp_1 | ('Belter',) ('Merry Christmas',)
- djangoApp_1 |
- Merry Christmas!
- Reference
- https://mariadb.com/resources/blog/mariadb-and-docker-use-cases-part-1/
来源: https://www.cnblogs.com/Belter/p/10174851.html