Skip to content

Commit 07a2754

Browse files
authored
kubectl debug: Display a warning message that the debug container's capabilities may not work with a non-root user (kubernetes#127696)
* Add warning message about capabilities of debug container * fix1 * fix2 * fix3
1 parent 3a14b61 commit 07a2754

File tree

4 files changed

+88
-0
lines changed

4 files changed

+88
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
labels:
5+
run: target
6+
name: target
7+
spec:
8+
securityContext:
9+
runAsUser: 1000
10+
runAsGroup: 1000
11+
runAsNonRoot: true
12+
containers:
13+
- image: busybox
14+
name: target
15+
command: ["/bin/sh", "-c", "sleep 100"]

staging/src/k8s.io/kubectl/pkg/cmd/debug/debug.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ var (
7575
debugging utilities without restarting the pod.
7676
* Node: Create a new pod that runs in the node's host namespaces and can access
7777
the node's filesystem.
78+
79+
Note: When a non-root user is configured for the entire target Pod, some capabilities granted
80+
by debug profile may not work.
7881
`))
7982

8083
debugExample = templates.Examples(i18n.T(`
@@ -495,6 +498,8 @@ func (o *DebugOptions) debugByEphemeralContainer(ctx context.Context, pod *corev
495498
}
496499
klog.V(2).Infof("new ephemeral container: %#v", debugContainer)
497500

501+
o.displayWarning((*corev1.Container)(&debugContainer.EphemeralContainerCommon), pod)
502+
498503
debugJS, err := json.Marshal(debugPod)
499504
if err != nil {
500505
return nil, "", fmt.Errorf("error creating JSON for debug container: %v", err)
@@ -611,6 +616,16 @@ func (o *DebugOptions) debugByCopy(ctx context.Context, pod *corev1.Pod) (*corev
611616
if err != nil {
612617
return nil, "", err
613618
}
619+
620+
var debugContainer *corev1.Container
621+
for i := range copied.Spec.Containers {
622+
if copied.Spec.Containers[i].Name == dc {
623+
debugContainer = &copied.Spec.Containers[i]
624+
break
625+
}
626+
}
627+
o.displayWarning(debugContainer, copied)
628+
614629
created, err := o.podClient.Pods(copied.Namespace).Create(ctx, copied, metav1.CreateOptions{})
615630
if err != nil {
616631
return nil, "", err
@@ -624,6 +639,32 @@ func (o *DebugOptions) debugByCopy(ctx context.Context, pod *corev1.Pod) (*corev
624639
return created, dc, nil
625640
}
626641

642+
// Display warning message if some capabilities are set by profile and non-root user is specified in .Spec.SecurityContext.RunAsUser.(#1650)
643+
func (o *DebugOptions) displayWarning(container *corev1.Container, pod *corev1.Pod) {
644+
if container == nil {
645+
return
646+
}
647+
648+
if pod.Spec.SecurityContext.RunAsUser == nil || *pod.Spec.SecurityContext.RunAsUser == 0 {
649+
return
650+
}
651+
652+
if container.SecurityContext == nil {
653+
return
654+
}
655+
656+
if container.SecurityContext.RunAsUser != nil && *container.SecurityContext.RunAsUser == 0 {
657+
return
658+
}
659+
660+
if (container.SecurityContext.Privileged == nil || !*container.SecurityContext.Privileged) &&
661+
(container.SecurityContext.Capabilities == nil || len(container.SecurityContext.Capabilities.Add) == 0) {
662+
return
663+
}
664+
665+
_, _ = fmt.Fprintln(o.ErrOut, `Warning: Non-root user is configured for the entire target Pod, and some capabilities granted by debug profile may not work. Please consider using "--custom" with a custom profile that specifies "securityContext.runAsUser: 0".`)
666+
}
667+
627668
// generateDebugContainer returns a debugging pod and an EphemeralContainer suitable for use as a debug container
628669
// in the given pod.
629670
func (o *DebugOptions) generateDebugContainer(pod *corev1.Pod) (*corev1.Pod, *corev1.EphemeralContainer, error) {

test/cmd/debug.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,3 +659,34 @@ EOF
659659
set +o nounset
660660
set +o errexit
661661
}
662+
663+
run_kubectl_debug_warning_tests() {
664+
set -o nounset
665+
set -o errexit
666+
667+
create_and_use_new_namespace
668+
kube::log::status "Testing kubectl debug warning"
669+
670+
### Non-root Pod Troubleshooting by ephemeral containers
671+
# Pre-Condition: Non-root Pod "busybox" is created
672+
kubectl create -f hack/testdata/pod-run-as-non-root.yaml "${kube_flags[@]:?}"
673+
kube::test::get_object_assert pod "{{range.items}}{{${id_field:?}}}:{{end}}" 'target:'
674+
# Command: add a new debug container with netadmin profile
675+
output_message=$(kubectl debug target -it --image=busybox --container=debug-container --attach=false --profile=netadmin "${kube_flags[@]:?}" 2>&1)
676+
kube::test::if_has_string "${output_message}" 'Warning: Non-root user is configured for the entire target Pod, and some capabilities granted by debug profile may not work. Please consider using "--custom" with a custom profile that specifies "securityContext.runAsUser: 0".'
677+
# Clean up
678+
kubectl delete pod target "${kube_flags[@]:?}"
679+
680+
### Non-root Pod Troubleshooting by pod copy
681+
# Pre-Condition: Non-root Pod "busybox" is created
682+
kubectl create -f hack/testdata/pod-run-as-non-root.yaml "${kube_flags[@]:?}"
683+
kube::test::get_object_assert pod "{{range.items}}{{${id_field:?}}}:{{end}}" 'target:'
684+
# Command: create a copy of target with a new debug container
685+
output_message=$(kubectl debug target -it --copy-to=target-copy --image=busybox --container=debug-container --attach=false --profile=netadmin "${kube_flags[@]:?}" 2>&1)
686+
kube::test::if_has_string "${output_message}" 'Warning: Non-root user is configured for the entire target Pod, and some capabilities granted by debug profile may not work. Please consider using "--custom" with a custom profile that specifies "securityContext.runAsUser: 0".'
687+
# Clean up
688+
kubectl delete pod target "${kube_flags[@]:?}"
689+
690+
set +o nounset
691+
set +o errexit
692+
}

test/cmd/legacy-script.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,6 +1048,7 @@ runTests() {
10481048
record_command run_kubectl_debug_restricted_tests
10491049
record_command run_kubectl_debug_netadmin_tests
10501050
record_command run_kubectl_debug_custom_profile_tests
1051+
record_command run_kubectl_debug_warning_tests
10511052
fi
10521053
if kube::test::if_supports_resource "${nodes}" ; then
10531054
record_command run_kubectl_debug_node_tests

0 commit comments

Comments
 (0)