【AWS IoT Greengrass V2】パブリックイメージの Docker コンテナをカスタムコンポーネントとしてローカルデプロイしてみる

AWS IoT Greengrass V2 で Docker コンテナをローカルでデプロイしてみました。
2021.10.09

前回の記事で Raspberry Pi に Docker 環境を構築しました。

今回はこの環境に Greengrass コンポーネントとして、Docker コンテナをデバイス上のローカルからデプロイしてみたいと思います。具体的な手順は下記のドキュメントを参考にしています。

検証内容

Docker コンテナを Greengrass コンポーネントで動かす場合、用途に応じて以下のような選択肢があります。

  • Amazon ECR または Docker Hub のパブリックイメージからコンテナを実行する
  • Amazon ECR のプライベートイメージからコンテナを実行する
  • S3 上のイメージからコンテナを実行する

また、上記においてそれぞれ「ローカル上でデプロイする」場合と「AWS側からデプロイする」2つのパターンがあります。

検証時に「ローカルでデプロイ」して、本番環境でリモートにある複数デバイスにデプロイする時は「AWS からデプロイする」ことになると思うので、それぞれのパターン別に検証していきたいと思います。
デプロイパターンとして検証する予定のものは下記になります。

1. Docker Hub のパブリックイメージから Raspberry Pi に Docker コンテナをローカルデプロイ(本記事)
2. Docker Hub のパブリックイメージから Raspberry Pi に Docker コンテナを AWS からデプロイ
3. Amazon ECR のプライベートイメージから Raspberry Pi に Docker コンテナをローカルデプロイ(予定)
4. Amazon ECR のプライベートイメージから Raspberry Pi に Docker コンテナをAWSからデプロイ(予定)

今回は、上記の「1. パブリックイメージから Raspberry Pi に Docker コンテナをローカルデプロイ」を試します。

検証内容の構成イメージ

今回の作業イメージです。
Docker Hub にある PostgreSQL のパブリックイメージをデバイス上で作業してデプロイします。

00-public-image-local-deploy

前提

既存イメージの削除

何もない状態から試したいので、前回の記事で動作確認に使ったコンテナやイメージがあれば消しておきましょう。

コンテナを削除する場合は、docker rmで消します。

$ docker rm [CONTAINER ID]

イメージの削除はdocker rmiで消します。

$ docker rmi [IMAGE ID]

Docker 実行ユーザーの設定変更

AWS IoT Greengrass 経由での Docker 実行ユーザは、デフォルトで ggc_userになるので、dockerグループにggc_userを追加しておきます。

$ sudo usermod -aG docker ggc_user

レシピとアーティファクト用のディレクトリ作成

ローカルデプロイするので、レシピとアーティファクト用のディレクトリを作成します。 適当なディレクトリ以下に下記のような階層でディレクトリを作成しておきます。
なお、コンポーネント名は「com.example.MyDockerComposeComponent」としています。

.
├── artifacts
│   └── com.example.MyDockerComposeComponent
│       └── 1.0.0
│           └── docker-compose.yaml
└── recipes
    └── com.example.MyDockerComposeComponent-1.0.0.yaml

docker-compose.yaml の作成

アーティファクトとしてdocker-compose.yamlを用意します。今回は下記の内容で作成しましたが内容に特に意味はありません。
作成したファイルは上記にある artifacts/com.example.MyDockerComposeComponent/1.0.0以下に保存します。

version: '3'

services:
  db:
    image: postgres:latest
    environment:
        POSTGRES_USER: postgres
        POSTGRES_PASSWORD: password
    ports:
      - 5432:5432

レシピの作成

下記の内容でレシピ(com.example.MyDockerComposeComponent-1.0.0.yaml)を作成します。レシピはrecipesディレクトリに保存します。

Docker コンテナのコンポーネントを動かすには、依存関係として「Docker application manager」というパブリックコンポーネントが必要になるので、ComponentDependenciesを記載している点がポイントになります。

なお、レシピは本記事の冒頭に記載した AWS ドキュメントに掲載されているものを参考にしています。

RecipeFormatVersion: '2020-01-25'
ComponentName: com.example.MyDockerComposeComponent
ComponentVersion: '1.0.0'
ComponentDescription: 'A component that uses Docker Compose to run images from public Docker Hub.'
ComponentPublisher: Amazon
ComponentDependencies:
  aws.greengrass.DockerApplicationManager:
    VersionRequirement: ~2.0.0
Manifests:
  - Platform:
      os: all
    Lifecycle:
      Run: docker-compose -f {artifacts:path}/docker-compose.yaml up

ローカルデプロイの実行

準備ができたら、Raspberry Pi 上で Greengrass CLI を使ってデプロイします。

(私の環境ではMyComponentというディレクトリ以下にアーティファクトとレシピを置いているので、各ディレクトリのパスはご利用環境に合わせてください。)

sudo /greengrass/v2/bin/greengrass-cli deployment create \
  --recipeDir ~/MyComponent/recipes \
  --artifactDir ~/MyComponent/artifacts \
  --merge "com.example.MyDockerComposeComponent=1.0.0"

しばらくするとデプロイが完了するので確認します。

$ sudo docker ps 
CONTAINER ID   IMAGE             COMMAND                  CREATED         STATUS         PORTS                                       NAMES
4fd770f6b691   postgres:latest   "docker-entrypoint.s…"   4 minutes ago   Up 4 minutes   0.0.0.0:5432->5432/tcp, :::5432->5432/tcp   100_db_1

実際に PostgreSQL に接続してみます。

$ psql -h localhost -U postgres
Password for user postgres: 
psql (11.12 (Raspbian 11.12-0+deb10u1), server 14.0 (Debian 14.0-1.pgdg110+1))
WARNING: psql major version 11, server major version 14.
         Some psql features might not work.
Type "help" for help.

postgres=#

なお、コンポーネントを削除するとコンテナも削除されます。
ローカルでデプロイしたコンポーネントを削除する場合は下記のコマンドを実行します。
(コンポーネント名はご利用環境に合わせてください)

$ sudo /greengrass/v2/bin/greengrass-cli deployment create \
--remove="com.example.MyDockerComposeComponent"

デプロイ状況の確認

通常のコンポーネントと同様に、デフォルトでは/greengrass/v2/logs以下のログにデプロイ状況が出力されます。
コンテナイメージのダウンロード(docker pull)されている状況などは、/greengrass/v2/logs/コンポーネント名.logに出力されています。

デプロイに失敗する場合は、/greengrass/v2/logs/greengrass.logも合わせて確認してみてください。

最後に

今回は第一歩としてローカルでデプロイしてみました。次は AWS 側からデプロイしてみたいと思います。