Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Same host rule in multiple ingress objects #76

Closed
thetechnick opened this issue Nov 18, 2016 · 14 comments
Closed

Same host rule in multiple ingress objects #76

thetechnick opened this issue Nov 18, 2016 · 14 comments

Comments

@thetechnick
Copy link
Contributor

In Kubernetes it is possible to create multiple ingress objects with rules referencing the same host. How the nginx ingress controller should handle this case is not written down in the kubernetes documentation (at least I cant find it).

The official kubernetes nginx ingress controller old repo or new repo and the gce ingress controller are merging multiple ingress configurations into one nginx server object. So to specify one of the examples in multiple ingress objects is valid and leads to the expected behavior.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: cafe-ingress1
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /tea
        backend:
          serviceName: tea-svc
          servicePort: 80
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: cafe-ingress2
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /coffee
        backend:
          serviceName: coffee-svc
          servicePort: 80

The nginxinc ingress controller does not merge these rules. If there is more than one ingress object defined, it will write multiple separate server objects into the nginx config folder.

Nginx is not happy about this :P
conflicting server name "example.com" on 0.0.0.0:80, ignored

Some tools like kube-lego rely on the merging behavior to work, so simply ignoring additional ingress objects is not the best solution.

Before implementing this merge feature, it is necessary to formulate exactly how the nginx ingress controller should behave and how the order of merging is determined.

Collisions or conflicts should be dealt with gracefully, so the ingress controller is not "blocked" while a issue exists and detailed log entries should be generated, so users are able to monitor the ingress controller.

@pleshakov
Copy link
Contributor

@thetechnick

Considering that we can end up having duplicated locations in multiple Ingress resources as well as annotations if we start to heavily use annotations to extend Ingress features, merging can become problematic. Agree that if we want to enable it,

it is necessary to formulate exactly how the nginx ingress controller should behave and how the order of merging is determined.

From my understanding only the contrib nginx controller currently do merging. For the gce one, a separate GCE HTTP load balancer is allocated.

I think the default behavior should be to not allow the same host names. If the user creates an Ingress with a duplicated hostname, the controller should Ignore it, reporting an Error.

However, if merging is very useful, it makes sense to add an option to enable it.

Please help me understand how kube-lego relies on the merging behavior to work.

@thetechnick
Copy link
Contributor Author

thetechnick commented Nov 21, 2016

@pleshakov
I think merging is a very useful feature, because I users would expect it to work.
How the ingress controller supports the sometimes very complex rules is up to the developer, but everything the kubernetes api allows should also be working with every ingress controller.

Kube-lego relies on the merging functionality, to add the acme challenge endpoints to the ingress points, using a separate ingress object in the namespace kube-lego runs in.

Example:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    ingress.kubernetes.io/ssl-redirect: "false"
    kubernetes.io/ingress.class: nginx
    kubernetes.io/tls-acme-challenge-endpoints: "true"
  name: kube-lego-nginx
spec:
  rules:
  - host: one.example.com
    http:
      paths:
      - backend:
          serviceName: kube-lego-nginx
          servicePort: 8080
        path: /.well-known/acme-challenge
  - host: two.example.com
    http:
      paths:
      - backend:
          serviceName: kube-lego-nginx
          servicePort: 8080
        path: /.well-known/acme-challenge
status:
  loadBalancer: {}

Edit:
I do not think that the merging will become too difficult, if the merging strategy is well defined.
To implement #77 I am using the oldest server (after ingress creation time) as a base and only add/override locations from the other ingress objects.
This way only the options that apply to those locations are taken over to the new merged server.

It is also possible to add config options for the merging strategy and to implement a new annotation: nginx.org/merge-weight: '200' (or similar) to give the user more power over the merging process.

@pleshakov
Copy link
Contributor

@thetechnick
Thanks for the clarification with the kube-lego. I think a better approach for now is to treat it as a special case. If the kubernetes.io/tls-acme-challenge-endpoints: "true" is present, add this location to the config for the main Ingress resource, for which the kubernetes.io/tls-acme: "true" is present.

I would wait to see the results of kubernetes/kubernetes#30151 and kubernetes/ingress-nginx#20 so that we have a behavior that is clearly defined and consistent across the controllers.

