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

allow non-standard listen ports #171

Merged
merged 1 commit into from
Aug 30, 2017
Merged

Conversation

seletskiy
Copy link
Contributor

PR introduces two new annotations:

  • nginx.org/listen-ports
  • nginx.org/listen-ports-ssl

When using ingress controller with hostNetwork: true it is possible to allow
to have non-standard ports (not 80 and 443) served by nginx. It's useful
for dynamic ports in ingress/port-based routing.

Fixes #98.

@pleshakov
Copy link
Contributor

@seletskiy Thanks!

A few suggestions:

  • Documentation: I think it is better to document those annotation in the table here, than having an example with yaml files. Please remove those yaml files. I can add documentation later after the PR is merged.
  • It is important to redirect to a different SSL port here, while for this case it is ok -- that one is for the case when NGINX is sitting behind a load balancer and SSL termination is done by that load balancer.
  • It is better to add Ports and SSLPorts to Config and parse annotations in createConfig

@seletskiy
Copy link
Contributor Author

seletskiy commented Aug 24, 2017

@pleshakov:

Documentation: I think it is better to document those annotation in the table here, than having an example with yaml files. Please remove those yaml files. I can add documentation later after the PR is merged.

Done.

It is important to redirect to a different SSL port here, while for this case it is ok -- that one is for the case when NGINX is sitting behind a load balancer and SSL termination is done by that load balancer.

Done: f1b118b#diff-394b0af448cb4ab4c28989f3aecae208L31

It is better to add Ports and SSLPorts to Config and parse annotations in createConfig

This will not work, because Config is not passed to the nginx.ingress.tmpl, so we can't extract ports from it here:

func (nginx *NginxController) AddOrUpdateIngress(name string, config IngressNginxConfig) {
glog.V(3).Infof("Updating NGINX configuration")
filename := nginx.getIngressNginxConfigFileName(name)
nginx.templateIt(config, filename)

Copy link
Contributor

@pleshakov pleshakov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@seletskiy
Thanks. I've added additional suggestions.

This will not work, because Config is not passed to the nginx.ingress.tmpl, so we can't extract ports from it here:

It be great if we could have ports and ssl ports defined in the Config, with default values set to [80] and [443]. When parsing the annotations in createConfig , we could overwrite those default values based on the annotations values, but always making sure that there is at least one port for regular and ssl ports.

server.SSL = true
server.SSLCertificate = pemFile
server.SSLCertificateKey = pemFile
if len(sslPorts) > 1 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. len(sslPorts) > 1 leads to a bug, as it only enables SSL termination when we have at least 2 SSL ports.
  2. this check is also unnecessary: we should always have at least 1 SSL port if SSL is enabled (if pemFile, ok := pems[serverName];)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right, sorry.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That check is simple a safe guard for case when annotation specifies empty value.

}
{{- if $server.HSTS}}
proxy_hide_header Strict-Transport-Security;
add_header Strict-Transport-Security "max-age={{$server.HSTSMaxAge}}; {{if $server.HSTSIncludeSubdomains}}includeSubDomains; {{end}}preload" always;{{end}}
{{- end}}
{{- if $server.RedirectToHTTPS}}
if ($http_x_forwarded_proto = 'http') {
return 301 https://$host$request_uri;
return 301 https://$host:{{index $server.SSLPorts 0}}$request_uri;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This redirect is for the case when SSL termination is done at a load balancer in front of NGINX. It can be enabled for Ingress resources without SSL termination. Thus, it is a bug and the config generation will fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted.

@@ -26,6 +26,7 @@ osx-nginx-ingress
nginx-ingress
osx-nginx-plus-ingress
nginx-plus-ingress
nginx-controller/nginx-controller
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's to ignore nginx-controller binary which appears when you run go build inside nginx-controller directory.

@seletskiy seletskiy force-pushed the master branch 2 times, most recently from 836dc94 to 1f6eff6 Compare August 28, 2017 13:57
@seletskiy
Copy link
Contributor Author

It be great if we could have ports and ssl ports defined in the Config, with default values set to [80] and [443]. When parsing the annotations in createConfig , we could overwrite those default values based on the annotations values, but always making sure that there is at least one port for regular and ssl ports.

OK, I've moved default values to Config struct. Check it out now.

@pleshakov
Copy link
Contributor

@seletskiy Thanks so much!
There is one thing left. This check is unnecessary, as we always make sure that there is at least one element in ingCfg.SSLPorts.

@seletskiy
Copy link
Contributor Author

@pleshakov: I've removed excessive if, rebased and resolved conflicts against new commits in upstream. Check it out again.

@pleshakov pleshakov merged commit 28ce8f7 into nginxinc:master Aug 30, 2017
@pleshakov
Copy link
Contributor

@seletskiy Thanks!!

@seletskiy
Copy link
Contributor Author

@pleshakov: Thanks for assistance. Do you plan to release new version of image on the Docker Hub?

@pleshakov
Copy link
Contributor

@seletskiy yes, we will release a new version today

@CodeSwimBikeRunner
Copy link

can anyone provide a working example?

@pleshakov
Copy link
Contributor

@ChristopherLClark here is an example. instead of 80 and 443, NGINX will listen on 9080 and 9443

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: cafe-ingress
  annotations:
     kubernetes.io/ingress.class: "nginx"
     nginx.org/listen-ports: "9080"
     nginx.org/listen-ports-ssl: "9443"
spec:
. . .

Also see https://github.com/nginxinc/kubernetes-ingress/blob/master/docs/configmap-and-annotations.md

@CodeSwimBikeRunner
Copy link

@pleshakov Hmm, this still doesnt quite meet my needs. I need to have kubernetes, in the spec, rules, portion be forwarding routes with ports.

So for example:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-iot-admin
  annotations: 
    kubernetes.io/ingress.class: nginx
    nginx.org/listen-ports: "30000"
  labels:
    app: iot-admin
spec:
  rules:
  - host: localhost:30000
    http:
      paths:
      - path: /
        backend:
          serviceName: service-iot-admin
          servicePort: 8080

In local development we can't use dns entries. So I would like to mimic the production cluster with localhost:30000 as the domain and then all requests go through that.

@pleshakov
Copy link
Contributor

@ChristopherLClark that should work OK, if you change localhost:30000 to localhost in your Ingress

@CodeSwimBikeRunner
Copy link

@pleshakov yes I ultimately ended up running kubernetes under port 80, and killed my other processes, but I was looking for a way where I could run kubernetes under a different port. This ended up being easier just switching to 80.

@boxer3379

This comment was marked as off-topic.

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

Successfully merging this pull request may close these issues.

Is it possible to route on the basis of port?
4 participants