Skip to content

Commit ff7aa7c

Browse files
chatbot-rag-app: adds Kubernetes manifest and instructions
Signed-off-by: Adrian Cole <[email protected]>
1 parent 21cfcc6 commit ff7aa7c

File tree

7 files changed

+365
-8
lines changed

7 files changed

+365
-8
lines changed

docker/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ Note: If you haven't checked out this repository, all you need is one file:
99
wget https://raw.githubusercontent.com/elastic/elasticsearch-labs/refs/heads/main/docker/docker-compose-elastic.yml
1010
```
1111

12-
Use docker compose to run Elastic stack in the background:
12+
Before you begin, ensure you have free CPU and memory on your Docker host. If
13+
you plan to use ELSER, assume a minimum of 8 cpus and 6GB memory for the
14+
containers in this compose file.
1315

16+
First, start this Elastic Stack in the background:
1417
```bash
1518
docker compose -f docker-compose-elastic.yml up --force-recreate --wait -d
1619
```
@@ -20,7 +23,6 @@ Then, you can view Kibana at http://localhost:5601/app/home#/
2023
If asked for a username and password, use username: elastic and password: elastic.
2124

2225
Clean up when finished, like this:
23-
2426
```bash
2527
docker compose -f docker-compose-elastic.yml down
2628
```

example-apps/chatbot-rag-app/Dockerfile

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ COPY frontend ./frontend
55
RUN cd frontend && yarn install
66
RUN cd frontend && REACT_APP_API_HOST=/api yarn build
77

8-
# langchain and vertexai depend on a large number of system packages including
9-
# linux-headers, g++, geos, geos-dev, rust and cargo. These are already present
10-
# on -slim and adding them to -alpine results in a larger image than -slim.
8+
# Use glibc-based image to get pre-compiled wheels for grpcio and tiktoken
119
FROM python:3.12-slim
1210

1311
WORKDIR /app

example-apps/chatbot-rag-app/README.md

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ Copy [env.example](env.example) to `.env` and fill in values noted inside.
2222
## Installing and connecting to Elasticsearch
2323

2424
There are a number of ways to install Elasticsearch. Cloud is best for most
25-
use-cases. We also have [docker-compose-elastic.yml](../../docker), that starts
26-
Elasticsearch, Kibana, and APM Server on your laptop with one command.
25+
use-cases. We also have [docker-compose-elastic.yml][docker-compose-elastic],
26+
that starts Elasticsearch, Kibana, and APM Server on your laptop in one step.
2727

2828
Once you decided your approach, edit your `.env` file accordingly.
2929

@@ -71,6 +71,62 @@ Clean up when finished, like this:
7171
docker compose down
7272
```
7373

74+
### Run with Kubernetes
75+
76+
Kubernetes is more complicated than Docker, but closer to the production
77+
experience for many users. [k8s-manifest.yml](k8s-manifest.yml) creates the
78+
same services, but needs additional configuration first.
79+
80+
First step is to setup your environment. [env.example](env.example) must be
81+
copied to a file name `.env` and updated with `ELASTICSEARCH_URL` and
82+
`OTEL_EXPORTER_OTLP_ENDPOINT` values visible to you Kubernetes deployment.
83+
84+
For example, if you started your Elastic Stack with [k8s-manifest-elastic.yml][k8s-manifest-elastic],
85+
you would update these values:
86+
```
87+
ELASTICSEARCH_URL=http://elasticsearch:9200
88+
OTEL_EXPORTER_OTLP_ENDPOINT=http://apm-server:8200
89+
```
90+
91+
Then, import your `.env` file as a configmap like this:
92+
```bash
93+
kubectl create configmap chatbot-rag-app-env --from-env-file=.env
94+
```
95+
96+
If you are using Vertex AI, make a secret for authentication:
97+
```bash
98+
kubectl create secret generic gcloud-credentials \
99+
--from-file=application_default_credentials.json=$HOME/.config/gcloud/application_default_credentials.json
100+
```
101+
102+
Now that your configuration is applied, create the chatbot-rag-app deployment
103+
and service by applying this manifest:
104+
```bash
105+
kubectl apply -f k8s-manifest.yml
106+
```
107+
108+
Next, block until chatbot-rag-app is available.
109+
```bash
110+
kubectl wait --for=condition=available --timeout=20m deployment/chatbot-rag-app
111+
```
112+
113+
*Note*: The first run may take several minutes to become available. Here's how
114+
to follow logs on this stage:
115+
```bash
116+
kubectl logs deployment.apps/chatbot-rag-app -c create-index -f
117+
```
118+
119+
Next, forward the kibana port:
120+
```bash
121+
kubectl port-forward service/kibana 5601:5601 &
122+
```
123+
124+
Clean up when finished, like this:
125+
126+
```bash
127+
kubectl delete -f k8s-manifest.yml
128+
```
129+
74130
### Run with Python
75131

