LoginSignup
0
0

More than 1 year has passed since last update.

DooD(Docker outside of Docker)で、Docker Composeで一部コンテナを逐次アップデートする

Posted at

Docker Composeで複数コンテナからなるサービスを動かしている最中に、一部コンテナをアップデートしたいことがあります1

そこで、本記事ではその方法を紹介します(もし、さらに良い方法がありましたらぜひ伺いたいです)。

前提

例えば下図のサービス構成で、service_1~3を動的に更新することを考えます。

この構成では、apiコンテナがコンテナ外部とのインタフェースになっています。コンテナ更新用のAPIにリクエストがあると、core_controllコンテナを介してservice_*用imageコンテナを都度ビルド、新規コンテナをアタッチする想定です。

<network>     api             internal
        |--------------|  |---------------|

                                 <=> [service_1]
     [api] <=>  [core_controll]  <=> [service_2]
                                 <=> [service_3]

新たにコンテナをビルドをするにはDockerデーモンにアクセスする必要があるのですが、デフォルト設定ではコンテナ内からアクセスできません。

そこで、DooD(Docker outside of Docker)を使用します2。DooDの説明にいては割愛します。

環境構築

ファイル構成を準備する

以下の通りファイルを配置します3

some_service/
- docker-compose.yml
- api/
  - Dockerfile
  - ...(APIサーバ用コード)...
- core_controll/
  - Dockerfile
  - docker-compose.yml
  - ...(core_controll用コード)...

service1/
- Dockerfile
- ...(service1用コード)...

service2/
- Dockerfile
- ...(service1用コード)...

service3/
- Dockerfile
- ...(service1用コード)...

この構成において、some_service直下でdocker-compose upを実行することによりapiコンテナ、core_controllコンテナを作成するようにしています。

DooDを使えるようにする

some_service/docker-compose.ymlについて、volumesで/var/run/docker.sock:/var/run/docker.sockと指定します。

この設定がホスト環境のDockerのsockをcore_controllコンテナに共有する設定になります。これにより、コンテナ側からホスト側のDockerを操作できるようになります。

some_service/docker-compose.yml

version: '3.4'

services:
  vision:
    container_name: "api"
    build:
      context: ./api
      dockerfile: Dockerfile
    restart: always
    tty: true
    ports:
      - "8000:8000"
    networks:
      - api

  core_controll:
    container_name: "core_controll"
    build:
      context: ./core_controll
      dockerfile: Dockerfile
    depends_on:
      - service1
      - service2
      - service3
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - api
      - internal

networks:
  api:
  internal:

コンテナ内部でdocker-composeコマンドを使えるようにする

core_controllコンテナ内でdocker-composeコマンドを使えるようインストールに加えます。

(Alpine Linux環境のためapkを使っていますが、ベースOSに応じてyumやapt-get等に読み替えてください)

FROM node:14-alpine

RUN apk add --update docker-compose

コンテナ内部でservice_*用コードを取得、ビルドする機構を作る

コード上で、以下2処理を記載します。

  • service1~3のコードをsome_service/下にフェッチします(サンプルコードではシェルスクリプトによりコピーしているので、割愛しています)。
  • サブプロセスでdocker-compose up -dを実行します。pythonの場合、subprocess.run、Node.jsの場合child_process.execなどが該当します。

service1~3構成用Docker Compose設定を記載する

some_service/core_controll/docker-compose.ymlにservice1~3の構成を記載します。

version: '3.4'

services:
  service1:
    container_name: "service1"
    build:
      context: ./service2
      dockerfile: Dockerfile
    networks:
      - internal

  service2:
    container_name: "service2"
    build:
      context: ./service2
      dockerfile: Dockerfile
    networks:
      - internal

  service3:
    container_name: "service3"
    build:
      context: ./service3
      dockerfile: Dockerfile
    networks:
      - internal

networks:
  internal:
    external:
      name: some_service_internal

このうち、networksでinternalネットワークと、some_service_internalネットワークを接続しています。このsome_service_internalネットワークは、some_service/docker-compose.ymlで設定したinternalネットワークに対応します。

以上で設定は完了です。

service1~3コンテナを動的に更新する

※ 具体的な実装例、および動作をテストしてみたい場合はサンプルコードをご覧ください。

(事前処理) some_service/下でdocker-compose up -dを実行し、apiコンテナとcore_controllコンテナを立ち上げておきます。

コンテナ更新用のAPIを呼び出し、core_controll下でdocker-composeコマンドによるビルドを行います。ビルドが成功していれば、service1~3コンテナが自動的にアタッチされます。

これによりサービス全体を動かしつつ、service1~3を動的に更新することができます。

サンプルコード

以下URLを参照ください。
https://github.com/pirika-inc/docker_compose_hot_container_update_sample

以上になります。ご覧いただきありがとうございます!


  1. 例えば深層学習において、あるメンバーはTensorFlowで解析するサービス、あるメンバーはPyTorchで解析するサービスを作る、という構成が挙げられます 

  2. 他にもDocker inside of Dockerもありますが、コンテナにprivileged権限を与える必要があります。セキュリティ観点上、--cap-dropや--deviceで権限を細かく制御する必要があり、公式にも推奨されません 

  3. 実運用では、service_*をgitのリモートリポジトリなどから持ってくることになります。通信インタフェースが一致している限り、別機能を持ったサービスを持ってくることも可能です 

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0