ARM上のGridDBとDocker

Dockerコンテナ上で動作するGridDBは新しいトピックではありません。以前にも取り上げています:https://griddb.net/ja/blog/run-a-griddb-server-in-docker-desktop/ & https://griddb.net/ja/blog/improve-your-devops-with-griddb-server-and-client-docker-containers/

本ブログでは、改めてDocker上でのGridDBの使用について触れたいと思いますが、代わりにARMアーキテクチャ上でのGridDBの使用、すなわちAppleシリコン(M1、M2など)を搭載したMacに焦点を当てます。そこで、本ブログでは、ARMデバイスで動作するDockerイメージを提供するとともに、お客様のDockerコンテナサービスと連携して動作するアプリケーションコンテナを起動する方法について説明します。

DockerでGridDBおよびGridDBアプリケーションを実行する

まず、この記事に添付されているソースコードをこちらでご覧いただけます:https://github.com/griddbnet/griddb-docker-arm。このソースコードには、ARMマシン上で実行するためにビルドできるDockerイメージ自体が含まれています。

このイメージ自体は、GridDB.net Dockerhub ページから取得することも可能です。イメージ/タグの完全な名前は、griddbnet/griddb:arm-5.5.0 です。nodejsアプリケーションのリポジトリも利用可能です。griddbnet/nodejs-arm:latest

GridDBサーバの実行

このイメージを取得して実行するには:

$ docker network create griddb-net
$ docker pull griddbnet/griddb:arm-5.5.0
$ docker run --name griddb-server \
    --network griddb-net \
    -e GRIDDB_CLUSTER_NAME=myCluster \
    -e GRIDDB_PASSWORD=admin \
    -e NOTIFICATION_MEMBER=1 \
    -d -t griddbnet/griddb:arm-5.5.0

これらのコマンドは、GridDBサーバーと、そのサーバーで実行する予定のコンテナのネットワークを作成します。また、ビルドされたイメージをダウンロードし、そのイメージをマシン上で実行します。実行を確認できたら、GridDBコンテナをデータストアとして使用して、アプリケーションコードを実行してみましょう。

アプリケーションコンテナの実行

まず、ソースコードを取得し、GridDBを接続に使用して任意のコードを実行するnodejsコンテナをビルドします。

$ git clone https://github.com/griddbnet/Blogs.git --branch docker-arm

次に、コンテナ化されたサーバーに対してnode.js GridDBのコードを実行するコマンドを紹介します。

まず、node.js GridDBの公式リポジトリに付属するサンプルコードを実行してみましょう。

$ cd Blogs/nodejs/node-api
$ docker build -t griddb_node_app .
$ docker run --name griddb-node --network griddb-net -e GRIDDB_CLUSTER_NAME=myCluster -e GRIDDB_USERNAME=admin -e GRIDDB_PASSWORD=admin -e IP_NOTIFICATION_MEMBER=griddb-server griddb_node_app

まず、公式のソースコードと比較して変更されたファイルを含むソースコードを取得する必要があります(C_Clientをmacos/ARM上で実行できるようにするための変更。これは、Java以外のプログラミング言語のコネクタに必要な変更です)。次に、クラスタ名、ユーザー/パスワードの組み合わせ、そして最後にコンテナにGridDBサーバーコンテナのIPアドレスを明示的に伝えるIP_NOTIFICATION_MEMBERなどのオプションを設定して、イメージをビルドし、実行します。

もちろん、ここで実行するのは、ご自身で作成したコードではなく、提供されたサンプルコードです。しかし、ご自身で作成したGridDB nodejsコードを実行するためのフレームワークも用意されています。その流れは次の通りです。コードを作成し、Dockerイメージをビルドし、Dockerネットワークを選択し、正しいホスト名/IPアドレスを指定して実行します。

nodejsアプリケーションのインターフェースに合わせて、JDBCとJavaもMシリーズチップを使用するARMベースのMacで動作することがテストされ、確認されています。

アプリケーションコンテナの作成例

Docker上で独自のアプリケーションを構築して実行するには、プロセスはシンプルです。任意の言語でアプリケーションを記述し、そのアプリケーション用のDockerfileを記述し、最後にコンテナを構築して実行します。GridDBコンテナを実行する際に使用したのと同じネットワークを使用するようにしてください。

