Introduce tap APIService, update linkerd tap#3167
Conversation
c2846f9 to
831e803
Compare
|
Integration test results for 831e803: fail 😕 |
831e803 to
3d58eb1
Compare
|
Integration test results for 3d58eb1: fail 😕 |
3d58eb1 to
ad43c40
Compare
|
Integration test results for ad43c40: fail 😕 |
ad43c40 to
c64937d
Compare
|
Integration test results for c64937d: fail 😕 |
|
Integration test results for e365353: fail 😕 |
e365353 to
4895534
Compare
|
Integration test results for 4895534: success 🎉 |
4895534 to
2048887
Compare
|
Integration test results for 2048887: success 🎉 |
adleong
left a comment
There was a problem hiding this comment.
I just gave this a quick once over and it looks great: no major surprises. Next I'll test and review in more detail.
controller/tap/apiserver.go
Outdated
| namespace, resource, name, req.Header.Get(a.usernameHeader), req.Header[a.groupHeader], | ||
| ) | ||
|
|
||
| err := pkgK8s.ResourceAuthzForUser( |
There was a problem hiding this comment.
Is this subject access review necessary? are there requests which could get past the aggregator but fail here?
There was a problem hiding this comment.
I haven't been able to craft a request that gets by the aggregator but fails this SAR, but I'm not convinced it's not possible. This is the recommended pattern from Kubernetes:
https://kubernetes.io/docs/tasks/access-kubernetes-api/configure-aggregation-layer/#extension-apiserver-authorizes-the-request
There was a problem hiding this comment.
I'm pretty sure this is the exact same SAR check that the aggregator does. So doing it here as well feels redundant. Removing it also allows us to remove the auth-delegator role binding.
|
|
||
| // TapReqToURL converts a TapByResourceRequest protobuf object to a URL for use | ||
| // with the Kubernetes tap.linkerd.io APIService. | ||
| func TapReqToURL(req *pb.TapByResourceRequest) string { |
There was a problem hiding this comment.
This feels pretty specific to the tap apiservice and a bit out of place in this file.
There was a problem hiding this comment.
I agree, but ended up putting it here for a few reasons:
- both
/cli/cmdand/controller/tapdepend on it, so it should be somewhere in/pkg protohttpalready depends on/controller/gen/public, so puttingTapReqToURLhere does not add any new edges to our dependency tree- it relates to the business of protobuf <-> http conversion
Given all this, the only other option would be to put that one function into a new package under /pkg, and that new package would still depend on /controller/gen/public (which is a more general issue to be fixed in #2751). Once #2751 completes, I'd be more open to a reorg of this code.
dadjeibaah
left a comment
There was a problem hiding this comment.
Took a quick glance as well and it all looks good. I'd like to kick the tires in a little bit.
I had one clarifying question. What does the current Tap Public API endpoint now serve? Does it give a deprecation warning or do we still need it for the dashboard?
grampelberg
left a comment
There was a problem hiding this comment.
Works for me, * gives me permissions out of the box.
- Appears that the default roles outside of cluster-admin (admin, edit, view) are unable to use tap. WDYT about adding a namespace scoped ClusterRole that allows tapping everything in the NS (as a follow-up)?
- Definitely gets
kubectl delete ns linkerdto hang, maybe we should have a follow-up issue to implementlinkerd remove?
|
Integration test results for 6e370f8: success 🎉 |
PR #3167 introduced a Tap APIService, and migrated `linkerd tap` to it. This change migrates `linkerd top` to the new Tap APIService. It also addresses a `panic: close of closed channel`, where two go routines could both call `close(done)` on exit. Fixes #3168 Signed-off-by: Andrew Seigner <[email protected]>
PR #3167 introduced a Tap APIService, and migrated `linkerd tap` to it. This change migrates `linkerd top` to the new Tap APIService. It also addresses a `panic: close of closed channel` issue, where two go routines could both call `close(done)` on exit. Fixes #3168 Signed-off-by: Andrew Seigner <[email protected]> fix Signed-off-by: Andrew Seigner <[email protected]>
PR #3167 introduced a Tap APIService, and migrated `linkerd tap` to it. This change migrates `linkerd top` to the new Tap APIService. It also addresses a `panic: close of closed channel` issue, where two go routines could both call `close(done)` on exit. Fixes #3168 Signed-off-by: Andrew Seigner <[email protected]>
PR #3167 introduced a Tap APIService, and migrated linkerd tap to it. This change migrates `linkerd profile --tap` to the new Tap APIService. Depends on #3186 Fixes #3169 Signed-off-by: Andrew Seigner <[email protected]>
PR #3167 introduced a Tap APIService, and migrated linkerd tap to it. This change migrates `linkerd profile --tap` to the new Tap APIService. Depends on #3186 Fixes #3169 Signed-off-by: Andrew Seigner <[email protected]>
PR #3167 introduced a Tap APIService, and migrated `linkerd tap` to it. This change migrates `linkerd top` to the new Tap APIService. It also addresses a `panic: close of closed channel` issue, where two go routines could both call `close(done)` on exit. Fixes #3168 Signed-off-by: Andrew Seigner <[email protected]>
PR #3167 introduced a Tap APIService, and migrated linkerd tap to it. This change migrates `linkerd profile --tap` to the new Tap APIService. Depends on #3186 Fixes #3169 Signed-off-by: Andrew Seigner <[email protected]>
PR #3167 introduced a Tap APIService, and migrated linkerd tap to it. This change migrates `linkerd profile --tap` to the new Tap APIService. Depends on #3186 Fixes #3169 Signed-off-by: Andrew Seigner <[email protected]>
Signed-off-by: Ivan Sim <[email protected]>
* Updated controller template with proxy partials * Declare dependency in requirements.yaml * Add partial template for proxy's metadata * Add proxy-init partial template * Script to lint Helm charts and update their dependencies * Update partials chart Chart.yaml * Add proxy-init and resource partial templates * Replace hard coded namespace variable in proxy env var * Ignore chart dependencies .tgz files * Add missing fields and re-order YAML elements to match CLI output * Reuse control plane's resource partial template in 'partials' chart * Set the proxy's destination service address env var * Add Grafana's template * Update api version of controller RBAC * Add Heartbeat template * Remove duplicated resources partial template * Add remainder control plane components templates * Add template for the 'linkerd-config' config map * Add debug container template * Update proxy partial with 'disable-identity' and 'disable-tap' variables Note that these are inject-only variables. Also added the LINKERD2_PROXY_TAP_SVC_NAME env var. * Add validation conditions to ensure identity and tap aren't disabled for control plane components * Add partials for service account token mount path and security context capabilities * Change proxy and proxy-init templates to use global scope Some of the nested variables are removed from values.yaml to ensure changes made to root-level variables are propagated directly into the partial templates. The previous approach of using YAML anchors in the values.yaml to share common values can get out-of-sync when values are changed via the Helm's `--set` option. * Update templates and values file to match #3161 * Perform a dry run installation if there is a local Tiller * Reorder JSON elements in linkerd-config * Re-adjust nested partials indentation to work with inject 'patch' chart Previously, the partials will render their content as an element in the list. While it works for installation, the toJson function in the 'inject' patch code ends up converting it into a JSON list, instead of the expected JSON object. * Trap the last fail command in the Helm shell script * Add the identity trust anchor * Address Thomas' feedback on handling HA All the HA-related variables are moved to values-ha.yaml * Convert ignore ports string to JSON list in linkerd-config Also fixed some indentation issues. * Add values-ha.yaml * Include the service account token mount path only if identity is enabled * Fixed malformed JSON in linkerd-config config map * Rename chart to 'linkerd2' * Add NOTES.txt * Fix incorrect variable path in proxy template * Remove fake TLS assets * Add 'required' constraint to identity trust anchors variable * Update tap templates per #3167 * Bump default version to edge-19.8.1 due to dependency on RSA support Signed-off-by: Ivan Sim <[email protected]>
PR #3167 introduced a Tap APIService, and migrated `linkerd tap` to it. This change migrates `linkerd top` to the new Tap APIService. It also addresses a `panic: close of closed channel` issue, where two go routines could both call `close(done)` on exit. Fixes #3168 Signed-off-by: Andrew Seigner <[email protected]>
PR #3167 introduced a Tap APIService, and migrated linkerd tap to it. This change migrates `linkerd profile --tap` to the new Tap APIService. Depends on #3186 Fixes #3169 Signed-off-by: Andrew Seigner <[email protected]>
* Updated controller template with proxy partials * Declare dependency in requirements.yaml * Add partial template for proxy's metadata * Add proxy-init partial template * Script to lint Helm charts and update their dependencies * Update partials chart Chart.yaml * Add proxy-init and resource partial templates * Replace hard coded namespace variable in proxy env var * Ignore chart dependencies .tgz files * Add missing fields and re-order YAML elements to match CLI output * Reuse control plane's resource partial template in 'partials' chart * Set the proxy's destination service address env var * Add Grafana's template * Update api version of controller RBAC * Add Heartbeat template * Remove duplicated resources partial template * Add remainder control plane components templates * Add template for the 'linkerd-config' config map * Add debug container template * Update proxy partial with 'disable-identity' and 'disable-tap' variables Note that these are inject-only variables. Also added the LINKERD2_PROXY_TAP_SVC_NAME env var. * Add validation conditions to ensure identity and tap aren't disabled for control plane components * Add partials for service account token mount path and security context capabilities * Change proxy and proxy-init templates to use global scope Some of the nested variables are removed from values.yaml to ensure changes made to root-level variables are propagated directly into the partial templates. The previous approach of using YAML anchors in the values.yaml to share common values can get out-of-sync when values are changed via the Helm's `--set` option. * Update templates and values file to match #3161 * Perform a dry run installation if there is a local Tiller * Reorder JSON elements in linkerd-config * Re-adjust nested partials indentation to work with inject 'patch' chart Previously, the partials will render their content as an element in the list. While it works for installation, the toJson function in the 'inject' patch code ends up converting it into a JSON list, instead of the expected JSON object. * Trap the last fail command in the Helm shell script * Add the identity trust anchor * Address Thomas' feedback on handling HA All the HA-related variables are moved to values-ha.yaml * Convert ignore ports string to JSON list in linkerd-config Also fixed some indentation issues. * Add values-ha.yaml * Include the service account token mount path only if identity is enabled * Fixed malformed JSON in linkerd-config config map * Rename chart to 'linkerd2' * Add NOTES.txt * Fix incorrect variable path in proxy template * Remove fake TLS assets * Add 'required' constraint to identity trust anchors variable * Update tap templates per #3167 * Bump default version to edge-19.8.1 due to dependency on RSA support Signed-off-by: Ivan Sim <[email protected]>
### Motivation PR #3167 introduced the tap APIService and migrated `linkerd tap` to use it. Subsequent PRs (#3186 and #3187) updated `linkerd top` and `linkerd profile --tap` to use the tap APIService. This PR moves the web's Go server to now also use the tap APIService instead of the public API. It also ensures an error banner is shown to the user when unauthorized taps fail via `linkerd top` command in *Overview* and *Top*, and `linkerd tap` command in *Tap*. ### Details The majority of these changes are focused around piping through the HTTP error that occurs and making sure the error banner generated displays the error message explaining to view the tap RBAC docs. `httpError` is now public (`HTTPError`) and the error message generated is short enough to fit in a control frame (explained [here](https://github.com/linkerd/linkerd2/blob/kleimkuhler%2Fweb-tap-apiserver/web/srv/api_handlers.go#L173-L175)). ### Testing The error we are testing for only occurs when the linkerd-web service account is not authorzied to tap resources. Unforutnately that is not the case on Docker For Mac (assuming that is what you use locally), so you'll need to test on a different cluster. I chose a GKE cluster made through the GKE console--not made through cluster-utils because it adds cluster-admin. Checkout the branch locally and `bin/docker-build` or `ares-build` if you have it setup. It should produce a linkerd with the version `git-04e61786`. I have already pushed the dependent components, so you won't need to `bin/docker-push git-04e61786`. Install linkerd on this GKE cluster and try to run `tap` or `top` commands via the web. You should see the following errors: ### Tap  ### Top  Signed-off-by: Kevin Leimkuhler <[email protected]>
The `linkerd upgrade --from-manifests` command supports reading the manifest output via `linkerd install`. PR #3167 introduced a tap APIService object into `linkerd install`, but the manifest-reading code in fake.go was never updated to support this new object kind. Update the fake clientset code to support APIService objects. Signed-off-by: Andrew Seigner <[email protected]>
The `linkerd upgrade --from-manifests` command supports reading the manifest output via `linkerd install`. PR #3167 introduced a tap APIService object into `linkerd install`, but the manifest-reading code in fake.go was never updated to support this new object kind. Update the fake clientset code to support APIService objects. Fixes #3559 Signed-off-by: Andrew Seigner <[email protected]>
The `linkerd upgrade --from-manifests` command supports reading the manifest output via `linkerd install`. PR #3167 introduced a tap APIService object into `linkerd install`, but the manifest-reading code in fake.go was never updated to support this new object kind. Update the fake clientset code to support APIService objects. Fixes #3559 Signed-off-by: Andrew Seigner <[email protected]>
The `linkerd upgrade --from-manifests` command supports reading the manifest output via `linkerd install`. PR #3167 introduced a tap APIService object into `linkerd install`, but the manifest-reading code in fake.go was never updated to support this new object kind. Update the fake clientset code to support APIService objects. Fixes #3559 Signed-off-by: Andrew Seigner <[email protected]>
The `linkerd upgrade --from-manifests` command supports reading the manifest output via `linkerd install`. PR #3167 introduced a tap APIService object into `linkerd install`, but the manifest-reading code in fake.go was never updated to support this new object kind. Update the fake clientset code to support APIService objects. Fixes #3559 Signed-off-by: Andrew Seigner <[email protected]>
The Tap Service enabled tapping of any meshed pod, regardless of user
privilege.
This change introduces a new Tap APIService. Kubernetes provides
authentication and authorization of Tap requests, and then forwards
requests to a new Tap APIServer, which implements a Kubernetes
aggregated API server. The Tap APIServer authenticates the client TLS
from Kubernetes, and authorizes the user via a SubjectAccessReview.
The
linkerd tapcommand now makes requests against the new APIService.The Tap APIService implements three Kubernetes-style endpoints:
GET /apis/tap.linkerd.io/v1alpha1
POST /apis/tap.linkerd.io/v1alpha1/watch/namespaces/:ns/tap
POST /apis/tap.linkerd.io/v1alpha1/watch/namespaces/:ns/:res/:name/tap
Users authorize to the new
tap.linkerd.io/v1alpha1via RBAC. Only thewatchverb is supported. Access is also available via subresourcessuch as
deployments/tapandpods/tap.This change introduces the following resources into the default Linkerd
install:
linkerdnamespace:kube-systemnamespace:Tasks not covered by this PR:
linkerd toplinkerd dashboardlinkerd profile --tapFixes #2725, #3162
Signed-off-by: Andrew Seigner [email protected]
This PR is based on https://github.com/linkerd/linkerd2/compare/dad/tap-pod-2