76132
If you want to run this example with Python, you need to do a few things listed
@@ -196,3 +252,5 @@ docker compose up --build --force-recreate
196252
---
197253
[loader-docs]: https://python.langchain.com/docs/how_to/#document-loaders
198254
[install-es]: https://www.elastic.co/search-labs/tutorials/install-elasticsearch
255+
[docker-compose-elastic]: ../../docker/docker-compose-elastic.yml
256+
[k8s-manifest-elastic]: ../../k8s/k8s-manifest-elastic.yml

example-apps/chatbot-rag-app/env.example

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ FLASK_APP=api/app.py
66
PYTHONUNBUFFERED=1
77

88
# How you connect to Elasticsearch: change details to your instance
9+
# This defaults to a Elastic Stack accessible via localhost. When this is
10+
# running inside Kubernetes, update to http://elasticsearch:9200 or similar.
911
ELASTICSEARCH_URL=http://localhost:9200
1012
ELASTICSEARCH_USER=elastic
1113
ELASTICSEARCH_PASSWORD=elastic
@@ -68,7 +70,9 @@ OTEL_SDK_DISABLED=true
6870
# Assign the service name that shows up in Kibana
6971
OTEL_SERVICE_NAME=chatbot-rag-app
7072

71-
# Default to send traces to the Elastic APM server
73+
# Default to send logs, traces and metrics to an Elastic APM server accessible
74+
# via localhost. If using running inside k8s, update to http://apm-server:8200
75+
# or similar.
7276
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:8200
7377
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
7478

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
apiVersion: apps/v1
3+
kind: Deployment
4+
metadata:
5+
name: chatbot-rag-app
6+
spec:
7+
replicas: 1
8+
selector:
9+
matchLabels:
10+
app: chatbot-rag-app
11+
template:
12+
metadata:
13+
labels:
14+
app: chatbot-rag-app
15+
spec:
16+
# The below will recreate your secret based on the gcloud credentials file
17+
# kubectl create secret generic gcloud-credentials \
18+
# --from-file=application_default_credentials.json=$HOME/.config/gcloud/application_default_credentials.json
19+
volumes:
20+
- name: gcloud-credentials
21+
secret:
22+
secretName: gcloud-credentials
23+
initContainers:
24+
- name: create-index
25+
image: &image ghcr.io/elastic/elasticsearch-labs/chatbot-rag-app:latest
26+
args: ["flask", "create-index"]
27+
env:
28+
- name: FLASK_APP
29+
value: api/app.py
30+
# This recreates your configmap based on your .env file:
31+
# kubectl create configmap chatbot-rag-app-env --from-env-file=.env
32+
envFrom: &envFrom
33+
- configMapRef:
34+
name: chatbot-rag-app-env
35+
volumeMounts: &volumeMounts
36+
- name: gcloud-credentials
37+
mountPath: /root/.config/application_default_credentials.json
38+
readOnly: true
39+
containers:
40+
- name: api-frontend
41+
image: *image
42+
ports:
43+
- containerPort: 4000
44+
envFrom: *envFrom
45+
volumeMounts: *volumeMounts
46+
---
47+
apiVersion: v1
48+
kind: Service
49+
metadata:
50+
name: api
51+
spec:
52+
selector:
53+
app: chatbot-rag-app
54+
ports:
55+
- protocol: TCP
56+
port: 4000
57+
targetPort: 4000

k8s/README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Running your own Elastic Stack with Kubernetes
2+
3+
If you'd like to start Elastic with Kubernetes, you can use the provided
4+
[manifest-elastic.yml](manifest-elastic.yml) file. This starts
5+
Elasticsearch, Kibana, and APM Server in an existing Kubernetes cluster.
6+
7+
Note: If you haven't checked out this repository, all you need is one file:
8+
```bash
9+
wget https://raw.githubusercontent.com/elastic/elasticsearch-labs/refs/heads/main/docker/docker-compose-elastic.yml
10+
```
11+
12+
Before you begin, ensure you have free CPU and memory in your cluster. If you
13+
plan to use ELSER, assume a minimum of 8 cpus and 6GB memory for the containers
14+
in this manifest.
15+
16+
First, start this Elastic Stack in the background:
17+
```bash
18+
kubectl apply -f k8s-manifest-elastic.yml
19+
```
20+
21+
**Note**: For simplicity, this adds an Elastic Stack to the default namespace.
22+
Commands after here are simpler due to this. If you want to choose a different
23+
one, use `kubectl`'s `--namespace` flag!
24+
25+
Next, block until the whole stack is available. First install or changing the
26+
Elastic Stack version can take a long time due to image pulling.
27+
```bash
28+
kubectl wait --for=condition=available --timeout=10m \
29+
deployment/elasticsearch \
30+
deployment/kibana \
31+
deployment/apm-server
32+
```
33+
34+
Next, forward the kibana port:
35+
```bash
36+
kubectl port-forward service/kibana 5601:5601 &
37+
```
38+
39+
Finally, you can view Kibana at http://localhost:5601/app/home#/
40+
41+
If asked for a username and password, use username: elastic and password: elastic.
42+
43+
Clean up when finished, like this:
44+
45+
```bash
46+
kubectl delete -f k8s-manifest-elastic.yml
47+
```

0 commit comments

Comments
 (0)