以前、Infinispan ServerとDockerを使ってこんなエントリを書きました。
Infinispan ServerのDockerイメージを作って、クラスタを構成してみる - CLOVER
この時は、こんな感じで「--net=host」を指定して実行していました。
## Node 1 $ docker run -it --rm --net=host infinispan-server:7.2.3 -Djboss.node.name=node1 ## Node 2 $ docker run -it --rm --net=host infinispan-server:7.2.3 -Djboss.socket.binding.port-offset=1000 -Djboss.node.name=node2 ## Node 3 $ docker run -it --rm --net=host infinispan-server:7.2.3 -Djboss.socket.binding.port-offset=2000 -Djboss.node.name=node3
が、これをもうちょっとどうにかならないかな?ということで、調べてみました。
結論としては、できました。以降、試した順番とは逆になりますが、結果を書いていってみます。
Infinispan Server/WildFly
1番てこずったのがこれですが、なんとかなりました。
参考にしたのは、このあたり。
Wildfly cluster in docker? |JBoss Developer
3.2.8. クラスタリングの変更 - Red Hat Customer Portal
Marek Goldmann | WildFly cluster using Docker on Fedora
結論としては、以下のパラメーターで細工をすればいいみたいです。
-Djboss.bind.address=[IPアドレス]
バインドするIPアドレスを指定してねってことですと。
※「-Djboss.bind.address=」は、「-b=」でもOKです
自動的にやるには、こんな感じ。
-Djboss.bind.address=`hostname -I`
そんなわけで、Dockerfileとしてはこのように作成しました。対象は、Infinispan Serverです。
Dockerfile
FROM java:8 ENV INFINISPAN_VERSION 8.0.1.Final RUN mkdir -p /opt/infinispan WORKDIR /opt/infinispan RUN wget -q http://downloads.jboss.org/infinispan/$INFINISPAN_VERSION/infinispan-server-$INFINISPAN_VERSION-bin.zip && \ unzip infinispan-server-$INFINISPAN_VERSION-bin.zip && \ mv infinispan-server-$INFINISPAN_VERSION infinispan-server && \ chmod +x infinispan-server/bin/standalone.sh RUN perl -wpi -e 's/-Xms\d+[a-z]/-Xms1g/g; s/-Xmx\d+[a-z]/-Xmx1g/g' infinispan-server/bin/standalone.conf* EXPOSE 8080 8181 9990 11211 11222 ADD start-clustered-server.sh start-clustered-server.sh RUN chmod a+x start-clustered-server.sh ENTRYPOINT ["./start-clustered-server.sh"]
デフォルトのメモリが低めで、Infinispan Server 8系からどうもclustered.shがなくなったみたいなので、ちょっとヒープを広げています。
RUN perl -wpi -e 's/-Xms\d+[a-z]/-Xms1g/g; s/-Xmx\d+[a-z]/-Xmx1g/g' infinispan-server/bin/standalone.conf*
start-clustered-server.shというのは、こんな内容で書いています。
start-clustered-server.sh
#!/bin/bash infinispan-server/bin/standalone.sh -c clustered.xml -Djboss.bind.address=`hostname -I` "$@"
これでビルドして
$ docker build -t kazuhira/infinispan-server-clustered:8.0.1 .
起動してみます。
## Node 1 $ docker run -it --rm -p 8080 -p 8181 -p 9990 -p 11211 -p 11222 kazuhira/infinispan-server-clustered:8.0.1 ## Node 2 $ docker run -it --rm -p 8080 -p 8181 -p 9990 -p 11211 -p 11222 kazuhira/infinispan-server-clustered:8.0.1
起動すると、ちゃんとクラスタが構成されてくれます。
14:21:33,130 INFO [org.infinispan.CLUSTER] (remote-thread--p2-t8) ISPN000310: Starting cluster-wide rebalance for cache default, topology CacheTopology{id=1, rebalanceId=1, currentCH=DefaultConsistentHash{ns=20, owners = (1)[2985f8e1a401: 20+0]}, pendingCH=DefaultConsistentHash{ns=20, owners = (2)[2985f8e1a401: 10+10, aa1b078b65f4: 10+10]}, unionCH=null, actualMembers=[2985f8e1a401, aa1b078b65f4]}
「-Djboss.bind.address」もしくは「-b」を指定しないと、個々のNodeが孤立してしまいます…。
あと、デフォルトで付与されていますが、「-Djava.net.preferIPv4Stack=true」も重要だと思われます。
動作確認。「11211」ポートにバインドされている、memcachedのポートを探します。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES be79fb0b6176 kazuhira/infinispan-server-clustered:8.0.1 "./start-clustered-se" 2 minutes ago Up 2 minutes 0.0.0.0:32832->8080/tcp, 0.0.0.0:32831->8181/tcp, 0.0.0.0:32830->9990/tcp, 0.0.0.0:32829->11211/tcp, 0.0.0.0:32828->11222/tcp loving_banach d633257fb4d6 kazuhira/infinispan-server-clustered:8.0.1 "./start-clustered-se" 2 minutes ago Up 2 minutes 0.0.0.0:32827->8080/tcp, 0.0.0.0:32826->8181/tcp, 0.0.0.0:32825->9990/tcp, 0.0.0.0:32824->11211/tcp, 0.0.0.0:32823->11222/tcp jolly_noyce
「32829」と「32824」ですね。
## set $ telnet localhost 32829 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. set key1 0 600 6 value1 STORED quit Connection closed by foreign host. ## get $ telnet localhost 32824 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. get key1 VALUE key1 0 6 value1 END quit Connection closed by foreign host.
OKそうですね。
一応、このDockerイメージについては、Docker Hubにpushしてあります。
https://hub.docker.com/r/kazuhira/infinispan-server-clustered/
Infinispan(Embedded Mode)
続いて、InfinispanのEmbedded Mode。
こちらは、システムプロパティ
-Djava.net.preferIPv4Stack=true
が付与されていればOKです。
こんなコードで確認しました。
設定ファイル。
infinispan.xml
<?xml version="1.0" encoding="UTF-8"?> <infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:infinispan:config:8.0 http://www.infinispan.org/schemas/infinispan-config-8.0.xsd" xmlns="urn:infinispan:config:8.0"> <jgroups> <stack-file name="udp" path="default-configs/default-jgroups-udp.xml"/> </jgroups> <cache-container name="cacheManager" shutdown-hook="REGISTER"> <transport cluster="cluster" stack="udp"/> <jmx duplicate-domains="true"/> <distributed-cache name="distCache"/> </cache-container> </infinispan>
import org.infinispan.*; import org.infinispan.manager.*; public class Server { public static void main(String... args) throws Exception { EmbeddedCacheManager manager = new DefaultCacheManager("infinispan.xml"); manager.getCache("distCache"); System.console().readLine(); } }
「-Djava.net.preferIPv4Stack=true」が設定されていなかった場合は、クラスタが構成されませんでした…。
Hazelcast
めっちゃ簡単で、特に何もせずともクラスタ構成可能でした。
以下のDockerイメージを、そのまま使っても大丈夫です。
https://hub.docker.com/r/hazelcast/hazelcast/
起動。
## Node 1 $ docker run -it --rm -p 5701 hazelcast/hazelcast ## Node 2 $ docker run -it --rm -p 5701 hazelcast/hazelcast
ごく普通にクラスタが構成されます。
Members [2] { Member [172.17.0.60]:5701 this Member [172.17.0.59]:5701 }
HazelcastのDockerイメージでの起動コマンドは、こんな感じです。
echo "Process id for hazelcast instance is written to location: " $PID_FILE $RUN_JAVA -server $JAVA_OPTS com.hazelcast.core.server.StartServer &
ごく普通に起動しているだけで、「-Djava.net.preferIPv4Stack=true」がなくてもクラスタ構成可能みたいです。
実際、自分で同じような簡単なプログラムを書いてDockerコンテナに載せて動かしても、クラスタが構成できました。
この差は、なんでしょうね…。
まあいいのですが。そういえば、Hazelcastでできるということは、PayaraでもDockerでクラスタが組めるということですね!
(ホストが異なる場合はわかりませんけど)
こちらも、動作確認。同じくmemcachedプロトコルで行います。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 423d721c1390 hazelcast/hazelcast "/bin/sh -c 'java -cp" 29 seconds ago Up 28 seconds 0.0.0.0:32834->5701/tcp hungry_einstein 7795f8a855b4 hazelcast/hazelcast "/bin/sh -c 'java -cp" 40 seconds ago Up 39 seconds 0.0.0.0:32833->5701/tcp elated_carson
「32834」と「32833」を使えばよさそうです。
set、get。
## set $ telnet localhost 32834 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. set key1 0 600 6 value1 STORED quit Connection closed by foreign host. ## get $ telnet localhost 32833 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. get key1 VALUE key1 0 6 value1 END quit Connection closed by foreign host.
こちらもOKそうです。