Search code examples
kuberneteskubernetes-ingressnginx-ingress

Can the same hostname be used in different namespaces in kubernetes?


I want to use my hostname as test.com in first namespace and example.com/demo in another namespace. However i am unable to do that since (in my opinion) the nginx-ingress controller always points to the first website (example.com). My nginx-ingress controller is running in the default namespace

#namespace prod
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: ingress
  namespace: production
    annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: 20m
spec:
  rules:
    - host: example.com
      http:
        paths:
          - path: /static
            backend:
              serviceName: app-svc
              servicePort: 80
          - path: /
            backend:
              serviceName: app-svc
              servicePort: 8000
  tls:
  - hosts:
    - example.com
    secretName: cert
status:
  loadBalancer:
    ingress:
      - ip: xx.xxx.xx.xxx


#namespace dev
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: test-ingress
  namespace: dev-env
    annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: 20m
spec:
  rules:
    - host: example.com
      http:
        paths:
          - path: /static
            backend:
              serviceName: app-svc
              servicePort: 80
          - path: /demo
            backend:
              serviceName: app-svc
              servicePort: 8000
  tls:
  - hosts:
    - example.com
    secretName: cert
status:
  loadBalancer:
    ingress:
      - ip: xx.xxx.xx.xxx
 
 

Solution

  • You can use the same hostname/domain, but in order to access distinct backend services, you have to define distinct paths, in your case you can do something like this:

    #namespace prod
    kind: Ingress
    apiVersion: extensions/v1beta1
    metadata:
      name: test-ingress
      namespace: prod-env
        annotations:
        nginx.ingress.kubernetes.io/proxy-body-size: 20m
    spec:
      rules:
        - host: example.com
          http:
            paths:
              - path: /prod/static
                backend:
                  serviceName: app-svc
                  servicePort: 80
              - path: /prod/
                backend:
                  serviceName: app-svc
                  servicePort: 8000
      tls:
      - hosts:
        - example.com
        secretName: selfsigned-cert
    status:
      loadBalancer:
        ingress:
          - ip: 80.180.31.153
    
    
    #namespace dev
    kind: Ingress
    apiVersion: extensions/v1beta1
    metadata:
      name: test-ingress
      namespace: dev-env
        annotations:
        nginx.ingress.kubernetes.io/proxy-body-size: 20m
    spec:
      rules:
        - host: example.com
          http:
            paths:
              - path: /dev/static
                backend:
                  serviceName: app-svc
                  servicePort: 80
              - path: /demo
                backend:
                  serviceName: app-svc
                  servicePort: 8000
      tls:
      - hosts:
        - example.com
        secretName: selfsigned-cert
    status:
      loadBalancer:
        ingress:
          - ip: 80.180.31.153
    

    Like this you have:

    example.com/prod/static -> points to app-svc:80 on prod-env namespace  
    example.com/prod/ -> points to app-svc:8000 on prod-env namespace  
    
    example.com/dev/static -> points to app-svc:8000 on dev-env namespace  
    example.com/demo -> points to app-svc:8000 on dev-env namespace 
    

    If you need to preserve the url after host, you should add a subdomain for each namespace:

    dev.example.com/static -> points to app-svc:80 on prod-env namespace  
    prod.example.com/static -> points to app-svc:8000 on dev-env namespace  
    

    In order for this one to work you have to have defined this as an A record in your domain DNS administration, pointing at the same IP as your loadBalancer (80.180.31.153 in this case):

    example.com A -> 80.180.31.153 (optional)   
    dev.exmaple.com A -> 80.180.31.153  
    prod.example.com A -> 80.180.31.153  
    

    or the easiest one:

    *.example.com A -> 80.180.31.153