Skip to content

Conversation

davidhadas
Copy link
Contributor

Fixes #13118
Alternative to #13122

Proposed Changes

  • Enabling downstream and anyone creating an image of queue proxy to extend queue proxy
  • This extendibility is a second step to enable the runtime security proposal here
  • Next possible steps: (1) Support QP mutation pattern (2) support for annotations or another method to enable activating/configuring extensions
  • Items for discussion: (a) Should we add the script to help demonstrate how extendibility works (or as a potential basis of an e2e testing)? (b)Should we allow extensions to change logger or env?

Release Note

Refactored queue-proxy binary to more easily support out-of-tree extension.

Fixes knative#13118
Alternative to knative#13122
Proposed Changes
Enabling downstream and anyone creating an image of queue proxy to extend queue proxy
This extendibility is a step to enable the runtime security proposal here

Release Note
Refactored queue-proxy binary to more easily support out-of-tree extension.
@knative-prow knative-prow bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. area/autoscale area/networking area/test-and-release It flags unit/e2e/conformance/perf test issues for product features labels Jul 19, 2022
@knative-prow
Copy link

knative-prow bot commented Jul 19, 2022

Hi @davidhadas. Thanks for your PR.

I'm waiting for a knative member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

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.

@knative-prow knative-prow bot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Jul 19, 2022
@codecov
Copy link

codecov bot commented Jul 19, 2022

Codecov Report

Merging #13133 (5137f03) into main (017b9d0) will decrease coverage by 0.06%.
The diff coverage is 0.00%.

@@            Coverage Diff             @@
##             main   #13133      +/-   ##
==========================================
- Coverage   86.78%   86.72%   -0.07%     
==========================================
  Files         196      196              
  Lines       14410    14416       +6     
==========================================
- Hits        12506    12502       -4     
- Misses       1609     1619      +10     
  Partials      295      295              
Impacted Files Coverage Δ
pkg/queue/sharedmain/main.go 0.64% <0.00%> (-0.03%) ⬇️
pkg/autoscaler/statserver/server.go 75.55% <0.00%> (-2.23%) ⬇️
pkg/reconciler/revision/controller.go 92.95% <0.00%> (+3.62%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 017b9d0...5137f03. Read the comment docs.

@psschwei
Copy link
Contributor

/ok-to-test

@knative-prow knative-prow bot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Jul 19, 2022
@psschwei
Copy link
Contributor

Items for discussion: (a) Should we add the script to help demonstrate how extendibility works (or as a potential basis of an e2e testing)?

I think initially this would belong in a sandbox/private repo rather than in serving core.

(b)Should we allow extensions to change logger or env?

My gut reaction to this one is "no", as I'd assume that any needed changes could be done in the configs rather than needing to change them. Is there a particular use case you have in mind?

Comment on lines 108 to 117
Env
}

