diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/debug/debug.go b/staging/src/k8s.io/kubectl/pkg/cmd/debug/debug.go index be825507d7d..ff4085b1e82 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/debug/debug.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/debug/debug.go @@ -213,7 +213,7 @@ func (o *DebugOptions) AddFlags(cmd *cobra.Command) { cmd.Flags().BoolVar(&o.ShareProcesses, "share-processes", o.ShareProcesses, i18n.T("When used with '--copy-to', enable process namespace sharing in the copy.")) cmd.Flags().StringVar(&o.TargetContainer, "target", "", i18n.T("When using an ephemeral container, target processes in this container name.")) cmd.Flags().BoolVarP(&o.TTY, "tty", "t", o.TTY, i18n.T("Allocate a TTY for the debugging container.")) - cmd.Flags().StringVar(&o.Profile, "profile", ProfileLegacy, i18n.T(`Options are "legacy", "general", "baseline", "netadmin", "restricted" or "sysadmin".`)) + cmd.Flags().StringVar(&o.Profile, "profile", ProfileGeneral, i18n.T(`Options are "general", "baseline", "restricted", "netadmin" or "sysadmin". Defaults to "general"`)) cmd.Flags().StringVar(&o.CustomProfileFile, "custom", o.CustomProfileFile, i18n.T("Path to a JSON or YAML file containing a partial container spec to customize built-in debug profiles.")) } @@ -401,7 +401,7 @@ func (o *DebugOptions) Validate() error { // Warning for legacy profile if o.Profile == ProfileLegacy { - fmt.Fprintln(o.ErrOut, `--profile=legacy is deprecated and will be removed in the future. It is recommended to explicitly specify a profile, for example "--profile=general".`) + fmt.Fprintln(o.ErrOut, `--profile=legacy is deprecated and planned to be removed in v1.39. It is recommended to specify other profile, for example "--profile=general".`) //nolint:errcheck } return nil diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/debug/debug_test.go b/staging/src/k8s.io/kubectl/pkg/cmd/debug/debug_test.go index cec08b796e3..d09fc684b89 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/debug/debug_test.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/debug/debug_test.go @@ -2620,7 +2620,7 @@ func TestCompleteAndValidate(t *testing.T) { Namespace: "test", PullPolicy: corev1.PullPolicy("Always"), ShareProcesses: true, - Profile: ProfileLegacy, + Profile: ProfileGeneral, TargetNames: []string{"mypod"}, }, }, @@ -2633,7 +2633,7 @@ func TestCompleteAndValidate(t *testing.T) { KeepInitContainers: true, Namespace: "test", ShareProcesses: true, - Profile: ProfileLegacy, + Profile: ProfileGeneral, TargetNames: []string{"mypod1", "mypod2"}, }, }, @@ -2646,7 +2646,7 @@ func TestCompleteAndValidate(t *testing.T) { KeepInitContainers: true, Namespace: "test", ShareProcesses: true, - Profile: ProfileLegacy, + Profile: ProfileGeneral, TargetNames: []string{"mypod1", "mypod2"}, }, }, @@ -2661,7 +2661,7 @@ func TestCompleteAndValidate(t *testing.T) { Interactive: true, Namespace: "test", ShareProcesses: true, - Profile: ProfileLegacy, + Profile: ProfileGeneral, TargetNames: []string{"mypod"}, TTY: true, }, @@ -2676,7 +2676,7 @@ func TestCompleteAndValidate(t *testing.T) { KeepInitContainers: true, Namespace: "test", ShareProcesses: true, - Profile: ProfileLegacy, + Profile: ProfileGeneral, TargetNames: []string{"mypod"}, }, }, @@ -2691,7 +2691,7 @@ func TestCompleteAndValidate(t *testing.T) { KeepInitContainers: true, Namespace: "test", ShareProcesses: true, - Profile: ProfileLegacy, + Profile: ProfileGeneral, TargetNames: []string{"mypod"}, TTY: true, }, @@ -2706,7 +2706,7 @@ func TestCompleteAndValidate(t *testing.T) { KeepInitContainers: true, Namespace: "test", PullPolicy: corev1.PullPolicy("Always"), - Profile: ProfileLegacy, + Profile: ProfileGeneral, ShareProcesses: true, TargetNames: []string{"mypod"}, }, @@ -2748,7 +2748,7 @@ func TestCompleteAndValidate(t *testing.T) { KeepInitContainers: true, Namespace: "test", ShareProcesses: true, - Profile: ProfileLegacy, + Profile: ProfileGeneral, TargetNames: []string{"mypod"}, TTY: true, }, @@ -2764,7 +2764,7 @@ func TestCompleteAndValidate(t *testing.T) { KeepInitContainers: true, Namespace: "test", ShareProcesses: true, - Profile: ProfileLegacy, + Profile: ProfileGeneral, TargetNames: []string{"mypod"}, }, }, @@ -2779,7 +2779,7 @@ func TestCompleteAndValidate(t *testing.T) { KeepInitContainers: true, Namespace: "test", ShareProcesses: true, - Profile: ProfileLegacy, + Profile: ProfileGeneral, TargetNames: []string{"mypod"}, }, }, @@ -2794,7 +2794,7 @@ func TestCompleteAndValidate(t *testing.T) { KeepInitContainers: true, Namespace: "test", ShareProcesses: true, - Profile: ProfileLegacy, + Profile: ProfileGeneral, TargetNames: []string{"mypod"}, }, }, @@ -2811,7 +2811,7 @@ func TestCompleteAndValidate(t *testing.T) { "app": "app-debugger", }, ShareProcesses: true, - Profile: ProfileLegacy, + Profile: ProfileGeneral, TargetNames: []string{"mypod"}, }, }, @@ -2831,7 +2831,7 @@ func TestCompleteAndValidate(t *testing.T) { "sidecar": "sidecar:debug", }, ShareProcesses: true, - Profile: ProfileLegacy, + Profile: ProfileGeneral, TargetNames: []string{"mypod"}, TTY: true, }, @@ -2848,7 +2848,7 @@ func TestCompleteAndValidate(t *testing.T) { KeepInitContainers: true, Namespace: "test", ShareProcesses: true, - Profile: ProfileLegacy, + Profile: ProfileGeneral, TargetNames: []string{"mypod"}, TTY: true, }, @@ -2870,7 +2870,7 @@ func TestCompleteAndValidate(t *testing.T) { KeepInitContainers: false, Namespace: "test", ShareProcesses: true, - Profile: ProfileLegacy, + Profile: ProfileGeneral, TargetNames: []string{"mypod"}, TTY: true, }, @@ -2911,7 +2911,7 @@ func TestCompleteAndValidate(t *testing.T) { KeepInitContainers: true, Namespace: "test", ShareProcesses: true, - Profile: ProfileLegacy, + Profile: ProfileGeneral, TargetNames: []string{"node/mynode"}, TTY: true, }, diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/debug/profiles.go b/staging/src/k8s.io/kubectl/pkg/cmd/debug/profiles.go index b7e3d178682..8c0b459df7c 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/debug/profiles.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/debug/profiles.go @@ -43,6 +43,8 @@ const ( // --profile flag's help text // ProfileLegacy represents the legacy debugging profile which is backwards-compatible with 1.23 behavior. + // + // Deprecated: legacyProfile is planned to be removed in v1.39. ProfileLegacy = "legacy" // ProfileGeneral contains a reasonable set of defaults tailored for each debugging journey. ProfileGeneral = "general" diff --git a/test/cmd/debug.sh b/test/cmd/debug.sh index f8b4e53e211..573a813c745 100755 --- a/test/cmd/debug.sh +++ b/test/cmd/debug.sh @@ -18,34 +18,46 @@ set -o errexit set -o nounset set -o pipefail -run_kubectl_debug_pod_tests() { +run_kubectl_debug_tests() { set -o nounset set -o errexit create_and_use_new_namespace - kube::log::status "Testing kubectl debug (pod tests)" + kube::log::status "Testing kubectl debug" ### Pod Troubleshooting by ephemeral containers + ### sets SYS_PTRACE in ephemeral container # Pre-Condition: Pod "nginx" is created kubectl run target "--image=${IMAGE_NGINX:?}" "${kube_flags[@]:?}" kube::test::get_object_assert pod "{{range.items}}{{${id_field:?}}}:{{end}}" 'target:' # Command: create a copy of target with a new debug container kubectl debug target -it --image=busybox --attach=false -c debug-container "${kube_flags[@]:?}" # Post-Conditions - kube::test::get_object_assert pod/target '{{range.spec.ephemeralContainers}}{{.name}}:{{end}}' 'debug-container:' + kube::test::get_object_assert pod/target '{{range.spec.ephemeralContainers}}{{.name}}:{{.image}}{{end}}' 'debug-container:busybox' + kube::test::get_object_assert pod/target '{{(index (index .spec.ephemeralContainers 0).securityContext.capabilities.add 0)}}' 'SYS_PTRACE' # Clean up kubectl delete pod target "${kube_flags[@]:?}" ### Pod Troubleshooting by Copy - # Pre-Condition: Pod "nginx" is created - kubectl run target "--image=${IMAGE_NGINX:?}" "${kube_flags[@]:?}" + # Pre-Condition: Pod "nginx" with labels, annotations, probes and initContainers is created + kubectl create -f hack/testdata/pod-with-metadata-and-probes.yaml kube::test::get_object_assert pod "{{range.items}}{{${id_field:?}}}:{{end}}" 'target:' # Command: create a copy of target with a new debug container + # labels, annotations, probes are removed and initContainers are kept, sets SYS_PTRACE in debugging container, sets shareProcessNamespace kubectl debug target -it --copy-to=target-copy --image=busybox --container=debug-container --attach=false "${kube_flags[@]:?}" # Post-Conditions kube::test::get_object_assert pod "{{range.items}}{{${id_field:?}}}:{{end}}" 'target:target-copy:' + kube::test::get_object_assert pod/target-copy '{{.metadata.labels}}' '' + kube::test::get_object_assert pod/target-copy '{{.metadata.annotations}}' '' kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{.name}}:{{end}}' 'target:debug-container:' kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{.image}}:{{end}}' "${IMAGE_NGINX:?}:busybox:" + kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{if (index . "livenessProbe")}}:{{end}}{{end}}' '' + kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{if (index . "readinessProbe")}}:{{end}}{{end}}' '' + kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{if (index . "startupProbe")}}:{{end}}{{end}}' '' + kube::test::get_object_assert pod/target-copy '{{range.spec.initContainers}}{{.name}}:{{end}}' 'init:' + kube::test::get_object_assert pod/target-copy '{{range.spec.initContainers}}{{.image}}:{{end}}' "busybox:" + kube::test::get_object_assert pod/target-copy '{{(index (index .spec.containers 1).securityContext.capabilities.add 0)}}' 'SYS_PTRACE' + kube::test::get_object_assert pod/target-copy '{{.spec.shareProcessNamespace}}' 'true' # Clean up kubectl delete pod target target-copy "${kube_flags[@]:?}" @@ -53,19 +65,20 @@ run_kubectl_debug_pod_tests() { kubectl create -f hack/testdata/pod-with-metadata-and-probes.yaml kube::test::get_object_assert pod "{{range.items}}{{${id_field:?}}}:{{end}}" 'target:' # Command: create a copy of target with a new debug container with --keep-* flags - # --keep-* flags intentionally don't work with legacyProfile(Only labels are removed) + # labels, annotations, probes are kept and initContainers are removed, sets SYS_PTRACE in debugging container, sets shareProcessNamespace kubectl debug target -it --copy-to=target-copy --image=busybox --container=debug-container --keep-labels=true --keep-annotations=true --keep-liveness=true --keep-readiness=true --keep-startup=true --keep-init-containers=false --attach=false "${kube_flags[@]:?}" # Post-Conditions kube::test::get_object_assert pod "{{range.items}}{{${id_field:?}}}:{{end}}" 'target:target-copy:' - kube::test::get_object_assert pod/target-copy '{{.metadata.labels}}' '' + kube::test::get_object_assert pod/target-copy '{{.metadata.labels}}' 'map\[run:target\]' kube::test::get_object_assert pod/target-copy '{{.metadata.annotations}}' 'map\[test:test\]' kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{.name}}:{{end}}' 'target:debug-container:' kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{.image}}:{{end}}' "${IMAGE_NGINX:?}:busybox:" kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{if (index . "livenessProbe")}}:{{end}}{{end}}' ':' kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{if (index . "readinessProbe")}}:{{end}}{{end}}' ':' kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{if (index . "startupProbe")}}:{{end}}{{end}}' ':' - kube::test::get_object_assert pod/target-copy '{{range.spec.initContainers}}{{.name}}:{{end}}' 'init:' - kube::test::get_object_assert pod/target-copy '{{range.spec.initContainers}}{{.image}}:{{end}}' "busybox:" + kube::test::get_object_assert pod/target-copy '{{.spec.initContainers}}' '' + kube::test::get_object_assert pod/target-copy '{{(index (index .spec.containers 1).securityContext.capabilities.add 0)}}' 'SYS_PTRACE' + kube::test::get_object_assert pod/target-copy '{{.spec.shareProcessNamespace}}' 'true' # Clean up kubectl delete pod target target-copy "${kube_flags[@]:?}" @@ -115,7 +128,7 @@ run_kubectl_debug_node_tests() { set -o errexit create_and_use_new_namespace - kube::log::status "Testing kubectl debug (pod tests)" + kube::log::status "Testing kubectl debug (node)" ### Node Troubleshooting by Privileged Container @@ -143,33 +156,24 @@ run_kubectl_debug_node_tests() { set +o errexit } -run_kubectl_debug_general_tests() { +# Deprecated: legacyProfile is planned to be removed in v1.39 +run_kubectl_debug_legacy_tests() { set -o nounset set -o errexit create_and_use_new_namespace - kube::log::status "Testing kubectl debug profile general" + kube::log::status "Testing kubectl debug profile legacy" ### Debug by pod copy - # Pre-Condition: Pod "nginx" with labels, annotations, probes and initContainers is created - kubectl create -f hack/testdata/pod-with-metadata-and-probes.yaml + # Pre-Condition: Pod "nginx" is created + kubectl run target "--image=${IMAGE_NGINX:?}" "${kube_flags[@]:?}" kube::test::get_object_assert pod "{{range.items}}{{${id_field:?}}}:{{end}}" 'target:' # Command: create a copy of target with a new debug container - # labels, annotations, probes are removed and initContainers are kept, sets SYS_PTRACE in debugging container, sets shareProcessNamespace - kubectl debug --profile general target -it --copy-to=target-copy --image=busybox --container=debug-container --attach=false "${kube_flags[@]:?}" + kubectl debug --profile legacy target -it --copy-to=target-copy --image=busybox --container=debug-container --attach=false "${kube_flags[@]:?}" # Post-Conditions kube::test::get_object_assert pod "{{range.items}}{{${id_field:?}}}:{{end}}" 'target:target-copy:' - kube::test::get_object_assert pod/target-copy '{{.metadata.labels}}' '' - kube::test::get_object_assert pod/target-copy '{{.metadata.annotations}}' '' kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{.name}}:{{end}}' 'target:debug-container:' kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{.image}}:{{end}}' "${IMAGE_NGINX:?}:busybox:" - kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{if (index . "livenessProbe")}}:{{end}}{{end}}' '' - kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{if (index . "readinessProbe")}}:{{end}}{{end}}' '' - kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{if (index . "startupProbe")}}:{{end}}{{end}}' '' - kube::test::get_object_assert pod/target-copy '{{range.spec.initContainers}}{{.name}}:{{end}}' 'init:' - kube::test::get_object_assert pod/target-copy '{{range.spec.initContainers}}{{.image}}:{{end}}' "busybox:" - kube::test::get_object_assert pod/target-copy '{{(index (index .spec.containers 1).securityContext.capabilities.add 0)}}' 'SYS_PTRACE' - kube::test::get_object_assert pod/target-copy '{{.spec.shareProcessNamespace}}' 'true' # Clean up kubectl delete pod target target-copy "${kube_flags[@]:?}" @@ -177,34 +181,30 @@ run_kubectl_debug_general_tests() { kubectl create -f hack/testdata/pod-with-metadata-and-probes.yaml kube::test::get_object_assert pod "{{range.items}}{{${id_field:?}}}:{{end}}" 'target:' # Command: create a copy of target with a new debug container with --keep-* flags - # labels, annotations, probes are kept and initContainers are removed, sets SYS_PTRACE in debugging container, sets shareProcessNamespace - kubectl debug --profile general target -it --copy-to=target-copy --image=busybox --container=debug-container --keep-labels=true --keep-annotations=true --keep-liveness=true --keep-readiness=true --keep-startup=true --keep-init-containers=false --attach=false "${kube_flags[@]:?}" + # --keep-* flags intentionally don't work with legacyProfile(Only labels are removed) + kubectl debug --profile legacy target -it --copy-to=target-copy --image=busybox --container=debug-container --keep-labels=true --keep-annotations=true --keep-liveness=true --keep-readiness=true --keep-startup=true --keep-init-containers=false --attach=false "${kube_flags[@]:?}" # Post-Conditions kube::test::get_object_assert pod "{{range.items}}{{${id_field:?}}}:{{end}}" 'target:target-copy:' - kube::test::get_object_assert pod/target-copy '{{.metadata.labels}}' 'map\[run:target\]' + kube::test::get_object_assert pod/target-copy '{{.metadata.labels}}' '' kube::test::get_object_assert pod/target-copy '{{.metadata.annotations}}' 'map\[test:test\]' kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{.name}}:{{end}}' 'target:debug-container:' kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{.image}}:{{end}}' "${IMAGE_NGINX:?}:busybox:" kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{if (index . "livenessProbe")}}:{{end}}{{end}}' ':' kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{if (index . "readinessProbe")}}:{{end}}{{end}}' ':' kube::test::get_object_assert pod/target-copy '{{range.spec.containers}}{{if (index . "startupProbe")}}:{{end}}{{end}}' ':' - kube::test::get_object_assert pod/target-copy '{{.spec.initContainers}}' '' - kube::test::get_object_assert pod/target-copy '{{(index (index .spec.containers 1).securityContext.capabilities.add 0)}}' 'SYS_PTRACE' - kube::test::get_object_assert pod/target-copy '{{.spec.shareProcessNamespace}}' 'true' + kube::test::get_object_assert pod/target-copy '{{range.spec.initContainers}}{{.name}}:{{end}}' 'init:' + kube::test::get_object_assert pod/target-copy '{{range.spec.initContainers}}{{.image}}:{{end}}' "busybox:" # Clean up kubectl delete pod target target-copy "${kube_flags[@]:?}" ### Debug by EC - ### sets SYS_PTRACE in ephemeral container - # Pre-Condition: Pod "nginx" is created kubectl run target "--image=${IMAGE_NGINX:?}" "${kube_flags[@]:?}" kube::test::get_object_assert pod "{{range.items}}{{${id_field:?}}}:{{end}}" 'target:' # Command: create a copy of target with a new debug container - kubectl debug --profile general target -it --image=busybox --container=debug-container --attach=false "${kube_flags[@]:?}" + kubectl debug --profile legacy target -it --image=busybox --attach=false -c debug-container "${kube_flags[@]:?}" # Post-Conditions - kube::test::get_object_assert pod/target '{{range.spec.ephemeralContainers}}{{.name}}:{{.image}}{{end}}' 'debug-container:busybox' - kube::test::get_object_assert pod/target '{{(index (index .spec.ephemeralContainers 0).securityContext.capabilities.add 0)}}' 'SYS_PTRACE' + kube::test::get_object_assert pod/target '{{range.spec.ephemeralContainers}}{{.name}}:{{end}}' 'debug-container:' # Clean up kubectl delete pod target "${kube_flags[@]:?}" @@ -212,12 +212,13 @@ run_kubectl_debug_general_tests() { set +o errexit } -run_kubectl_debug_general_node_tests() { +# Deprecated: legacyProfile is planned to be removed in v1.39 +run_kubectl_debug_legacy_node_tests() { set -o nounset set -o errexit create_and_use_new_namespace - kube::log::status "Testing kubectl debug profile general (node)" + kube::log::status "Testing kubectl debug profile legacy (node)" ### Debug node ### empty securityContext, uses host namespaces, mounts root partition @@ -225,7 +226,7 @@ run_kubectl_debug_general_node_tests() { # Pre-Condition: node exists kube::test::get_object_assert nodes "{{range.items}}{{${id_field:?}}}:{{end}}" '127.0.0.1:' # Command: create a new node debugger pod - output_message=$(kubectl debug --profile general node/127.0.0.1 --image=busybox --attach=false "${kube_flags[@]:?}" -- true) + output_message=$(kubectl debug --profile legacy node/127.0.0.1 --image=busybox --attach=false "${kube_flags[@]:?}" -- true) # Post-Conditions kube::test::get_object_assert pod "{{(len .items)}}" '1' debugger=$(kubectl get pod -o go-template="{{(index .items 0)${id_field:?}}}") diff --git a/test/cmd/legacy-script.sh b/test/cmd/legacy-script.sh index ebcefb676f1..c0f83437b16 100755 --- a/test/cmd/legacy-script.sh +++ b/test/cmd/legacy-script.sh @@ -1042,8 +1042,8 @@ runTests() { # kubectl debug # #################### if kube::test::if_supports_resource "${pods}" ; then - record_command run_kubectl_debug_pod_tests - record_command run_kubectl_debug_general_tests + record_command run_kubectl_debug_tests + record_command run_kubectl_debug_legacy_tests record_command run_kubectl_debug_baseline_tests record_command run_kubectl_debug_restricted_tests record_command run_kubectl_debug_netadmin_tests @@ -1052,7 +1052,7 @@ runTests() { fi if kube::test::if_supports_resource "${nodes}" ; then record_command run_kubectl_debug_node_tests - record_command run_kubectl_debug_general_node_tests + record_command run_kubectl_debug_legacy_node_tests record_command run_kubectl_debug_baseline_node_tests record_command run_kubectl_debug_restricted_node_tests record_command run_kubectl_debug_netadmin_node_tests