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

Document how to set up remote clusters across k8s boundaries #2593

Merged
merged 23 commits into from
Feb 24, 2020
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions docs/elasticsearch-specification.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Before you deploy and run ECK, take some time to look at the basic and advanced
- <<{p}-advanced-node-scheduling,Advanced Elasticsearch node scheduling>>
- <<{p}-orchestration>>
- <<{p}-snapshots,Create automated snapshots>>
- <<{p}-remote-clusters,Remote clusters>>
- <<{p}-readiness>>
- <<{p}-prestop>>

Expand Down Expand Up @@ -547,6 +548,7 @@ spec:
include::orchestration.asciidoc[]
include::advanced-node-scheduling.asciidoc[]
include::snapshots.asciidoc[]
include::remote-clusters.asciidoc[]


[id="{p}-readiness"]
Expand Down
127 changes: 127 additions & 0 deletions docs/remote-clusters.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
ifdef::env-github[]
****
link:https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-remote-clusters.html[View this document on the Elastic website]
****
endif::[]
[id="{p}-remote-clusters"]
=== Remote clusters

The link:https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-remote-clusters.html[remote clusters module] in Elasticsearch enables you to establish uni-directional connections to a remote cluster. This functionality is used in cross-cluster replication and cross-cluster search.

When using remote cluster connections with ECK, the necessary setup depends on where the remote cluster is deployed.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
When using remote cluster connections with ECK, the necessary setup depends on where the remote cluster is deployed.
When using remote cluster connections with ECK, the setup process depends on where the remote cluster is deployed.


[id="{p}-remote-clusters-connect-internal"]
==== Connect from an Elasticsearch cluster running in the same Kubernetes cluster

TBD

[id="{p}-remote-clusters-connect-external"]
==== Connect from an Elasticsearch cluster running outside the Kubernetes cluster

NOTE: While it is technically possible to configure remote cluster connections using older versions of Elasticsearch, this guide only covers the setup for Elasticsearch 7.6 and later. The setup process is significantly simplified in Elasticsearch 7.6 due to improved support for the indirection introduced by Kubernetes services.

You can configure a remote cluster connection to an ECK-managed Elasticsearch cluster from another cluster running outside the Kubernetes cluster as follows:

. Ensure that both clusters trust each other's certificate authority.
. Configure the remote cluster connection via the Elasticsearch REST API.

For illustration purposes, consider the following example:

* `cluster_one` resides inside Kubernetes and is managed by ECK
* `cluster_two` is not hosted inside the same Kubernetes cluster as `cluster_one` and may not even be managed by ECK

To configure `cluster_one` as a remote cluster in `cluster_two`:


===== Ensure both clusters trust each others certificate authority
Copy link
Contributor

Choose a reason for hiding this comment

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

This can probably be a bullet point instead of a heading

Copy link
Contributor

Choose a reason for hiding this comment

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

There's only two of them though with significant amount of text in between, so I think it might be kind of far apart for bullets, right?


The certificate authority (CA) used by ECK to issue certificates for the Elasticsearch transport layer is stored in a secret named `<cluster_name>-es-transport-certs-public`. Extract the certificate for `cluster_one` as follows:

[source,sh]
----
kubectl get secret cluster_one-es-transport-certs-public \
-o go-template='{{index .data "ca.crt" | base64decode}}' > remote.ca.crt
charith-elastic marked this conversation as resolved.
Show resolved Hide resolved
----

You then need to configure the CA as one of the trusted CAs in `cluster_two`. If that cluster is hosted outside of Kubernetes, simply add the CA certificate extracted in the above step to the list of CAs in link:https://www.elastic.co/guide/en/elasticsearch/reference/current/security-settings.html#_pem_encoded_files_3[`xpack.security.transport.ssl.certificate_authorities`]

If `cluster_two` is also managed by an ECK instance, proceed as follows:

Create a secret with the CA certificate you just extracted:
[source,sh]
----
kubectl create secret generic remote-certs --from-file=remote.ca.crt
----

Use this secret to configure `cluster_one`'s CA as a trusted CA in `cluster_two`:
Copy link
Contributor

Choose a reason for hiding this comment

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

This assumes cluster_two is deployed through ECK, may be worth repeating again.


[source,yaml,subs="attributes"]
----
apiVersion: elasticsearch.k8s.elastic.co/{eck_crd_version}
kind: Elasticsearch
metadata:
name: cluster_two
spec:
nodeSets:
- config:
xpack.security.transport.ssl.certificate_authorities:
- /usr/share/elasticsearch/config/other/remote.ca.crt
pebrc marked this conversation as resolved.
Show resolved Hide resolved
count: 3
name: default
podTemplate:
spec:
containers:
- name: elasticsearch
volumeMounts:
- mountPath: /usr/share/elasticsearch/config/other
name: remote-certs
volumes:
- name: remote-certs
secret:
secretName: remote-certs
version: {version}
----

Repeat the above steps to add the CA of `cluster_two` to `cluster_one` as well.

===== Configure the remote cluster connection via the Elasticsearch REST API

Expose the transport layer of `cluster_one`.

[source,yaml]
----
apiVersion: v1
kind: Service
metadata:
name: cluster_one-es-transport
pebrc marked this conversation as resolved.
Show resolved Hide resolved
spec:
selector:
common.k8s.elastic.co/type: elasticsearch
elasticsearch.k8s.elastic.co/cluster-name: cluster_one
type: LoadBalancer
Copy link
Contributor

Choose a reason for hiding this comment

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

This will mostly work with cloud providers. I would add a note that it could also be done with an Ingress resource.

ports:
- protocol: TCP
port: 9300
targetPort: 9300
----
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This will be redundant once we have #2543


Finally, configure `cluster_one` as a remote cluster in `cluster_two` using the Elasticsearch REST API:

[source,sh]
----
PUT _cluster/settings
{
"persistent": {
"cluster": {
"remote": {
"cluster_one": {
"mode": "proxy", <1>
"proxy_address": "${LOADBALANCER_IP}:9300" <2>
}
}
}
}
}
----
<1> Use "proxy" mode as `cluster_two` will be connecting to `cluster_one` through the Kubernetes service abstraction.
<2> Replace `${LOADBALANCER_IP}` with the IP address assigned to the `LoadBalancer` configured above. if you have configured a DNS entry for the service, you can use the DNS name instead of the IP address as well.