MacからAWSへDocker環境を一時移転


1.M1版MacとDockerの相性について

 初のApple製SoC(Apple Silicon:M1)を搭載したMacが2020年11月17日に発売された。IntelからArm系のCPUに変更されたため、既存のソフトウェアの互換性が懸念されていたがAppleでは本機リリースと同時にエミュレーション環境であるRosseta2をリリースしておりIntel Mac用ソフトウェアを問題なく動作させることが可能と言われている。
但し、Dockerについては公式が互換性問題に言及しており、現時点(2020年11月)では完全な動作が難しいとのことである(リンク)※
  ※2020年12月11日に早くもプレビュー版が発表された

2.M1 Macがどうしても欲しいので、Docker環境の引っ越しをやってみた

 2012年型のMacbook Proユーザである私は、2020年からの新しいmacOS(Big Sur)がサポートされない為、今年中にMacを買い替えるつもりでいたが、一部互換性の問題はあるにしても、M1 Macのレビュー評価がおしなべて高く、現時点でIntel版Macを購入する気にはとてもなれない。
 そこで、一時的な互換性問題を当面やり過ごして、M1 Macを導入することに決めた。私は現在、DockerをMacにインストールし、ローカルをホストとして、その中にAnacondaを入れて、Pythonの開発環境を構築しているが、M1 Mac対応のDockerがリリースされるまでの間、Docker環境(ホスト)をMacの外部に移設することを試みた。

 移設先候補は以下とする
  ・AWS(無料枠でのEC2 Ubuntu server)

