Docker(七)——多容器应用

如果我们想添加 MySQL 到我们的应用栈。下面产生了几个问题,MySQL在哪里运行?安装在同一个容器还是分开安装?总得来说,每个容器应该只做一件事情,并做好。

原因如下:

  • 很可能需要扩展 APIs,但是前端和数据库不同。
  • 独立的容器使得能够控制版本,更新的版本是隔离的。
  • 当你为本地数据库使用一个容器,你可能会想在生产环境终端数据库使用一个管理服务。所以,你不想将你的数据库和应用一起发送。
  • 运行多个进程需要一个进程管理器(容器只能启动一个进程),这增加了容器启动和关闭的复杂性。

因为这些原因,我们将会以下面的工作方式更新我们的应用:


容器联网

容器默认是独立工作的,不知道其他在机器中的进程和容器。我们可以使用网络去使一个容器可以和另一个容器通信。

如果两个容器在同一个网络,那么可以互相通信。否则不行。


启动 MySQL

这里有两种方式将一个容器放入一个网络。

  • 在开始时分配它。
  • 连接一个现存的容器

下面我们将先建立一个网络,再在启动 MySQL 容器时将其加入进去。

  1. 创建网络
docker network create todo-app
  1. 启动一个 MySQL 容器,并将其加入到网络中。我们也将定义一些环境变量,使数据库可以用来初始化。
docker run -d --network todo-app --network-alias mysql -v todo-mysql-data:/var/lib/my
sql -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=todos mysql:5.7

你可能会注意到,我们正使用一个 todo-mysql-data volume,然后将其挂载到 /var/lib/mysql,MySQL在这存储数据。但是,我们没有运行 docker volume create 命令。Docker 推测我们想使用一个 named volume 然后自动给我们创建了一个。

  1. 为了确定我们安装了数据库并且运行了,连接数据库并验证它的连接。
docker exec -it <mysql-container-id> mysql -u root -p

当密码提示出现时,键入密码。在 MySQL shell 列出数据库,你可以看到 todos 数据库。

mysql> SHOW DATABASES;

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| todos              |
+--------------------+
5 rows in set (0.00 sec)

连接 MySQL

现在我们知道 MySQL 已经被安装和运行了。现在的问题是,如果我们在相同的网络内运行另一个容器,我们将如何找到这个容器?

为了解决这个问题,我们将要使用 nicolaka/netshoot 容器,这个容器有许多用于检测和调试网络问题的工具。

  1. 首先,使用 nicolaka/netshoot 镜像启动一个新容器。确保连接在同一个网络内。
docker run -it --network todo-app nicolaka/netshoot
  1. 在容器内部,我们将使用 dig 命令,一个有用的域名解析工具。我们将查找主机名为 mysql 的 IP 地址。
dig mysql

输出如下:

; <<>> DiG 9.16.22 <<>> mysql
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24223
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;mysql.                         IN      A

;; ANSWER SECTION:
mysql.                  600     IN      A       172.18.0.2

;; Query time: 2 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Fri Mar 04 09:31:59 UTC 2022
;; MSG SIZE  rcvd: 44

ANSWER SECTION,你会看到一个 A 记录给 mysql,这将解析为 172.18.0.2。虽然 mysql 不是一个标准的合法主机名,Docker也能够将其解析为有着网络别名容器的 IP 地址。

所以,我们的应用只要连接到主机名为 mysql,就可以和数据库通信。


使用 MySQL 运行应用

todo 应用支持设置一些环境变量去设置 MySQL 的连接设置。

  • MYSQL_HOST - 运行 MySQL 服务器的主机名
  • MYSQL_USER - 连接使用的用户名
  • MYSQL_PASSWORD - 连接使用的密码
  • MYSQL_DB - 连接时使用的数据库

下面,我们开启设备准备容器

  1. 对于 MySQL8.0 以及更高版本,在 mysql 中运行下面的命令
mysql> ALTER USER 'root' IDENTIFIED WITH mysql_native_password BY 'secret';
mysql> flush privileges;
  1. 明确环境变量,同时将容器连接至我们的应用网络
docker run -dp 3000:3000 -w /app -v "$(pwd):/app" --network todo-app -e MYSQL_HOST=mysql -e MYSQL_USER=root -e MYSQL_PASSWORD=secret -e MYSQL_DB=todos node:12-alpine sh -c "yarn install && yarn run dev"
  1. 如果我们看容器的日志( docker logs <container-id> ),我们将会看到表明正在使用 mysql 数据库的信息。
yarn install v1.22.17
[1/4] Resolving packages...
warning Resolution field "ansi-regex@5.0.1" is incompatible with requested version "ansi-regex@^2.0.0"
warning Resolution field "ansi-regex@5.0.1" is incompatible with requested version "ansi-regex@^3.0.0"
success Already up-to-date.
Done in 0.44s.
yarn run v1.22.17
$ nodemon src/index.js
[nodemon] 2.0.13
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node src/index.js`
Waiting for mysql:3306.
Connected!
Connected to mysql db at host mysql
Listening on port 3000
  1. 在浏览器打开应用,并添加一些项。
  2. 连接 MySQL 数据库,验证是否有项被写入数据库。
docker exec -it <mysql-container-id> mysql -p todos

在 MySQL shell 中运行下面的命令

mysql> select * from todo_items;

+--------------------------------------+-------+-----------+
| id                                   | name  | completed |
+--------------------------------------+-------+-----------+
| a6a1d6df-73d1-4277-9d0d-cc7d7f4df0de | 1321  |         0 |
| 84e1989c-b1ec-4329-b7b9-32943f3b75fa | 21312 |         0 |
| e9c22587-f676-4fca-b9b3-f2503d5160c5 | 321   |         0 |
+--------------------------------------+-------+-----------+
3 rows in set (0.00 sec)

你可以看到添加的项,被加入到 MySQL 数据库中。

如果你此时打开 Dashboard,会发现有两个容器在运行。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值