はじめに
会社の業務でAWS IoT Greengrassについて勉強したので、Ubuntu搭載デバイスとAWS IoTを利用したアプリケーションを紹介したいと思います。
今回はGreengrassでDockerアプリケーションをデプロイする方法12を紹介します。
過去の記事:
UbuntuにAWS IoT Greengrassをインストールする
GreengrassのLambdaを作成してエッジデバイスにデプロイする
※先日、Greengrass V23がリリースされましたが、この記事ではV1を使用します。
環境
動作確認済デバイス(OS)
-
e-RT3 Plus F3RP70-2L4(Ubuntu 18.04 32bit)
横河電機のエッジコントローラです。AWS IoT Greengrassの認定デバイス5に登録されています(e-RT3のページはこちら)。 -
Raspberry Pi 4 Model B (Ubuntu Server 20.04 32bit)
これらのデバイスでは armhf アーキテクチャのパッケージが動作します。
また、Windows 10 搭載のPCでデバイスを操作しています。
作業の流れ
-
Dockerアプリケーションの作成
開発用PCでDockerアプリケーションを開発します。 -
Dockerイメージのプッシュ
Dockerイメージを作成してAmazon Elastic Container Registry (ECR)にプッシュします。 -
docker-composeのアップロード
docker-composeを作成してAmazon Simple Storage Service (S3)にアップロードします。 -
Dockerアプリケーションのデプロイ
必要なロールをGreengrass Groupに付与し、Dockerアプリケーションのデプロイメントコネクタ1を使用してDockerアプリケーションをデバイスにデプロイします。Dockerコンテナが起動し、アプリケーションが稼働します。
準備
AWS CLIのインストール
PCにAWS CLIをインストールします。
インストール方法は以下のガイドを参照してください。
Windows での AWS CLI バージョン 2 のインストール、更新、アンインストール
初回使用時には設定を行う必要があります。詳しくは以下のガイドを参照してください。
設定の基本 - AWS Command Line Interface
※PCがproxy環境下にある場合はproxy設定が必要です。詳しくはコマンドのプロキシ設定をご覧ください。
Docker Desktop on Windowsのインストール
PCにDocker Desktop on Windowsをインストールします。
インストール方法はこちらのページを参照してください。
※PCがproxy環境下にある場合はproxy設定が必要です。詳しくはこちらのページをご覧ください。
Python3.7のインストール
デバイスにGreengrassでDockerアプリケーションをデプロイするために必要なPython3.7をインストールします。
※デバイスがproxy環境下にある場合はproxy設定が必要です。詳しくはこちらをご覧ください。
-
e-RT3の場合
sudo apt update sudo apt install python3.7
username@ubuntu:~$ python3.7 --version Python 3.7.5
-
Raspberry Pi (Ubuntu Server 20.04 32bit)の場合
aptでインストールできないので、ソースからビルドしてインストールします。
ビルドに必要なパッケージをインストールします。sudo apt update sudo apt install build-essential libbz2-dev libdb-dev \ libreadline-dev libffi-dev libgdbm-dev liblzma-dev \ libncursesw5-dev libsqlite3-dev libssl-dev \ zlib1g-dev uuid-dev
公式サイトからPython3.7のソースをダウンロードしてビルドします。
wget https://www.python.org/ftp/python/3.7.9/Python-3.7.9.tar.xz tar xvf Python-3.7.9.tar.xz cd Python-3.7.9 ./configure make sudo make altinstall cd ~
インストールの成功を確認します。
username@ubuntu:~$ python3.7 --version Python 3.7.9
dockerのインストール
デバイスにdockerとdocker-composeをインストールします。
docker
-
e-RT3の場合
最新版をインストールするために、公式ドキュメント6に従ってインストールします。
dockerのインストールに必要なパッケージをインストールします。sudo apt update sudo apt install \ apt-transport-https \ ca-certificates \ curl \ gnupg-agent \ software-properties-common
資格情報7に必要なパッケージをインストールします。
sudo apt install pass
GPGキーを追加します。
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
フィンガープリントの下8桁で検索し、キーが追加されたことを確認します。
username@ubuntu:~$ sudo apt-key fingerprint 0EBFCD88 pub rsa4096 2017-02-22 [SCEA] 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 uid [ unknown] Docker Release (CE deb) <docker@docker.com> sub rsa4096 2017-02-22 [S]
リポジトリを追加します。
sudo add-apt-repository \ "deb [arch=armhf] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable"
dockerエンジンをインストールします。
sudo apt update sudo apt install docker-ce docker-ce-cli containerd.io #サービス起動 sudo systemctl start docker #サービス自動起動 sudo systemctl enable docker
username@ubuntu:~$ docker --version Docker version 20.10.1, build 831ebea
-
Raspberry Pi(Ubuntu Server 20.04 32bit)の場合
Dockerの公式リポジトリにUbuntu20.04 armhf用のパッケージがないので、docker.ioでインストールします。
sudo apt install docker.io #サービス起動 sudo systemctl start docker #サービス自動起動 sudo systemctl enable docker
username@ubuntu:~$ docker --version Docker version 19.03.8, build afacb8b7f0
インストールの成功を確認します。
テスト用のイメージでコンテナを起動し、以下のようなメッセージが表示されたら成功です。
username@ubuntu:~$ sudo docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
※デバイスがproxy環境下にある場合はproxy設定が必要です。詳しくはdockerのプロキシ設定をご覧ください。
docker-compose
pipを利用してインストールします8。
必要なパッケージをインストールします。
sudo apt update
sudo apt install libffi-dev libssl-dev python3-dev python3-venv
仮想環境を作成してpipでインストールします。
python3 -m venv venv
source venv/bin/activate
(venv) username@ubuntu:~$ pip install wheel
(venv) username@ubuntu:~$ pip install docker-compose
(venv) username@ubuntu:~$ sudo cp venv/bin/docker-compose /usr/bin
(venv) username@ubuntu:~$ deactivate
インストールの成功を確認します。
username@ubuntu:~$ docker-compose --version
docker-compose version 1.27.4, build unknown
ユーザー設定
GreengrassからデプロイされたDockerアプリケーションを実行するユーザーの設定を行います。
デフォルトではggc_userとなるので、今回はこのユーザーを使用します。
S3バケットからダウンロードしたdocker-composeを保存するディレクトリを作成し、アクセス権を設定します。
sudo mkdir /home/ggc_user/myCompose
sudo chown ggc_user:ggc_group /home/ggc_user/myCompose
sudo chmod 700 /home/ggc_user/myCompose
ggc_userをdockerグループに追加します。
sudo usermod -aG docker ggc_user
一度ログアウトして設定を反映させます。
1. Dockerアプリケーションの作成
PCでDockerアプリケーションを作成します。
今回は、アクセスすると「Hello World from Docker Container!」というメッセージを表示するPythonのwebアプリケーションを作成します。
以下の3つのファイルを同一のフォルダに保存してください。
Flaskを利用したPythonのプログラムです。アクセスすると「Hello World from Docker Container!」というメッセージを表示します。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World from Docker Container!"
if __name__ == "__main__":
app.run()
必要なPythonのパッケージを記したファイルです。今回はFlaskのみ利用します。
Flask
Dockerのイメージを作成する際のコマンドを記したファイルです。
32bit arm用のイメージに必要なファイルやパッケージをインストールしています。
FROM arm32v7/python:3.7-alpine
WORKDIR /usr/src/app
ENV FLASK_APP app.py
ENV FLASK_RUN_HOST 0.0.0.0
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["flask", "run"]
2. Dockerイメージのプッシュ
Dockerイメージを作成してECRにプッシュします。
リポジトリの作成
イメージの作成とプッシュ
-
PCのDocker Desktop on Windowsを起動しておきます。
-
Dockerアプリケーションの作成で作成したDockerfileのあるディレクトリでコマンドプロンプトを開き、表示されたコマンドを順番に実行します。
-
ECRにdockerイメージがプッシュされたことを確認します。
イメージのURIをこの後の手順で使用するので控えておきます。
3. docker-composeのアップロード
docker-composeの作成
PCでdocker-composeを作成します。
以下の内容をdocker-compose.yml
という名前で保存してください。
<image-uri>
の部分はイメージの作成とプッシュで控えておいたURIで置き換えてください。
version: '3'
services:
web:
image: "<image-uri>"
ports:
- "5000:5000"
S3バケットの作成
docker-composeのアップロード
-
「ファイルを追加」をクリックしdocker-composeの作成で作成したdocker-compose.ymlをアップロードします。
4. Dockerアプリケーションのデプロイ
ロールの作成とアタッチ
GreengrassがS3バケット、ECRにアクセスするために必要なロールを作成して、Greengrassグループにアタッチします。
ポリシーの作成
-
JSONタブをクリックして以下のJSONを入力し、S3バケットへのアクセスを許可します。
<bucket-name>
の部分はS3バケットの作成で作成したS3バケット名に置き換えてください。
入力が完了したら「ポリシーの確認」をクリックします。{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAccessToComposeFileS3Bucket", "Action": [ "s3:GetObject" ], "Effect": "Allow", "Resource": "arn:aws:s3:::<bucket-name>/*" } ] }
-
同様の手順で、以下のJSONを使用してECRへのアクセスを許可するポリシーを作成します。
<region>
、<account-id>
の部分は使用しているリージョンとアカウントIDで、<repository-name>
の部分はリポジトリの作成で作成したリポジトリ名で置き換えてください。{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowGetEcrRepositories", "Effect": "Allow", "Action": [ "ecr:GetDownloadUrlForLayer", "ecr:BatchGetImage" ], "Resource": [ "arn:aws:ecr:<region>:<account-id>:repository/<repository-name>" ] }, { "Sid": "AllowGetEcrAuthToken", "Effect": "Allow", "Action": "ecr:GetAuthorizationToken", "Resource": "*" } ] }
ロールの作成
-
「IAM」→「ロール」と進み、「ロールの作成」をクリックします。
-
ポリシーの作成で作成した2つのポリシーを選択します。
-
タグは設定せずに次へ進みます。
ロールのアタッチ
-
ロールの作成で作成したロールを選択して「保存」をクリックします。
デプロイと動作確認
-
S3に保存したdocker-compose.ymlと、ユーザー設定で作成した、デバイス上でdocker-composeを保存するディレクトリを指定して、「追加」をクリックします。
-
デプロイ完了後、しばらく待ってからPCで
http://<デバイスのIPアドレス>:5000
にアクセスします。
※デバイスとPCが同一のネットワークに属している必要があります。 -
以下の画面が表示されたら成功です。
※うまくいかない場合はデバイスの/greengrass/ggc/var/log/
以下にあるログを確認してください。
補足
環境により設定は異なりますが、参考までに今回私が行ったproxy設定を紹介します。
コマンドのプロキシ設定
Windowsのコマンドプロンプトで以下の内容を入力します。
set HTTP_PROXY=http://username:password@example.com:port/
set HTTPS_PROXY=http://username:password@example.com:port/
dockerのプロキシ設定
Dockerのドキュメント9に従ってプロキシ設定を行います。
-
まずディレクトリを作成し、そのディレクトリ内にファイルを作成します。
sudo mkdir -p /etc/systemd/system/docker.service.d sudo vi /etc/systemd/system/docker.service.d/http-proxy.conf
-
下記のフォーマットで
HTTP_PROXY
、HTTPS_PROXY
の環境変数をファイルに書き込み、保存します。
どちらか一方のみで良い場合やNO_PROXY
の設定が必要な場合など、環境に合わせて適宜内容を変更してください。/etc/systemd/system/docker.service.d/http-proxy.conf[Service] Environment="HTTP_PROXY=http://username:password@example.com:port/" Environment="HTTPS_PROXY=http://username:password@example.com:port/"
-
設定を反映するためにデーモンをリロードし、再起動します。
sudo systemctl daemon-reload sudo systemctl restart docker
-
設定内容が反映されているか確認します。
# 一般ユーザusernameの場合 username@ubuntu:~$ sudo systemctl show --property=Environment docker Environment=HTTP_PROXY=http://username:password@example.com:port/ HTTPS_PROXY=http://username:password@example.com:port/