From 9f0bb963b1a32848c1298a366ce38abe17f38a1b Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Mon, 17 Feb 2025 14:41:28 +0800 Subject: [PATCH] chatbot-rag-app: adds Kubernetes manifest and instructions Signed-off-by: Adrian Cole --- docker/docker-compose-elastic.yml | 8 +-- example-apps/chatbot-rag-app/README.md | 43 +++++++++++++ example-apps/chatbot-rag-app/k8s-manifest.yml | 61 +++++++++++++++++++ 3 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 example-apps/chatbot-rag-app/k8s-manifest.yml diff --git a/docker/docker-compose-elastic.yml b/docker/docker-compose-elastic.yml index 6d2b0b8b..8f900890 100644 --- a/docker/docker-compose-elastic.yml +++ b/docker/docker-compose-elastic.yml @@ -2,7 +2,7 @@ name: elastic-stack services: elasticsearch: - image: docker.elastic.co/elasticsearch/elasticsearch:8.17.0 + image: docker.elastic.co/elasticsearch/elasticsearch:8.17.2 container_name: elasticsearch ports: - 9200:9200 @@ -30,7 +30,7 @@ services: depends_on: elasticsearch: condition: service_healthy - image: docker.elastic.co/elasticsearch/elasticsearch:8.17.0 + image: docker.elastic.co/elasticsearch/elasticsearch:8.17.2 container_name: elasticsearch_settings restart: 'no' command: > @@ -42,7 +42,7 @@ services: ' kibana: - image: docker.elastic.co/kibana/kibana:8.17.0 + image: docker.elastic.co/kibana/kibana:8.17.2 container_name: kibana depends_on: elasticsearch_settings: @@ -66,7 +66,7 @@ services: interval: 1s apm-server: - image: docker.elastic.co/apm/apm-server:8.17.0 + image: docker.elastic.co/apm/apm-server:8.17.2 container_name: apm-server depends_on: elasticsearch: diff --git a/example-apps/chatbot-rag-app/README.md b/example-apps/chatbot-rag-app/README.md index bf10b9ec..c9779a30 100644 --- a/example-apps/chatbot-rag-app/README.md +++ b/example-apps/chatbot-rag-app/README.md @@ -69,6 +69,49 @@ Clean up when finished, like this: docker compose down ``` +### Run with Kubernetes + +Our Kubernetes manifest will run similar to Docker, using host networking by +default to eliminate the need to forward ports or use special hostnames to +access localhost. Unless you change [k8s-manifest.yml](k8s-manifest.yml), the +app chatbot-rag-app will do the following: +* The init-container named "ingest-data" ingests data into elasticsearch +* The container named "api-frontend", listens on http://localhost:4000 + +**Double-check you have a `.env` file with all your variables set first!** + +Then, import your .env file as a configmap like this: +```bash +kubectl create configmap chatbot-rag-app-env --from-env-file=.env +``` + +If you are using Vertex AI, make a secret for authentication: +```bash +kubectl create secret generic gcloud-credentials \ + --from-file=application_default_credentials.json=$HOME/.config/gcloud/application_default_credentials.json +``` + +Now, apply the manifest: +```bash +kubectl apply -f k8s-manifest.yml +``` + +*Note*: First time creating the index can fail on timeout. You can verify that +like this: +```bash +kubectl logs -l app=chatbot-rag-app -c ingest-data +``` + +If you need to retry, do a rolling restart like this: +```bash +kubectl rollout restart deployment/chatbot-rag-app +``` + +Clean up when finished, like this: +```bash +kubectl delete -f k8s-manifest.yml +``` + ### Run locally If you want to run this example with Python and Node.js, you need to do a few diff --git a/example-apps/chatbot-rag-app/k8s-manifest.yml b/example-apps/chatbot-rag-app/k8s-manifest.yml new file mode 100644 index 00000000..158da949 --- /dev/null +++ b/example-apps/chatbot-rag-app/k8s-manifest.yml @@ -0,0 +1,61 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: chatbot-rag-app +spec: + replicas: 1 + selector: + matchLabels: + app: chatbot-rag-app + template: + metadata: + labels: + app: chatbot-rag-app + spec: + # Simplify networking so that it can look for elasticsearch on localhost + hostNetwork: true + # The below will recreate your secret based on the gcloud credentials file + # kubectl create secret generic gcloud-credentials \ + # --from-file=application_default_credentials.json=$HOME/.config/gcloud/application_default_credentials.json + volumes: + - name: gcloud-credentials + secret: + secretName: gcloud-credentials + initContainers: + - name: ingest-data + image: &image ghcr.io/elastic/elasticsearch-labs/chatbot-rag-app:latest + imagePullPolicy: &imagePullPolicy IfNotPresent + args: ["flask", "create-index"] + env: + - name: FLASK_APP + value: api/app.py + # The below will recreate your configmap based on the .env file + # kubectl create configmap chatbot-rag-app-env --from-env-file=.env + envFrom: &envFrom + - configMapRef: + name: chatbot-rag-app-env + volumeMounts: &volumeMounts + - name: gcloud-credentials + mountPath: /root/.config/application_default_credentials.json + readOnly: true + containers: + - name: api-frontend + image: *image + imagePullPolicy: *imagePullPolicy + ports: + - containerPort: 4000 + envFrom: *envFrom + volumeMounts: *volumeMounts +--- +apiVersion: v1 +kind: Service +metadata: + name: api +spec: + selector: + app: chatbot-rag-app + ports: + - protocol: TCP + port: 4000 + targetPort: 4000