3.Docker環境をAWSへ移設

 3.0 解説の前提条件

   ・ローカル端末としてMacを使用していること
   ・AWSのアカウント取得が済んでいること
   ・既に動作するDockerfile若しくはDocker imageが手元にあること
   ・AWS無料試用期間(アカウント作成から1年)の期間内であること
   ・日本国内からAWSにログインしていること

 3.1 EC2サーバを立てる

 ・ルートユーザーとして、AWSアカウントとパスワード(次のページ)を入力し、サインイン

 ・サービス:EC2を検索して選択

 ・「インスタンスを起動」プルダウンから「インスタンスを起動」を選択

 ・マシンイメージを選択。念の為「無料利用枠のみ」にチェックを入れる。ここではUbuntu Serverを選択

 ・インスタンスタイプの選択:無料枠としては”t2.micro”一択になる。
  選択後、「次のステップ:インスタンスの詳細の設定」へ

 ・インスタンスの詳細の設定は特に変更不要と思われる。変更すると有料となる設定もあるので注意
  「次のステップ:ストレージの追加」へ

 ・ストレージは必要に応じてサイズを決定する。デフォルトは8GBだが、自分が持つDockerfileをBuildするには不十分なのでサイズ(GiB)を無料枠上限の30GBに変更する。
  「次のステップ:タグの追加」へ

 ・後ほど実行するキーペアの作成のためのタグを追加する。例に倣ってキーに名前を、値にサーバー名を入力した
  入力後、「次のステップ:セキュリティグループの設定」へ

 ・セキュリティの要件はケースバイケースなのでここでは詳細について言及しないが、せめてIPアドレスを制限しないと下記のごとく警告が出る。この場合、”ソース”のプルダウンから”マイIP”を選択すると、現在接続しているローカル側のグローバルIPアドレスが自動で入力される。複数箇所からのアクセスを想定している場合でなければ、特に差し支えないと思われるので、この設定とする。
  次の「確認と作成」へ

 ・インスタンス作成の確認画面。設定どおりであれば、「起動」を選択

 ・キーペアを作成する。初めてインスタンスを作成する場合は既存のキーはないはずなので「新しいキーペアの作成」を選択してキーペア名(pemファイル名)を入力し、ダウンロードして保存する。

 ・インスタンスを作成中とあるが、この画面のまま待っていても何も変わらない。「インスタンスの表示」を選択する

 ・インスタンスの状態を表示する画面に移る。インスタンスが下記のごとく「実行中」になっていると、(無料で使用可能な)月750時間のカウントがスタートしている。インスタンスの行を選択すると、下に詳細が表示される。画面中央の”パブリックIPv4 DNS”がサーバの接続先となる。

 ・月あたり750時間は稼働しっぱなしでも超過することはない(750÷24=31.25>31日なので)とは思うが、無料課金の終了間際等で、知らずに課金が始まることもあるかと思うのでサーバを使わないときは常にインスタンスを停止する癖をつけておきたい。
  停止する方法は「インスタンスの状態」プルダウンから「インスタンスを停止」を選ぶ

 ・確認画面が出るので、再度「停止」を選択

 ・下記の表示となったら課金状態から抜けられているはず尚、”正常に停止しました”の緑の帯が表示されてから、インスタンスが”停止済み”となるまでは若干のライムラグが生じる。

 3.2 Docker準備

 ・まず、AWSサーバにログインする。ターミナルからsshでログインする。事前にpemファイルをchmodで上書き禁止にするとよい

    $ chmod 400 keypair名.pem
    $ ssh -i <keypairのパス/keypair名.pem> ubuntu@<パブリック IPv4 DNS>

 ・ubuntuアップデート後、dockerをインストールする

    $ sudo apt update
    $ sudo apt upgrade
    $ sudo apt install docker.io

 ・インストール後、ユーザubuntuに対するDockerへの管理者権限を付与する。その後一旦exitし再ログイン後にdockerのコマンドをsudoなしで入力し、受け付けることを確認する。

    $ sudo gpasswd -a ubuntu docker

 ・一旦exitし、sftpでAWSサーバにDockerファイルとワークディレクトリを転送する。docker imageの入手方法によってはDockerfileがない場合もあるので、その場合はdocker imageを直接転送することになるが、anacondaを含むdocker imageはかなり容量の大きいファイルとなるので、転送前に確認要。

    $ sftp -i <keypairのパス/keypair名.pem> ubuntu@<パブリック IPv4 DNS>
    $ put <任意のディレクトリ>/Dockerfile
     ※ローカルディレクトリを指定しなければログインしたときのローカルフォルダ
      (この場合はDesktop)となる
      リモートのディレクトリを指定しなければ接続時のデフォルト
      (/home/ubuntu)に置かれる
    $ put -r <ローカルで使っていたワークディレクトリ>
    $ exit

 ・ファイル転送が終わったらsftpをexitし、sshで入り直す。

 3.3 Docker build

 ・Dockerfileをbuildし、Docker imageを作成する。build context用のディレクトリを置く場合は事前に準備する。buildが完了したら、docker imagesコマンドでimageが出来ていることを確認する。

    $ mkdir anaconda_build(build contextの作成、任意)
    $ mv Dockerfile anaconda_build
    $ cd anaconda_build
    $ docker build .
     (buildが終わったら)
    $ docker images


 3.4 Jupyter Notebookのリモート接続とワークディレクトリの確認

 ・下記のコマンドでdocker runし、anacondaを立ち上げたあと、MacのブラウザからAWSサーバに接続し、Jupyter Notebookが立ち上がることを確認する。その時、指定したワークディレクトリが見えていて、sftpで転送したファイルが入っていること。


    $ docker run -v ~/workdir:/workdir -p 8888:8888 <image ID>
      (下記スクショはディレクトリ名が”work”になっているが、”workdir”の間違い)



ここまでくれば、これまでと同様にanaconda環境が構築されたはず。
このサーバがいずれ不要となったら、”インスタンスを終了”すればキレイサッパリ消えてくれるので、楽なものである。その際、ワークディレクトリにある成果物を事前にsftp getで回収することを忘れないようにしたい。

今後の課題

 Docker環境移設(ラズパイ編)
→ラズパイで使えるanaconda(arm64版)リポジドリが存在しないことが判ったので、
  後日取り組むこととしたい

参考文献

 米国AI開発者がゼロから教えるDocker講座(Udemy)