type Env struct {
ServingNamespace string `split_words:"true" required:"true"`
ServingRevision string `split_words:"true" required:"true"`
ServingConfiguration string `split_words:"true" required:"true"`
ServingPodIP string `split_words:"true" required:"true"`
ServingPod string `split_words:"true" required:"true"`
ServingService string `split_words:"true"` // optional
Copy link
Contributor

Choose a reason for hiding this comment

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

a couple of minor nits:

  • maybe don't rename the config struct ?
  • perhaps a more descriptive name than Env (PodDetails? Caveat here is that I'm terrible at naming...)
  • I'd put Env under the metrics config section (i.e. where the old fields were removed)

Copy link
Contributor Author

@davidhadas davidhadas Jul 19, 2022

Choose a reason for hiding this comment

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

Note that Env struct is identical in content to:
type RequestLogRevision struct from https://pkg.go.dev/knative.dev/serving/pkg/http#RequestLogRevision which is also being used later in main.go, How about naming it "Revision"

I am not sure it should be under
// Metrics configuration

Copy link
Member

Choose a reason for hiding this comment

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

I think "Env" is a good name, as it's describing the "environment" (i.e. Pod) where the queue-proxy is running.

A few bits (like ServingService) won't vary per queue-proxy, but this struct seems to be "where am I on the map" rather than "what am I doing".

@davidhadas
Copy link
Contributor Author

/assign @davidhadas

@knative-prow knative-prow bot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jul 19, 2022
Copy link
Member

@evankanderson evankanderson left a comment

Choose a reason for hiding this comment

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

It looks like this shouldn't collide with the internal encryption work, which is nice!

I'm going to let @psschwei / @dprotaso do the final approval, but this LGTM.

A few smaller comments / nits. I appreciate the goal of reducing code movement throughout the file, but I think there might be a bigger benefit of consistently using the state in Defaults, rather than mirroring it into/out of the struct at strategic times. (In particular if we added a second extension point in the future.)

Comment on lines 108 to 117
Env
}

type Env struct {
ServingNamespace string `split_words:"true" required:"true"`
ServingRevision string `split_words:"true" required:"true"`
ServingConfiguration string `split_words:"true" required:"true"`
ServingPodIP string `split_words:"true" required:"true"`
ServingPod string `split_words:"true" required:"true"`
ServingService string `split_words:"true"` // optional
Copy link
Member

Choose a reason for hiding this comment

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

I think "Env" is a good name, as it's describing the "environment" (i.e. Pod) where the queue-proxy is running.

A few bits (like ServingService) won't vary per queue-proxy, but this struct seems to be "where am I on the map" rather than "what am I doing".

Comment on lines 120 to 125
type Defaults struct {
Ctx context.Context
Logger *zap.SugaredLogger
Transport http.RoundTripper
Env Env
}
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, I'm wondering if Main should be a method on Defaults.

I suspect not.

I'm also wondering about the name... Configuration, Process, Execution, QueueProxy?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This list includes two parts:

  • parameters whose value is determined by the service and provided for the extensions to use (but not to change)
  • parameters whose default is determined by the service and provided for the extensions such that may change them
    Maybe we should have divided this struct into two:
 type Defaults {
      Ctx              context.Context
      Transport    http.RoundTripper
 }	
 type Config {
     Env
     Logger  *zap.SugaredLogger
 }
 type QueueProxy struct {
        Invariables     Config
        Mutables        Defaults
 }

Copy link
Contributor

Choose a reason for hiding this comment

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

I wouldn't split, I'd just note in comments which ones are considered mutable and which ones aren't.

Since they're exported types, an overview comment on the Defaults and Env structs themselves wouldn't be a bad idea.

Comment on lines 134 to 136
d := &Defaults{
Ctx: signals.NewContext(),
}
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer to make d concrete here, rather than a pointer.

return err
}

d.Env = env.Env
Copy link
Member

Choose a reason for hiding this comment

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

I can see that you're slicing the "where I'm at" out of the larger configuration. I'm wondering whether we should simply pass along all the config/privateEnv, and accept that plugins could (for example) adjust EnableProfiling without other high-level config.

Copy link
Member

Choose a reason for hiding this comment

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

This could enable splitting out envconfig into a pluggable module, though I'm not sure I'd recommend it, since I think we want that functionality enabled by default rather than every caller needing to say sharedmain.EnvConfig.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This ensures that extensions receive a copy of the Env and cannot change the Env used by the service which I think is appropriate here.

Copy link
Member

Choose a reason for hiding this comment

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

I think just having a read-only Env is ok for now - I think as people request more we can move properties from private => public with a discussion

}.String()),
zap.String(logkey.Pod, env.ServingPod))

d.Logger = logger
Copy link
Member

Choose a reason for hiding this comment

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

Why not put this on 147? Reducing code movement?

I'd be inclined to s/logger/d.Logger/ throughout.

Copy link
Contributor Author

@davidhadas davidhadas Jul 20, 2022

Choose a reason for hiding this comment

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

This ensures that extensions receive a copy of the logger and cannot change the logger used by the service which I think is appropriate here.

Copy link
Member

Choose a reason for hiding this comment

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

I'm ok either way.

Longer term I would expect the logger be pluggable in the future

func WithLogger(l *zap.SugaredLogger) func(q *Defaults) {
	return func(d *Defaults) {
		d.Logger = l
		return
	}
}

Comment on lines 164 to 165
ctx := d.Ctx
transport := d.Transport
Copy link
Member

Choose a reason for hiding this comment

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

Again, I'd be inclined to substitute these throughout.


