Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: deploying Infinispan with Operator #569

Merged
merged 1 commit into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions doc/kubernetes/collector/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,56 @@ helm template --debug ${STARTDIR}/../../../provision/minikube/keycloak \
| yq \
> ${BUILDDIR}/helm/keycloak-ispn.yaml


# Infinispan single cluster
helm template --debug ${STARTDIR}/../../../provision/infinispan/ispn-helm \
--set namespace=ispn-namespace \
--set replicas=3 \
--set crossdc.enabled=false \
--set metrics.histograms=false \
--set hotrodPassword="strong-password" \
--set cacheDefaults.crossSiteMode=ASYNC \
--set cacheDefaults.stateTransferMode=AUTO \
> ${BUILDDIR}/helm/ispn-single.yaml

# Infinispan site A deployment
helm template --debug ${STARTDIR}/../../../provision/infinispan/ispn-helm \
--set namespace=ispn-namespace \
--set replicas=3 \
--set crossdc.enabled=true \
--set crossdc.local.name=site-a \
--set crossdc.local.gossipRouterEnabled=true \
--set crossdc.remote.name=site-b \
--set crossdc.remote.gossipRouterEnabled=true \
--set crossdc.remote.namespace=ispn-namespace \
--set crossdc.remote.url=openshift://api.site-b \
--set crossdc.remote.secret=xsite-token-secret \
--set crossdc.route.enabled=true \
--set crossdc.route.tls.keystore.secret=xsite-keystore-secret \
--set crossdc.route.tls.truststore.secret=xsite-truststore-secret \
--set metrics.histograms=false \
--set hotrodPassword="strong-password" \
--set cacheDefaults.crossSiteMode=ASYNC \
--set cacheDefaults.stateTransferMode=AUTO \
> ${BUILDDIR}/helm/ispn-site-a.yaml

# Infinispan site B deployment
helm template --debug ${STARTDIR}/../../../provision/infinispan/ispn-helm \
--set namespace=ispn-namespace \
--set replicas=3 \
--set crossdc.enabled=true \
--set crossdc.local.name=site-b \
--set crossdc.local.gossipRouterEnabled=true \
--set crossdc.remote.name=site-a \
--set crossdc.remote.gossipRouterEnabled=true \
--set crossdc.remote.namespace=ispn-namespace \
--set crossdc.remote.url=openshift://api.site-a \
--set crossdc.remote.secret=xsite-token-secret \
--set crossdc.route.enabled=true \
--set crossdc.route.tls.keystore.secret=xsite-keystore-secret \
--set crossdc.route.tls.truststore.secret=xsite-truststore-secret \
--set metrics.histograms=false \
--set hotrodPassword="strong-password" \
--set cacheDefaults.crossSiteMode=ASYNC \
--set cacheDefaults.stateTransferMode=AUTO \
> ${BUILDDIR}/helm/ispn-site-b.yaml
2 changes: 2 additions & 0 deletions doc/kubernetes/modules/ROOT/nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
* xref:running/index.adoc[]
** xref:running/keycloak-deployment.adoc[]
** xref:running/keycloak-with-external-infinispan.adoc[]
** xref:running/infinispan-deployment.adoc[]
** xref:running/infinispan-crossdc-deployment.adoc[]
** xref:running/concepts/index.adoc[]
*** xref:running/concepts/database-connections.adoc[]
*** xref:running/concepts/threads.adoc[]
Expand Down
2 changes: 2 additions & 0 deletions doc/kubernetes/modules/ROOT/pages/running/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ It summarizes the logic which is condensed in the Helm charts and scripts in thi

* xref::running/keycloak-deployment.adoc[]
* xref::running/keycloak-with-external-infinispan.adoc[]
* xref::running/infinispan-deployment.adoc[]
* xref::running/infinispan-crossdc-deployment.adoc[]

See xref:./concepts/index.adoc[] to learn more about the concepts behind this.
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
= Infinispan Deployment: Multiple Clusters
:description: This describes how to deploy Infinispan with cross-site enabled.
:site-a: Site-A
:site-b: Site-B
:ocp: OpenShift
:operator-docs: https://infinispan.org/docs/infinispan-operator/main/operator.html
:xsite-docs: https://infinispan.org/docs/stable/titles/xsite/xsite.html
:ispn: Infinispan
:ispn-operator: Infinispan Operator
:kc: Keycloak

