intra-mart IMBox用CassandraをDockerで立てよう

# 概要

intra-mart の[IMBox](http://www.intra-mart.jp/download/product/iap/imbox/imbox_administrator_guide/texts/about/about.html)を利用するにあたり、
Cassandraサーバをたてる必要がありますが、これをDockerでやろうというものです。

## なぜ自作しようとしたのか

DockerHubでCassandraを探しますと、もちろんオフィシャルイメージがあります。
![https   hub.docker.com _ cassandra .png](https://qiita-image-store.s3.amazonaws.com/0/111676/9d383433-d9ff-6690-9434-08bdf4d719ca.png)


[intra-mart Accel Platform Cassandra管理者ガイド 第14版 2016-04-01](http://www.intra-mart.jp/document/library/iap/public/imbox/cassandra_administrator_guide/texts/install/get-cassandra.html)によりますと、
以下のように記述してあります。

> 注意
> 2015年7月現在のApacheCassandraの最新版は、2.1.8ですが、
> 1.2～2.1は、intra-mart Accel Platformで利用しているCassandraのライブラリがサポートしていないため、
> 現状は、1.1台の最新の**1.1.12**をご利用ください。
> Cassandraのバージョンアップに関しては、 Cassandraのバージョンアップ を参照してください。

なんということでしょう！　古すぎてオフィシャルではイメージが提供されていないようです。

*筆者注１：　2016/06/27現在、Cassandraの最新は3.7です。*
*筆者注２：「Cassandra管理者ガイド 第14版 2016-04-01」を参照しているつもりですが、"2015年7月現在"とドキュメントのリリース日より半年以上も古いのは気になります。*

というわけで、1.1.12のCassandraを使うために、泣く泣く自作することにしました。
intra-martの本家の人が提供してくれたらいいのに、と思うこのごろです。docker-compose.ymlとか公開されないかなー。

## 環境

試したCassandraの環境は以下の通りです。

|application|version|説明|
|-----------|-------|----|
|Cassandra  | 1.1.12|Apache公式サイトから入手|
|Java       |OpenJDK1.8.| java:8-jdk-alpineイメージ付属のもの|

とりあえずintra-martの管理者ガイドやセットアップガイドをもとに環境を作成する。
クラスタを組む場合やデータの永続化については今は考えないものとする。

[iAP2015Summer Apache Cassandra システム要件](http://accel-archives.intra-mart.jp/2015-summer/document/iap/public/iap_release_note/texts/support_environment/cassandra.html)によると、
JDKのバージョンは、JDK8u51 以上、という記載があるので、OpenJDK8にしてみた。（Cassandra自体は7でも動く模様）

# Docker化するにあたり

## IMBox用設定

IMBox用には、接続認証設定と、キースペースの作成方法（認証設定ありの場合）がポイントになります。

[Cassandra への接続認証設定](http://www.intra-mart.jp/document/library/iap/public/imbox/cassandra_administrator_guide/texts/authentication/index.html#for-linux)に従って、認証ライブラリの取得、展開から認証設定の追加を行います。

あわせて、[キースペースの作成方法 (認証設定ありの場合)](http://www.intra-mart.jp/document/library/iap/public/imbox/cassandra_administrator_guide/texts/maintenance/index.html#maintenance-addkeyspace)に従って、access.propertiesの記述を行います。
おなじみのaoyagiユーザで作成しています。

Dockerfileとしてはこんな感じになりました。

```Dockerfile
FROM java:7-jdk-alpine

ENV CASSANDRA_VER 1.1.12

# Install Cassandra
RUN apk add --no-cache libc6-compat bash && \
    apk add --virtual=dependencies --no-cache wget unzip && \
    wget http://archive.apache.org/dist/cassandra/${CASSANDRA_VER}/apache-cassandra-${CASSANDRA_VER}-bin.tar.gz && \
    tar xvzf apache-cassandra-${CASSANDRA_VER}-bin.tar.gz -C /usr/local && \
    ln -s /usr/local/apache-cassandra-1.1.12 /usr/local/cassandra && \
    rm -f apache-cassandra-${CASSANDRA_VER}-bin.tar.gz

# Copy files
COPY ./config/* /usr/local/cassandra/conf/
COPY entrypoint.sh /usr/local/cassandra/

# Authentication Settings
RUN wget http://www.intra-mart.jp/download/product/iap/imbox/cassandra_simple_auth.zip && \
    unzip cassandra_simple_auth.zip -d /tmp/cassandra && \
    rm -f cassandra_simple_auth.zip && \
    apk del dependencies && \
    cp /tmp/cassandra/lib/*.jar /usr/local/cassandra/lib/ && \
    cp /tmp/cassandra/conf/*.properties /usr/local/cassandra/conf/ && \
    rm -rf /tmp/cassandra && \
    echo "aoyagi=aoyagi_pwd" >> /usr/local/cassandra/conf/passwd.properties && \
    echo "\n #IMBox settings" >> /usr/local/cassandra/conf/access.properties && \
    echo "imbox_keyspace.<rw>=aoyagi" >> /usr/local/cassandra/conf/access.properties && \
    echo "imbox_keyspace.<ro>=user" >> /usr/local/cassandra/conf/access.properties && \
    echo "imbox_keyspace.*.<rw>=aoyagi" >> /usr/local/cassandra/conf/access.properties && \
    echo "imbox_keyspace.*.<ro>=user" >> /usr/local/cassandra/conf/access.properties && \
    chmod +x /usr/local/cassandra/entrypoint.sh

ENTRYPOINT ["/usr/local/cassandra/entrypoint.sh"]


# 7199: jmx port
# 9160: cassandra port
EXPOSE 7199 9160
```

## 待ち受けポートの設定

conf/cassandra.ymlで、待ち受けのListenAddressを0.0.0.0にしておきます。
コンテナで割り当てられる172.17.0.xといったアドレスからでも、ホストからでも、という観点です。

```yaml
# The address to bind the Thrift RPC service to -- clients connect
# here. Unlike ListenAddress above, you *can* specify 0.0.0.0 here if
# you want Thrift to listen on all interfaces.
# 
# Leaving this blank has the same effect it does for ListenAddress,
# (i.e. it will be based on the configured hostname of the node).
rpc_address: 0.0.0.0
# port for Thrift to listen for clients on
rpc_port: 9160
```

# Cassandraコンテナの起動


-e CLUSTER_NAMEでクラスタ名を渡してやります。コンテナ起動時にimbox_keyspaceというキースペースを（存在しなければ）作成します。

- intra-mart（resin）もコンテナで、コンテナ間のリンクでやる場合

[メモリの設定](http://www.intra-mart.jp/document/library/iap/public/imbox/cassandra_administrator_guide/texts/install/linux.html#id5)に従って、最大ヒープサイズは自動設定されます。


```sh
docker run -d -it --name cassandra -e CLUSTER_NAME="TestCluster" tsgkadot/imbox-cassandra
```

- 使用メモリサイズも指定したい場合

**MAX_HEAP_SIZEとHEAP_NEWSIZEはセットで指定する必要があります。**
どちらか一方ではエラーとなります。

```sh
docker run -d -it --name cassandra -e CLUSTER_NAME="TestCluster" -e MAX_HEAP_SIZE=1G -e HEAP_NEWSIZE=256
m tsgkadot/imbox-cassandra
```

- Dockerのホストで通信したい場合(port 9601で通信するものとする）

```sh
docker run -d -it --name cassandra -p 9601:9601 -e CLUSTER_NAME="TestCluster" tsgkadot/imbox-cassandra
```


起動したあと、コンテナのログを確認します。
```
docker logs cassandra | tail -n 10
```
表示されるログはこんな風になります。
起動時にimbox_keyspaceが存在するかどうかを確認して、 not_foundだったので、create keyspaceをしています。
```
Check keyspaces...
Connected to: "TestCluster" on 6359a19ac14b/9160
Line 1 => Keyspace 'imbox_keyspace' not found.
Connected to: "TestCluster" on 6359a19ac14b/9160
bee71ee6-5310-3bcc-be67-99313e1b81b0
Waiting for schema agreement...
... schemas agree across the cluster
Create imbox_keyspace
DONE!
```

*keyspaceやユーザ/パスワードは、コンテナ起動時に設定として渡したいところですが、無精につき未対応。*

# intra-martコンテナの起動

[intra-martが起動するDockerコンテナを作成する。alpineで。](http://qiita.com/kirareyaku/items/8564013885f23528b973)　で作成したコンテナを使用する場合、こんな感じになります。

--linkでcassandraのコンテナを渡します。

```sh
docker run -it -d --name imart -p 8080:8080 --link cassandra:cassandra --link postgres:postgres -
v /home/intramart/war/:/opt/resin/webapps -v /home/intramart/lib/:/opt/resin/webapp-jars imart-base:4.0.48
```

## テナントセットアップ

テナントセットアップ画面にて、Cassandra接続情報の画面で、以下のように入力します。

|ラベル | 値 | 説明 |
|:----------|-------------|------------------------------------------------------------------------------------:|
| クラスタ名 | TestCluster |Cassandraコンテナ起動時に渡した CLUSTER_NAMEの文字列の値                                |
|キースペース|imbox_keyspace|コンテナ起動時に生成されるキースペース名。             |
|接続先|cassandra:9160| --link cassandra:cassandraでCassandraコンテナにこの名前でアクセスできるようになっているはず。 |
|レプリケーションファクタ|1|デフォルト値|
|認証情報設定| checked | 認証情報設定を行っているので、チェックします。|
|認証ユーザ名| aoyagi | aoyagiユーザを作成しているので、これを利用します。|
|認証パスワード| aoyagi_pwd | aoyagiユーザを作成しているので、これを利用します。|

「テスト接続」ボタンを押下して、接続ができることを確認します。

RPCのListernAddressをlocalhostや127.0.0.1などに設定していた場合、ここでCassandraに接続できません、というエラーになります。

![tenantSetting.png](https://qiita-image-store.s3.amazonaws.com/0/111676/c4e6e291-03a9-f130-282d-b871d461f5b4.png)



# IMBox用の設定と動作確認

IMBoxをメニューから開くためには、少なくとも以下のような設定が必要なようです。

- 対象ユーザがIMBoxを使える会社の組織に**主所属として所属**していること
- ログインユーザの**所属組織に認可の参照権限が付与**されていること

動かない場合は、[トラブルシュート](http://www.intra-mart.jp/document/library/iap/public/imbox/imbox_specification/texts/appendix/trouble_shooting.html#cassandra)を見ながら、原因をつぶします。

動作確認は、ログイン後にグローバルメニュー「Top」-「IMBox」を選択して、IMBoxの画面を開きます。

![CompanyBox.png](https://qiita-image-store.s3.amazonaws.com/0/111676/6c78588b-700f-434e-bd5e-d186b5941e53.png)

おおお、森大輔郎さん(Usercd=U11110)でIMBoxの画面が開けました。

# おまけ

Dockerfile以外に変更したもの、entrypoint.shの中身については、以下を参照してください。

- [imbox-cassandra](https://hub.docker.com/r/tsgkadot/imbox-cassandra/)