とことんDevOps | 日本仮想化技術のDevOps技術情報メディア

DevOpsに関連する技術情報を幅広く提供していきます。

日本仮想化技術がお届けする「とことんDevOps」では、DevOpsに関する技術情報や、日々のDevOps業務の中での検証結果、TipsなどDevOpsのお役立ち情報をお届けします。
主なテーマ: DevOps、CI/CD、コンテナ開発、IaCなど
読者登録と各種SNSのフォローもよろしくお願いいたします。

以前書いたDockerのマニフェストをARM Macでも動くようにGitHub Copilotを使って修正する

現在YugabyteDBを検証しています。YugabyteDBの動作検証のためにDockerも相変わらず使っています。 検証の初期はIntel CPU版のMacを使っていました。なので特に問題なくLinuxのDockerで動くコードをそのままIntel CPU版のMacでも動かせていました。 つい先日、M4のMac miniが安価で出ていたので購入しまして、若干その修正が必要になりました。 手で修正するのは簡単なのですが基本私は面倒くさがりなので、AIを使って対応してみようと思いました。

macOS版のDocker Desktopについて

macOS版のDocker Desktopでは、バージョン4.25以降のバージョンではRosetta 2に対応しており、設定を有効化してコンテナを起動するときにオプションを追加指定することで、ARM Mac上でx86_64向けのコンテナを起動できます。

実際起動するときは、interactiveとかdetachとかポートのpublishオプションなどを追加すると思います。 --platform linux/amd64オプションを付与することにより、ARM Mac上でx86_64向けのコンテナを起動できます。

# Rosetta 2を使って、macOSのDocker Desktopでx86_64のコンテナを起動する
docker run --platform linux/amd64 <イメージ名>

背景

念のために言っておくと、YugabyteDB自体のコンテナイメージはx86_64のイメージの他、ARM対応のイメージも提供されています。そのため、特別なことをしないでもARM Mac上でYugabyteDBのコンテナーを動かすことはできます。

ただコンテナーの中でsysbenchを動かす必要があり、かつ対抗がYugabyteDBという分散DBなので、本家のsysbenchではなく、分散DBにも対応するコードが入ったsysbenchをインストールする必要がありました。そのsysbenchのパッケージがx86_64でしか提供されていなかったために、このような対応が必要だったというわけです。

本題

変更前のマニフェストは次に公開されているものを使います。 https://github.com/ytooyama/yuga-sysbench-example

Dockerfile

Dockerfileは二つ用意しており、base用とsysbench用です。

YugabyteDBのオフィシャルイメージは、AlmaLinux 8をコアに利用したイメージになっています。 base用はiproute-tcのRPMパッケージをインストールするだけの内容になっています。これならARM64向けのimageを使っても良いかもしれませんが、コンテナ間でア クセスする必要があるので、sysbenchコンテナはx86_64で、そのほかはaarch64でコンテナで動かす前提にします。

ただ、Dockerfileには特別なタグは設定しません。

# ベースイメージとして指定されたYugabyteDBのイメージを使用
FROM docker.io/yugabytedb/yugabyte:2.25.2.0-b359

# 必要なパッケージをインストール
RUN dnf install -y iproute-tc && dnf clean all

# デフォルトのコマンドを指定(必要に応じて変更)
CMD ["/bin/bash"]

前述のように、Yugabyteのパッチが適用されたsysbenchをインストールするようにDockerfileに記述します。 次のようなDockerfileを作成しました。

# ベースイメージとして指定されたYugabyteDBのイメージを使用
FROM docker.io/yugabytedb/yugabyte:2.25.2.0-b359

# 必要なパッケージをインストール
RUN curl -LO https://github.com/yugabyte/sysbench/releases/download/1.0.0-yb/sysbench-1.0.0-1.el8.x86_64.rpm && dnf install -y ./sysbench-1.0.0-1.el8.x86_64.rpm && dnf clean all && rm -rf sysbench-1.0.0-1.el8.x86_64.rpm 

# デフォルトのコマンドを指定(必要に応じて変更)
CMD ["/bin/bash"]

ちょっとした愚痴ですが、インストール手順を見ると必ずwgetが使われるのですが、RHELやRHELクローンは最小インストールにするとcurlはだいたい入っていることが多いもののwgetは入っていないので、できればcurlを使って欲しいなあなんて良く思います。毎回それを忘れて「command not found」の出力を見る私も私ですけど。