{description}

== Audience

This guide describes the procedures required to deploy {ispn} in a multiple-cluster environment (cross-site).
For simplicity, this guide uses the minimum configuration possible that allows {kc} to be used with an external {ispn}.

This guide assumes two {ocp} clusters named `{site-a}` and `{site-b}`.

See xref:running/index.adoc[] for additional guides.

== Prerequisites

include::partial$running/infinispan-prerequisites.adoc[]

== Procedure

include::partial$running/infinispan-install-operator.adoc[]
include::partial$running/infinispan-credentials.adoc[]
+
These commands must be executed on both {ocp} clusters.

. Create a service account.
+
A service account is required to establish a connection between clusters.
The {ispn-operator} uses it to inspect the network configuration from the remote site and to configure the local {ispn} cluster accordingly.
+
For more details check {operator-docs}#managed-cross-site-connections_cross-site[Managing Cross-Site Connections] documentation.
+

.. First, create the service account and generate an access token in both {ocp} clusters.
+
.Create the service account in `{site-a}`
[source,bash]
----
oc create sa -n ispn-namespace xsite-sa
oc policy add-role-to-user view -n ispn-namespace -z xsite-sa
oc create token -n ispn-namespace xsite-sa > site-a-token.txt
----
+
.Create the service account in `{site-b}`
[source,bash]
----
oc create sa -n ispn-namespace xsite-sa
oc policy add-role-to-user view -n ispn-namespace -z xsite-sa
oc create token -n ispn-namespace xsite-sa > site-b-token.txt
----
+
.. The next step is to deploy the token from `{site-a}` into `{site-b}` and vice-versa
+
.Deploy `{site-b}` token into `{site-a}`
[source,bash]
----
oc create secret generic -n ispn-namespace xsite-token-secret \
--from-literal=token="$(cat site-b-token.txt)"
----
+
.Deploy `{site-a}` token into `{site-b}`
[source,bash]
----
oc create secret generic -n ispn-namespace xsite-token-secret \
--from-literal=token="$(cat site-a-token.txt)"
----

. Create TLS secrets
+
In this guide Infinispan uses an {ocp} Route for the cross-site communication.
It uses the SNI extension of TLS to direct the traffic to the correct Pods.
To achieve that, JGroups use TLS sockets, which require a Keystore and Truststore with the correct certificates.
+
For more information check {operator-docs}#securing-cross-site-connections_cross-site[Securing Cross Site Connections] documentation or this https://developers.redhat.com/learn/openshift/cross-site-and-cross-applications-red-hat-openshift-and-red-hat-data-grid[Red Hat Developer Guide].
+
Upload the Keystore and the Truststore in an {ocp} Secret.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this meant to be a heading?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean? It is not a header.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The statement was so concise, I wasn't sure if it was meant to be a heading for the statements that follow.

Maybe we can expand it slightly so the purpose of this action is clear:

"The Keystore and Truststore must be deployed to {ocp} Secrets so that they can be utilised by the {ispn} deployment."

Then maybe remove the rest of the content before ".Deploy a Keystore".

The secret contains the file content, the password to access it, and the type of the store.
How to create the certificates and the stores are out of the scope of this guide.
+
To upload the Keystore as a Secret, use the following command:
+
.Deploy a Keystore
[source,bash]
----
oc -n ispn-namespace create secret generic xsite-keystore-secret \
--from-file=keystore.p12="./certs/keystore.p12" \ # <1>
--from-literal=password=secret \ #<2>
--from-literal=type=pkcs12 #<3>
----
<1> The filename and the path to the Keystore.
<2> The password to access the Keystore.
<3> The Keystore type.
+
To upload the Truststore as a Secret, use the following command:
+
.Deploy a Truststore
[source,bash]
----
oc -n ispn-namespace create secret generic xsite-truststore-secret \
--from-file=truststore.p12="./certs/truststore.p12" \ # <1>
--from-literal=password=caSecret \ # <2>
--from-literal=type=pkcs12 # <3>
----
<1> The filename and the path to the Truststore.
<2> The password to access the Truststore.
<3> The Truststore type.
+
NOTE: Keystore and Truststore must be uploaded in both {ocp} clusters.