The error reporting in case of multiple Ingresses with the same hostnames must be added and the configs must not be generated instead of what we have know.

@thetechnick
Copy link
Contributor Author

@pleshakov
I would rather not add special cases depending on other projects, if there are other projects out there that need this feature, this will become a mess quite fast. Also if kube-lego decides to rename their annotations, it would break the special case here...

I am really curious about the future of the kubernetes ingress resource, but these new changes will not arrive in kubernetes before 1.6 or 1.7 and will very likely include changes in the API objects.
Because the official solution to the merging problems is so far away, I would welcome this ingress controller to adapt the "non official" strategy of merging the ingress objects/generated configs ordered by age, which is used by the contrib nginx ingress controller and openshift.

I know this is not ideal (I really dislike this lack of undefined behavior) ,but I see no downside of going with the established pattern until a more robust and easy to use solution is available.

After the official solution has arrived I would be glad to help with the implementation.

@kartojal
Copy link

kartojal commented May 29, 2017

Any work on this? Facing some issues with kube-lego and nginxinc/kubernetes-ingress. There is conflicts in my actual config, because kube-lego config creates a new configuration file, generating a name server conflict, so i can not redirect from HTTP to HTTPS.

Example:
When you go to https://example.com works good, but http://example.com does not do the redirection to the https maybe because its reading the kube-lego configuration with only the location /.well-known .

Any workaround? Should i use the kubernetes/ingress controller in my use case?

@pleshakov
Copy link
Contributor

@kartojal
Please use the kubernetes/ingress controller for your use case. The necessary behavior for kube-lego to work properly is not supported by our controller.

@nikitsrj
Copy link

nikitsrj commented Jul 26, 2017

I have created two different namespaces for different environment. one is devops-qa and another is devops-dev. I created two ingress in different namespaces. So while creating ingress of qa env in devops-qa namespace, the rules written inside ingress of qa is working fine. Means I am able to access the webpage of qa env. The moment I will create the ingress of dev env in devops-dev namespace, I will be able to access the webpage of dev env but wont be able to access the webpage of qa. And when I delete the dev ingress then again I will be able to access the qa env website

Below is the ingree of both dev and qa env.

Dev Ingress

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: cafe-ingress-dev
  namespace: devops-dev
spec:
  tls:
  - hosts:
    - cafe.example.com
    secretName: default-token-jhtx3
  rules:
  - host: cafe.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: miqpdev-svc
          servicePort: 80

QA Ingress

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: cafe-ingress-qa
  namespace: devops-qa
spec:
  tls:
  - hosts:
    - cafe.example.com
    secretName: default-token-bjg3z
  rules:
  - host: cafe.example.com
    http:
      paths:
      - path: /greentea
        backend:
          serviceName: greentea-svc
          servicePort: 80
      - path: /blackcoffee
        backend:
          serviceName: blackcoffee-svc
          servicePort: 80

The token mentioned in the ingress file is of each namespace. How can i run both the ingress and will be able to get all the websites deployed in both dev and qa env ?

@pleshakov
Copy link
Contributor

@nikitswaraj12345
Unfortunately, it is not possible to use multiple Ingress resources with the same host name, like cafe.example.com in your case. One of the resources will simply overwrite the others. Is it important for you to use the same host name?

If you would like to use the same host name in multiple namespaces, I can only suggest deploying a separate Ingress controller per each namespace.

@nikitsrj
Copy link

@pleshakov But with different hostname as well its overriding :( I tried both .

@pleshakov
Copy link
Contributor

with different hostnames it should not override. When you make a request to the Ingress controller, are you setting the host header of the request to the correct value -- either <hostname1> or <hostname2>?

@paulwalker
Copy link

Can someone please tell me how to configure use of the kubernetes/ingress vs the nginx ingress controller? All of the links to the differing documentation seem to be broken right now.

@pleshakov
Copy link
Contributor

@paulwalker the kubernetes/ingress repo has been renamed. Please check https://github.com/kubernetes/ingress-nginx

@isaachawley
Copy link
Contributor

I believe this is now handled by mergable ingresses.

@juan-kabbali
Copy link

I believe this is now handled by mergable ingresses.

New mergable ingresses link here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants