Docker多容器应用程序

来自泡泡学习笔记
BrainBs讨论 | 贡献2023年8月18日 (五) 09:16的版本 (创建页面,内容为“ 到目前为止,您已经在使用单个容器应用程序。但是,现在您将在应用程序堆栈中添加MySQL。经常会出现以下问题-“MySQL将在哪里运行?在同一个容器中安装还是分开运行?”一般来说,每个容器应该只做一件事并且做好。以下是运行容器分开的一些原因: * 在扩展API和前端与数据库时,可能需要进行不同的扩展。 * 独立的容器允许您以隔离的方式…”)
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳到导航 跳到搜索

到目前为止,您已经在使用单个容器应用程序。但是,现在您将在应用程序堆栈中添加MySQL。经常会出现以下问题-“MySQL将在哪里运行?在同一个容器中安装还是分开运行?”一般来说,每个容器应该只做一件事并且做好。以下是运行容器分开的一些原因:

  • 在扩展API和前端与数据库时,可能需要进行不同的扩展。
  • 独立的容器允许您以隔离的方式进行版本管理和更新版本。
  • 虽然您可能在本地使用容器进行数据库,但在生产中可能希望使用托管服务进行数据库。您不希望将数据库引擎与应用程序一起发布。
  • 运行多个进程将需要一个进程管理器(容器只启动一个进程),这增加了容器启动/关闭的复杂性。

容器网络

请记住,默认情况下,容器独立运行,不知道同一台机器上的其他进程或容器。那么,如何让一个容器与另一个容器进行通信呢?答案是网络。如果您将两个容器放置在同一个网络上,它们可以相互通信。

启动MySQL

有两种方法可以将容器放入网络中:

在启动容器时分配网络。 将已经运行的容器连接到网络。 在接下来的步骤中,您将首先创建网络,然后在启动时将MySQL容器附加到该网络。

  1. 创建网络。
    docker network create todo-app
    
  2. 启动一个MySQL容器并将其附加到网络上。您还将定义一些环境变量,数据库将使用这些变量来初始化数据库。
docker run -d \
    --network todo-app --network-alias mysql \
    -v todo-mysql-data:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=secret \
    -e MYSQL_DATABASE=todos \
    mysql:8.0

在上面的命令中,您可以看到–network-alias标志。在稍后的部分中,您将了解更多关于该标志的信息。

提示

您会注意到上面的命令中有一个名为todo-mysql-data的卷,它挂载在/var/lib/mysql上,那是MySQL存储其数据的位置。但是,您从未运行过docker volume create命令。Docker会识别您要使用一个命名卷,并自动为您创建一个卷。

  1. 要确认数据库是否正常运行,请连接到数据库并验证连接。
docker exec -it <mysql-container-id> mysql -u root -p
  1. 在密码提示符出现时,输入secret。在MySQL shell中,列出数据库并验证是否看到todos数据库。

mysql> SHOW DATABASES;

您应该看到类似以下的输出。

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| todos              |
+--------------------+
5 rows in set (0.00 sec)
  1. 退出MySQL shell以返回到您计算机上的shell。
mysql> exit

现在,您有了一个名为todos的数据库,并且它已准备好供您使用。

连接到MySQL

既然您知道MySQL正在运行,您可以使用它。但是,您如何使用它呢?如果在同一网络上运行另一个容器,您如何找到该容器?请记住,每个容器都有自己的IP地址。

为了回答上述问题并更好地理解容器网络,您将使用nicolaka/netshoot容器,该容器附带了许多有用于故障排除或调试网络问题的工具。

使用nicolaka/netshoot镜像启动一个新的容器。确保将其连接到相同的网络。

docker run -it --network todo-app nicolaka/netshoot

在容器内部,您将使用dig命令,这是一个有用的DNS工具。您将查找主机名mysql的IP地址。

dig mysql 您应该获得如下输出。

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

;; QUESTION SECTION:
;mysql.             IN  A

;; ANSWER SECTION:
mysql.          600 IN  A   172.23.0.2

;; Query time: 0 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Tue Oct 01 23:47:24 UTC 2019
;; MSG SIZE  rcvd: 44

在“ANSWER SECTION”中,您将看到一个名为mysql的A记录,其解析为172.23.0.2(您的IP地址可能具有不同的值)。虽然mysql通常不是有效的主机名,但Docker能够将其解析为具有该网络别名的容器的IP地址。记住,您之前使用了–network-alias标志。

这意味着您的应用程序只需要连接到名为mysql的主机,它就能与数据库通信。

使用MySQL运行您的应用程序

todo应用程序支持设置一些环境变量来指定MySQL连接设置。它们是:

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

注意

尽管在开发中接受使用环境变量设置连接设置,但在生产中运行应用程序时,这是不推荐的。

一个更安全的机制是使用容器编排框架提供的密钥支持。在大多数情况下,这些密钥作为文件挂载到正在运行的容器中。您会发现许多应用程序(包括MySQL镜像和todo应用程序)还支持具有_FILE后缀的环境变量,用于指向包含变量的文件。

例如,设置MYSQL_PASSWORD_FILE变量将导致应用程序使用所引用文件的内容作为连接密码。Docker不会对这些环境变量提供任何支持。您的应用程序需要知道查找变量并获取文件内容。

现在可以启动您的开发准备容器了。

  1. 指定前面提到的每个环境变量,以及将容器连接到您的应用程序网络。确保在运行此命令时,您位于getting-started-app目录中。
docker run -dp 127.0.0.1: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:18-alpine \
    sh -c "yarn install && yarn run dev"
  1. 如果查看容器的日志(docker logs -f <container-id>),您应该会看到类似下面的消息,表示它正在使用mysql数据库。
nodemon src/index.js
[nodemon] 2.0.20
[nodemon] to restart at any time, enter `rs`
[nodemon] watching dir(s): *.*
[nodemon] starting `node src/index.js`
Connected to mysql db at host mysql
Listening on port 3000
  1. 在浏览器中打开应用程序并向待办事项列表添加一些项目。

  2. 连接到mysql数据库并证明项目正在写入数据库中。记住,密码是secret。

docker exec -it <mysql-container-id> mysql -p todos
  1. 在mysql shell中运行以下命令:
mysql> select * from todo_items;
 +--------------------------------------+--------------------+-----------+
 | id                                   | name               | completed |
 +--------------------------------------+--------------------+-----------+
 | c906ff08-60e6-44e6-8f49-ed56a0853e85 | Do amazing things! |         0 |
 | 2912a79e-8486-4bc3-a4c5-460793a575ab | Be awesome!        |         0 |
 +--------------------------------------+--------------------+-----------+

您的表格将会有所不同,因为它包含您的项目。但是,您应该能够在那里看到它们被存储。