How can I make two container connect each other via serviceName in K8S?

12/31/2020

I declared two containers in minikube cluster, elasticsearch and kibana. kibana needs to access elasticsearch endpoint at 9200 port. I declared elasticsearch as StatefulSet and give a serviceName elasticsearch.

When I look at kibana log I can see this error:

{"type":"log","@timestamp":"2020-12-31T03:37:45Z","tags":["warning","elasticsearch","monitoring"],"pid":6,"message":"Unable to revive connection: http://elasticsearch:9200/"}
{"type":"log","@timestamp":"2020-12-31T03:37:45Z","tags":["warning","elasticsearch","monitoring"],"pid":6,"message":"No living connections"}

it means kibana can't reach elasticsearch hostname. Is there anything wrong with my configuration?

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: es-cluster
spec:
  serviceName: elasticsearch-entrypoint 
  replicas: 1
  selector:
    matchLabels:
      name: elasticsearch
  template:
    metadata:
      labels:
        name: elasticsearch
    spec:
      containers:
        - name: elasticsearch
          image: elasticsearch:7.10.1
          ports:
            - containerPort: 9200
              name: rest
            - containerPort: 9300
              name: inter-node
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kibana
spec:
  replicas: 1
  selector:
    matchLabels:
      name: kibana
  template:
    metadata:
      labels:
        name: kibana
    spec:
      containers:
        - name: kibana
          image: kibana:7.10.1
          ports:
            - containerPort: 5601
          env:
            - name: ELASTICSEARCH_HOSTS
              value: http://es-cluster-0.elasticsearch-entrypoint.default.svc.local:9200
---
apiVersion: v1
kind: Service
metadata:
  name: elasticsearch-entrypoint
  namespace: default
spec:
  clusterIP: None
  selector:
    name: elasticsearch
  ports:
  - port: 9200
    name: rest
  - port: 9300
    name: inter-node
---
apiVersion: v1
kind: Service
metadata:
  name: kibana-entrypoint
  namespace: default
spec:
  selector:
    name: kibana
  ports:
  - port: 5601
-- Joey Yi Zhao
elasticsearch
kubernetes

2 Answers

12/31/2020

From the docs

StatefulSets currently require a Headless Service to be responsible for the network identity of the Pods. You are responsible for creating this service by specifying clusterIP: None

apiVersion: v1
kind: Service
metadata:
  name: elasticsearch
  namespace: default
spec:
  clusterIP: None
  selector:
    name: elasticsearch
  ports:
  - port: 9200
  - port: 9300

Then you can access it via elasticsearch:9200 and elasticsearch:9300

-- Arghya Sadhu
Source: StackOverflow

12/31/2020

You need to create a headless governing service for your statefulSet:

apiVersion: v1
kind: Service
metadata:
  name: elasticsearch-entrypoint
  namespace: default
spec:
  clusterIP: None
  selector:
    name: elasticsearch
  ports:
  - port: 9200
    name: rest
  - port: 9300
    name: inter-node

In your deployment of kibana env variable ELASTICSEARCH_HOSTS need to set http://es-cluster-0.elasticsearch-entrypoint.default.svc.cluster.local:9200.

The template is like my_pod_name.my_Service_Name.my_Namespace.svc.cluster-domain.example , but you can skip the cluster-domain.example part. Only Service_Name.Namespace.svc will work fine.

here is the full yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: es-cluster
spec:
  serviceName:  elasticsearch-entrypoint
  replicas: 1
  selector:
    matchLabels:
      name: elasticsearch
  template:
    metadata:
      labels:
        name: elasticsearch
    spec:
      containers:
        - name: elasticsearch
          image: elasticsearch:7.10.1
          ports:
            - containerPort: 9200
              name: rest
            - containerPort: 9300
              name: inter-node
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kibana
spec:
  replicas: 1
  selector:
    matchLabels:
      name: kibana
  template:
    metadata:
      labels:
        name: kibana
    spec:
      containers:
        - name: kibana
          image: kibana:7.10.1
          ports:
            - containerPort: 5601
          env:
            - name: ELASTICSEARCH_HOSTS
              value: http://es-cluster-0.elasticsearch-entrypoint.default.svc.cluster.local:9200
---
apiVersion: v1
kind: Service
metadata:
  name: elasticsearch-entrypoint
  namespace: default
spec:
  clusterIP: None
  selector:
    name: elasticsearch
  ports:
  - port: 9200
    name: rest
  - port: 9300
    name: inter-node
---
apiVersion: v1
kind: Service
metadata:
  name: kibana-entrypoint
  namespace: default
spec:
  selector:
    name: kibana
  ports:
  - port: 5601
-- Emon46
Source: StackOverflow