You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(scheduler): require caller authentication on /refit (#2882)
* fix(scheduler): authenticate /refit endpoint callers via TokenReview
Any in-cluster caller that could reach the scheduler Service could
previously call /refit and move another pod's device allocation onto a
different device, since the endpoint had no caller authentication
(#2878).
The device plugin now sends its bound ServiceAccount token as a bearer
credential on refit calls. The scheduler verifies it with the
TokenReview API, requires the token to belong to the configured
device-plugin ServiceAccount, and confirms the token's bound pod runs
on the node the request claims -- all before touching any allocation
state. The expected ServiceAccount identity is chart-populated so it
stays consistent with the device-plugin's actual namespace/name
instead of being hardcoded.
As defense in depth, the scheduler Service now defaults to ClusterIP
instead of NodePort, and a new NetworkPolicy (enabled by default)
restricts ingress on the scheduler's HTTP port to the device-plugin's
pods and the kube-system namespace.
/filter and /bind are unaffected: kube-scheduler is their caller by
convention and they follow the standard extender protocol, which is
out of scope for this issue.
Signed-off-by: AyushSrivastava1818 <ayush.sri0705@gmail.com>
* fix(chart): default scheduler.networkPolicy.enabled to false
/filter, /bind, /refit, and the admission /webhook all share one port
on the scheduler extender -- NetworkPolicy has no per-path awareness,
so restricting that port also gates /webhook, which kube-apiserver
calls to run HAMi's mutation.
kube-apiserver commonly runs hostNetwork (kubeadm/most on-prem
clusters), and Kubernetes documents NetworkPolicy behavior for
hostNetwork pods as undefined -- Calico (projectcalico/calico#1987)
and Cilium (host-network traffic needs its separate Host Firewall
feature) are both known not to match such traffic against
namespaceSelector. With admissionWebhook.failurePolicy: Ignore
(the chart default), a blocked /webhook doesn't fail closed: pods
admit without HAMi's mutation, so a pod requesting only gpucores/
gpumem never gets the nvidia.com/gpu count resource injected, never
enters HAMi's Filter/Bind, and runs with zero GPU enforcement and no
error surfaced.
/refit's own caller authentication (TokenReview) is an application-layer
check and is unaffected by this either way.
Default the policy off (opt-in) and document the requirement in
values.yaml, the template's own header comment, and NOTES.txt so an
operator who does enable it is warned to verify their CNI matches
apiserver traffic against namespaceSelector first.
Signed-off-by: AyushSrivastava1818 <ayush.sri0705@gmail.com>
* fix(refit): address PR #2882 review comments
- Thread r.Context() into RefitNumaAllocation/authenticateRefitCaller
instead of context.Background(), so TokenReview respects request
cancellation and deadline (issue #2878).
- Validate --device-plugin-namespace and --device-plugin-service-account
at scheduler startup; refuse to start with empty values that would
cause every /refit TokenReview to fail silently.
- Remove dead req.Header.Del in CheckRedirect: the redirect is never
executed once the error is returned, so no header manipulation is needed.
- Fail closed when the projected SA token file cannot be read instead of
silently degrading to unauthenticated; surface a clear error rather than
letting the server reject an unauthenticated request after a full round
trip.
- Fix all tests that relied on plain-HTTP test servers: convert them to
use HTTPS plus a synthetic token via numaRefitTestServerTLS. Add
TestRequestNumaRefitMissingToken to cover the new fail-closed path.
- Fix deployment.yaml to always bind the scheduler on
scheduler.service.httpTargetPort (default 443) regardless of whether
admissionWebhook is enabled, eliminating the silent port mismatch that
left /refit unreachable when the webhook was disabled.
Signed-off-by: AyushSrivastava1818 <ayush.sri0705@gmail.com>
---------
Signed-off-by: AyushSrivastava1818 <ayush.sri0705@gmail.com>
Copy file name to clipboardExpand all lines: cmd/scheduler/main.go
+14Lines changed: 14 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -79,6 +79,8 @@ func init() {
79
79
rootCmd.Flags().DurationVar(&config.NodeLockTimeout, "node-lock-timeout", time.Minute*5, "timeout for node locks")
80
80
rootCmd.Flags().DurationVar(&config.NodeLockRetryTimeout, "node-lock-retry-timeout", 28*time.Second, "timeout for retrying LockNode when contended by another PodGroup member (0 disables retry). Align the Extender's httpTimeout in KubeSchedulerConfiguration with this value.")
81
81
rootCmd.Flags().BoolVar(&config.ForceOverwriteDefaultScheduler, "force-overwrite-default-scheduler", true, "Overwrite schedulerName in Pod Spec when set to the const DefaultSchedulerName in https://k8s.io/api/core/v1 package")
82
+
rootCmd.Flags().StringVar(&config.DevicePluginNamespace, "device-plugin-namespace", "", "namespace of the device-plugin ServiceAccount allowed to call the /refit endpoint")
83
+
rootCmd.Flags().StringVar(&config.DevicePluginServiceAccount, "device-plugin-service-account", "", "name of the device-plugin ServiceAccount allowed to call the /refit endpoint")
82
84
83
85
rootCmd.Flags().BoolVar(&config.LeaderElect, "leader-elect", false, "The pod of hami-scheduler enable leader select")
84
86
rootCmd.Flags().StringVar(&config.LeaderElectResourceName, "leader-elect-resource-name", "", "The name of resource object that is used for leader election")
@@ -130,6 +132,18 @@ func start() error {
130
132
returnfmt.Errorf("empty hostname returned")
131
133
}
132
134
135
+
// Refuse to start with an unusable /refit identity: empty namespace or
136
+
// service-account means every TokenReview will fail, but silently – the
137
+
// scheduler would appear healthy while all refit calls are rejected.
0 commit comments