curl -LO https://github.com/yugabyte/sysbench/releases/download/1.0.0-yb/sysbench-1.0.0-1.el8.x86_64.rpm
sudo yum install -y sysbench-1.0.0-1.el8.x86_64.rpm 

Dockerfileを用意したらこう実行すれば、linux/amd64なイメージをARM Mac上でビルドできます。

# docker buildコマンドでlinux/amd64アーキテクチャのイメージをビルドする例
docker build --platform linux/amd64 -t <イメージ名> -f <Dockerfileのパス> .

ただそれだと、コンテナーを実行する前にイメージをビルドしておく必要があります。 人は便利なものを目の前にするとより手間無く便利に、もっと言ってしまえば全自動で環境を用意できる方法を求めてしまいがちです。

そこで、Docker Compose側でlinux/amd64なイメージをARM Mac上でビルドするように書き換えてみます。 現時点のマニフェストの一部を紹介すると次のような感じで、イメージを指定して各コンテナーを作成しています。

services:
  sysbench:
    image: ytooyama/yugabyte-dev-sysbench:2.25.2.0-b359
    restart: unless-stopped
    tty: true
    volumes:
      - sysbench-vol:/root/data/    
    networks:
      - yugaplus-network
  yugabyte1:
    image: ytooyama/yugabyte-dev-tc:2.25.2.0-b359
    restart: unless-stopped
...

これを修正していきましょう。 フォルダツリーをVisual Studio Codeで開きます。 Visual Studio Codeを最近インストールした場合は、おそらくGitHub CopilotとGitHub Copilot Chatの拡張機能はインストール済みだと思いますが、入っていなければインストールしてください。 インストール後、自分のGitHubアカウントなどでGitHub Copilotにログインします。

フォルダツリーのなかからdocker-compose.ymlを探してVisual Studio Codeで開きます。

Visual Studio Codeの上部に「Chatの切り替え」と言うボタンがあるので押すと、GitHub Copilot Chat(画面上は「Copilotで編集する エージェントモード」)が開かれたと思います。ここでGitHub Copilotと対話して、目的のマニフェストにしていきましょう。

GitHub Copilot Chatに次のように記述します。 「このマニフェストを同じプロジェクトディレクトリー配下にある、dockerfileを使ってイメージビルドしてコンテナを起動するように変更したい。platform linux/amd64なコンテナーにするため、イメージはlinux/amd64でビルドする前提でお願いします。」

そうすると文脈を理解して、docker-compose.ymlを書き換えてくれました。sysbenchとそれ以外のコンテナーで適切なDockerfileを使ってイメージビルドして、YugabyteDBのコンテナーについてはイメージタグを指定してくれています。2個目と3個目のコンテナーでは1個目で指定したイメージタグを指定してくれているので、2個目と3個目は1個目と同じイメージで起動します。同じ内容のイメージをそれぞれビルドしたりすることなく、効率的にイメージをビルド、コンテナーを作成するマニフェストの修正を提案してくれました。

ただAIが提案する内容はいかなる場合も同じ提案をしてくれるわけではなく、この記事と全く同じ提案をしない場合もあります。その場合は引き続きGitHub Copilot Chatと対話してください。

最終的に目的の状態まで持ってこれたら、Chatに「この設定を反映してください」等と入力するか、画面上に「保持」のようなボタンが表示されるのでそれをクリックします。

ボタンを押すと、GitHub Copilotによって変更がファイルに反映されます。ついでにcap_addのインデントの問題も修正してくれていますね。ケーパビリティの「NET_ADMIN」は普通コンテナでアプリケーションを実行する場合は不要ですが、tcコマンドで遅延を発生させたテストをしたかったので追加しています。

最終的に編集前と編集後のマニフェストを比べると、次のようになりました。コード生成AIは色々ありますが、リポジトリーとしてGitHubを使い、コードのライティングにVisual Studio Codeを使っているのなら、GitHub Copilotは本当に便利です ね。まずは無料で使ってみて、ガッチリはまるようならGitHub Copilot Proを検討しても良い気がします。

docs.github.com

% diff -u docker-compose.yml docker-compose-fix.yml
--- docker-compose.yml  2025-07-31 13:25:45
+++ docker-compose-fix.yml  2025-07-31 13:19:26
@@ -1,13 +1,21 @@
 services:
   sysbench:
-    image: ytooyama/yugabyte-dev-sysbench:2.25.2.0-b359
+    build:
+      context: ../
+      dockerfile: base/sysbench-dockerfile
+    platform: linux/amd64
+    image: ytooyama/yugabyte-dev-sysbench:latest
     tty: true
     volumes:
-      - sysbench-vol:/root/data/    
+      - sysbench-vol:/root/data/
     networks:
       - yugaplus-network
+
   yugabyte1:
-    image: ytooyama/yugabyte-dev-tc:2.25.2.0-b359
+    build:
+      context: ../
+      dockerfile: base/base-dockerfile
+    image: ytooyama/yugabyte-dev-tc:latest
     command: sh -c "bin/yugabyted start --advertise_address=yugabyte1 --background=false"
     ports:
       - "15433:15433"
@@ -17,10 +25,10 @@
     networks:
       - yugaplus-network
     cap_add:
-    - NET_ADMIN      
+      - NET_ADMIN
 
   yugabyte2:
-    image: ytooyama/yugabyte-dev-tc:2.25.2.0-b359
+    image: ytooyama/yugabyte-dev-tc:latest
     command: sh -c "sleep 12 && bin/yugabyted start --advertise_address=yugabyte2 --background=false --join=yugabyte1"
     ports:
       - "5434:5433"
@@ -29,10 +37,10 @@
     networks:
       - yugaplus-network
     cap_add:
-    - NET_ADMIN
+      - NET_ADMIN
 
   yugabyte3:
-    image: ytooyama/yugabyte-dev-tc:2.25.2.0-b359
+    image: ytooyama/yugabyte-dev-tc:latest
     command: sh -c "sleep 12 && bin/yugabyted start --advertise_address=yugabyte3 --background=false --join=yugabyte1"
     ports:
       - "5435:5433"
@@ -41,7 +49,7 @@
     networks:
       - yugaplus-network
     cap_add:
-    - NET_ADMIN
+      - NET_ADMIN
 
 volumes:
   yugabyte1-vol:

修正したdocker-compose.ymlを右クリックして「Compose Up」を実行してみます。

次のようなエラーが出る事があります。

これはdocker-compose.ymlに上から順にコンテナの情報を記述しても上から順に実行されるのではなく、動いた順に処理が実行されるためです。yugabyte1と2と3はyugabyte1で作ったイメージと同じイメージを使うようにマニフェストを記述しているわけですから、yugabyte1のイメージができてホストに登録されるまで、yugabyte2とyugabyte3は起動できません。 なぜならyugabyte2とyugabyte3で指定しているimage: ytooyama/yugabyte-dev-tc:latestがデフォルトのイメージサーバーであるDockr Hubにないので、image pullできないためです。

しかしyugabyte1の処理が終わると、全部のコンテナーが動いて動作確認完了です。

今回はsysbenchだけx86_64のコンテナーで動かしましたが、すべてのコンテナーをx86_64で動かすことも可能です。少々遅くなりますけどね。こんな感じでYugabyteDBをコンテナで動かすことができました。

% psql -h 127.0.0.1 -p 5433 -U yugabyte -d yugabyte -c "SELECT * FROM yb_servers()" 
Timing is on.
   host    | port | num_connections | node_type | cloud  |   region    | zone  | public_ip |               uuid               |            universe_uuid             
-----------+------+-----------------+-----------+--------+-------------+-------+-----------+----------------------------------+--------------------------------------
 yugabyte2 | 5433 |               0 | primary   | cloud1 | datacenter1 | rack1 | yugabyte2 | 28e8247474fa495cbd6fdf8f6eca296c | 0cbbf832-7e4d-45d1-aee5-9289bd794da3
 yugabyte3 | 5433 |               0 | primary   | cloud1 | datacenter1 | rack1 | yugabyte3 | 43b29cbab182494783486b9b3337ec75 | 0cbbf832-7e4d-45d1-aee5-9289bd794da3
 yugabyte1 | 5433 |               0 | primary   | cloud1 | datacenter1 | rack1 | yugabyte1 | d34754b8a3d34c5a80a2821688e4959a | 0cbbf832-7e4d-45d1-aee5-9289bd794da3
(3 rows)

sysbenchは同じプロジェクトのコンテナーの中で動いていますので、yugabyte1, yugabyte2, yugabyte3みたいにホストを指定してベンチマーク対象にできます。あとはこちらの手順に従ってベンチマークするなり、YugabyteDBを触るなりが可能です。

docs.yugabyte.com

今回構築したのは3ノードのYugabyteDBです。 YugabyteDBは先ほども言ったように分散DBです。可能な限り台数を用意してスケールさせればよりパフォーマンスが向上にします。 その上、分散DBクラスターを割りと簡単に利用できるのが良いところです。

もっと色々勉強して、人にお勧めできるようになりたいです。