1
votes

I am trying to run a kubernetes closer locally using minikube. This is my first try with kubernetes. Therefore I am not familiar with all aspects of it. I am trying to deploy a spring boot app which connects to elastic search server.

springboot deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: myapp
          image: myapp1:latest
          imagePullPolicy: Never

Elastic search sever deployment.yaml

    apiVersion: apps/v1
kind: Deployment
metadata:
  name: elasticsearch
spec:
  selector:
    matchLabels:
      run: elasticsearch
  replicas: 1
  template:
    metadata:
      labels:
        run: elasticsearch
    spec:
      containers:
        - image: docker.elastic.co/elasticsearch/elasticsearch:6.6.1
          name: elasticsearch
          imagePullPolicy: IfNotPresent
          env:
            - name: discovery.type
              value: single-node
            - name: cluster.name
              value: elasticsearch
          ports:
          - containerPort: 9300
            name: nodes
          - containerPort: 9200
            name: client

Exposed elastic search service as follows

apiVersion: v1
kind: Service
metadata:
  name: elasticsearch
  labels:
    service: elasticsearch
spec:
  ports:
    - name: client
      port: 9200
      protocol: TCP
      targetPort: 9200
    - name: nodes
      port: 9300
      protocol: TCP
      targetPort: 9300
  type: NodePort

  selector:
    run: elasticsearch

Similarly, I exposed service of springboot app also. Now I am wondering how can I connect from springboot services to elastic search service.

When springbbot and elastic search was normal deployment on the same machine ( not in kubernetes), I connected using as

RestClient.builder(new HttpHost("localhost", 9200))
                .build();

What's the best way to connect to the elastic search from springboot in kubernetes?

Save the ip of the elastic search service in an environment variable and use it in springboot or use the service name of the elastic search service?

Please advice

2
Can you paste correct Elastic search sever deployment.yaml ?Matt
The deployment.yaml provided in the question is the one. I do not have anything elsenantitv
Then why your "deployment" is kind: Service ? and why your elasticsearch deployment is the same as elasticsearch service?Matt
@HelloWorld Sorry. I did not notice it. Corrected it. Thanksnantitv
All yaml files look fine. Try using full domain name: elasticsearch.default.svc.cluster.local. Also if you are getting Connection refused try figuring out where is you springboot app trying to connect. (e.g. print HttpHost ip address to logs or run tcpdump and look at destination ip).Matt

2 Answers

2
votes

You should be able to get to the service, from within the cluster, using:

http://servicename.servicenamespace:serviceport

Kubernetes dns internal to the cluster will resolve the service name as a host name. If they are in the same namespace you probably don't need the serivcenamespace

Given the yaml above and if you used the default namespace for both elasticsearch and your myapp, then myapp process can connect via:

http://elasticsearch:9200
1
votes

Now, I am able to connect to the elastic search from my springboot app. Somehow springboot is not able to connect it using http://elasticsearch:9200.

Instead, I pass the ip and port of the exposed elastic search service (9200 port's equivalent output of minikube service elasticsearch --url) (ip of the node:exposed Nodeport of 9200)to every springboot request which connects to the elastic search service and now I am able to connect it.

I know that it's not the ideal solution and I do not know why it can not resolve the servicename to ip. But atleast I am able to proceed.

It will be helpful, if somebody can suggest someways to fix/diagnose the issue

******* UPDATE ******

Finally springboot is able to connect with elastic search using http://elasticsearch:9200. I do not know which change done by me fixed that. I changed my elasticsearch from a Deployment to Statefulset as shown in the following yaml but that change was not done to fix this issue.

Another change which I did is in the label. I changed it from "run":"elasticsearch" to "app":"elastcisearch" but I do not know whether this helped in that. (I am going to read more labels change and will see whether this has any effect). Please see the final elasticsearch.yaml file ( more explanation of the file can be seen at Minikube - Not able to get any result from elastic search to if it uses existing indices)

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: elasticsearch
spec:
  serviceName: "elasticsearch"
  replicas: 1
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      initContainers:
      - name: set-permissions
        image: registry.hub.docker.com/library/busybox:latest
        command: ['sh', '-c', 'mkdir -p /usr/share/elasticsearch/data && chown 1000:1000 /usr/share/elasticsearch/data' ]
        volumeMounts:
        - name: data
          mountPath: /usr/share/elasticsearch/data
      containers:
      - name: elasticsearch
        image: docker.elastic.co/elasticsearch/elasticsearch:6.6.1
        env:
        - name: discovery.type
          value: single-node
        ports:
        - containerPort: 9200
          name: client
        - containerPort: 9300
          name: nodes
        volumeMounts:
        - name: data
          mountPath: /usr/share/elasticsearch/data
      volumes:
      - name: data
        hostPath:
          path: /indexdata
---
apiVersion: v1
kind: Service
metadata:
  name: elasticsearch
  labels:
    service: elasticsearch
spec:
  ports:
  - port: 9200
    name: client
  - port: 9300
    name: nodes
  type: NodePort  
  selector:
    app: elasticsearch