可能最近在关注我博客的同学会隐隐猜到今天我可能会更新 GRPC 系列的第 5 篇,但是,很遗憾,我没有。尽管我没有更新这个系列,我也不希望让对我博客内容有兴趣的同学失望,所以我先小小透露一下下一节我就要介绍 Interceptor 的实现了,有没有很期待;同时,这一篇文章肯定也不能太水,所以我决定来聊聊 Docker 的一点小知识。

在使用 Docker 的时候,我们经常会遇到这么一个场景,那就是需要外部的服务访问我们 Docker Container 运行的服务,例如我们 Container 运行的是一个 DB,那么需要对外暴露才有用;或者,我们运行的是一个 Web 程序,可能需要访问其他 Container 中运行的 DB,这些场景都是很常见的。当然,实现的方式五花八门,但是可能不外乎是两种,分别是将服务暴露出来,让外部服务直接使用,这种使用场景其实不将 Contianer 当 Container 使用,可以认为和以前在同一台机器上运行应用和 DB 的原理是一致的;另外一种方式就是通过 Docker 的 link 将两个 Container 连接起来,这样 Container 可以通过内部的网络联通,虽然这种方式现在不被 Docker 所推荐了,但是,今天我却要来聊聊这种方式的实现机制以及替代方案。

在开始之前,我还是先来一个例子尝试一下 link 的功能,我这里挑选的示例是被广为使用的博客系统 Wordpress,然后以 link Mysql 为示例进行介绍:

当你参照这个命令执行之后你会发现,访问本地的地址: localhost:9080,你的 wordpress 已经运行起来了,等待你的配置了。这里我当然不会继续看关于 Wordpress 的事情啦,而是来看看上面运行的这几条命令,分析一下都有什么含义和为什么要这么做。

这前面两条 pull image 的命令就无需解释啦,都懂的。然后第三条运行 mysql 的应该也不用多做介绍了,除了需要知道 mariadb 就是 mysql 之外。。。

重要的第四条来了,这里先来看 --link 这个参数,这也是这篇文章的重点,这里的问题就是如果我们需要将一个 Container 链接到另外一个 Container,那么不是应该指定一个 Container 的名字就好了么,为什么还要分割一下,所以想到这里,就应该来看下 Docker 的官方文档怎么说:

OK,这里官方文档是说前面这个是你要链接的 Container 的名字或者 ID,后面哪个为 alias,alias 可以省略,省略的话就和前面的 Container 同名。那么既然可以省略的话,它的作用是啥,这又是本文的关键啦,继续看看:

这里官方说得很清楚啦,第一件事情,就是通过这个 alias 设置 Container 内部的环境变量。至于有什么环境变量呢,这里也给出了解释,分别有:

为了验证是否真的就像文档里面说的,我这里就进去 Wordpress 的 Container 里面看看是不是有我们期望的所有环境变量:

这里可以看到,上面列举的第 3 和第 4 的所有环境变量都可以看到,第二个我们执行的时候设置的环境变量也没问题,也是可以看到的,它是:

-e WORDPRESS_DB_PASSWORD=my-secret-pw 

那至于第一个 Mariadb 中设置的 ENV 我们要怎么确认呢,我找到了它的 Dockerfile:点击查看,可以看到,这里设置的几个变量都是在的,我找两个来截图示例一下:

没问题,都是有的。但是,难道这就是 link 做的所有事情了吗?我又继续找了找,结果是,不是的,还有更多的事情。在文档中我先看到了这一段:

它说因为环境变量是不会实时自动改变的,所以如果对于源 Container 变动的情况,会导致我们使用环境变量中的地址出错,所以,为了避免这种情况,它还做了一个事情,那就是修改了 /etc/hosts 文件:

这里我们也确认一下是不是真的有修改:

嗯,没毛病,正如它所说的。

看上去挺好用的,为什么官方就不推荐使用它了呢?其实,原因也是很简单的,随着 Docker 网络功能的不断增强,以及需要关联的 Container 不断的增加,这种方式的弊端就逐渐显露出来了,例如,你需要在运行 Container 的时候指定一堆的 link,虽说 Compose 可以帮助你解决这些问题,但是,这还是太麻烦了,还是需要明确指定。

所以,在比较新的 Docker 中,官方是推荐通过网络的方式来实现,下面这里举个例子:

可以发现,通过这种方式,真的可以简化很多,对于多个 Container 连接的情况支持得更好得,对于这个特性我觉得是积极得。

到此,本文也就差不多结束了,虽然可能还略带遗憾未能就 docker network 展开进行更深层次得介绍,但是,无妨,通过前面这么多内容的介绍,相信你已经对 Container 的 link 机制有了一个不一样的理解,而且可能会更愿意接受新的方式。