Node.js

例えば、簡単なNode.jsスクリプトを記述して「偽」のデータを生成するとします。

アプリケーションの接続を無関係に保つために、接続の詳細をコマンドライン引数として保持することができます。つまり、Dockerコンテナを実行する際に、接続したいDockerコンテナを、上記と同様の方法で入力するだけです。Dockerコンテナを実行する際に環境の詳細を入力すると、これらの詳細がエントリーポイントのスクリプトによって取得されます。

以下は、ARMマシンにGridDB Node.jsコネクタとc_clientコネクタをインストールするためのDockerfileです。このファイルのほとんどは、必要なものをすべてインストールしており、これにはc_client rpmファイルのインストールも含まれています。この例では、実行したいファイル(gen-data.js)をエントリポイントスクリプトとともに単にコピーしています。

FROM rockylinux:9.3

ENV GRIDDB_NODE_API_VERSION=0.8.5
ENV NODE_PATH=/root/node-api-${GRIDDB_NODE_API_VERSION}

# Install griddb server
RUN set -eux \
    && dnf update -y \
    # Install nodejs version 16.x and c client for griddb nodejs_client
    && dnf install -y curl make python3 tar --allowerasing \
    && dnf groupinstall -y 'Development Tools'

RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash

RUN source ~/.nvm/nvm.sh && nvm install 20 && nvm use 20


COPY ./lib/griddb-c-client-5.5.0-linux.aarch64.rpm /
RUN rpm -Uvh /griddb-c-client-5.5.0-linux.aarch64.rpm

SHELL ["/bin/bash", "--login", "-c"]
# Copy entrypoint script and sample for fixlist
RUN mkdir /app
COPY run-griddb.sh gen-data.js /app/

WORKDIR /root

# Install nodejs client
RUN curl -L https://github.com/griddb/node-api/archive/refs/tags/${GRIDDB_NODE_API_VERSION}.tar.gz -o ${GRIDDB_NODE_API_VERSION}.tar.gz -sS \
    && tar -xzvf ${GRIDDB_NODE_API_VERSION}.tar.gz \
    && cd node-api-${GRIDDB_NODE_API_VERSION} 

WORKDIR /root/node-api-${GRIDDB_NODE_API_VERSION}
RUN  npm install 
RUN rm ../${GRIDDB_NODE_API_VERSION}.tar.gz

WORKDIR /app
# Set permission executable for script
RUN chmod a+x run-griddb.sh

# Run sample
CMD ["/bin/bash", "run-griddb.sh"]

そして、これがシンプルな run-griddb.sh スクリプトです。このスクリプトは基本的に、GridDBのDockerコンテナに接続するための適切な引数とともに、nodeコマンドを実行します。

#!/bin/bash

if [ -z "$GRIDDB_CLUSTER_NAME" ]; then
    GRIDDB_CLUSTER_NAME='dockerGridDB'
fi

if [ -z "$NOTIFICATION_ADDRESS" ]; then
    NOTIFICATION_ADDRESS=239.0.0.1
fi

if [ -z "$NOTIFICATION_PORT" ]; then
    NOTIFICATION_PORT=31999
fi

if [ -z "$GRIDDB_USERNAME" ]; then
    GRIDDB_USERNAME='admin'
fi

if [ -z "$GRIDDB_PASSWORD" ]; then
    GRIDDB_PASSWORD='admin'
fi

if [ -z "$IP_NOTIFICATION_MEMBER" ]; then
    echo "Run GridDB node_api client with GridDB server mode MULTICAST : $NOTIFICATION_ADDRESS $NOTIFICATION_PORT $GRIDDB_CLUSTER_NAME $GRIDDB_USERNAME $GRIDDB_PASSWORD"
    source ~/.nvm/nvm.sh && nvm use 20
    node sample1.js $NOTIFICATION_ADDRESS $NOTIFICATION_PORT $GRIDDB_CLUSTER_NAME $GRIDDB_USERNAME $GRIDDB_PASSWORD
