Skip to content

Commit 692f3d5

Browse files
committed
add docs of server database and UI
1 parent 78e4ba7 commit 692f3d5

File tree

7 files changed

+485
-0
lines changed

7 files changed

+485
-0
lines changed

docs/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
- [Social Network](./user-guide/workloads/social-network.md)
2727
- [Trace Analysis](./user-guide/trace-analysis.md)
2828
- [Web Interface](./user-guide/web-interface.md)
29+
- [Database Management](./user-guide/database.md)
2930

3031
---
3132

docs/src/user-guide/database.md

Lines changed: 379 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,379 @@
1+
# Database
2+
3+
This document aims to guide users through the installation and testing of a multi-node Docker-based Elasticsearch database cluster. It provides detailed steps for setting up the cluster and verifying its functionality.
4+
5+
## Elastic Multi-Node Docker Installation Guide
6+
7+
### Core Conclusion
8+
This guide demonstrates the deployment of a multi-node Elasticsearch cluster (including Kibana) using Docker. By splitting configuration files, synchronizing certificates, and setting environment variables, cross-node deployment is achieved, resulting in a healthy and functional cluster environment.
9+
10+
### 1. Environment Preparation
11+
- **Basic Requirements**:
12+
- Docker: 24.0.7+
13+
- Docker Compose: v2.21.0+
14+
- Operating System: Linux/amd64
15+
16+
- **Image Details**:
17+
- Elasticsearch: 8.15.2
18+
- Kibana: 8.15.2
19+
20+
- **Node Planning**:
21+
At least two nodes are required. In this example, we use two nodes:
22+
- Node 1: IP address `ip1`, hosting Elasticsearch instance `es01` and Kibana.
23+
- Node 2: IP address `ip2`, hosting Elasticsearch instance `es02`.
24+
25+
### 2. Pre-Deployment Preparation
26+
27+
#### 1. Directory and Permission Configuration (All Nodes)
28+
- **Create Mount Directories by Node Role**:
29+
- Node 1: Create `/opt/data/{es01,kibana}`
30+
- Node 2: Create `/opt/data/es02`
31+
- **Set Directory Permissions**:
32+
Execute the following command to set permissions, ensuring compatibility with the non-root user (ID 1000) inside the container:
33+
```bash
34+
chown -R 1000:1000 /opt/data/<directory>
35+
```
36+
37+
#### 2. Configuration File Preparation (Node 1 First)
38+
- **Create `.env` File**:
39+
Define core parameters such as Elastic and Kibana passwords, cluster name, version, ports, and memory limits. Below is an example:
40+
```env
41+
# Password for the 'elastic' user (at least 6 characters)
42+
ELASTIC_PASSWORD=1qazXSW@
43+
44+
# Password for the 'kibana_system' user (at least 6 characters)
45+
KIBANA_PASSWORD=1qazXSW@
46+
47+
# Version of Elastic products
48+
STACK_VERSION=8.15.2
49+
50+
# Set the cluster name
51+
CLUSTER_NAME=es-cluster
52+
53+
# Set to 'basic' or 'trial' to automatically start the 30-day trial
54+
LICENSE=basic
55+
#LICENSE=trial
56+
57+
# Port to expose Elasticsearch HTTP API to the host
58+
ES_PORT=9200
59+
#ES_PORT=127.0.0.1:9200
60+
61+
# Port to expose Kibana to the host
62+
KIBANA_PORT=5601
63+
#KIBANA_PORT=80
64+
65+
# Increase or decrease based on the available host memory (in bytes)
66+
MEM_LIMIT=17179869184
67+
68+
# Project namespace (defaults to the current folder name if not set)
69+
#COMPOSE_PROJECT_NAME=myproject
70+
```
71+
72+
- **Create `docker-compose.yaml` File**:
73+
Include the following services:
74+
- `setup`: For certificate generation.
75+
- `es01`: Elasticsearch instance.
76+
- `kibana`: Kibana instance.
77+
Configure mount directories, environment variables, and network modes as needed. Below is an example:
78+
```yaml
79+
version: "3"
80+
81+
services:
82+
setup:
83+
image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
84+
volumes:
85+
- ./certs:/usr/share/elasticsearch/config/certs
86+
user: "0"
87+
command: >
88+
bash -c '
89+
if [ x${ELASTIC_PASSWORD} == x ]; then
90+
echo "Set the ELASTIC_PASSWORD environment variable in the .env file";
91+
exit 1;
92+
elif [ x${KIBANA_PASSWORD} == x ]; then
93+
echo "Set the KIBANA_PASSWORD environment variable in the .env file";
94+
exit 1;
95+
fi;
96+
if [ ! -f config/certs/ca.zip ]; then
97+
echo "Creating CA";
98+
bin/elasticsearch-certutil ca --silent --pem -out config/certs/ca.zip;
99+
unzip config/certs/ca.zip -d config/certs;
100+
fi;
101+
if [ ! -f config/certs/certs.zip ]; then
102+
echo "Creating certs";
103+
echo -ne \
104+
"instances:\n"\
105+
" - name: es01\n"\
106+
" dns:\n"\
107+
" - es01\n"\
108+
" ip:\n"\
109+
" - ip1\n"\
110+
" - name: es02\n"\
111+
" dns:\n"\
112+
" - es02\n"\
113+
" ip:\n"\
114+
" - ip2\n"\
115+
> config/certs/instances.yml;
116+
bin/elasticsearch-certutil cert --silent --pem -out config/certs/certs.zip --in config/certs/instances.yml --ca-cert config/certs/ca/ca.crt --ca-key config/certs/ca/ca.key;
117+
unzip config/certs/certs.zip -d config/certs;
118+
fi;
119+
echo "Setting file permissions"
120+
chown -R root:root config/certs;
121+
find . -type d -exec chmod 750 \{\} \;;
122+
find . -type f -exec chmod 640 \{\} \;;
123+
echo "Waiting for Elasticsearch availability";
124+
until curl -s --cacert config/certs/ca/ca.crt https://ip1:9200 | grep -q "missing authentication credentials"; do sleep 30; done;
125+
echo "Setting kibana_system password";
126+
until curl -s -X POST --cacert config/certs/ca/ca.crt -u "elastic:${ELASTIC_PASSWORD}" -H "Content-Type: application/json" https://ip1:9200/_security/user/kibana_system/_password -d "{\"password\":\"${KIBANA_PASSWORD}\"}" | grep -q "^{}"; do sleep 10; done;
127+
echo "All done!";
128+
'
129+
healthcheck:
130+
test: ["CMD-SHELL", "[ -f config/certs/es01/es01.crt ]"]
131+
interval: 1s
132+
timeout: 5s
133+
retries: 120
134+
135+
es01:
136+
depends_on:
137+
setup:
138+
condition: service_healthy
139+
image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
140+
volumes:
141+
- ./certs:/usr/share/elasticsearch/config/certs
142+
- /opt/data/es01:/usr/share/elasticsearch/data
143+
environment:
144+
- node.name=es01
145+
- cluster.name=${CLUSTER_NAME}
146+
- cluster.initial_master_nodes=es01,es02
147+
- discovery.seed_hosts=ip2
148+
- ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
149+
- bootstrap.memory_lock=true
150+
- xpack.security.enabled=true
151+
- xpack.security.http.ssl.enabled=true
152+
- xpack.security.http.ssl.key=certs/es01/es01.key
153+
- xpack.security.http.ssl.certificate=certs/es01/es01.crt
154+
- xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt
155+
- xpack.security.transport.ssl.enabled=true
156+
- xpack.security.transport.ssl.key=certs/es01/es01.key
157+
- xpack.security.transport.ssl.certificate=certs/es01/es01.crt
158+
- xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt
159+
- xpack.security.transport.ssl.verification_mode=certificate
160+
- xpack.license.self_generated.type=${LICENSE}
161+
restart: always
162+
network_mode: host
163+
ulimits:
164+
memlock:
165+
soft: -1
166+
hard: -1
167+
healthcheck:
168+
test:
169+
[
170+
"CMD-SHELL",
171+
"curl -s -k --cacert config/certs/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'",
172+
]
173+
interval: 10s
174+
timeout: 10s
175+
retries: 120
176+
177+
kibana:
178+
depends_on:
179+
es01:
180+
condition: service_healthy
181+
image: docker.elastic.co/kibana/kibana:${STACK_VERSION}
182+
volumes:
183+
- ./certs:/usr/share/kibana/config/certs
184+
- /opt/data/kibana:/usr/share/kibana/data
185+
environment:
186+
- SERVERNAME=kibana
187+
- ELASTICSEARCH_HOSTS=https://ip1:9200
188+
- ELASTICSEARCH_USERNAME=kibana_system
189+
- ELASTICSEARCH_PASSWORD=${KIBANA_PASSWORD}
190+
- ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=config/certs/ca/ca.crt
191+
restart: always
192+
network_mode: host
193+
healthcheck:
194+
test:
195+
[
196+
"CMD-SHELL",
197+
"curl -k -s -I http://localhost:5601 | grep -q 'HTTP/1.1 302 Found'",
198+
]
199+
interval: 10s
200+
timeout: 10s
201+
retries: 120
202+
```
203+
204+
### 3. Cluster Deployment Steps
205+
206+
#### 1. Start `es01` Node and Kibana
207+
- Navigate to the configuration directory on the `es01` node and start the services:
208+
```bash
209+
docker compose up -d
210+
```
211+
- Wait for the health checks to pass. You can verify the status using:
212+
```bash
213+
docker compose ps
214+
```
215+
Ensure the status shows `Healthy` or `Started`.
216+
217+
#### 2. Synchronize Configuration Files to Other Nodes
218+
- On the `es01` node, execute the following command to synchronize the certificate directory and `.env` file to the target node:
219+
```bash
220+
scp -r certs/ .env target-node:/opt/compose/es/
221+
```
222+
223+
#### 3. Deploy `es02` Node
224+
- On the `es02` node, create a dedicated `docker-compose.yaml` file. Retain only the configuration for the corresponding `es` service, adapting parameters such as node name and discovery nodes. Below is an example:
225+
```yaml
226+
version: '3'
227+
services:
228+
es02:
229+
image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
230+
volumes:
231+
- ./certs:/usr/share/elasticsearch/config/certs
232+
- /opt/data/es02/:/usr/share/elasticsearch/data
233+
environment:
234+
- node.name=es02
235+
- cluster.name=${CLUSTER_NAME}
236+
- cluster.initial_master_nodes=es01,es02
237+
- discovery.seed_hosts=ip1
238+
- bootstrap.memory_lock=true
239+
- xpack.security.enabled=true
240+
- xpack.security.http.ssl.enabled=true
241+
- xpack.security.http.ssl.key=certs/es02/es02.key
242+
- xpack.security.http.ssl.certificate=certs/es02/es02.crt
243+
- xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt
244+
- xpack.security.transport.ssl.enabled=true
245+
- xpack.security.transport.ssl.key=certs/es02/es02.key
246+
- xpack.security.transport.ssl.certificate=certs/es02/es02.crt
247+
- xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt
248+
- xpack.security.transport.ssl.verification_mode=certificate
249+
- xpack.license.self_generated.type=${LICENSE}
250+
restart: always
251+
network_mode: host
252+
ulimits:
253+
memlock:
254+
soft: -1
255+
hard: -1
256+
healthcheck:
257+
test:
258+
[
259+
"CMD-SHELL",
260+
"curl -s -k --cacert config/certs/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'",
261+
]
262+
interval: 10s
263+
timeout: 10s
264+
retries: 120
265+
```
266+
- Start the service on the `es02` node:
267+
```bash
268+
docker compose up -d
269+
```
270+
- Wait for the health checks to pass. Ensure the status changes to `Healthy`.
271+
272+
### 4. Cluster Verification
273+
274+
#### 1. Verify Cluster Nodes
275+
- Execute the following command to check if all nodes have successfully joined the cluster:
276+
```bash
277+
curl --user "elastic:<password>" -k https://<es01-node-IP>:9200/_cat/nodes?v
278+
```
279+
280+
#### 2. Check Cluster Health
281+
- Run the following command to confirm the cluster status is `green` (healthy):
282+
```bash
283+
curl --user "elastic:<password>" -k https://<es01-node-IP>:9200/_cat/health?v
284+
```
285+
286+
#### 3. Access Kibana
287+
- Open a browser and navigate to:
288+
```
289+
http://<es01-node-IP>:5601
290+
```
291+
- Log in using the `elastic` username and password to verify the availability of the Kibana visualization interface.
292+
293+
![Kibana Frontend Interface](images/db.png)
294+
295+
#### 4. Client Read/Write Data Test
296+
Below is an example Python script to test data read/write operations:
297+
```python
298+
from elasticsearch import Elasticsearch
299+
import ssl
300+
import random
301+
import time
302+
import requests
303+
requests.packages.urllib3.disable_warnings()
304+
305+
# Elasticsearch configuration
306+
HOST = "https://ip1:9200" # Elasticsearch address
307+
USER = "elastic" # Username
308+
PASSWORD = "xxx" # Password
309+
310+
def create_client():
311+
"""
312+
Create an Elasticsearch client using self-signed certificates.
313+
"""
314+
try:
315+
# Create Elasticsearch client
316+
client = Elasticsearch(
317+
hosts=[HOST],
318+
basic_auth=(USER, PASSWORD),
319+
verify_certs=False
320+
)
321+
print("Elasticsearch client created")
322+
return client
323+
except Exception as e:
324+
print(f"Error creating Elasticsearch client: {e}")
325+
raise
326+
327+
def main():
328+
client = create_client()
329+
330+
# Test connection
331+
try:
332+
print("Testing connection...")
333+
if client.ping():
334+
print("Successfully connected to Elasticsearch!")
335+
else:
336+
print("Failed to connect to Elasticsearch!")
337+
return
338+
except Exception as e:
339+
print(f"Error connecting to Elasticsearch: {e}")
340+
return
341+
342+
# Example: Create index
343+
index_name = "test-index"
344+
try:
345+
if not client.indices.exists(index=index_name):
346+
client.indices.create(index=index_name)
347+
print(f"Index {index_name} created")
348+
except Exception as e:
349+
print(f"Error creating index: {e}")
350+
return
351+
352+
# Example: Randomly write 10 documents
353+
print("Writing data...")
354+
for i in range(10):
355+
doc = {
356+
"id": i,
357+
"message": f"Random message {i}",
358+
"value": random.randint(1, 100),
359+
"timestamp": time.strftime("%Y-%m-%dT%H:%M:%S")
360+
}
361+
try:
362+
response = client.index(index=index_name, document=doc)
363+
print(f"Document written, ID: {response['_id']}")
364+
except Exception as e:
365+
print(f"Error writing document: {e}")
366+
367+
# Example: Read 10 documents
368+
print("Reading data...")
369+
try:
370+
response = client.search(index=index_name, query={"match_all": {}}, size=10)
371+
print(f"Search results: {len(response['hits']['hits'])} documents")
372+
for hit in response['hits']['hits']:
373+
print(hit['_source'])
374+
except Exception as e:
375+
print(f"Error reading documents: {e}")
376+
377+
if __name__ == "__main__":
378+
main()
379+
```

docs/src/user-guide/images/1.png

592 KB
Loading

docs/src/user-guide/images/2.png

664 KB
Loading

docs/src/user-guide/images/3.png

285 KB
Loading

docs/src/user-guide/images/db.png

302 KB
Loading

0 commit comments

Comments
 (0)