在迁移到DockerCompose版本2时遇到的困难

在将DockerCompose配置文件的格式从Version1更改为Version2时,遇到了一些困难,所以我将它们列出来。如果有错误或更好的方法,请告诉我,谢谢。

系统构成

这次迁移的系统由两个Rails应用程序和一个反向代理组成。这两个Rails应用程序都是基于相同的镜像,只是配置略有不同。实际上容器还有一些,但不太相关,所以省略了。

DockerContainerRelation.png

另外,我们还对Docker Engine和Docker Compose进行了升级。

移行前移行後Docker Engine1.101.12Docker Compose1.61.8

转移前的设置

每个应用程序的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非常方便,但更新速度很快,跟上进度很困难啊。必须经常检查一下,不能掉以轻心。

广告
将在 10 秒后关闭
bannerAds