LoginSignup
5
3

More than 3 years have passed since last update.

GreengrassでDockerアプリケーションをデプロイする

Last updated at Posted at 2020-12-23

はじめに

会社の業務で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でデバイスを操作しています。

作業の流れ

architecture.png

  1. Dockerアプリケーションの作成
    開発用PCでDockerアプリケーションを開発します。

  2. Dockerイメージのプッシュ
    Dockerイメージを作成してAmazon Elastic Container Registry (ECR)にプッシュします。

  3. docker-composeのアップロード
    docker-composeを作成してAmazon Simple Storage Service (S3)にアップロードします。

  4. 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!」というメッセージを表示します。

app.py
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World from Docker Container!"

if __name__ == "__main__":
    app.run()

必要なPythonのパッケージを記したファイルです。今回はFlaskのみ利用します。

requirements.txt
Flask

Dockerのイメージを作成する際のコマンドを記したファイルです。
32bit arm用のイメージに必要なファイルやパッケージをインストールしています。

Dockerfile
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にプッシュします。

リポジトリの作成

  1. 左上のサービスからElastic Container Registryに進み、「Repositories」→「リポジトリを作成」をクリックします。
    docker-24.png

  2. 任意のリポジトリ名を入力し、「リポジトリを作成」をクリックします。
    docker-25.png

イメージの作成とプッシュ

  1. PCのDocker Desktop on Windowsを起動しておきます。

  2. リポジトリのページに移動し、「プッシュコマンドの表示」をクリックします。
    docker-31.png

  3. Dockerアプリケーションの作成で作成したDockerfileのあるディレクトリでコマンドプロンプトを開き、表示されたコマンドを順番に実行します。
    docker-32.png

  4. ECRにdockerイメージがプッシュされたことを確認します。
    イメージのURIをこの後の手順で使用するので控えておきます。
    docker-37.png

3. docker-composeのアップロード

docker-composeの作成

PCでdocker-composeを作成します。
以下の内容をdocker-compose.ymlという名前で保存してください。
<image-uri>の部分はイメージの作成とプッシュで控えておいたURIで置き換えてください。

docker-compose.yml
version: '3'
services:
  web:
    image: "<image-uri>"
    ports:
      - "5000:5000"

S3バケットの作成

  1. 左上のメニューからS3へ進み、「バケット」→「バケットを作成」をクリックします。
    docker-26.png

  2. 任意のバケット名を入力し、「バケットを作成」をクリックします。
    docker-27.png

docker-composeのアップロード

  1. 作成したバケットをクリックし「アップロード」をクリックします。
    docker-28.png

  2. 「ファイルを追加」をクリックしdocker-composeの作成で作成したdocker-compose.ymlをアップロードします。
    docker-29.png

4. Dockerアプリケーションのデプロイ

ロールの作成とアタッチ

GreengrassがS3バケット、ECRにアクセスするために必要なロールを作成して、Greengrassグループにアタッチします。

ポリシーの作成

  1. 「IAM」→「ポリシー」と進み、「ポリシーの作成」をクリックします。
    docker-7.png

  2. 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>/*" 
            }
        ]
    }
    

    docker-17.png

  3. 任意の名前と説明を入力して「ポリシーの作成」をクリックします。
    docker-16.png

  4. 同様の手順で、以下の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": "*"
            }
        ]
    }
    

ロールの作成

  1. 「IAM」→「ロール」と進み、「ロールの作成」をクリックします。
  2. ユースケースの選択でGreengrassを選択し、次へ進みます。
    docker-19.png

  3. ポリシーの作成で作成した2つのポリシーを選択します。
    docker-20.png

  4. タグは設定せずに次へ進みます。

  5. 任意の名前と説明を入力してロールを作成します。
    docker-21.png

ロールのアタッチ

  1. Greengrassのグループへ進み、「設定」→「ロールの追加」をクリックします。
    docker-22.png

  2. ロールの作成で作成したロールを選択して「保存」をクリックします。
    docker-23.png

デプロイと動作確認

  1. グループのページに進み、「コネクタ」→「コネクタの追加」をクリックします。
    docker-33.png

  2. 「Docker Application Deployment」を選択し、「次へ」をクリックします。
    docker-34.png

  3. S3に保存したdocker-compose.ymlと、ユーザー設定で作成した、デバイス上でdocker-composeを保存するディレクトリを指定して、「追加」をクリックします。
    docker-35.png

  4. グループのページに進み、デプロイをクリックします。
    docker-30.png

  5. デプロイ完了後、しばらく待ってからPCでhttp://<デバイスのIPアドレス>:5000にアクセスします。
    ※デバイスとPCが同一のネットワークに属している必要があります。

  6. 以下の画面が表示されたら成功です。
    docker-38-2.png
    ※うまくいかない場合はデバイスの/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に従ってプロキシ設定を行います。

  1. まずディレクトリを作成し、そのディレクトリ内にファイルを作成します。

    sudo mkdir -p /etc/systemd/system/docker.service.d
    sudo vi /etc/systemd/system/docker.service.d/http-proxy.conf
    
  2. 下記のフォーマットで HTTP_PROXYHTTPS_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/"
    
  3. 設定を反映するためにデーモンをリロードし、再起動します。

    sudo systemctl daemon-reload
    sudo systemctl restart docker
    
  4. 設定内容が反映されているか確認します。

    # 一般ユーザ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/
    

参考

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3