ランサーズ等のサービスを開発・運用する中で得た知識やノウハウを紹介しています。

Labels:  Aurora, DevOps, Docker, EC2, MySQL, RDS 投稿者:kanazawa

Docker開発環境のM1 Mac対応

SREチームの金澤です。

M1 Macが市場に出回り、社内でも業務用PCとして採用し始めました。

従来のMacと比べてもコストパフォーマンスが良く、大方問題なく動作しているため、今後も積極的に採用していきたいところですが、最もMacを利用している開発部では、Dockerが安定して動作することが採用の必須条件になります。

M1 MacはARMアーキテクチャのCPUを採用している関係で、Docker開発環境を問題なく動かすために、いくつかの対応が必要でしたので、今回その内容をブログにまとめます。

ランサーズ開発環境のM1 Mac対応

Docker for Macは、ARMアーキテクチャに対応中ですが、対応版はまだ正式リリースされていません。
※現時点では、3/26にリリースされたRC2版を利用しています。
https://docs.docker.com/docker-for-mac/apple-m1/

開発環境のM1 Mac対応

ランサーズの開発環境は、本番AWSでのサーバー構成をエミュレートした構成になっています。

リバースプロキシコンテナ(ELBコンテナ)

AWSのELBをエミュレートしたコンテナ。社内ではELBコンテナと呼んでいます。

今まで、リバースプロキシの処理にH2Oを利用していましたが、M1 Mac環境だとこの処理でタイムアウトしてしまいました。Appコンテナ等で採用しているNginxは正しく動作したので、H2OからNginxに変更するしたところ、正しく動作することを確認。

H2OがM1 Macで動かない原因の詳細までは調べ切れませんでしたが、取り急ぎワークアラウンドとしてNginxに変更することで対応しました。

Appコンテナ

ランサーズのAppコンテナは、x86_64環境でビルドしたコンテナをAWS ECRにpushし、それを開発者がpullして利用する形をとっています。

pullしたコンテナは、M1 Mac上でも問題なく動作しました。

MySQLコンテナ

ランサーズのMySQL5.7コンテナは、x86_64環境でデータをインポートしたものを、同様にAWS ECRにpushしています。

このコンテナも同様に、問題なく動作しました。

他開発環境のM1 Mac対応

ランサーズ以外のサービスについては、開発環境、本番環境共にDockerで運用しています。
ランサーズ開発環境と違い、ECRからpullせず、すべてのコンテナをPC上でビルドしていました。

Appコンテナ

一部のサービスでビルドに失敗しました。

% docker-compose up -d
Docker Compose is now in the Docker CLI, try `docker compose up`

Building app
[+] Building 68.3s (10/39)
 => [internal] load build definition from Dockerfile                                                                                                                            

...

