-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Add annotations for proxy_pass customization #2343
Add annotations for proxy_pass customization #2343
Conversation
RateLimit ratelimit.Config | ||
Redirect redirect.Config | ||
Rewrite rewrite.Config | ||
SecureUpstream secureupstream.Config | ||
ServerSnippet string | ||
ServiceUpstream bool | ||
ServiceNameAsVhost bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of introducing a new annotation type for service-name-as-vhost
, could it somehow be consolidated with upstream-vhost
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could - I'm not sure whether you mean adding the service-name-as-host
annotation onto the existing upstreamVhost
type using a Config
struct (the same way other multi-annotation types are handled), or simply removing the service-name-as-vhost
annotation and replacing {{ if $location.ServiceUpstreamAsVhost }}
with something like {{ if (and (not (empty $location.UpstreamVhost)) (not (empty $location.ProxyPass.Address))) }}
in the nginx template to replicate the functionality, but either one is doable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't have a very precise idea in mind and was rather opening the discussion to try improving the customization of the Host header (if possible) right away. I believe there is a better way than "if, elsif, else" to approach this.
I can roughly imagine something similar to the affinity feature, where you select a mode (eg. affinity: cookie
) and configure it via fine-grained options (eg. session-cookie-name: jsessionid
).
Here the mode could be an enum of preserve
(preserve request Host, the default), service
(what you implemented) or custom
(the equivalent of the current upstream-vhost
annotation).
@aledbf do you have an opinion on that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@antoineco Turns out I actually don't need the service-name-as-vhost
annotation, as it's easier to integrate with linkerd by adding a custom header (via custom nginx template or configuration snippet) and then having linkerd route on that instead of trying to change the Host
header.
ProxyToLocalNode bool `json:"proxyToLocalNode"` | ||
} | ||
|
||
// Equal tests for equality between two Redirect types |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Redirect" -> "proxyPass config"
rootfs/etc/nginx/template/nginx.tmpl
Outdated
@@ -1059,7 +1059,9 @@ stream { | |||
proxy_set_header X-Service-Name $service_name; | |||
{{ end }} | |||
|
|||
{{ if not (empty $location.Backend) }} | |||
{{ if (or (not (empty $location.ProxyPass.Address)) (not (empty $location.ProxyPass.Port))) }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
empty
is optional for primitive types -> if or $x $y
@@ -481,6 +482,7 @@ func (n *NGINXController) getBackendServers(ingresses []*extensions.Ingress) ([] | |||
CorsConfig: anns.CorsConfig, | |||
ExternalAuth: anns.ExternalAuth, | |||
Proxy: anns.Proxy, | |||
ProxyPass: anns.ProxyPass, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this indentation a GitHub glitch or did you forget running gofmt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops - forgot to run gofmt, as I'm used to running it via make
😛
A squash wouldn't hurt and you will have to run |
Oops, looks like the changes to nginx.conf.tmpl are gone 😨 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add corresponding changes to the tmpl file and run make code-generator
.
@@ -404,6 +404,14 @@ func buildProxyPass(host string, b interface{}, loc interface{}, dynamicConfigur | |||
} | |||
} | |||
|
|||
if location.ProxyPass.Address != "" || location.ProxyPass.Port != "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you ever use a port alone?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I figured that the address could be omitted if ProxyToLocalNode
was set along with the port.
@antoineco I realized last night right before squashing that Moving that logic into the |
@Capitrium tests are failing, can you try rebasing on |
Thanks for your pull request. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please follow instructions at https://git.k8s.io/community/CLA.md#the-contributor-license-agreement to sign the CLA. It may take a couple minutes for the CLA signature to be fully registered; after that, please reply here with a new comment and we'll verify. Thanks.
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
@Capitrium I think an actual |
@antoineco When you say |
The one before the screwup, in theory this is the second entry from the top in your reflog. |
Ok thanks - think I've fixed it now 😆 |
@Capitrium could you also document the new annotations in https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/annotations.md? |
Codecov Report
@@ Coverage Diff @@
## master #2343 +/- ##
==========================================
- Coverage 41.61% 41.61% -0.01%
==========================================
Files 74 75 +1
Lines 5291 5325 +34
==========================================
+ Hits 2202 2216 +14
- Misses 2792 2805 +13
- Partials 297 304 +7
Continue to review full report at Codecov.
|
@ElvinEfendi docs are updated now. |
@Capitrium #2395 should help with test flakiness |
I think I have to pass that issue to someone else, because I'm obviously missing an important point here. |
/assign @aledbf |
@Capitrium tomorrow I will take a look at this PR. This change should not be required. We already have users running Istio just adding the annotations |
@antoineco No worries, I appreciate the effort!
Requests to the Additionally, using |
That's a very interesting point we may want to look into. Regarding the PR itself, excluding the absence of E2E tests it looks good to me. |
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: Capitrium Assign the PR to them by writing The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/retest Edit: guess that didn't trigger a retest... 😛The dynamic configuration e2e tests seem a little flaky, I've run them several times on my local minikube env and they all usually pass but I've seen the odd failure/flake reported. |
@aledbf e2e tests have been added and the build is passing, I think the only thing left is to determine whether this change is actually needed - I believe that it is, given the issues that I've previously mentioned when using rewrites with the |
another month, another merge, another set of build errors... I have the proxy_pass e2e tests passing when running locally, but there are some errors on other tests, and I had to remove the @aledbf friendly ping: would love to get this looked at again soon if possible! I've also spoken to the Linkerd folks, and they've indicated that Istio and Linkerd are substantially different and agree that the |
That's a problem. First, we cannot start adding code for all the service meshes available but more importantly, it should not be required to specify any special configuration to the mesh. From my point of view that removes any benefit we can get from it and makes things unnecessarily complex.
Please try to see this issue from my point of view. If we add this (in the current state) we need to add a mesh in the e2e tests and create scenarios only for this. Sadly the |
While I disagree with you here, I'm not sure this is entirely relevant. I feel like we're getting away from what this PR actually does: it allows users to set a custom
Sorry, I'm a bit confused here: why do you think we need to add a service mesh to the e2e framework to allow users to set TLDR: Don't worry about Linkerd or supporting other service meshes 😄 - let's reduce the use case here to setting a custom |
@aledbf Not sure if you saw my follow-up questions above, just summarizing them here:
|
Yes, basically you are reimplementing Service type=ExternalName using annotations in Ingress Please check this example #629 (comment) |
@aledbf thanks for the link - I can see how there is overlap between being able to set an arbitrary However, it doesn't look like a service with an ExternalName of |
I think we could add support for |
Unless the upstream server is deployed as a daemonset, right? |
Right. Just in case the ingress controller is not aware of how a service deployed |
Issues go stale after 90d of inactivity. If this issue is safe to close now please do so with Send feedback to sig-testing, kubernetes/test-infra and/or fejta. |
Stale issues rot after 30d of inactivity. If this issue is safe to close now please do so with Send feedback to sig-testing, kubernetes/test-infra and/or fejta. |
Rotten issues close after 30d of inactivity. Send feedback to sig-testing, kubernetes/test-infra and/or fejta. |
@fejta-bot: Closed this PR. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
What this PR does / why we need it:
Integration with the linkerd service mesh requires customization of the
proxy_pass
address in the nginx template. This PR adds the following annotations to allow users to customize theproxy_pass
address:The
proxy-pass-address
andproxy-pass-port
annotations allow users to setproxy_pass
to a linkerd address, so that traffic is passed to the service mesh as in the basic nginx-linkerd example.If
proxy-to-local-node
istrue
, theproxy_pass
address will be set to the value parsed byos.Getenv("NODE_NAME")
, which can be set to the name of the node using the downward API. This is useful when running linkerd as a daemonset, ensuring that traffic reaching an nginx ingress controller pod will be forwarded to the linkerd pod running on the same node; when using linkerd in a linker-to-linker configuration with TLS enabled, this ensures traffic does not leave the node unencrypted.