【问题标题】:Kubernetes - Connect Elastic search from a springboot app in minikubeKubernetes - 从 minikube 中的 Spring Boot 应用程序连接 Elasticsearch
【发布时间】:2020-08-24 15:24:13
【问题描述】:

我正在尝试使用 minikube 在本地更近地运行 kubernetes。这是我第一次尝试 Kubernetes。所以 我不熟悉它的所有方面。 我正在尝试部署一个连接到弹性搜索服务器的 Spring Boot 应用程序。

springboot 部署.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

弹性搜索服务器 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

暴露弹性搜索服务如下

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

同样,我也暴露了 springboot app 的服务。 现在我想知道如何从 springboot 服务连接到弹性搜索服务。

当 springbbot 和弹性搜索在同一台机器上正常部署时(不在 kubernetes 中),我使用 as 连接

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

在 kubernetes 中从 springboot 连接到弹性搜索的最佳方式是什么?

将elasticsearch服务的ip保存在环境变量中,在springboot中使用还是使用elasticsearch服务的服务名?

请指教

【问题讨论】:

  • 你能正确粘贴Elastic search sever deployment.yaml吗?
  • 问题中提供的deployment.yaml就是那个。我没有别的了
  • 那为什么你的“部署”是kind: Service?为什么你的 elasticsearch 部署和 elasticsearch 服务一样?
  • @HelloWorld 抱歉。我没有注意到它。更正了它。谢谢
  • 所有 yaml 文件看起来都很好。尝试使用完整的域名:elasticsearch.default.svc.cluster.local. 另外,如果您收到Connection refused,请尝试找出您的 springboot 应用程序在哪里尝试连接。 (例如,将 HttpHost ip 地址打印到日志或运行 tcpdump 并查看目标 ip)。

标签: spring-boot elasticsearch kubernetes


【解决方案1】:

您应该能够从集群中访问该服务,使用:

http://servicename.servicenamespace:serviceport

集群内部的 Kubernetes dns 会将服务名称解析为主机名。如果它们在同一个命名空间中,您可能不需要服务命名空间

鉴于上面的 yaml,如果您对 elasticsearch 和 myapp 都使用了默认命名空间,那么 myapp 进程可以通过以下方式连接:

http://elasticsearch:9200

【讨论】:

  • 我试过了。它抛出java.net.ConnectException: Connection refused at org.elasticsearch.client.RestClient$SyncResponseListener.get(RestClient.java:952) ~[elasticsearch-rest-client-6.6.1.jar:6.6.1] at org.elasticsearch.client.RestClient.performRequest(RestClient.java:229) ~[elasticsearch-rest-client-6.6.1.jar:6.6.1] at org.elasticsearch.client.RestClient.performRequest(RestClient.java:323) ~[elasticsearch-rest-client-6.6.1.jar:6.6.1] on line client.performRequest("GET", "/_search", Collections.emptyMap(), new StringEntity(query, ContentType.APPLICATION_JSON)
  • 但是我可以直接使用ip192.168.64.3:30876/_search?q=user:kimchy连接弹性搜索
【解决方案2】:

现在,我可以从我的 springboot 应用程序连接到 弹性搜索。 不知何故,springboot 无法使用 http://elasticsearch:9200 连接它。

相反,我传递了暴露的弹性搜索服务的ip和端口minikube service elasticsearch --url的9200端口等效输出)(节点的ip:将 9200 的 Nodeport 暴露给每个连接到弹性搜索服务的 springboot 请求,现在我可以连接它了。

我知道这不是理想的解决方案,我不知道为什么它不能将 servicename 解析为 ip。但至少我可以继续。

如果有人可以提出解决/诊断问题的建议,这将很有帮助

******** 更新 ******

终于 springboot 能够使用http://elasticsearch:9200 连接弹性搜索。我不知道我所做的哪个更改解决了这个问题。我将我的 elasticsearch 从 Deployment 更改为 Statefulset,如下面的 yaml 所示,但该更改并未解决此问题。

我所做的另一个更改是在标签中。我将它从 "run":"elasticsearch" 更改为 "app":"elastcisearch" 但我不知道这是否有帮助。 (我将阅读更多标签更改,并查看这是否有任何影响)。 请看最终的elasticsearch.yaml文件(文件的更多解释可以看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

【讨论】:

    猜你喜欢
    • 2019-12-16
    • 2020-03-07
    • 2020-06-25
    • 1970-01-01
    • 2014-09-25
    • 2021-06-09
    • 1970-01-01
    • 1970-01-01
    • 2018-09-26
    相关资源
    最近更新 更多