🐳

COS 上に複数の Docker コンテナを実行させる方法

2024/08/16に公開

はじめに

クラウドエースの北野です。

Container Optimized OS (以降、COS と呼びます。)上で複数の Docker コンテナを実行する方法を紹介します。

Google Cloud コンソールから COS を選択し Docker コンテナを作成する場合や、メタデータの gce-container-declaration に値を指定して Docker コンテナを作成する場合、コンテナは 1 つしかできません。

本記事では、COS に複数のコンテナを起動させる方法を紹介します。
実行方法を簡単に紹介すると、以下の通りです。

  • メタデータの user-data に複数の Docker コンテナを起動する cloud-init の構成定義ファイルを定義し COS を作成します。

複数のコンテナを起動する cloud-init 構成定義の内容は以下の通りです。

#cloud-config

write_files:
  - path: /etc/systemd/system/<APP1Service>.service
    permissions: 0644
    owner: root
    content: |
      [Unit]
      Description=Start App1 Service container

      [Service]
      ExecStop=/usr/bin/docker stop <App1Name>
      ExecStart=/usr/bin/docker run --rm --network host --name <App1Name> <DockerImageRepoURI>

  - path: /etc/systemd/system/<APP2Service>.service
    permissions: 0644
    owner: root
    content: |
      [Unit]
      Description=Start App2 Service container

      [Service]
      ExecStop=/usr/bin/docker stop <App2Name>
      ExecStart=/usr/bin/docker run --rm --network host --name <App2Name> <DockerImageRepoURI>

runcmd:
  - systemctl daemon-reload
  - systemctl start <APP1Service>.service
  - systemctl start <APP2Service>.service

Container Optimized OS (COS) とは

COS はコンテナの実行に特化した Google の Chromium OS プロジェクトにより管理される OS です。Google Kubernetes Engine (GKE) のノードに利用することのできる OS です。特徴として、以下があります。

  • 小さいフットプリント
  • 高いセキュリティ性
  • 自動アップデート

COS はセキュリティを担保するため、Docker コンテナの起動に必要とされる最小限度のアプリケーションしかインストールされていません。

今回、cloud-init を使い COS 上で複数の Docker コンテナを動かします。

cloud-init とは

cloud-init は様々なクラウドプラットフォームの VM インスタンスに使えるインスタンスを初期化するオープンソースのツールです。VM の起動時に VM が作成されるプラットフォームを識別して、プラットフォームに応じた初期化をします。

cloud-init は VM の OS の起動までの処理を以下のステップに分けて処理を管理しています。

  1. Local
  2. Network
  3. Config
  4. Final

Local ステップでは、cloud-init の構成定義ファイルをデータソースから取得します。
Network ステップでは、構成定義ファイルの cloud_init_modules を実行します。ここでは、ディスクの初期化、マウント、hostname、設定ファイルの作成などをします。
Config ステップでは、cloud_config_modules を実行します。コマンド実行など cloud_init_modules に依存する設定 ( systemd で任意プロセスの実行など) をします。
Final ステップでは、cloud_final_modules を実行します。boot 処理の後半で実施される処理 ( chef や ansible などの構成管理ツールによる OS の設定など)を実施します。

各モジュールで実施できる内容はこちらの公式ドキュメントを参考にしてください。

cloud-init を使った COS 上に複数のコンテナを起動方法

複数のコンテナの起動方法は以下の通りです。

  1. cloud_init_modules でコンテナを起動する systemd の定義ファイルの作成
  2. cloud_config_modules で systemd の実行による Docker コンテナの起動

cloud_init_modules でファイルを作成するには、write_files を使います。
cloud_config_modules で任意のコマンドを実行するのには、runcmd を使います。

cloud-init で 任意の systemd を実行する構成定義は以下になります。

#cloud-config

write_files:
  - path: /etc/systemd/system/sample.service
    permissions: 0644
    owner: root
    content: |
      [Unit]
      Description=Start Sample Service container

      [Service]
      ExecStop=/usr/bin/docker stop sample
      ExecStart=/usr/bin/docker run --rm --network host --name sample <DockerImageRepoURI>

runcmd:
  - systemctl daemon-reload
  - systemctl start sample.service

write_files は以下の設定ができます。

設定項目 設定内容
path 作成するファイルパス
permissions ファイルのアクセス権限
owner ファイルのオーナ
content ファイルの中身
encoding content の内容のエンコード方式 (b64/gzip)

Google Cloud の Compute Engine で cloud-init の構成定義を user-data または user-data-encoding に定義すると、cloud-init が Local 処理時に構成定義ファイルを取得します。

最後に sleep コマンドを実行する コンテナを2台起動してみます。cloud-init の構成定義ファイルは以下の通りです。

#cloud-config

write_files:
  - path: /etc/systemd/system/sleep1.service
    permissions: 0644
    owner: root
    content: |
      [Unit]
      Description=Start Sleep1 container

      [Service]
      Environment="HOME=/home/cloudservice"
      ExecStart=/usr/bin/docker run --rm --network host --name sleep1 alpine sleep infinity
      ExecStop=/usr/bin/docker stop sleep1

  - path: /etc/systemd/system/sleep2.service
    permissions: 0644
    owner: root
    content: |
      [Unit]
      Description=Start Sleep2 container

      [Service]
      Environment="HOME=/home/cloudservice"
      ExecStart=/usr/bin/docker run --rm --network host --name sleep2 alpine sleep infinity
      ExecStop=/usr/bin/docker stop sleep2
      
runcmd:
  - systemctl daemon-reload
  - systemctl start sleep1.service
  - systemctl start sleep2.service

Compute Engine を作成するときに OS に COS を選択し、メタデータに user-data の項目を追加し、値に上記の値を追加します。
インスタンス作成

ログインをしてコンテナが起動しているかを確認すると以下のように2台のインスタンスが起動していることが分かるかと思います。
OS内の情報

おわりに

COS 上で cloud-init を使って Docker コンテナを起動する方法を説明し、複数の Docker コンテナを起動する方法を紹介しました。システム要件 (IoT のプロトコルを使いたいなど)によっては Cloud Run が使えない、Docker コンテナの検証を簡単にしたい場合など、ぜひ COS を使ってみてください。

Discussion