Skip to content

Commit d403e94

Browse files
[Development][Add] Added support for keystore in elasticsearch (#44)
* Added support for elastic keystore Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com> * Added support for elastic keystore Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com> * Added example for keystore Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com> * Updated documentation for v0.4.0 Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com> Signed-off-by: iamabhishek-dubey <abhishekbhardwaj510@gmail.com>
1 parent c1a2a62 commit d403e94

File tree

17 files changed

+276
-11
lines changed

17 files changed

+276
-11
lines changed

api/v1beta1/elasticsearch_types.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,12 @@ type ElasticsearchSpec struct {
2929
Security *Security `json:"esSecurity,omitempty"`
3030
// +kubebuilder:validation:default:={esMaster:{replicas: 3}}
3131
// +kubebuilder:default:={storage:{accessModes: {ReadWriteOnce}, storageSize: "1Gi"},jvmMaxMemory: "1g", jvmMinMemory: "1g", replicas: 3}
32-
ESMaster *NodeSpecificConfig `json:"esMaster,omitempty"`
33-
ESData *NodeSpecificConfig `json:"esData,omitempty"`
34-
ESIngestion *NodeSpecificConfig `json:"esIngestion,omitempty"`
35-
ESClient *NodeSpecificConfig `json:"esClient,omitempty"`
36-
ESPlugins *[]string `json:"esPlugins,omitempty"`
32+
ESMaster *NodeSpecificConfig `json:"esMaster,omitempty"`
33+
ESData *NodeSpecificConfig `json:"esData,omitempty"`
34+
ESIngestion *NodeSpecificConfig `json:"esIngestion,omitempty"`
35+
ESClient *NodeSpecificConfig `json:"esClient,omitempty"`
36+
ESPlugins *[]string `json:"esPlugins,omitempty"`
37+
ESKeystoreSecret *string `json:"esKeystoreSecret,omitempty"`
3738
}
3839

3940
// NodeSpecificConfig defines the properties for elasticsearch nodes

config/crd/bases/logging.logging.opstreelabs.in_elasticsearches.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -3630,6 +3630,8 @@ spec:
36303630
type: string
36313631
type: object
36323632
type: object
3633+
esKeystoreSecret:
3634+
type: string
36333635
esMaster:
36343636
default:
36353637
jvmMaxMemory: 1g

docs/config.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ weight = 1
6969
unsafe = true
7070
[markup.highlight]
7171
# See a complete list of available styles at https://xyproto.github.io/splash/docs/all.html
72-
style = "rainbow_dash"
72+
# style = "rainbow_dash"
73+
style = "pygments"
7374
# Uncomment if you want your chosen highlight style used for code blocks without a specified language
7475
# guessSyntax = "true"
7576

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
title: "Elasticsearch"
3+
linkTitle: "Elasticsearch"
4+
weight: 4
5+
description: >
6+
Advance configuration information for Elasticsearch
7+
---
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
title: "Keystore Integration"
3+
linkTitle: "Keystore Integration"
4+
weight: 6
5+
description: >
6+
Keystore integration configuration for elasticsearch
7+
---
8+
9+
## Keystore integation
10+
11+
Keystore is a recommended way of integrating different credentials like:- AWS, GCP, Azure and Slack, etc. to elasticsearch cluster. We simply need to create a Kubernetes secret and the operator can take care the integration of Kubernetes secret to elasticsearch keystore.
12+
13+
```shell
14+
$ kubectl create secret generic slack-hook \
15+
--from-literal=xpack.notification.slack.account.monitoring.secure_url='https://hooks.slack.com/services/asdasdasd/asda'
16+
```
17+
18+
or yaml file is also one of the way for creating the secret.
19+
20+
```yaml
21+
---
22+
apiVersion: v1
23+
kind: Secret
24+
metadata:
25+
name: encryption-key
26+
data:
27+
xpack.notification.slack.account.monitoring.secure_url: aHR0cHM6Ly9ob29rcy5zbGFjay5jb20vc2VydmljZXMvYXNkYXNkYXNkL2FzZGFzZGFzL2FzZGFzZA==
28+
# other secrets key value pairs can be defined here
29+
type: Opaque
30+
```
31+
32+
Then simply we can define the keystore secret name in CRD definition.
33+
34+
```yaml
35+
---
36+
apiVersion: logging.logging.opstreelabs.in/v1beta1
37+
kind: Elasticsearch
38+
metadata:
39+
name: elasticsearch
40+
spec:
41+
esClusterName: "prod"
42+
esVersion: "7.16.0"
43+
esKeystoreSecret: encryption-key
44+
```
45+
46+
Validation of keystore can be done using `elasticsearch-keystore` command.
47+
48+
```shell
49+
$ kubectl exec -it elasticsearch-master-0 -n ot-operators -- ./bin/elasticsearch-keystore list
50+
...
51+
keystore.seed
52+
xpack.notification.slack.account.monitoring.secure_url
53+
```
54+
55+
## Helm Configuration
56+
57+
Keystore integration can also be done using helm chart of elasticsearch. We just need to define the keystore secret name in the values file of elasticsearch helm chart.
58+
59+
https://github.com/OT-CONTAINER-KIT/helm-charts/blob/main/charts/elasticsearch/values.yaml#L9
60+
61+
```shell
62+
$ helm upgrade elasticsearch ot-helm/elasticsearch --namespace ot-operators \
63+
--set esMaster.storage.storageClass=do-block-storage \
64+
--set esData.storage.storageClass=do-block-storage --install
65+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
title: "Plugins Management"
3+
linkTitle: "Plugins Management"
4+
weight: 5
5+
description: >
6+
Plugins related configuration for elasticsearch
7+
---
8+
9+
## Plugins Installation
10+
11+
Plugins installation has been simplified using the Logging Operator. To install the plugins inside the elasticsearch, we just need to define the list of plugins inside the `esPlugins` section of elasticsearch CRD.
12+
13+
For example:-
14+
15+
```yaml
16+
---
17+
apiVersion: logging.logging.opstreelabs.in/v1beta1
18+
kind: Elasticsearch
19+
metadata:
20+
name: elasticsearch
21+
spec:
22+
esClusterName: "prod"
23+
esVersion: "7.16.0"
24+
esPlugins: ["repository-s3"]
25+
```
26+
27+
Validation of plugin installation can be done using `elasticsearch-plugin` or `curl` command.
28+
29+
```shell
30+
$ kubectl exec -it elasticsearch-master-0 -n ot-operators -- ./bin/elasticsearch-plugin list
31+
...
32+
repository-s3
33+
```
34+
35+
```shell
36+
$ kubectl exec -it elasticsearch-master-0 -n ot-operators -- curl http://localhost:9200/_cat/plugins
37+
...
38+
elasticsearch-master-1 repository-s3 7.16.0
39+
elasticsearch-master-2 repository-s3 7.16.0
40+
elasticsearch-master-0 repository-s3 7.16.0
41+
```
42+
43+
## Helm Configuration
44+
45+
Plugin installation can also be done using helm chart of elasticsearch. We just need to define the plugins list in the values file of elasticsearch helm chart.
46+
47+
https://github.com/OT-CONTAINER-KIT/helm-charts/blob/main/charts/elasticsearch/values.yaml#L8
48+
49+
```shell
50+
$ helm upgrade elasticsearch ot-helm/elasticsearch --namespace ot-operators \
51+
--set esMaster.storage.storageClass=do-block-storage \
52+
--set esData.storage.storageClass=do-block-storage --install
53+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
title: "Advance Configuration"
3+
linkTitle: "Advance Configuration"
4+
weight: 4
5+
description: >
6+
Advance configuration information for Logging Operator
7+
---

docs/content/en/docs/Configuration/elasticsearch-config.md

+18
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ The values.yaml file for Elasticsearch setup can be found [here](https://github.
1616
|----------------------------------|-----------------|--------------------------------------------------------------------|
1717
| clusterName | elastic-prod | Name of the elasticsearch cluster |
1818
| esVersion | 7.17.0 | Major and minor version of elaticsearch |
19+
| esPlugins | [] | Plugins list to install inside elasticsearch |
20+
| esKeystoreSecret | - | Keystore secret to include in elasticsearch cluster |
1921
| customConfiguration | {} | Additional configuration parameters for elasticsearch |
2022
| esSecurity.enabled | true | To enabled the xpack security of elasticsearch |
2123
| esMaster.replicas | 3 | Number of replicas for elasticsearch master node |
@@ -88,6 +90,22 @@ esClusterName: "prod"
8890
esVersion: "7.16.0"
8991
```
9092

93+
### esPlugins
94+
95+
`esPlugins` is a CRD parameter through which we can define the list of plugins that needs to install inside elasticsearch cluster.
96+
97+
```yaml
98+
esPlugins: ["respository-s3", "repository-gcs"]
99+
```
100+
101+
### esKeystoreSecret
102+
103+
`esKeystoreSecret` is a CRD parameter through which we can define the keystore related secret to include in elasticsearch cluster.
104+
105+
```yaml
106+
esKeystoreSecret: keystore-secret
107+
```
108+
91109
### esMaster
92110

93111
`esMaster` is a general configuration parameter for Elasticsearch CRD for defining the configuration of Elasticsearch Master node. This includes Kubernetes related configurations and Elasticsearch properties related configurations.

docs/content/en/docs/Development/_index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ title: "Development"
33
linkTitle: "Development"
44
weight: 5
55
description: >
6-
Development related information for MongoDB Operator
6+
Development related information for Logging Operator
77
---

docs/content/en/docs/Release History/CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ description: >
66
Changelog version history for Logging Operator
77
---
88

9+
### v0.4.0
10+
11+
**September 3, 2022**
12+
13+
**🏄 Features**
14+
15+
- Added elasticsearch 8.X version support
16+
- Added plugin's installation support in elasticsearch
17+
- Added keystore integration in elasticsearch
18+
919
### v0.3.0
1020

1121
**July 4, 2022**
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
---
22
title: "Release History"
33
linkTitle: "Release History"
4-
weight: 5
4+
weight: 6
55
description: >
6-
Release history information for MongoDB
6+
Release history information for Logging Operator
77
---
8-

docs/content/en/docs/_index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ menu:
88
weight: 20
99
---
1010

11-
All of Logging Operator documentation
11+
All the Logging Operator documentation and examples.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
apiVersion: logging.logging.opstreelabs.in/v1beta1
3+
kind: Elasticsearch
4+
metadata:
5+
name: elasticsearch
6+
spec:
7+
esClusterName: "prod"
8+
esVersion: "7.16.0"
9+
esKeystoreSecret: encryption-key
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
apiVersion: v1
3+
data:
4+
xpack.notification.slack.account.monitoring.secure_url: aHR0cHM6Ly9ob29rcy5zbGFjay5jb20vc2VydmljZXMvYXNkYXNkYXNkL2FzZGFzZGFzL2FzZGFzZA==
5+
# other secrets key value pairs can be defined here
6+
kind: Secret
7+
metadata:
8+
name: encryption-key
9+
type: Opaque

k8sgo/elasticsearch/statefulset.go

+28
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ func CreateElasticsearchStatefulSet(cr *loggingv1beta1.Elasticsearch, nodeConfig
6060
if cr.Spec.ESPlugins != nil {
6161
statefulsetParams.ESPlugins = cr.Spec.ESPlugins
6262
}
63+
if cr.Spec.ESKeystoreSecret != nil {
64+
statefulsetParams.ESKeystoreSecret = cr.Spec.ESKeystoreSecret
65+
}
6366
statefulsetParams.ExtraVolumes = getVolumes(cr)
6467

6568
if nodeConfig != nil {
@@ -119,6 +122,13 @@ func getVolumeMounts(cr *loggingv1beta1.Elasticsearch, role string) *[]corev1.Vo
119122
MountPath: "/usr/share/elasticsearch/plugins",
120123
})
121124
}
125+
if cr.Spec.ESKeystoreSecret != nil {
126+
volumeMounts = append(volumeMounts, corev1.VolumeMount{
127+
Name: "keystore-volume",
128+
MountPath: "/usr/share/elasticsearch/config/elasticsearch.keystore",
129+
SubPath: "elasticsearch.keystore",
130+
})
131+
}
122132
return &volumeMounts
123133
}
124134

@@ -145,6 +155,24 @@ func getVolumes(cr *loggingv1beta1.Elasticsearch) *[]corev1.Volume {
145155
},
146156
})
147157
}
158+
if cr.Spec.ESKeystoreSecret != nil {
159+
volume = append(volume, corev1.Volume{
160+
Name: "keystore-volume",
161+
VolumeSource: corev1.VolumeSource{
162+
EmptyDir: &corev1.EmptyDirVolumeSource{},
163+
},
164+
})
165+
}
166+
if cr.Spec.ESKeystoreSecret != nil {
167+
volume = append(volume, corev1.Volume{
168+
Name: "keystore-secret",
169+
VolumeSource: corev1.VolumeSource{
170+
Secret: &corev1.SecretVolumeSource{
171+
SecretName: *cr.Spec.ESKeystoreSecret,
172+
},
173+
},
174+
})
175+
}
148176
return &volume
149177
}
150178

k8sgo/init_command.go

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
Copyright 2022 Opstree Solutions.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package k8sgo
18+
19+
const keyStoreCommand = `set -euo pipefail
20+
elasticsearch-keystore create
21+
for i in /tmp/keystoreSecrets/*/*; do
22+
key=$(basename $i)
23+
echo "Adding file $i to keystore key $key"
24+
elasticsearch-keystore add-file "$key" "$i"
25+
done
26+
# Add the bootstrap password since otherwise the Elasticsearch entrypoint tries to do this on startup
27+
if [ ! -z ${ELASTIC_PASSWORD+x} ]; then
28+
echo 'Adding env $ELASTIC_PASSWORD to keystore as key bootstrap.password'
29+
echo "$ELASTIC_PASSWORD" | elasticsearch-keystore add -x bootstrap.password
30+
fi
31+
cp -a /usr/share/elasticsearch/config/elasticsearch.keystore /tmp/keystore/`

k8sgo/statefulset.go

+25
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package k8sgo
1818

1919
import (
2020
"context"
21+
"fmt"
2122
"strings"
2223

2324
appsv1 "k8s.io/api/apps/v1"
@@ -46,6 +47,7 @@ type StatefulSetParameters struct {
4647
SecurityContext *corev1.PodSecurityContext
4748
ExtraVolumes *[]corev1.Volume
4849
ESPlugins *[]string
50+
ESKeystoreSecret *string
4951
}
5052

5153
// PVCParameters is a struct to pass arguments for PVC
@@ -186,6 +188,9 @@ func generateStatefulSetDef(params StatefulSetParameters) *appsv1.StatefulSet {
186188
if params.ESPlugins != nil {
187189
statefulset.Spec.Template.Spec.InitContainers = append(statefulset.Spec.Template.Spec.InitContainers, getPluginInitContainers(params))
188190
}
191+
if params.ESKeystoreSecret != nil {
192+
statefulset.Spec.Template.Spec.InitContainers = append(statefulset.Spec.Template.Spec.InitContainers, getKeystoreInitContainer(params))
193+
}
189194
if params.ExtraVolumes != nil {
190195
statefulset.Spec.Template.Spec.Volumes = *params.ExtraVolumes
191196
}
@@ -251,3 +256,23 @@ func getPluginInitContainers(params StatefulSetParameters) corev1.Container {
251256
},
252257
}
253258
}
259+
260+
// getKeystoreInitContainer is a method to create init container for keystore
261+
func getKeystoreInitContainer(params StatefulSetParameters) corev1.Container {
262+
secretName := fmt.Sprintf("/tmp/keystoreSecrets/%s", *params.ESKeystoreSecret)
263+
return corev1.Container{
264+
Name: "keystore",
265+
Image: params.ContainerParams.Image,
266+
Command: []string{"bash", "-c", keyStoreCommand},
267+
VolumeMounts: []corev1.VolumeMount{
268+
{
269+
Name: "keystore-volume",
270+
MountPath: "/tmp/keystore",
271+
},
272+
{
273+
Name: "keystore-secret",
274+
MountPath: secretName,
275+
},
276+
},
277+
}
278+
}

0 commit comments

Comments
 (0)