How access MongoDB in Kubernetes from outside the cluster

8/23/2019

I deployed mongodb in a Kubernetes cluster with this helm chart : https://github.com/helm/charts/tree/master/stable/mongodb. All is right. I can connect to mongo from within a replicatset container or from outside the cluster with a port-forward, or with a NodePort service. But I can't connect via an ingress.

When the ingress is deployed, I can curl mongodb and have this famous message : "It looks like you are trying to access MongoDB over HTTP on the native driver port.". But I can't connect with a mongo client, the connection stucks and I can see in mongodb logs that I never reach mongo.

Does someone have any information about accessing mongodb via an ingress object ? Maybe it's a protocol problem ?

The ingress manifests :

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ template "mongodb.fullname" . }}
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: {{ .Values.ingress.hostName }}
    http:
      paths:
        - path: /
          backend:
            serviceName: "{{ template "mongodb.fullname" $ }}"
            servicePort: mongodb
  tls:
  - hosts:
    - {{ .Values.ingress.hostName }}
    secretName: secret

Thank you very much !

-- Antoine
kubernetes
kubernetes-ingress
mongodb
portforwarding

2 Answers

8/23/2019

There are 2 ways to do this.

  1. you can create mongo url & directly point it in deployment

  2. You can create service called service type (ExternalName) with mongo url mentioned in it. Then this service you can define in deployment.

kind: Service
apiVersion: v1
metadata:
  name: <service-name>
  namespace: <namespace>
spec:
  type: ExternalName
  externalName: xx.xx.xx.xx
  ports:
  - port: xxxx
-- Sachin Arote
Source: StackOverflow

8/23/2019

Ingress controllers are designed for HTTP connections, as the error hinted, the ingress is not the way to access mongodb.

None of the information in an ingress definition makes much sense for a plain TCP connection, host names and http URL paths don't apply to plain TCP connections.

Some ingress controllers (like nginx-ingress) can support plain TCP load balancers but not via an ingress definition. They use custom config maps.

Use a Service with type: loadBalancer if your hosting environment supports it or type: nodePort if not. There is an example in the stable mongodb helm chart and it's associated values.

apiVersion: v1
kind: Service
metadata:
  name: {{ template "mongodb.fullname" . }}
  labels:
    app: {{ template "mongodb.name" . }}
spec:
  type: loadBalancer
  ports:
  - name: mongodb
    port: 27017
    targetPort: mongodb
  - name: metrics
    port: 9216
    targetPort: metrics
-- Matt
Source: StackOverflow