// allow extensions to read d and return modified context and transport
for _, opts := range opts {
opts(d)
Copy link
Member

Choose a reason for hiding this comment

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

Slight preference for opts(&d) to make it clear that d is modified in-place here, but I don't care strongly.

@knative-prow knative-prow bot added the area/API API objects and controllers label Jul 20, 2022
@davidhadas
Copy link
Contributor Author

/retest

@davidhadas
Copy link
Contributor Author

Tests fail, but it does not seem like a code issue
/retest

Copy link
Contributor

@psschwei psschwei left a comment

Choose a reason for hiding this comment

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

In general this LGTM but want to give Dave a chance to comment before merging.

/assign @dprotaso

Comment on lines 120 to 125
type Defaults struct {
Ctx context.Context
Logger *zap.SugaredLogger
Transport http.RoundTripper
Env Env
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I wouldn't split, I'd just note in comments which ones are considered mutable and which ones aren't.

Since they're exported types, an overview comment on the Defaults and Env structs themselves wouldn't be a bad idea.

Comment on lines +26 to +28
if sharedmain.Main() != nil {
os.Exit(1)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

we should also probably log the error here

Copy link
Contributor Author

@davidhadas davidhadas Jul 25, 2022

Choose a reason for hiding this comment

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

Since we let downstream change this file, I think it is best if we log inside sharedmain to ensure consistent logging.

@knative-prow knative-prow bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Jul 25, 2022
@davidhadas
Copy link
Contributor Author

/retest

1 similar comment
@davidhadas
Copy link
Contributor Author

/retest

davidhadas added a commit to davidhadas/serving that referenced this pull request Jul 25, 2022
@knative-prow
Copy link

knative-prow bot commented Jul 25, 2022

@davidhadas: The specified target(s) for /test were not found.
The following commands are available to trigger required jobs:

  • /test build-tests_serving_main
  • /test contour-latest_serving_main
  • /test contour-tls_serving_main
  • /test gateway-api-latest_serving_main
  • /test istio-latest-no-mesh-tls_serving_main
  • /test istio-latest-no-mesh_serving_main
  • /test kourier-stable-tls_serving_main
  • /test kourier-stable_serving_main
  • /test unit-tests_serving_main
  • /test upgrade-tests_serving_main

The following commands are available to trigger optional jobs:

  • /test https_serving_main
  • /test istio-latest-mesh-short_serving_main
  • /test istio-latest-mesh-tls_serving_main
  • /test istio-latest-mesh_serving_main
  • /test performance-tests-kperf_serving_main
  • /test performance-tests-mako_serving_main

Use /test all to run the following jobs that were automatically triggered:

  • build-tests_serving_main
  • istio-latest-no-mesh-tls_serving_main
  • istio-latest-no-mesh_serving_main
  • unit-tests_serving_main
  • upgrade-tests_serving_main

In response to this:

/test e2e / test (v1.22.9, istio, runtime) (pull_request)

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.

return err
}

d.Env = env.Env
Copy link
Member

Choose a reason for hiding this comment

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

I think just having a read-only Env is ok for now - I think as people request more we can move properties from private => public with a discussion

}.String()),
zap.String(logkey.Pod, env.ServingPod))

d.Logger = logger
Copy link
Member

Choose a reason for hiding this comment

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

I'm ok either way.

Longer term I would expect the logger be pluggable in the future

func WithLogger(l *zap.SugaredLogger) func(q *Defaults) {
	return func(d *Defaults) {
		d.Logger = l
		return
	}
}

@dprotaso
Copy link
Member

/lgtm
/approve

@knative-prow knative-prow bot added the lgtm Indicates that a PR is ready to be merged. label Jul 25, 2022
@knative-prow
Copy link

knative-prow bot commented Jul 25, 2022

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: davidhadas, dprotaso

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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@knative-prow knative-prow bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 25, 2022
@knative-prow knative-prow bot merged commit 63523f9 into knative:main Jul 25, 2022
mbaynton added a commit to posit-hosted/knative-serving that referenced this pull request Sep 18, 2025
This builds on knative#13133 to make it possible to adjust settings on the
*httputil.ReverseProxy that queue-proxy uses, or to replace it entirely
with any http.Handler, using the out-of-tree extension pattern.
mbaynton added a commit to posit-hosted/knative-serving that referenced this pull request Sep 19, 2025
This builds on knative#13133 to make it possible to adjust settings on the
*httputil.ReverseProxy that queue-proxy uses, or to replace it entirely
with any http.Handler, using the out-of-tree extension pattern.
knative-prow bot pushed a commit that referenced this pull request Oct 6, 2025
* Make queue-proxy's reverse proxy handler extendable

This builds on #13133 to make it possible to adjust settings on the
*httputil.ReverseProxy that queue-proxy uses, or to replace it entirely
with any http.Handler, using the out-of-tree extension pattern.

* Ensure configured Transport is used

If an integrator customizes the Transport in an Options function, we want to
apply the provided Transport to our default httputil.ReverseProxy
regardless of which Option sets the Transport and regardless of whether
or not other Option functions replace our default http.Handler.

Add some tests for this since the interactions beteween
Options.Transport and Options.ProxyHandler can be subtle.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. area/API API objects and controllers area/autoscale area/networking area/test-and-release It flags unit/e2e/conformance/perf test issues for product features lgtm Indicates that a PR is ready to be merged. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Queue Proxy Extensions

4 participants