到目前为止,我们已经学会了如何基于单容器应用进行开发工作。但是,我们现在想要把MySQL添加到应用栈中。我们会问:MySQL在哪里运行?是把MySQL和应用安装在同一个容器中,还是分开运行2个容器?总的来说:每个容器应该只做一件事,而且要把这件事做好。有以下几个原因:
1、你很有可能不得不将API和前端不同于数据库地规模化
2、分离容器让你能够版本独立,且独立地更新版本
3、尽管你本地使用数据库的话,会使用容器,但是生产环境中,可能想要将托管服务用于数据库。这样你就不会想要把数据库引擎和你的应用一起发布上线了。
4、容器只能启动一个进程,运行多个进程就会需要一个进程管理器,这会增加容器启停的复杂性。
当然还有其它原因。综上所述,我们接下来就把应用做如下更新:
容器网络
记住一点:容器默认是独立运行的,对同一台机器上运行的其它进程和容器都一无所知。所以,我们怎么样让一个容器和另一个容器对话呢?答案是:网络。你不需要是一名网络工程师,只要记得这个规则就行:
如果2个容器在同一个网络,那么它们俩就能够互相对话;如果不在,那就不行。
启动MySQL
有2种方式把一个容器连上一个网络:1、启动时就把容器连上网络2、网络连接一个现有的容器
我们会先创建一个网络,然后在启动时连上MySQL容器。
1、创建网络
dockernetworkcreatetodo-app
2、启动一个MySQL容器,并把容器连上网络。我们也会定义一些环境变量,数据库会用它们来初始化数据库,参见MySQLDockerHub清单的EnvironmentVariables段落。
dockerrun-d\
--networktodo-app--network-aliasmysql\
-vtodo-mysql-data:/var/lib/mysql\
-eMYSQL_ROOT_PASSWORD=secret\
-eMYSQL_DATABASE=todos\
mysql:5.7
如果你使用的是PowerShell的话,把上述命令的\替换成`即可。
关于--network-alias旗标,我们一会儿再聊。
专家提示
你应该有注意到我们使用一个具名卷,名字是todo-mysql-data,并将其挂载到了/var/lib/mysql,这里是MySQL存储数据的地方。不过,我们并没有运行dockervolumecreate命令。Docker识别出,我们想要使用一个具名卷,接着就为我们自动创建了一个。
3、为了确认我们的数据库跑起来了,我们尝试连接数据库,并验证是否连接成功。
dockerexec-itmysql容器idmysql-p
当密码提示符出现,输入secret。在MySQLshell中,列出数据库,并确认你看到了todos数据库。
mysqlSHOWDATABASES;
你应该会看到以下输出:
好了,我们已经有了我们的todos数据库,并且随时可以使用。
连接MySQL
既然我们已经知道MySQL已经正常运行了,让我们来使用MySQL吧。但是,问题……怎么用?如果我们在同一个网络运行另一个容器的话,我们如何找到容器?记住,每个容器都有自己的IP地址。
要弄清楚怎样才能使用MySQL,我们会用到nicolaka/netshoot容器,它自带了很多可以用于排错和调试网络问题的工具。
1、使用nicolaka/netshoot启动一个新容器。确保容器连接了同一个网络。
dockerrun-it--networktodo-appnicolaka/netshoot
2、在容器中,使用dig命令,这个命令是一个好用的DNS工具。我们会用它来查找主机名为mysql的IP地址。
digmysql
应该会看到如下输出:
在ANSWERSECTION中,你会看到mysql的A记录,解析为.18.0.2,你的IP地址很可能是另一个值。尽管mysql通常并不是一个有效的主机名,但是Docker能够将其解析为:网络别名为mysql的容器的IP地址。还接的之前用到的--network-alias旗标么?
这也就意味着,我们的应用只需要连接主机名为mysql的主机,然后就能和数据库连通了。没有比这更简单的了!
基于MySQL运行应用
待办任务应用支持通过设置一些环境变量,来指定MySQL的连接设置。它们是:
MYSQL_HOST
运行MySQL服务器的主机名
MYSQL_USER
连接数据库服务器使用的用户名
MYSQL_PASSWORD
连接数据库服务器使用的密码
MYSQL_DB
连上以后,使用的数据库
警告
尽管使用环境变量设置连接设置,用于开发的话通常是没问题的,但是生产环境运行应用的时候,这样做是极不推荐的。前Docker的安全一把手DiogoMonica专门写了一篇博客来解释原因。
一个更加安全的机制是使用容器编排框架所提供的密钥支持机制。在大多数情况下,这些密钥作为文件在容器中挂载。你会看到很多应用,包括MySQL镜像和待办应用,也会通过_FILE后缀,指向包含变量的文件的方式,来支持环境变量。
作为一个例子,设置MYSQL_PASSWORD_FILE变量会导致应用去使用变量所指向的文件的内容,作为连接密码。Docker不会做任何事来支持这些环境变量。你的应用需要知道如何查找变量,并获取文件内容。
那么具体如何使用这些环境变量来让我们的应用连接MySQL数据库呢?请看下回分解。