Print kubectl debug messages received when starting a container (#108591)

* kubectl debug: print container messages

This provides feedback to the user, for example that the server is
unable to pull the debug container image.

* Label debug container updates as warnings

Co-authored-by: Eddie Zaneski <eddiezane@gmail.com>

Co-authored-by: Eddie Zaneski <eddiezane@gmail.com>

Kubernetes-commit: 90956e6d3e9df02d932f9954911b89a3fd1619fb
This commit is contained in:
Lee Verberne 2022-03-10 02:51:35 +01:00 committed by Kubernetes Publisher
parent 1932a5f96f
commit 3d7e4b3f7f
3 changed files with 18 additions and 14 deletions

8
go.mod
View File

@ -32,9 +32,9 @@ require (
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 golang.org/x/sys v0.0.0-20220209214540-3681064d5158
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.0.0-20220226220324-b8c40e080bc5 k8s.io/api v0.0.0-20220226220324-b8c40e080bc5
k8s.io/apimachinery v0.0.0-20220305020656-da0995ba93c3 k8s.io/apimachinery v0.0.0-20220309082612-aa725640f715
k8s.io/cli-runtime v0.0.0-20220304062546-5a23dd4f767a k8s.io/cli-runtime v0.0.0-20220304062546-5a23dd4f767a
k8s.io/client-go v0.0.0-20220303122547-eb103e0abf62 k8s.io/client-go v0.0.0-20220308221144-2f52a105e63e
k8s.io/component-base v0.0.0-20220301021127-30d23418100a k8s.io/component-base v0.0.0-20220301021127-30d23418100a
k8s.io/component-helpers v0.0.0-20220221181225-89b3c2ca20da k8s.io/component-helpers v0.0.0-20220221181225-89b3c2ca20da
k8s.io/klog/v2 v2.40.1 k8s.io/klog/v2 v2.40.1
@ -49,9 +49,9 @@ require (
replace ( replace (
k8s.io/api => k8s.io/api v0.0.0-20220226220324-b8c40e080bc5 k8s.io/api => k8s.io/api v0.0.0-20220226220324-b8c40e080bc5
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20220305020656-da0995ba93c3 k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20220309082612-aa725640f715
k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20220304062546-5a23dd4f767a k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20220304062546-5a23dd4f767a
k8s.io/client-go => k8s.io/client-go v0.0.0-20220303122547-eb103e0abf62 k8s.io/client-go => k8s.io/client-go v0.0.0-20220308221144-2f52a105e63e
k8s.io/code-generator => k8s.io/code-generator v0.0.0-20220226191723-8d7923dd2451 k8s.io/code-generator => k8s.io/code-generator v0.0.0-20220226191723-8d7923dd2451
k8s.io/component-base => k8s.io/component-base v0.0.0-20220301021127-30d23418100a k8s.io/component-base => k8s.io/component-base v0.0.0-20220301021127-30d23418100a
k8s.io/component-helpers => k8s.io/component-helpers v0.0.0-20220221181225-89b3c2ca20da k8s.io/component-helpers => k8s.io/component-helpers v0.0.0-20220221181225-89b3c2ca20da

8
go.sum
View File

@ -921,12 +921,12 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.0.0-20220226220324-b8c40e080bc5 h1:z4oqfOInb6p7EwsJbKUe2IcKaeSBWmfYEIsIdFHq6ak= k8s.io/api v0.0.0-20220226220324-b8c40e080bc5 h1:z4oqfOInb6p7EwsJbKUe2IcKaeSBWmfYEIsIdFHq6ak=
k8s.io/api v0.0.0-20220226220324-b8c40e080bc5/go.mod h1:xmVR3mDgBB2FAJoueQFwuWn03L5odGCiOKivsptcgRU= k8s.io/api v0.0.0-20220226220324-b8c40e080bc5/go.mod h1:xmVR3mDgBB2FAJoueQFwuWn03L5odGCiOKivsptcgRU=
k8s.io/apimachinery v0.0.0-20220305020656-da0995ba93c3 h1:JEGi8vCoh23TJCSXA4pExj5REB7X4bn2SbWsEuI8abY= k8s.io/apimachinery v0.0.0-20220309082612-aa725640f715 h1:aEJAi7cAk/Tdn4gS+ENqYU/eFdT+f+QRy2Z+fC7tNzU=
k8s.io/apimachinery v0.0.0-20220305020656-da0995ba93c3/go.mod h1:6HjHJr7AD3yHuu+gOdE3O1dqE21lBVCDBk5W7wry/WI= k8s.io/apimachinery v0.0.0-20220309082612-aa725640f715/go.mod h1:6HjHJr7AD3yHuu+gOdE3O1dqE21lBVCDBk5W7wry/WI=
k8s.io/cli-runtime v0.0.0-20220304062546-5a23dd4f767a h1:GLtjCZTc3Qx7ZuYJb+gKDGT1XTBqENco3v64fSYJjPk= k8s.io/cli-runtime v0.0.0-20220304062546-5a23dd4f767a h1:GLtjCZTc3Qx7ZuYJb+gKDGT1XTBqENco3v64fSYJjPk=
k8s.io/cli-runtime v0.0.0-20220304062546-5a23dd4f767a/go.mod h1:R3r66bEzcK8AGKIBf7tz+CW0cOyn7CfOtPfblRlGT6o= k8s.io/cli-runtime v0.0.0-20220304062546-5a23dd4f767a/go.mod h1:R3r66bEzcK8AGKIBf7tz+CW0cOyn7CfOtPfblRlGT6o=
k8s.io/client-go v0.0.0-20220303122547-eb103e0abf62 h1:kpsNQiWWMoxhrGbeNBVlojVEIkOUUXs+prjf7026YDE= k8s.io/client-go v0.0.0-20220308221144-2f52a105e63e h1:qX/9E7tnbtpQ57WiGjJNvmiJ9BD1lkptbLj7oKxKwYY=
k8s.io/client-go v0.0.0-20220303122547-eb103e0abf62/go.mod h1:X+9ONiZCJ4K5521TlOgbcMrYFvkjacBd90IPckfzTac= k8s.io/client-go v0.0.0-20220308221144-2f52a105e63e/go.mod h1:jk4568EW9+eYwEkJh+0fP6CmWVDSYeFM2okIbNwRdaw=
k8s.io/code-generator v0.0.0-20220226191723-8d7923dd2451/go.mod h1:BunYIiSvEAW736r5Q7j7shOSPkb80INs0kWYJvW2o6I= k8s.io/code-generator v0.0.0-20220226191723-8d7923dd2451/go.mod h1:BunYIiSvEAW736r5Q7j7shOSPkb80INs0kWYJvW2o6I=
k8s.io/component-base v0.0.0-20220301021127-30d23418100a h1:ZEEAhoBrshp9Dskp4Cu01GWusuSj7rxqT9gpGHPT87M= k8s.io/component-base v0.0.0-20220301021127-30d23418100a h1:ZEEAhoBrshp9Dskp4Cu01GWusuSj7rxqT9gpGHPT87M=
k8s.io/component-base v0.0.0-20220301021127-30d23418100a/go.mod h1:GxjPIEe+u2ujTZ5FAWeI72IXLuFY8otpmXIeWIP0G7M= k8s.io/component-base v0.0.0-20220301021127-30d23418100a/go.mod h1:GxjPIEe+u2ujTZ5FAWeI72IXLuFY8otpmXIeWIP0G7M=

View File

@ -357,7 +357,7 @@ func (o *DebugOptions) Run(f cmdutil.Factory, cmd *cobra.Command) error {
opts.Config = config opts.Config = config
opts.AttachFunc = attach.DefaultAttachFunc opts.AttachFunc = attach.DefaultAttachFunc
if err := handleAttachPod(ctx, f, o.podClient, debugPod.Namespace, debugPod.Name, containerName, opts); err != nil { if err := o.handleAttachPod(ctx, f, debugPod.Namespace, debugPod.Name, containerName, opts); err != nil {
return err return err
} }
} }
@ -701,7 +701,7 @@ func containerNameToRef(pod *corev1.Pod) map[string]*corev1.Container {
} }
// waitForContainer watches the given pod until the container is running // waitForContainer watches the given pod until the container is running
func waitForContainer(ctx context.Context, podClient corev1client.PodsGetter, ns, podName, containerName string) (*corev1.Pod, error) { func (o *DebugOptions) waitForContainer(ctx context.Context, ns, podName, containerName string) (*corev1.Pod, error) {
// TODO: expose the timeout // TODO: expose the timeout
ctx, cancel := watchtools.ContextWithOptionalTimeout(ctx, 0*time.Second) ctx, cancel := watchtools.ContextWithOptionalTimeout(ctx, 0*time.Second)
defer cancel() defer cancel()
@ -710,11 +710,11 @@ func waitForContainer(ctx context.Context, podClient corev1client.PodsGetter, ns
lw := &cache.ListWatch{ lw := &cache.ListWatch{
ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
options.FieldSelector = fieldSelector options.FieldSelector = fieldSelector
return podClient.Pods(ns).List(ctx, options) return o.podClient.Pods(ns).List(ctx, options)
}, },
WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
options.FieldSelector = fieldSelector options.FieldSelector = fieldSelector
return podClient.Pods(ns).Watch(ctx, options) return o.podClient.Pods(ns).Watch(ctx, options)
}, },
} }
@ -722,6 +722,7 @@ func waitForContainer(ctx context.Context, podClient corev1client.PodsGetter, ns
var result *corev1.Pod var result *corev1.Pod
err := intr.Run(func() error { err := intr.Run(func() error {
ev, err := watchtools.UntilWithSync(ctx, lw, &corev1.Pod{}, nil, func(ev watch.Event) (bool, error) { ev, err := watchtools.UntilWithSync(ctx, lw, &corev1.Pod{}, nil, func(ev watch.Event) (bool, error) {
klog.V(2).Infof("watch received event %q with object %T", ev.Type, ev.Object)
switch ev.Type { switch ev.Type {
case watch.Deleted: case watch.Deleted:
return false, errors.NewNotFound(schema.GroupResource{Resource: "pods"}, "") return false, errors.NewNotFound(schema.GroupResource{Resource: "pods"}, "")
@ -740,6 +741,9 @@ func waitForContainer(ctx context.Context, podClient corev1client.PodsGetter, ns
if s.State.Running != nil || s.State.Terminated != nil { if s.State.Running != nil || s.State.Terminated != nil {
return true, nil return true, nil
} }
if !o.Quiet && s.State.Waiting != nil && s.State.Waiting.Message != "" {
fmt.Fprintf(o.ErrOut, "Warning: container %s: %s\n", containerName, s.State.Waiting.Message)
}
return false, nil return false, nil
}) })
if ev != nil { if ev != nil {
@ -751,8 +755,8 @@ func waitForContainer(ctx context.Context, podClient corev1client.PodsGetter, ns
return result, err return result, err
} }
func handleAttachPod(ctx context.Context, f cmdutil.Factory, podClient corev1client.PodsGetter, ns, podName, containerName string, opts *attach.AttachOptions) error { func (o *DebugOptions) handleAttachPod(ctx context.Context, f cmdutil.Factory, ns, podName, containerName string, opts *attach.AttachOptions) error {
pod, err := waitForContainer(ctx, podClient, ns, podName, containerName) pod, err := o.waitForContainer(ctx, ns, podName, containerName)
if err != nil { if err != nil {
return err return err
} }