これは、なにをしたくて書いたもの?
- Infinispan Serverを、OKD(Kubernetes)上にデプロイして、クラスタを構成してみたい
- Node Discoveryの方法は、マルチキャストではなく別の方法を使うのが通例のようなので、そちらの確認も
- KubernetesのAPIを使う方法と、DNSを使う方法があるらしい
今回は、OKDにデプロイして、DNSを使ったNode Discoveryでクラスタを構成してみます。
環境
今回の環境は、こちら。
$ minishift version minishift v1.29.0+72fa7b2 $ oc version oc v3.11.0+0cbc58b kubernetes v1.11.0+d4cacc0 features: Basic-Auth GSSAPI Kerberos SPNEGO Server https://192.168.42.138:8443 kubernetes v1.11.0+d4cacc0
また、Infinispan ServerはDockerHubにあるDockerイメージを使用することにします。
DockerHub / jboss/infinispan-server
バージョンは、9.4.4.Finalです。
https://github.com/jboss-dockerfiles/infinispan/tree/9.4.4.Final/server
InfinispanのKubernetes(OpenShift)へのデプロイ方法
「Infinispan OpenShift」あたりのキーワードで探すと、以下のようなエントリが見つかります。
Infinispan: Configuration management on OpenShift, Kubernetes and Docker
Infinispan: Running Infinispan cluster on OpenShift
OpenShift/Kubernetes tutorial - Infinispan
これらは、いずれもJGroupsのKUBE_PINGを使った構成です。
Running on Cloud Services / Kubernetes and OpenShift
GitHub - jgroups-extras/jgroups-kubernetes: JGroups discovery protocol for Kubernetes
JGroups / Initial membership discovery / KUBE_PING
JGroupsを使ってKubernetes上でNode Discoveryを行う場合は、DNS_PINGも使用することができます。
JGroups / Initial membership discovery / DNS_PING
Infinispan側のNode Discoveryのドキュメントには、特に書かれていませんが…。
JGroups側のドキュメントにあるとおり、DNS_PINGをKubernetes上で使う場合にはHeadless Serviceを作成する必要が
あります。
In order to enable DNS discovery for application deployed on Kubernetes/OpenShift one must create a Governing Headless Service with proper selectors covering desired pods. The service will ensure that DNS entries are populated as soon as pods are in Ready state.
Headless Serviceとは、Kubernetes内でロードバランシングのためのIP(ClusterIP)を持たないServiceで、DNS Round Robinを
使ったエンドポイントを提供するもののようです。
今回は、こちらを使ってInfinispan ServerをOKD(Kubernetes)内でクラスタリングしてみたいと思います。
参考)
OpenShiftでJBossクラスタを構成する仕組み - 見習いプログラミング日記
https://github.com/jboss-openshift/openshift-ping
なお、JGroups自身に含まれるDNS_PINGは、こちらの模様。
https://github.com/belaban/JGroups/tree/JGroups-4.0.15.Final/src/org/jgroups/protocols/dns
構成
DNS_PINGを使うということで、OKD内にHeadless Serviceを作成する必要があります。
ですが、動作確認やクラスタの構成状態をInfinispan Serverの管理コンソール上からも確認したいので、次のような
構成にしてみたいと思います。
RouteからはPodへ直接ルーティングするので、図中のServiceからPodへの線は省略しています。
また、Infinispan Serverのイメージには、DNS_PINGを使用した設定は含まれていないため、あらかじめ含まれている
cloud.xmlをコピー&修正し、DNS_PINGを追加した設定ファイルをConfigMapからボリュームとしてマウントする
方針でやってみたいと思います。
定義は、全部YAMLで書きます。だいぶ長くなるので、途中の説明では省略して載せるものもありますが、それらは
最後にまとめて記載しておきます。また、YAMLの中身は定義するリソースごとに「---」で区切り、複数のリソース定義が
含まれてるひとつのYAMLファイルで記載しました。
Infinispan Serverに含まれる、cloud.xmlを入手する
Infinispan Serverのディストリビューションのzipファイルから取り出してもいいのですが、今回は「oc cp」で取得してみましょう。
Infinispan ServerのDockerイメージをOKDにデプロイして、「oc cp」でpodからcloud.xmlをコピー。
$ oc new-app jboss/infinispan-server:9.4.4.Final $ oc cp infinispan-server-1-29g95:/opt/jboss/infinispan-server/standalone/configuration/cloud.xml cloud.xml
要らなくなったリソースは、削除。
$ oc delete all --all pod "infinispan-server-1-29g95" deleted replicationcontroller "infinispan-server-1" deleted service "infinispan-server" deleted deploymentconfig.apps.openshift.io "infinispan-server" deleted imagestream.image.openshift.io "infinispan-server" deleted
ここで手に入れたcloud.xmlを編集して、DNS_PINGを追加したいと思います。
ConfigMap
まずは、ConfigMap。ここで、DNS_PINGを使えるようにJGroupsのProtocol Stackを定義します。
ConfigMapに、cloud.xmlの内容を貼り付けて編集します。キー名は、「cloud-custom.xml」としました。
--- ## ConfigMap apiVersion: v1 kind: ConfigMap metadata: name: infinispan-server-configmap data: cloud-custom.xml: | <?xml version='1.0' encoding='UTF-8'?> <server xmlns="urn:jboss:domain:8.0"> <extensions> <extension module="org.infinispan.extension"/> <extension module="org.infinispan.server.endpoint"/> <extension module="org.jboss.as.connector"/> <extension module="org.jboss.as.deployment-scanner"/> <extension module="org.jboss.as.jdr"/> <extension module="org.jboss.as.jmx"/> <extension module="org.jboss.as.logging"/> <extension module="org.jboss.as.naming"/> <extension module="org.jboss.as.remoting"/> <extension module="org.jboss.as.security"/> <extension module="org.jboss.as.transactions"/> <extension module="org.jgroups.extension"/> <extension module="org.wildfly.extension.elytron"/> <extension module="org.wildfly.extension.io"/> </extensions> 〜省略〜 <subsystem xmlns="urn:infinispan:server:jgroups:9.4"> <channels default="cluster"> <channel name="cluster"/> </channels> <stacks default="${jboss.default.jgroups.stack:dns}"> <stack name="dns"> <transport type="TCP" socket-binding="jgroups-tcp"> <property name="logical_addr_cache_expiration">360000</property> </transport> <protocol type="dns.DNS_PING"> <property name="dns_query">${dns.ping.name:infinispan-server-ping}</property> </protocol> <protocol type="MERGE3"/> <protocol type="FD_SOCK" socket-binding="jgroups-tcp-fd"/> <protocol type="FD_ALL"/> <protocol type="VERIFY_SUSPECT"/> <protocol type="pbcast.NAKACK2"> <property name="use_mcast_xmit">false</property> </protocol> <protocol type="UNICAST3"/> <protocol type="pbcast.STABLE"/> <protocol type="pbcast.GMS"/> <protocol type="MFC"/> <protocol type="FRAG3"/> </stack> <stack name="kubernetes"> <transport type="TCP" socket-binding="jgroups-tcp"> <property name="logical_addr_cache_expiration">360000</property> </transport> <protocol type="kubernetes.KUBE_PING"/> <protocol type="MERGE3"/> <protocol type="FD_SOCK" socket-binding="jgroups-tcp-fd"/> <protocol type="FD_ALL"/> <protocol type="VERIFY_SUSPECT"/> <protocol type="pbcast.NAKACK2"> <property name="use_mcast_xmit">false</property> </protocol> <protocol type="UNICAST3"/> <protocol type="pbcast.STABLE"/> <protocol type="pbcast.GMS"/> <protocol type="MFC"/> <protocol type="FRAG3"/> </stack> </stacks> </subsystem> 〜省略〜
オリジナルのcloud.xmlに含まれるJGroupsサブシステムには、GossipRouterだったり、Azure向けだったり、AWS向けだったり
いろいろな定義が入っているのですが、今回はばっさり削除してDNS_PINGとKUBE_PINGだけ残しました。
※KUBE_PINGも使わないのですが…
デフォルトのProtocol Stackを「dns」にして
<stacks default="${jboss.default.jgroups.stack:dns}">
「dns.DNS_PING」を使うように設定。DNSクエリの内容は「infinispan-server-ping」という名前をデフォルトにしていますが、
これは後に定義するHeadless Serviceの名前になります。
<stack name="dns"> <transport type="TCP" socket-binding="jgroups-tcp"> <property name="logical_addr_cache_expiration">360000</property> </transport> <protocol type="dns.DNS_PING"> <property name="dns_query">${dns.ping.name:infinispan-server-ping}</property> </protocol>
protocol以外の定義は、他のProtocol Stackの内容をそのままコピーしただけです。
ImageStream
DockerHubから、Infinispan Serverのイメージを取得するように、ImageStreamを定義。
--- ## ImageStream apiVersion: v1 kind: ImageStream metadata: labels: app: infinispan-server name: infinispan-server spec: lookupPolicy: local: false tags: - from: kind: DockerImage name: jboss/infinispan-server:9.4.4.Final name: 9.4.4.Final referencePolicy: type: Source
DeploymentConfig
--- ## DeploymentConfig apiVersion: v1 kind: DeploymentConfig metadata: labels: app: infinispan-server name: infinispan-server spec: replicas: 3 〜省略〜 template: metadata: 〜省略〜 spec: containers: - image: jboss/infinispan-server:latest name: infinispan-server ports: - containerPort: 8181 protocol: TCP 〜省略〜 - containerPort: 8080 protocol: TCP env: - name: MGMT_USER value: ispn-admin - name: MGMT_PASS value: admin-password - name: APP_USER value: ispn-user - name: APP_PASS value: user-password args: - -c - custom/cloud.xml volumeMounts: - name: config mountPath: /opt/jboss/infinispan-server/standalone/configuration/custom volumes: - name: config configMap: name: infinispan-server-configmap items: - key: cloud-custom.xml path: cloud.xml 〜省略〜
先ほどConfigMapで定義した、「cloud-custom.xml」を「/opt/jboss/infinispan-server/standalone/configuration/custom/cloud.xml」
としてマウントします。
volumeMounts: - name: config mountPath: /opt/jboss/infinispan-server/standalone/configuration/custom volumes: - name: config configMap: name: infinispan-server-configmap items: - key: cloud-custom.xml path: cloud.xml
で、この設定ファイルを使うために、起動引数を指定します。
args: - -c - custom/cloud.xml
このあたりは、Infinispan Serverの管理ユーザー(Management Consoleで使う)と、アプリケーションユーザー(REST Cacheへの
アクセスで使う)の定義です。
※本来ならSecretsとか使うところでしょうが、今回は端折りました…
env: - name: MGMT_USER value: ispn-admin - name: MGMT_PASS value: admin-password - name: APP_USER value: ispn-user - name: APP_PASS value: user-password
Replica数は3にしてあり、クラスタがうまく構成できた場合には、Nodeが3となる想定となります。
spec: replicas: 3
Headless Service
DNSによるNode Discoveryで使用する、Headless Serviceの定義。
--- ## Service Ping apiVersion: v1 kind: Service metadata: labels: app: infinispan-server name: infinispan-server-ping spec: ports: - name: 7600-tcp port: 7600 protocol: TCP targetPort: 7600 - name: 8080-tcp port: 8080 protocol: TCP targetPort: 8080 - name: 8181-tcp port: 8181 protocol: TCP targetPort: 8181 - name: 8888-tcp port: 8888 protocol: TCP targetPort: 8888 - name: 9990-tcp port: 9990 protocol: TCP targetPort: 9990 - name: 11211-tcp port: 11211 protocol: TCP targetPort: 11211 - name: 11222-tcp port: 11222 protocol: TCP targetPort: 11222 - name: 57600-tcp port: 57600 protocol: TCP targetPort: 57600 selector: app: infinispan-server deploymentconfig: infinispan-server sessionAffinity: None type: ClusterIP clusterIP: None
ポイントは、「type」を「ClusterIP」とし、「clusterIP」を「None」に設定していることです。
type: ClusterIP clusterIP: None
また、「name」は「infinispan-server-ping」と指定しており、この値をJGroupsの「dns.DNS_PING」での設定に使用しました。
metadata: labels: app: infinispan-server name: infinispan-server-ping
Service
こちらは、通常のロードバランシングのためのServiceです。ですが、実際にはRouteからPodに直接リクエストが転送されるので、
今回はほぼ使いません。
--- ## Service apiVersion: v1 kind: Service metadata: labels: app: infinispan-server name: infinispan-server spec: ports: - name: 7600-tcp port: 7600 protocol: TCP targetPort: 7600 - name: 8080-tcp port: 8080 protocol: TCP targetPort: 8080 - name: 8181-tcp port: 8181 protocol: TCP targetPort: 8181 - name: 8888-tcp port: 8888 protocol: TCP targetPort: 8888 - name: 9990-tcp port: 9990 protocol: TCP targetPort: 9990 - name: 11211-tcp port: 11211 protocol: TCP targetPort: 11211 - name: 11222-tcp port: 11222 protocol: TCP targetPort: 11222 - name: 57600-tcp port: 57600 protocol: TCP targetPort: 57600 selector: app: infinispan-server deploymentconfig: infinispan-server sessionAffinity: None type: ClusterIP
先ほどのHeadless Serviceとの差は、「name」、それから「clusterIP」の指定がないことくらいですね。
Route
最後にRouteです。Serviceのポート8080(REST Cacheへのアクセス用)と、ポート9990(Management Console用)に向けて
2つ作成します。
--- ## Route 8080 apiVersion: v1 kind: Route metadata: labels: app: infinispan-server name: infinispan-server-rest-endpoint spec: port: targetPort: 8080-tcp to: kind: Service name: infinispan-server --- ## Route 9990 apiVersion: v1 kind: Route metadata: labels: app: infinispan-server name: infinispan-server-management-endpoint spec: port: targetPort: 9990-tcp to: kind: Service name: infinispan-server
OKDへのデプロイ
では、ここまで書いてきたYAMLをひとつにまとめて、「oc create」で作成します。
$ oc create -f infinispan-server.yml configmap/infinispan-server-configmap created imagestream.image.openshift.io/infinispan-server created deploymentconfig.apps.openshift.io/infinispan-server created service/infinispan-server created service/infinispan-server-ping created route.route.openshift.io/infinispan-server-rest-endpoint created route.route.openshift.io/infinispan-server-management-endpoint created ## もしくは $ oc apply -f infinispan-server.yml
うまくいけば、「oc logs -f」とかでログを見ていると、クラスタが3 Nodeで構成されたことが確認できます。
$ oc logs -f dc/infinispan-server 12:52:57,368 INFO [org.infinispan.CLUSTER] (MSC service thread 1-2) ISPN000094: Received new cluster view for channel cluster: [infinispan-server-1-fkktq|2] (3) [infinispan-server-1-fkktq, infinispan-server-1-cbfl4, infinispan-server-1-hcmrx]
なお、作成されたリソースは、こんな感じです。
$ oc get all -l app=infinispan-server NAME READY STATUS RESTARTS AGE pod/infinispan-server-1-cbfl4 1/1 Running 0 2m pod/infinispan-server-1-fkktq 1/1 Running 0 2m pod/infinispan-server-1-hcmrx 1/1 Running 0 2m NAME DESIRED CURRENT READY AGE replicationcontroller/infinispan-server-1 3 3 3 2m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/infinispan-server ClusterIP 172.30.127.50 <none> 7600/TCP,8080/TCP,8181/TCP,8888/TCP,9990/TCP,11211/TCP,11222/TCP,57600/TCP 2m service/infinispan-server-ping ClusterIP None <none> 7600/TCP,8080/TCP,8181/TCP,8888/TCP,9990/TCP,11211/TCP,11222/TCP,57600/TCP 2m NAME REVISION DESIRED CURRENT TRIGGERED BY deploymentconfig.apps.openshift.io/infinispan-server 1 3 3 config,image(infinispan-server:9.4.4.Final) NAME DOCKER REPO TAGS UPDATED imagestream.image.openshift.io/infinispan-server 172.30.1.1:5000/myproject/infinispan-server 9.4.4.Final 2 minutes ago NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD route.route.openshift.io/infinispan-server-management-endpoint infinispan-server-management-endpoint-myproject.192.168.42.138.nip.io infinispan-server 9990-tcp None route.route.openshift.io/infinispan-server-rest-endpoint infinispan-server-rest-endpoint-myproject.192.168.42.138.nip.io infinispan-server 8080-tcp None
Serviceについては、ClusterIPが設定されているものと、そうでないもの(Headless Service)の2つができています。
$ oc get svc -l app=infinispan-server NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE infinispan-server ClusterIP 172.30.127.50 <none> 7600/TCP,8080/TCP,8181/TCP,8888/TCP,9990/TCP,11211/TCP,11222/TCP,57600/TCP 2m infinispan-server-ping ClusterIP None <none> 7600/TCP,8080/TCP,8181/TCP,8888/TCP,9990/TCP,11211/TCP,11222/TCP,57600/TCP 2m
ConfigMaps。
$ oc get cm NAME DATA AGE infinispan-server-configmap 1 4m
確認
では、Infinispan Server側でも確認してみましょう。
まずは、Management Consoleにアクセスしてみましょう。
今回のRoute定義だと、「http://infinispan-server-management-endpoint-myproject.192.168.42.138.nip.io」にアクセスします。
「ispn-admin / admin-password」でログインして「Clusters」タブをクリックすると、「# Nodes」の欄が「3」になって
いることが確認できます。
続いて、REST Cacheで確認してみましょう。こちらのエンドポイントは、今回のRoute定義だと
「http://infinispan-server-rest-endpoint-myproject.192.168.42.138.nip.io」となります。
アクセスする際のユーザーは、「ispn-user / user-password」です。
Cache「default」へのPUT。
$ curl -i -u ispn-user:user-password -H 'Content-Type: application/octet-stream' -XPUT infinispan-server-rest-endpoint-myproject.192.168.42.138.nip.io/rest/default/key1 -d 'value1' HTTP/1.1 200 OK etag: 282873 content-length: 0 Set-Cookie: 8d4a0c695072f3e868e215a6a39613bf=98238418a66019e96ee420b1fdd6f2db; path=/; HttpOnly Cache-control: private
Cache「default」からのGET。
$ curl -i -u ispn-user:user-password -H 'Content-Type: application/octet-stream' infinispan-server-rest-endpoint-myproject.192.168.42.138.nip.io/rest/default/key1 HTTP/1.1 200 OK etag: 282873 last-modified: Thu, 1 Jan 1970 00:00:00 GMT content-type: application/octet-stream content-length: 6 Set-Cookie: 8d4a0c695072f3e868e215a6a39613bf=1ab5bbda3b0a54ef51fca2d8a3fd91e7; path=/; HttpOnly Cache-control: private value1
エントリを、もう2つくらい追加してみましょう。
$ curl -i -u ispn-user:user-password -H 'Content-Type: application/octet-st-XPUT infinispan-server-rest-endpoint-myproject.192.168.42.138.nip.io/rest/default/key2 -d 'value2' HTTP/1.1 200 OK etag: 1200749911 content-length: 0 Set-Cookie: 8d4a0c695072f3e868e215a6a39613bf=01ebff39b1b0ff27611c04f7848cb3d9; path=/; HttpOnly Cache-control: private $ curl -i -u ispn-user:user-password -H 'Content-Type: application/octet-st-XPUT infinispan-server-rest-endpoint-myproject.192.168.42.138.nip.io/rest/default/key3 -d 'value3' HTTP/1.1 200 OK etag: 1801018020 content-length: 0 Set-Cookie: 8d4a0c695072f3e868e215a6a39613bf=1ab5bbda3b0a54ef51fca2d8a3fd91e7; path=/; HttpOnly Cache-control: private
Management Consoleで、Cacheの統計情報を見てみます。
3エントリ入っていることが、確認できます。
ところで、このNodeはどこを見ているかというと、こちらのようです。
該当のPodを削除してみます。
$ oc delete pod/infinispan-server-1-fkktq pod "infinispan-server-1-fkktq" deleted
replicasを3にしているので、新しいPodができます。
$ oc get pod NAME READY STATUS RESTARTS AGE infinispan-server-1-cbfl4 1/1 Running 0 17m infinispan-server-1-dkk2t 1/1 Running 0 39s infinispan-server-1-hcmrx 1/1 Running 0 17m
Pod再作成後も、問題なくデータを取得することができました。
※消すのが他のNodeだったり、2つのNodeでもリバランスが終わった後であれば順番に削除していっても大丈夫です
※データは、他のNodeから取得して復元します
$ curl -u ispn-user:user-password -H 'Content-Type: application/octet-stream' infinispan-server-rest-endpoiroject.192.168.42.138.nip.io/rest/default/key1 value1 $ curl -u ispn-user:user-password -H 'Content-Type: application/octet-stream' infinispan-server-rest-endpoint-myproject.192.168.42.138.nip.io/rest/default/key2 $ curl -u ispn-user:user-password -H 'Content-Type: application/octet-stream' infinispan-server-rest-endpoint-myproject.192.168.42.138.nip.io/rest/default/key3 value3
OKそうですね。これで、OKD上でInfinispan ServerをDNS_PINGを使ってクラスタを構成できました、と。
オマケ
今回作成した、YAMLファイルの全体です。
infinispan-server.yml
--- ## ConfigMap apiVersion: v1 kind: ConfigMap metadata: name: infinispan-server-configmap data: cloud-custom.xml: | <?xml version='1.0' encoding='UTF-8'?> <server xmlns="urn:jboss:domain:8.0"> <extensions> <extension module="org.infinispan.extension"/> <extension module="org.infinispan.server.endpoint"/> <extension module="org.jboss.as.connector"/> <extension module="org.jboss.as.deployment-scanner"/> <extension module="org.jboss.as.jdr"/> <extension module="org.jboss.as.jmx"/> <extension module="org.jboss.as.logging"/> <extension module="org.jboss.as.naming"/> <extension module="org.jboss.as.remoting"/> <extension module="org.jboss.as.security"/> <extension module="org.jboss.as.transactions"/> <extension module="org.jgroups.extension"/> <extension module="org.wildfly.extension.elytron"/> <extension module="org.wildfly.extension.io"/> </extensions> <management> <security-realms> <security-realm name="ManagementRealm"> <authentication> <local default-user="$local"/> <properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/> </authentication> <authorization map-groups-to-roles="false"> <properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/> </authorization> </security-realm> <security-realm name="ApplicationRealm"> <server-identities> <ssl> <keystore path="application.keystore" relative-to="jboss.server.config.dir" keystore-password="password" alias="server" key-password="password" generate-self-signed-certificate-host="localhost"/> </ssl> </server-identities> <authentication> <local default-user="$local" allowed-users="*"/> <properties path="application-users.properties" relative-to="jboss.server.config.dir"/> </authentication> <authorization> <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/> </authorization> </security-realm> </security-realms> <audit-log> <formatters> <json-formatter name="json-formatter"/> </formatters> <handlers> <file-handler name="file" formatter="json-formatter" relative-to="jboss.server.data.dir" path="audit-log.log"/> </handlers> <logger log-boot="true" enabled="false"> <handlers> <handler name="file"/> </handlers> </logger> </audit-log> <management-interfaces> <http-interface security-realm="ManagementRealm"> <http-upgrade enabled="true"/> <socket-binding http="management-http"/> </http-interface> </management-interfaces> <access-control> <role-mapping> <role name="SuperUser"> <include> <user name="$local"/> </include> </role> </role-mapping> </access-control> </management> <profile> <subsystem xmlns="urn:jboss:domain:logging:3.0"> <console-handler name="CONSOLE"> <level name="INFO"/> <formatter> <named-formatter name="COLOR-PATTERN"/> </formatter> </console-handler> <periodic-rotating-file-handler name="FILE" autoflush="true"> <formatter> <named-formatter name="PATTERN"/> </formatter> <file relative-to="jboss.server.log.dir" path="server.log"/> <suffix value=".yyyy-MM-dd"/> <append value="true"/> </periodic-rotating-file-handler> <size-rotating-file-handler name="HR-ACCESS-FILE" autoflush="true"> <formatter> <named-formatter name="ACCESS-LOG"/> </formatter> <file relative-to="jboss.server.log.dir" path="hotrod-access.log"/> <append value="true"/> <rotate-size value="10M"/> <max-backup-index value="10"/> </size-rotating-file-handler> <size-rotating-file-handler name="REST-ACCESS-FILE" autoflush="true"> <formatter> <named-formatter name="ACCESS-LOG"/> </formatter> <file relative-to="jboss.server.log.dir" path="rest-access.log"/> <append value="true"/> <rotate-size value="10M"/> <max-backup-index value="10"/> </size-rotating-file-handler> <logger category="com.arjuna"> <level name="WARN"/> </logger> <logger category="org.jboss.as.config"> <level name="DEBUG"/> </logger> <logger category="sun.rmi"> <level name="WARN"/> </logger> <logger category="org.infinispan.HOTROD_ACCESS_LOG" use-parent-handlers="false"> <!-- Set to TRACE to enable access logging for hot rod or use DMR --> <level name="INFO"/> <handlers> <handler name="HR-ACCESS-FILE"/> </handlers> </logger> <logger category="org.infinispan.REST_ACCESS_LOG" use-parent-handlers="false"> <!-- Set to TRACE to enable access logging for rest or use DMR --> <level name="INFO"/> <handlers> <handler name="REST-ACCESS-FILE"/> </handlers> </logger> <root-logger> <level name="INFO"/> <handlers> <handler name="CONSOLE"/> <handler name="FILE"/> </handlers> </root-logger> <formatter name="PATTERN"> <pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/> </formatter> <formatter name="COLOR-PATTERN"> <pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/> </formatter> <formatter name="ACCESS-LOG"> <pattern-formatter pattern="%X{address} %X{user} [%d{dd/MMM/yyyy:HH:mm:ss z}] "%X{method} %m %X{protocol}" %X{status} %X{requestSize} %X{responseSize} %X{duration}%n"/> </formatter> </subsystem> <subsystem xmlns="urn:jboss:domain:deployment-scanner:2.0"> <deployment-scanner path="deployments" relative-to="jboss.server.base.dir" scan-interval="5000" runtime-failure-causes-rollback="${jboss.deployment.scanner.rollback.on.failure:false}"/> </subsystem> <subsystem xmlns="urn:jboss:domain:datasources:5.0"> <datasources> <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true"> <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url> <driver>h2</driver> <security> <user-name>sa</user-name> <password>sa</password> </security> </datasource> <drivers> <driver name="h2" module="com.h2database.h2"> <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class> </driver> </drivers> </datasources> </subsystem> <subsystem xmlns="urn:wildfly:elytron:4.0" final-providers="combined-providers" disallowed-providers="OracleUcrypto"> <providers> <aggregate-providers name="combined-providers"> <providers name="elytron"/> <providers name="openssl"/> </aggregate-providers> <provider-loader name="elytron" module="org.wildfly.security.elytron"/> <provider-loader name="openssl" module="org.wildfly.openssl"/> </providers> <audit-logging> <file-audit-log name="local-audit" path="audit.log" relative-to="jboss.server.log.dir" format="JSON"/> </audit-logging> <security-domains> <security-domain name="ApplicationDomain" default-realm="ApplicationRealm" permission-mapper="default-permission-mapper"> <realm name="ApplicationRealm" role-decoder="groups-to-roles"/> <realm name="local"/> </security-domain> <security-domain name="ManagementDomain" default-realm="ManagementRealm" permission-mapper="default-permission-mapper"> <realm name="ManagementRealm" role-decoder="groups-to-roles"/> <realm name="local" role-mapper="super-user-mapper"/> </security-domain> </security-domains> <security-realms> <identity-realm name="local" identity="$local"/> <properties-realm name="ApplicationRealm"> <users-properties path="application-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ApplicationRealm"/> <groups-properties path="application-roles.properties" relative-to="jboss.server.config.dir"/> </properties-realm> <properties-realm name="ManagementRealm"> <users-properties path="mgmt-users.properties" relative-to="jboss.server.config.dir" digest-realm-name="ManagementRealm"/> <groups-properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/> </properties-realm> </security-realms> <mappers> <simple-permission-mapper name="default-permission-mapper" mapping-mode="first"> <permission-mapping> <principal name="anonymous"/> <permission-set name="default-permissions"/> </permission-mapping> <permission-mapping match-all="true"> <permission-set name="login-permission"/> <permission-set name="default-permissions"/> </permission-mapping> </simple-permission-mapper> <constant-realm-mapper name="local" realm-name="local"/> <simple-role-decoder name="groups-to-roles" attribute="groups"/> <constant-role-mapper name="super-user-mapper"> <role name="SuperUser"/> </constant-role-mapper> </mappers> <permission-sets> <permission-set name="login-permission"> <permission class-name="org.wildfly.security.auth.permission.LoginPermission"/> </permission-set> <permission-set name="default-permissions"/> </permission-sets> <http> <http-authentication-factory name="management-http-authentication" security-domain="ManagementDomain" http-server-mechanism-factory="global"> <mechanism-configuration> <mechanism mechanism-name="DIGEST"> <mechanism-realm realm-name="ManagementRealm"/> </mechanism> </mechanism-configuration> </http-authentication-factory> <provider-http-server-mechanism-factory name="global"/> </http> <sasl> <sasl-authentication-factory name="application-sasl-authentication" sasl-server-factory="configured" security-domain="ApplicationDomain"> <mechanism-configuration> <mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/> <mechanism mechanism-name="DIGEST-MD5"> <mechanism-realm realm-name="ApplicationRealm"/> </mechanism> </mechanism-configuration> </sasl-authentication-factory> <sasl-authentication-factory name="management-sasl-authentication" sasl-server-factory="configured" security-domain="ManagementDomain"> <mechanism-configuration> <mechanism mechanism-name="JBOSS-LOCAL-USER" realm-mapper="local"/> <mechanism mechanism-name="DIGEST-MD5"> <mechanism-realm realm-name="ManagementRealm"/> </mechanism> </mechanism-configuration> </sasl-authentication-factory> <configurable-sasl-server-factory name="configured" sasl-server-factory="elytron"> <properties> <property name="wildfly.sasl.local-user.default-user" value="$local"/> </properties> </configurable-sasl-server-factory> <mechanism-provider-filtering-sasl-server-factory name="elytron" sasl-server-factory="global"> <filters> <filter provider-name="WildFlyElytron"/> </filters> </mechanism-provider-filtering-sasl-server-factory> <provider-sasl-server-factory name="global"/> </sasl> </subsystem> <subsystem xmlns="urn:infinispan:server:core:9.4" default-cache-container="clustered"> <cache-container name="clustered" default-cache="default" statistics="true"> <transport lock-timeout="60000"/> <global-state/> <distributed-cache-configuration name="transactional"> <transaction mode="NON_XA" locking="PESSIMISTIC"/> </distributed-cache-configuration> <distributed-cache-configuration name="async" mode="ASYNC"/> <replicated-cache-configuration name="replicated"/> <distributed-cache-configuration name="persistent-file-store"> <persistence> <file-store shared="false" fetch-state="true"/> </persistence> </distributed-cache-configuration> <distributed-cache-configuration name="indexed"> <indexing index="LOCAL" auto-config="true"/> </distributed-cache-configuration> <distributed-cache-configuration name="memory-bounded"> <memory> <binary size="10000000" eviction="MEMORY"/> </memory> </distributed-cache-configuration> <distributed-cache-configuration name="persistent-file-store-passivation"> <memory> <object size="10000"/> </memory> <persistence passivation="true"> <file-store shared="false" fetch-state="true"> <write-behind modification-queue-size="1024" thread-pool-size="1"/> </file-store> </persistence> </distributed-cache-configuration> <distributed-cache-configuration name="persistent-file-store-write-behind"> <persistence> <file-store shared="false" fetch-state="true"> <write-behind modification-queue-size="1024" thread-pool-size="1"/> </file-store> </persistence> </distributed-cache-configuration> <distributed-cache-configuration name="persistent-rocksdb-store"> <persistence> <rocksdb-store shared="false" fetch-state="true"/> </persistence> </distributed-cache-configuration> <distributed-cache-configuration name="persistent-jdbc-string-keyed"> <persistence> <string-keyed-jdbc-store datasource="java:jboss/datasources/ExampleDS" fetch-state="true" preload="false" purge="false" shared="false"> <string-keyed-table prefix="ISPN"> <id-column name="id" type="VARCHAR"/> <data-column name="datum" type="BINARY"/> <timestamp-column name="version" type="BIGINT"/> </string-keyed-table> <write-behind modification-queue-size="1024" thread-pool-size="1"/> </string-keyed-jdbc-store> </persistence> </distributed-cache-configuration> <distributed-cache name="default"/> <replicated-cache name="repl" configuration="replicated"/> </cache-container> </subsystem> <subsystem xmlns="urn:infinispan:server:endpoint:9.4"> <hotrod-connector socket-binding="hotrod" cache-container="clustered"> <topology-state-transfer lazy-retrieval="false" lock-timeout="1000" replication-timeout="5000"/> </hotrod-connector> <rest-connector socket-binding="rest" cache-container="clustered"> <authentication security-realm="ApplicationRealm" auth-method="BASIC"/> </rest-connector> </subsystem> <subsystem xmlns="urn:infinispan:server:jgroups:9.4"> <channels default="cluster"> <channel name="cluster"/> </channels> <stacks default="${jboss.default.jgroups.stack:dns}"> <stack name="dns"> <transport type="TCP" socket-binding="jgroups-tcp"> <property name="logical_addr_cache_expiration">360000</property> </transport> <protocol type="dns.DNS_PING"> <property name="dns_query">${dns.ping.name:infinispan-server-ping}</property> </protocol> <protocol type="MERGE3"/> <protocol type="FD_SOCK" socket-binding="jgroups-tcp-fd"/> <protocol type="FD_ALL"/> <protocol type="VERIFY_SUSPECT"/> <protocol type="pbcast.NAKACK2"> <property name="use_mcast_xmit">false</property> </protocol> <protocol type="UNICAST3"/> <protocol type="pbcast.STABLE"/> <protocol type="pbcast.GMS"/> <protocol type="MFC"/> <protocol type="FRAG3"/> </stack> <stack name="kubernetes"> <transport type="TCP" socket-binding="jgroups-tcp"> <property name="logical_addr_cache_expiration">360000</property> </transport> <protocol type="kubernetes.KUBE_PING"/> <protocol type="MERGE3"/> <protocol type="FD_SOCK" socket-binding="jgroups-tcp-fd"/> <protocol type="FD_ALL"/> <protocol type="VERIFY_SUSPECT"/> <protocol type="pbcast.NAKACK2"> <property name="use_mcast_xmit">false</property> </protocol> <protocol type="UNICAST3"/> <protocol type="pbcast.STABLE"/> <protocol type="pbcast.GMS"/> <protocol type="MFC"/> <protocol type="FRAG3"/> </stack> </stacks> </subsystem> <subsystem xmlns="urn:jboss:domain:io:3.0"> <worker name="default" io-threads="2" task-max-threads="2"/> <buffer-pool name="default"/> </subsystem> <subsystem xmlns="urn:jboss:domain:jca:5.0"> <archive-validation enabled="true" fail-on-error="true" fail-on-warn="false"/> <bean-validation enabled="true"/> <default-workmanager> <short-running-threads> <core-threads count="50"/> <queue-length count="50"/> <max-threads count="50"/> <keepalive-time time="10" unit="seconds"/> </short-running-threads> <long-running-threads> <core-threads count="50"/> <queue-length count="50"/> <max-threads count="50"/> <keepalive-time time="10" unit="seconds"/> </long-running-threads> </default-workmanager> <cached-connection-manager/> </subsystem> <subsystem xmlns="urn:jboss:domain:jdr:1.0"/> <subsystem xmlns="urn:jboss:domain:jmx:1.3"> <expose-resolved-model/> <expose-expression-model/> <remoting-connector/> </subsystem> <subsystem xmlns="urn:jboss:domain:naming:2.0"> <remote-naming/> </subsystem> <subsystem xmlns="urn:jboss:domain:remoting:4.0"> <http-connector name="http-remoting-connector" connector-ref="default" security-realm="ApplicationRealm"/> </subsystem> <subsystem xmlns="urn:jboss:domain:security:2.0"> <security-domains> <security-domain name="other" cache-type="default"> <authentication> <login-module code="Remoting" flag="optional"> <module-option name="password-stacking" value="useFirstPass"/> </login-module> <login-module code="RealmDirect" flag="required"> <module-option name="password-stacking" value="useFirstPass"/> </login-module> </authentication> </security-domain> <security-domain name="jboss-web-policy" cache-type="default"> <authorization> <policy-module code="Delegating" flag="required"/> </authorization> </security-domain> <security-domain name="jaspitest" cache-type="default"> <authentication-jaspi> <login-module-stack name="dummy"> <login-module code="Dummy" flag="optional"/> </login-module-stack> <auth-module code="Dummy"/> </authentication-jaspi> </security-domain> <security-domain name="jboss-ejb-policy" cache-type="default"> <authorization> <policy-module code="Delegating" flag="required"/> </authorization> </security-domain> </security-domains> </subsystem> <subsystem xmlns="urn:jboss:domain:transactions:5.0"> <core-environment node-identifier="${jboss.tx.node.id:1}"> <process-id> <uuid/> </process-id> </core-environment> <recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/> <object-store path="tx-object-store" relative-to="jboss.server.data.dir"/> </subsystem> </profile> <interfaces> <interface name="management"> <inet-address value="${jboss.bind.address.management:127.0.0.1}"/> </interface> <interface name="public"> <inet-address value="${jboss.bind.address:127.0.0.1}"/> </interface> </interfaces> <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}"> <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/> <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9993}"/> <socket-binding name="hotrod" port="11222"/> <socket-binding name="hotrod-internal" port="11223"/> <socket-binding name="hotrod-multi-tenancy" port="11224"/> <socket-binding name="jgroups-mping" port="0" multicast-address="${jboss.default.multicast.address:234.99.54.14}" multicast-port="45700"/> <socket-binding name="jgroups-tcp" port="7600"/> <socket-binding name="jgroups-tcp-fd" port="57600"/> <socket-binding name="jgroups-udp" port="55200" multicast-address="${jboss.default.multicast.address:234.99.54.14}" multicast-port="45688"/> <socket-binding name="jgroups-udp-fd" port="54200"/> <socket-binding name="memcached" port="11211"/> <socket-binding name="rest" port="8080"/> <socket-binding name="rest-multi-tenancy" port="8081"/> <socket-binding name="rest-ssl" port="8443"/> <socket-binding name="txn-recovery-environment" port="4712"/> <socket-binding name="txn-status-manager" port="4713"/> <outbound-socket-binding name="remote-store-hotrod-server"> <remote-destination host="remote-host" port="11222"/> </outbound-socket-binding> <outbound-socket-binding name="remote-store-rest-server"> <remote-destination host="remote-host" port="8080"/> </outbound-socket-binding> </socket-binding-group> </server> --- ## ImageStream apiVersion: v1 kind: ImageStream metadata: labels: app: infinispan-server name: infinispan-server spec: lookupPolicy: local: false tags: - from: kind: DockerImage name: jboss/infinispan-server:9.4.4.Final name: 9.4.4.Final referencePolicy: type: Source --- ## DeploymentConfig apiVersion: v1 kind: DeploymentConfig metadata: labels: app: infinispan-server name: infinispan-server spec: replicas: 3 selector: app: infinispan-server deploymentconfig: infinispan-server strategy: type: Rolling template: metadata: labels: app: infinispan-server deploymentconfig: infinispan-server spec: containers: - image: jboss/infinispan-server:latest name: infinispan-server ports: - containerPort: 8181 protocol: TCP - containerPort: 8888 protocol: TCP - containerPort: 9990 protocol: TCP - containerPort: 11211 protocol: TCP - containerPort: 11222 protocol: TCP - containerPort: 57600 protocol: TCP - containerPort: 7600 protocol: TCP - containerPort: 8080 protocol: TCP env: - name: MGMT_USER value: ispn-admin - name: MGMT_PASS value: admin-password - name: APP_USER value: ispn-user - name: APP_PASS value: user-password args: - -c - custom/cloud.xml volumeMounts: - name: config mountPath: /opt/jboss/infinispan-server/standalone/configuration/custom volumes: - name: config configMap: name: infinispan-server-configmap items: - key: cloud-custom.xml path: cloud.xml restartPolicy: Always triggers: - type: ConfigChange - imageChangeParams: automatic: true containerNames: - infinispan-server from: kind: ImageStreamTag name: infinispan-server:9.4.4.Final type: ImageChange --- ## Service apiVersion: v1 kind: Service metadata: labels: app: infinispan-server name: infinispan-server spec: ports: - name: 7600-tcp port: 7600 protocol: TCP targetPort: 7600 - name: 8080-tcp port: 8080 protocol: TCP targetPort: 8080 - name: 8181-tcp port: 8181 protocol: TCP targetPort: 8181 - name: 8888-tcp port: 8888 protocol: TCP targetPort: 8888 - name: 9990-tcp port: 9990 protocol: TCP targetPort: 9990 - name: 11211-tcp port: 11211 protocol: TCP targetPort: 11211 - name: 11222-tcp port: 11222 protocol: TCP targetPort: 11222 - name: 57600-tcp port: 57600 protocol: TCP targetPort: 57600 selector: app: infinispan-server deploymentconfig: infinispan-server sessionAffinity: None type: ClusterIP --- ## Service Ping apiVersion: v1 kind: Service metadata: labels: app: infinispan-server name: infinispan-server-ping spec: ports: - name: 7600-tcp port: 7600 protocol: TCP targetPort: 7600 - name: 8080-tcp port: 8080 protocol: TCP targetPort: 8080 - name: 8181-tcp port: 8181 protocol: TCP targetPort: 8181 - name: 8888-tcp port: 8888 protocol: TCP targetPort: 8888 - name: 9990-tcp port: 9990 protocol: TCP targetPort: 9990 - name: 11211-tcp port: 11211 protocol: TCP targetPort: 11211 - name: 11222-tcp port: 11222 protocol: TCP targetPort: 11222 - name: 57600-tcp port: 57600 protocol: TCP targetPort: 57600 selector: app: infinispan-server deploymentconfig: infinispan-server sessionAffinity: None type: ClusterIP clusterIP: None --- ## Route 8080 apiVersion: v1 kind: Route metadata: labels: app: infinispan-server name: infinispan-server-rest-endpoint spec: port: targetPort: 8080-tcp to: kind: Service name: infinispan-server --- ## Route 9990 apiVersion: v1 kind: Route metadata: labels: app: infinispan-server name: infinispan-server-management-endpoint spec: port: targetPort: 9990-tcp to: kind: Service name: infinispan-server