Search code examples
dockerkubernetesgoogle-compute-enginedevops

Can a host be redirected to a service path in Kubernetes?


I'm trying to try to match a host address to a service path, as an example, let's think i have an nginx pod servying to sites: site1 and site2. Let's think about a service called my-nginx-service which services my two sites as paths:

- my-nginx-service (178.123.55.37:80) 
    - /site1
    - /site2

There exists a way to map it to something like:

- host: site-one.mydomain.com
    http:
      paths:
      - backend:
          serviceName: nginx-service
          servicePort: 80
          servicePath: /site2
  - host: site-two.mydomain.com
    http:
      paths:
      - backend:
          serviceName: nginx-service
          servicePort: 80
          servicePath: /site2

? I have not found anything about it in docs. Or maybe I've not understood well them.

Thank you very much for your time!


Solution

  • What you are trying to do (if I understood right) is impossible, because services are unaware of host names. You might be able to reach what you want by modifying nginx configuration within the pod, but that would not be a K8s approach.

    What you need to do is to add an ingress resource. Ingresses are aware of host names. They do load balancing between services. So, /site1 one would go to one service, and /site2 to the other one.

    This is what the ingress should look like:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: ingress
    spec:
      rules:
      - host: site-one.mydomain.com
        http:
          paths:
          - backend:
              serviceName: nginx-service1
              servicePort: 80
      - host: site-two.mydomain.com
        http:
          paths:
          - backend:
              serviceName: nginx-service2
              servicePort: 80
    

    As you can see site1 and site2 would be running in different deployments, with different services targeting them. Ingress, which is L7 Load Balancer would be able to check the host name and forward the request to the right service, which in the end would hit the right pod.

    You can also add paths to each host, so site-one.mydomain.com/path1, site-one.mydomain.com/path2 and site-two.mydomain.com/path1 (for example), would be forwarded to different services.

    The Ingress yaml file would look like this:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: ingress
    spec:
      rules:
      - host: site-one.mydomain.com
        http:
          paths:
          - path: /path1
            backend:
              serviceName: nginx-service1
              servicePort: 80
          - path: /path2
            backend:
              serviceName: nginx-service2
              servicePort: 8080
          - path: /
            backend:
              serviceName: nginx-service3
              servicePort: 80
      - host: site-two.mydomain.com
        http:
          paths:
          - path: /path1
            backend:
              serviceName: nginx-service1
              servicePort: 80
    

    I know this is not what you exactly are asking, but this is the right way to achieve what you want.