else
    echo "Run GridDB node_api client with GridDB server mode FixedList : $IP_NOTIFICATION_MEMBER:10001 $GRIDDB_CLUSTER_NAME $GRIDDB_USERNAME $GRIDDB_PASSWORD"
    source ~/.nvm/nvm.sh && nvm use 20.
    node gen-data.js $IP_NOTIFICATION_MEMBER:10001 $GRIDDB_CLUSTER_NAME $GRIDDB_USERNAME $GRIDDB_PASSWORD
fi
$ docker build -t nodejs-gen-griddb .

現在のDockerfileは「nodejs-gen-griddb」というタグで構築しています。次に、接続情報を指定して実行します。

$ docker run  --network griddb-net -e GRIDDB_CLUSTER_NAME=myCluster -e GRIDDB_USERNAME=admin -e GRIDDB_PASSWORD=admin -e IP_NOTIFICATION_MEMBER=griddb-server nodejs-gen-griddb 

JDBC

JavaとJDBCを使用してGridDBサーバーに接続し、SQLコマンドを実行する別の例を紹介します。

まず、Javaプログラムを作成します。ここでは、単に接続を行い、新しいテーブルを作成します。

    String notificationMember = args[0];
    String clusterName = args[1];
    String databaseName = args[2];
    // String notificationMember = "griddb-server:20001";
    // String clusterName = "myCluster";
    // String databaseName = "public";
    String username = "admin";
    String password = "admin";
    String encodeClusterName = URLEncoder.encode(clusterName, "UTF-8");
    String encodeDatabaseName = URLEncoder.encode(databaseName, "UTF-8");
    String jdbcUrl = "jdbc:gs://" + notificationMember + "/" + encodeClusterName + "/" + encodeDatabaseName;
    System.out.println(jdbcUrl);

    Properties prop = new Properties();
    prop.setProperty("user", username);
    prop.setProperty("password", password);

    con = DriverManager.getConnection(jdbcUrl, prop);

    System.out.println("Connected to cluster via SQL Interface");

    String SQL = "CREATE TABLE IF NOT EXISTS devices (ts TIMESTAMP PRIMARY KEY, co DOUBLE, humidity DOUBLE,light BOOL,lpg DOUBLE,motion BOOL,smoke DOUBLE,temp DOUBLE) USING TIMESERIES WITH (expiration_type='PARTITION',expiration_time=90,expiration_time_unit='DAY') PARTITION BY RANGE (ts) EVERY (60, DAY)SUBPARTITION BY HASH (ts) SUBPARTITIONS 64;";

    Statement stmt = con.createStatement();
    stmt.executeUpdate(SQL);
    System.out.println("Successfully created container called: devices");

そして、GridDBサーバー上で実行するJavaプログラムをビルドするためのdockerfileを作成します。

FROM alpine:3.14

WORKDIR /app
RUN apk add --no-cache wget
RUN apk add openjdk11

RUN wget https://repo1.maven.org/maven2/com/github/griddb/gridstore-jdbc/5.6.0/gridstore-jdbc-5.6.0.jar
ENV CLASSPATH /app/gridstore-jdbc-5.6.0.jar

COPY ./src ./src
WORKDIR /app/src/main/java/
RUN javac net/griddb/jdbc/Jdbc.java

CMD ["java",  "net/griddb/jdbc/Jdbc.java", "griddb-server:20001", "myCluster", "public"]

このビルドプロセスでは、Javaとwgetをインストールし、最新のGridDB JDBCドライバをダウンロードし、クラスパス環境に追加し、Javaコードをコンパイルして実行します。すべてがうまくいけば、Dockerイメージを実行し、ネットワークをGridDBサーバーが接続されている場所と等しく設定して、そのように動作させることができるはずです。

この場合、コマンドライン引数をDockerfile自体に残したままにしています。つまり、コードの実行方法を柔軟に変更できるということです。

まとめ

これで、ARMデバイス上でnodejsとJDBCコンテナの両方を実行できるようになりました。他のプログラミング言語を実行できるようになった場合は、GridDBフォーラムまでお知らせください。 https://forum.griddb.net

ブログの内容について疑問や質問がある場合は Q&A サイトである Stack Overflow に質問を投稿しましょう。 GridDB 開発者やエンジニアから速やかな回答が得られるようにするためにも "griddb" タグをつけることをお忘れなく。 https://stackoverflow.com/questions/ask?tags=griddb

Leave a Reply

Your email address will not be published. Required fields are marked *