在迁移到DockerCompose版本2时遇到的困难
在将DockerCompose配置文件的格式从Version1更改为Version2时,遇到了一些困难,所以我将它们列出来。如果有错误或更好的方法,请告诉我,谢谢。
系统构成
这次迁移的系统由两个Rails应用程序和一个反向代理组成。这两个Rails应用程序都是基于相同的镜像,只是配置略有不同。实际上容器还有一些,但不太相关,所以省略了。
另外,我们还对Docker Engine和Docker Compose进行了升级。
转移前的设置
每个应用程序的docker-compose.yml在迁移之前如下所示。由于镜像是自定义的,而不是官方提供的,所以名称已经进行了相应的更改。
反向代理和Rails应用程序可以进行通信,但没有使用Docker Compose的external_links选项。这是因为当停止反向代理下的应用程序时,反向代理也会停止,导致无法连接到其他应用程序。这是一年左右前构建的信息,所以现在可能不同了。
- リバースプロキシ(一部抜粋)
nginx:
image: hoge/nginx:latest
ports:
- "80:80"
- Railsアプリ1(一部抜粋)
redis:
image: hoge/redis:latest
rails:
image: hoge/rails:latest
links:
- redis:redis
- Railsアプリ2(一部抜粋)
redis:
image: hoge/redis:latest
rails:
image: hoge/rails:latest
links:
- redis:redis
迁移后的配置(第一次失败)
首先,我尝试简单地改变了格式。
- リバースプロキシ(一部抜粋)
version: '2'
services:
nginx:
image: hoge/nginx:latest
ports:
- "80:80"
- Railsアプリ1(一部抜粋)
version: '2'
services:
redis:
image: hoge/rails:latest
rails:
image: hoge/rails:latest
depends_on:
- redis
- Railsアプリ2(一部抜粋)
version: '2'
services:
redis:
image: hoge/redis:latest
rails:
image: hoge/rails:latest
depends_on:
- redis
只是简单地更改了格式,由于这个原因,反向代理应用无法连接到Rails应用程序的容器。在Version1时,所有容器都属于同一个子网,所以可以连接,但在上述的设置中,每个应用程序都属于不同的网络,这是原因。因此,我们设置了专用网络,以确保所有应用程序都属于同一个网络。
第二次失败的迁移设置。
- リバースプロキシ(一部抜粋)
version: '2'
services:
nginx:
image: hoge/nginx:latest
ports:
- "80:80"
networks:
- proxy_network
networks:
proxy_network:
external: true
- Railsアプリ1(一部抜粋)
version: '2'
services:
redis:
image: hoge/redis:latest
networks:
- proxy_network
rails:
image: hoge/rails:latest
depends_on:
- redis
networks:
- proxy_network
networks:
proxy_network:
external: true
- Railsアプリ2(一部抜粋)
version: '2'
services:
redis:
image: hoge/redis:latest
networks:
- proxy_network
rails:
image: hoge/rails:latest
depends_on:
- redis
networks:
- proxy_network
networks:
proxy_network:
external: true
我已经定义了一个名为proxy_network的应用程序共享网络。创建网络的命令如下所示。
$ docker network create --driver bridge proxy_network
通过加入共同的网络,现在可以从反向代理连接到各个应用程序。
新问题的出现
我本以为问题解决了,但接下来出现了一种现象,只有一方的Rails应用程序无法连接到redis。尽管Rails1应用程序的redis容器IP地址为172.21.0.2,但在Rails1应用程序的rails容器中ping redis时却打到了172.21.0.5。通过查询,发现172.21.0.5是Rails2的redis容器。在Rails应用程序中,我将连接到redis容器的主机名设置为DockerCompose中设置的服务名redis。但由于将所有应用程序归属于公共网络,服务名redis包含了Rails1和Rails2这两个应用程序,导致服务名重复,使得容器内置的DNS返回了不同的IP地址,这似乎是问题的原因。在调查这个现象时,逐个运行Rails应用程序可以正常连接,所以找到原因花了相当长的时间。
因此,我想了两种方法来解决这个问题。
-
- サービス名が重複しないように変更する
- 外部アプリケーションからアクセス不要なコンテナは共通ネットワークではない別のネットワークに属するようにする
每次增加新的应用程序时,我觉得添加新网络会使配置变得复杂,所以这次我选择了第一种方法来应对。现在想想,分离网络可能更直接和容易些。
过渡后的设置(第三次失败)
version: '2'
services:
nginx:
image: hoge/nginx:latest
ports:
- "80:80"
networks:
- proxy_network
networks:
proxy_network:
external: true
- Railsアプリ1(一部抜粋)
version: '2'
services:
rails1_redis:
image: hoge/redis:latest
networks:
- proxy_network
rails1:
image: hoge/rails:latest
depends_on:
- rails1_redis
networks:
- proxy_network
networks:
proxy_network:
external: true
- Railsアプリ2(一部抜粋)
version: '2'
services:
rails2_redis:
image: hoge/redis:latest
networks:
- proxy_network
rails2:
image: hoge/rails:latest
depends_on:
- rails2_redis
networks:
- proxy_network
networks:
proxy_network:
external: true
现在,已经能够正确识别从rails1容器到rails1_redis容器,以及从rails2容器到rails2_redis容器的IP地址。
再次发生问题
我原以为这次问题会解决,但是这次尝试通过Rails应用程序访问rails1_redis时,出现了InvalidURIError错误。看来问题的原因似乎是主机名中含有“_”。因此,我将服务名的“_”更改为“-”。尽管这与DockerCompose没有直接关系,但由于是由于服务名的更改而引起的问题,所以我一并写下来。
移行后的设置(最终形式)
version: '2'
services:
nginx:
image: hoge/nginx:latest
ports:
- "80:80"
networks:
- proxy_network
networks:
proxy_network:
external: true
- Railsアプリ1(一部抜粋)
version: '2'
services:
rails1-redis:
image: hoge/redis:latest
networks:
- proxy_network
rails1:
image: hoge/rails:latest
depends_on:
- rails1-redis
networks:
- proxy_network
networks:
proxy_network:
external: true
- Railsアプリ2(一部抜粋)
version: '2'
services:
rails2-redis:
image: hoge/redis:latest
networks:
- proxy_network
rails2:
image: hoge/rails:latest
depends_on:
- rails2-redis
networks:
- proxy_network
networks:
proxy_network:
external: true
经过这一切,最终一切都恢复正常了。
DockerCompose非常方便,但更新速度很快,跟上进度很困难啊。必须经常检查一下,不能掉以轻心。