. Create an {ispn} Cluster with Cross-Site enabled
+
The {operator-docs}#setting-up-xsite[Setting Up Cross-Site] documentation provides all the information on how to create and configure your {ispn} cluster with cross-site enabled, including the previous steps.
+
A basic example is provided in this guide using the credentials, tokens and TLS Keystore/Truststore created by the commands from the previous steps.
+
.The {ispn} CR for `{site-a}`
[source,yaml]
----
include::example$helm/ispn-site-a.yaml[tag=infinispan-crossdc]
----
<1> The cluster name
<2> Allows the cluster to be monitored by Prometheus.
<3> If using a custom credential, configure here the secret name.
<4> The name of the local site, in this case `{site-a}`.
<5> Exposing the cross-site connection using {ocp} Route.
<6> The secret name where the Keystore exists as defined in the previous step.
<7> The alias of the certificate inside the Keystore.
<8> The secret key (filename) of the Keystore as defined in the previous step.
<9> The secret name where the Truststore exists as defined in the previous step.
<10> The Truststore key (filename) of the Keystore as defined in the previous step.
<11> The remote site's name, in this case `{site-b}`.
<12> The namespace of the {ispn} cluster from the remote site.
<13> The {ocp} API URL for the remote site.
<14> The secret with the access toke to authenticate into the remote site.
+
For `{site-b}`, the {ispn} CR looks similar to the above.
Note the differences in point 4, 11 and 13.
+
.The {ispn} CR for `{site-b}`
[source,yaml]
----
include::example$helm/ispn-site-b.yaml[tag=infinispan-crossdc]
----

. Creating the caches for {kc}.
+
{kc} requires the following caches to be present: `sessions`, `actionTokens`, `authenticationSessions`, `offlineSessions`, `clientSessions`, `offlineClientSessions`, `loginFailures`, and `work`.
+
The {ispn} {operator-docs}#creating-caches[Cache CR] allows to deploy the caches in the {ispn} cluster.
Cross-site needs to be enabled per cache as documented by {xsite-docs}[Cross Site Documentation].
The documentation contains more details about the options used by this guide.
The following example shows the Cache CR for `{site-a}`.
+
.sessions in `{site-a}`
[source,yaml]
----
include::example$helm/ispn-site-a.yaml[tag=infinispan-cache-sessions]
----
<1> The cross-site merge policy, invoked when there is a write-write conflict.
Set this for the caches `sessions`, `authenticationSessions`, `offlineSessions`, `clientSessions` and `offlineClientSessions`, and do not set it for all other caches.
<2> The remote site name.
<3> The cross-site communication, in this case ASYNC.
<4> The state transfer mode.
Automatic mode is only available in ASYNC mode.
In automatic mode, the state transfer is triggered after a network partition automatically.
+
For `{site-b}`, the Cache CR is similar except in point 2.
+
.session in `{site-b}`
[source,yaml]
----
include::example$helm/ispn-site-b.yaml[tag=infinispan-cache-sessions]
----
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
= Infinispan Deployment: Single Cluster
:description: This describes the Infinispan deployment in a single cluster environment.
:operator-docs: https://infinispan.org/docs/infinispan-operator/main/operator.html

{description}

== Audience

This guide describes the procedure required to deploy Infinispan in a single cluster environment.
For simplicity, this guide uses the minimum configuration possible that allows Keycloak to be used with an external infinispan.

See xref:running/index.adoc[] for additional guides.

== Prerequisites

include::partial$/running/infinispan-prerequisites.adoc[]

== Procedure

include::partial$/running/infinispan-install-operator.adoc[]
include::partial$/running/infinispan-credentials.adoc[]

. Create an Infinispan cluster.
+
The {operator-docs}#creating-clusters[Creating Infinispan clusters] documentation provides all the information on how to create and configure your Infinispan cluster.
+
.Infinispan CR
[source,yaml]
----
include::example$helm/ispn-single.yaml[tag=infinispan-single]
----
<1> The cluster name
<2> Allows the cluster to be monitored by Prometheus
<3> If using a custom credential, configure here the secret name created in the previous step.

