Vojtěch
Vojtěch

Reputation: 12416

Kubernetes Externalname working with https

We are trying to create an ExternalName service for Kubernetes to hide URL linking to our Firebase:

kind: Service
apiVersion: v1
metadata:
  name: firebase
  namespace: devel
spec:
  type: ExternalName
  externalName: firebase-project-123456.firebaseio.com

The service is created correctly, and we can ping to http://firebase. However connecting to the firebase endpoint doesn't work:

curl -v http://firebase/activity.json
< HTTP/1.1 404 Not Found
< Content-Type: text/html; charset=UTF-8
< Referrer-Policy: no-referrer

One idea is that there is an issue with https (as the target service runs on https), however then we wouldn't probably get 404, but some other error. I have no idea what might be wrong on the way.

Upvotes: 4

Views: 6216

Answers (2)

Mikhail_Sam
Mikhail_Sam

Reputation: 11208

I ran into the same problem and @MarcinRomaszewicz's answer and the problem statement are correct. But his answer does not contain details of the implementation of such a solution. I did some research and found it. This is more relevant than the idea of spinning up nginx: let's use K8S Ingresses.

kind: Service
apiVersion: v1
metadata:
  name: backend-svc
  namespace: my-namespace
  annotations:
    ingress.kubernetes.io/preserve-host: "false"
spec:
  type: ExternalName
  externalName: backend.address.com
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: backend-ing
  namespace: my-namespace
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    nginx.ingress.kubernetes.io/upstream-vhost: backend.address.com
spec:
  rules:
    - host: myweb.address.com
      http:
        paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: backend-svc
                port:
                  number: 443
---

In this example, I create a Service of type ExternalService simply to redirect to some other service (in fact, in my example it is also Ingress in k8S, but in a different namespace and even cluster) And create an Ingress to receive requests from myweb.address.com/api and forward them to our external service.

The main information here is Ingress annotations! Use upstream-vhost to solve the problem!

P.S. Another recommendation is to use port 443 and backend-protocol annotation to work over HTTPS instead of HTTP.

Upvotes: 3

Marcin Romaszewicz
Marcin Romaszewicz

Reputation: 969

You might be running into a virtual host issue. firebase-project-123456.firebaseio.com is a virtual host name which is then used to route your request to the correct backend. A Kubernetes external service is essentially a DNS CNAME, which forces a second DNS lookup for the actual host name.

See if this works for you:

curl -v -H "Host: firebase-project-123456.firebaseio.com" http://firebase/activity.json

If it does, that's what you're running into. You might have to make a trivially simple service instead, which proxies your requests to the correct URL at firebase.

Upvotes: 4

Related Questions