------
 > [ 6/35] RUN apt-get update -y &&     apt-get upgrade -y &&     apt-get install -y --no-install-recommends     bash     build-essential     default-mysql-client     git     libcurl4-openssl-dev     libghc-yaml-dev     libqt5webkit5-dev     libxml2-dev     libxslt-dev     libyaml-dev     linux-headers-amd64     locales     nginx     nodejs     openssl     python3-pip     ruby-dev     ruby-json     ssh     sudo     supervisor     tzdata     vim     yarn     zlib1g-dev &&     apt-get clean -y &&     rm -rf /var/cache/apt/archives/* /var/lib/apt/lists/*:
#9 0.223 Hit:1 http://deb.debian.org/debian buster InRelease
#9 0.223 Hit:2 http://security.debian.org/debian-security buster/updates InRelease
#9 0.265 Hit:3 https://deb.nodesource.com/node_12.x buster InRelease
...
#9 17.04 This may mean that the package is missing, has been obsoleted, or
#9 17.04 is only available from another source
#9 17.04
#9 17.07 E: Package 'linux-headers-amd64' has no installation candidate
%

原因は、Dockerfileで以下のパッケージををインストールしていた箇所です。

linux-header-amd64

linux-headerについては、アーキテクチャ別にパッケージが用意されています。
M1 Mac上では、

linux-header-arm64

をインストールする必要があります。

M1 Macの場合はarm64版をインストールするために、以下のようにしました。

linux-headers-$(if [ $(uname -m) = "aarch64" ]; then echo arm64; else echo amd64; fi)

※ちなみに、原因調査中に、以下の指定による解決方法も見つかりましたが、どちらも正しくインストールできませんでした。

linux-header-$(uname -a) 
linux-header-generic

MySQLコンテナ

ランサーズで利用しているMySQLのバージョンは5.7です。
AWSで利用しているRDS AuroraがMySQL5.7ベースなので、開発環境もそれに合わせたものを利用しています。

ところが、オフィシャルで提供しているMySQL5.7コンテナはArm64をサポートしていません。
(MySQL8.0はサポートしている)

そこで、以下の解決方法を考えました。

  1. x86_64環境でビルドしたコンテナをECRにpushし、それをpullして利用する
     ・ランサーズのMySQLコンテナが正しく動作することを確認済
  2. MySQL5.7に相当するMariaDBをインストールする

2.については、Maria DBでJSON型をサポートしていない点が、互換性の面において問題となる可能性が高いと判断し、見送りました。
1.については、ランサーズ開発環境で問題なく動作することを確認できていました。
x86_64環境でDockerfileをビルドしたMySQLコンテナをECRにpushしておき、M1 Mac環境でそれをpullして使うことは可能です。

今回、1. の方法を選択し、正しく動作することを確認しました。

おまけ:AWS Graviton環境での動作検証

ランサーズでは、PC上で動作するDocker開発環境に加え、開発中の機能を検証するためのBackStage環境をAWS環境に構築しています。
EC2インスタンスにDockerをインストールし、PC開発環境と同じDockerコンテナで動作させる仕組みです。

今まで、この環境をt3a.mediumインスタンスで運用していましたが、Arm64に対応したため、AWS Graviton環境のt4g.mediumでも動くか検証してみました。

結果、正常に動いたのはRedisコンテナと、ELBコンテナのみでした。

Redisコンテナは、Arm64にも対応したマルチアーキテクチャのコンテナで、ELBコンテナも、マルチアーキテクチャのalphineコンテナをベースにビルドする形にしていたため動きましたが、それ以外のコンテナは起動できませんでした。

Docker for Macでは、M1 Macでもx86アーキテクチャのコンテナが動くように設計されていますが、純粋なArm64のLinux環境ではx86アーキテクチャのコンテナは、(予想通りでありましたが)動かないことを確認できました。

(これらを動くようにするには、Docker Buildのフェーズで、もう少し細かい配慮が必要そうです)

さいごに

今回、弊社開発環境で対応が必要だったことは、以下の3点でした。

・H2Oではなく、Nginxを使う
・linux-headerのインストールをArm64にも対応させる
・MySQL5.7はx86_64環境でビルドしたものをECRにpushしておき、それを使う

多少苦労しましたが、M1 Macで動作させることができたことにより、今後、社内でもM1 Macの導入が進んでいきそうです。

2000年代中盤以降、PC市場、およびサーバー市場がx86_64にほぼ統一されていたため、CPUアーキテクチャの違いを考慮するという状況があまり発生しませんでした。

これはある意味幸せな状態だったのですが、そこに競争力のある新しいアーキテクチャのCPUが、優れたコストパフォーマンスでPC、およびサーバー市場に食い込み始めてきたというのが最近の状況かと思います。

インフラ屋にとっては、以前よりも面倒な状態にまたなりますが、競争により、より優れた製品が市場に投入されていくこと自体は良いことだと思います。

今後は、Dockerコンテナやgolangのバイナリで、複数のCPUアーキテクチャを考慮する必要がある程度出てくると思います。

ソースからビルドする機会も多少増えるかも知れませんね。

ランサーズではサービスを成長させてくれるエンジニア、デザイナーを募集しています!
ご興味がある方は、以下URLよりご応募ください。


【中途採用】
フロントエンドエンジニア
サーバーサイドエンジニア
コーポレートエンジニア
SREエンジニア

【新卒採用・その他】
21・22新卒
その他採用情報

関連記事

PHP, CakePHPバージョンアップに向けてCIで品質を担保・向上していく

こんにちは、エンジニアの上野です。 今回はソース例や実際のサンプルソースを交えながら 「PHPバージョンアップに向けてCIで品質を担保・向上していく」と題してlancers.jp本体に導入しているCircleCIでの取り組みについてご紹介します。 導入背景 P …

新規事業開発におけるエンジニアの心得〜失敗事例から学ぶツクラナイ開発〜

tsuyoshi(@numanomanu)です。 先日、エンジニア向けのイベントで登壇して来たので、その時の資料を共有させていただきます。【サポーターズCoLab勉強会】新規事業開発におけるエンジニアの心得。 私自身、昨年、CtoCサービスの新規事業の立ち上げ …

gyazo_logo
[Gyazo] 今更聞けない?簡単画像共有アプリ Gyazo のプライベート環境構築方法

こんにちわ!ランサーズのsatoshiです。 今回は、ランサーズの開発メンバーがスクリーンショットの共有に利用している Gyazo という技術についてご紹介したいと思います。 Gyazo とは? Gyazo とはもともと、「スクリーンショットの瞬間共有」という …