. Create the caches for Keycloak.
+
Keycloak requires the following caches to be present: `sessions`, `actionTokens`, `authenticationSessions`, `offlineSessions`, `clientSessions`, `offlineClientSessions`, `loginFailures`, and `work`.
+
Use the {operator-docs}#creating-caches[Infinispan Cache CR] to deploy the caches in the Infinispan cluster.
+
See below for an example for the `sessions` cache.
Repeat this for all other caches listed above.
+
.Cache CR for the `sessions` cache
[source,yaml]
----
include::example$helm/ispn-single.yaml[tag=infinispan-cache-sessions]
----
+
The https://infinispan.org/docs/stable/titles/configuring/configuring.html[Infinispan documentation] contains more detail about cache configuration ands its options.
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ See xref:running/index.adoc[] for additional guides.

* OpenShift or Kubernetes cluster running.
* Existing xref:running/keycloak-deployment.adoc[Basic Keycloak deployment] as it will be extended.
* Existing deployment of Infinispan with the Operator (TODO).
* Existing Infinispan deployment, for example, one of xref:running/infinispan-deployment.adoc[] or xref:running/keycloak-with-external-infinispan.adoc[].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should "infinispan" be "{ispn}"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ispn attribute does not exist in this file.


== Procedure

. Prepare an Infinispan Cache configuration XML from the file `cache-ispn.xml` which is part of the Keycloak distribution:
For each `distributed-cache` entry, add the tags `<persistence />` and `<state-transfer />` as shown below.
.. For each `distributed-cache` entry, add the tags `<persistence />` and `<state-transfer />` as shown below.
+
[source,xml,indent=0]
----
Expand All @@ -33,6 +33,14 @@ include::example$helm-keycloak-config/kcb-infinispan-cache-remote-store-config.x
<5> New tag `<state-transfer />` to avoid a state transfer on node startup and instead use the remote store.
This speeds up the startup of new nodes.

.. Prepare an Infinispan Cache configuration XML from the file `cache-ispn.xml` which is part of the Keycloak distribution:
For each `replicated-cache` entry, add the tag `<persistence />` as shown below.
+
[source,xml,indent=0]
----
include::example$helm-keycloak-config/kcb-infinispan-cache-remote-store-config.xml[tag=keycloak-ispn-remotestore-work]
----

. Place the Infinispan Cache configuration XML in a ConfigMap.
+
[source,yaml]
Expand Down Expand Up @@ -66,6 +74,8 @@ include::example$helm/keycloak-ispn.yaml[tag=keycloak-ispn]
<2> The hostname and port of the remote cache Infinispan cluster.
<3> The credentials required, username and password, to access the remote cache Infinispan cluster.
<4> Mounting the cache configuration Volume in Kubernetes.
<5> `jboss.site.name` is an arbitrary Infinispan site name which Keycloak needs for its embedded Infinispan deployment; this site name is related only to embedded Infinispan and does not need to match any value from the external Infinispan deployment
<5> `jboss.site.name` is an arbitrary Infinispan site name which Keycloak needs for its embedded Infinispan deployment when a remote store is used. This site name is related only to the embedded Infinispan and does not need to match any value from the external Infinispan deployment.
However, matching the `jboss.site.name` with the external Infinispan deployment site name helps debugging possible future issues.
If you are using multiple sites for Keycloak in a cross-DC setup like xref::running/infinispan-crossdc-deployment.adoc[], the site name must be different in each site.
<6> Defining the cache configuration Volume using the already created ConfigMap in Kubernetes.

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
. Configure the credential to access the Infinispan cluster.
+
Keycloak needs this credential to be able to authenticate with the Infinispan cluster.
The following `identities.yaml` file sets the username and password with admin permissions
+
[source,yam]
----
credentials:
- username: developer
password: strong-password
roles:
- admin
----
+
The `identities.yaml` could be set in a secret as one of the following:

* As a Kubernetes Resource:
+
.Credential Secret
[.wrap]
[source,yaml]
----
include::example$helm/ispn-single.yaml[tag=infinispan-credentials]
----
<1> The `identities.yaml` from the previous example base64 encoded.
+
* Using the CLI
+
[source,bash]
----
kubectl create secret generic connect-secret --from-file=identities.yaml
----
+
Check https://infinispan.org/docs/infinispan-operator/main/operator.html#configuring-authentication[Configuring Authentication] documentation for more details.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
. Install the https://infinispan.org/docs/infinispan-operator/main/operator.html#installation[Infinispan Operator]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* OpenShift or Kubernetes cluster running
* Understanding of the https://infinispan.org/docs/infinispan-operator/main/operator.html[Infinispan Operator]
Loading