Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for troubleshooting distroless containers #27140

Open
verb opened this issue Jun 9, 2016 · 28 comments

Comments

Projects
None yet
@verb
Copy link
Contributor

commented Jun 9, 2016

I favor running distroless container images in production, usually built from SCRATCH with the binary and bare minimum of libraries. This has a number of benefits and works well the vast majority of the time, but it's difficult on the occasion where I need to troubleshoot something in production.

It'd be nice if there was a way to enable some sort of debug mode for a running pod where a set of tools could be attached that I could then exec within the container.

I'm willing to do the work to develop this feature, if necessary, but I'm not exactly sure what the next steps should be. I'm opening this issue to find out if anyone is working on something similar and/or get early guidance on how this could fit into the Kubernetes road map.

If it's the case that no one else is working on something similar and such a feature would be welcomed, my expectation is the next step would be to write a design proposal.


Tracking issue: kubernetes/enhancements#277
KEP: https://git.k8s.io/enhancements/keps/sig-node/20190212-ephemeral-containers.md

@therc

This comment has been minimized.

Copy link
Contributor

commented Jun 13, 2016

Maybe just use shared PID namespaces in Docker 1.12 (and rkt's equivalent, if/when it's there): moby/moby#10163

You'd create a new container with a debug image (or one of many) and attach it to the existing pod.

@verb

This comment has been minimized.

Copy link
Contributor Author

commented Jun 13, 2016

Ah, that would be perfect! I see that #1615 exists for sharing a PID namespace in a pod, which also led me to discover this issue may very well be a dupe of #24957 (though @smarterclayton only mentions debugging as one of many possible uses).

Before I close this issue as a dupe, I just want to make sure I understand how it would work. I see two possibilities --

  1. We attach a new container to a running pod. I assume this would look something like a kubectl attach, but if I try to do this in 1.2 I get the error spec.containers: Forbidden: pod updates may not add or remove containers. (am I doing this incorrectly?)
  2. We create a new pod using the PID namespace of the target pod we want to debug, in which case we would want support for that in the implementation of shared PID namespaces.

Though not as useful as a debug container, something that could work in the interim would be to attach a volume to a running container, if that were possible. (In 1.2 it doesn't seem to be: spec: Forbidden: pod updates may not change fields other than containers[*].image or spec.activeDeadlineSeconds)

@smarterclayton

This comment has been minimized.

Copy link
Contributor

commented Jun 13, 2016

Today, it's not possible to mutate a running pod. Attach connects to an existing container (if the Stdin and/or TTY flags were set).

Another option beyond those you mention above would be to allow adhoc container execution inside of a pod that mounts the majority of the namespaces of another container. I.e.:

  1. Have pod 1 with containers A and B
  2. Launch a transient container C that attaches to container A inside of pod 1:
    1. C shares the pid namespace of A
    2. C mounts the filesystem of A at /mnt/attach (or similar)
    3. C also joins other namespaces of A as necessary, esp. cgroup (or pod cgroup)

Scheduling a new pod doesn't convey to the runtime that C should be cleaned up if 1/A is removed (which we want, probably). However, in the flow above C would have to share resources with A so there are various edge cases around guaranteed pods having no more CPU to spare for C.

Another option would be to implement container volumes #831 and mount your debug tools into your bare bones image. That's not adhoc though, so it doesn't quite fit your use case.

@davidopp

This comment has been minimized.

Copy link
Member

commented Jun 24, 2016

General observation: if we're going to make it possible to add containers to pods, we should do it in a general way, not just to cover this use case.

I can't imagine we're going to implement adding containers to pods soon though.

@j3ffml j3ffml added the team/ux label Jun 28, 2016

@verb

This comment has been minimized.

Copy link
Contributor Author

commented Jul 8, 2016

I've gotten a lot of great suggestions so far, so I thought I'd summarize them:

  1. Volume solutions make binaries available for kubectl exec inside of a running container
    1. Allow mutation of a running container (via kubectl patch or equivalent) to add volumes. This would be especially useful in conjunction with #831 to support container images as volumes.
    2. Implicitly create a unique, empty volume attached to every container that's run. Tools can be unpacked into this volume at debug time, perhaps using an existing package solution like nix or SNAP. (credit: @thockin)
  2. Container solutions run a new container process in shared namespaces. The debug container image (obviously) brings its own filesystem, so the filesystem roots (including volume mounts) of other containers must be made available to the debug container somehow.
    1. Extend kubectl exec to allow executing commands from arbitrary container images which are then automatically fetched and run within the existing pod cgroup/pid/net/etc namespaces. (e.g. kubectl exec 123456-7890 -X gcr.io/debug-image -i -t -- bash)
    2. Allow permanent mutation of a running pod to add a new container using the standard shared pod namespaces (requires at least #1615 for a pod shared PID namespace).
    3. Support creating a new, standalone pod that uses the same namespace as the target pods.
  3. Node solutions (for lack of a better term) are independent of the pod/container constructs.
    1. Support running binaries provided by the node inside the container namespaces (#10834). This could be an extension of kubectl as well (e.g. kubectl exec 123456-7890 -H /bin/busybox -i -t)

I'm not yet familiar with the kubernetes implementation, but the volume solutions strike me as the easiest to implement and those requiring mutation of pods the most difficult.

The solutions that extend kubectl exec "feel" the most natural to me as a user. The backend steps (read: docker commands to run) seem conceptually straightforward, but there may be some technical hurdles (e.g. I'm getting ptrace not permitted when attempting to strace across container images, but that's happening within the same image as well).

I don't like coupling this functionality to the node, so I'll start down the road of writing a proposal to support kubectl exec of arbitrary container images (2i in the above list).

@thockin

This comment has been minimized.

Copy link
Member

commented Jul 8, 2016

The idea of running a "toolbox" container that is not part of a pod, but has the same namespaces as the pod is cute, but a little scary and opaque.

If we allowed adding a container to a pod, it could just be a shiny form of that.

Another option might be to include a container in the pod that is "inactive" until later activated.

@erictune

This comment has been minimized.

Copy link
Member

commented Jul 8, 2016

How far do you get if you have your build system produce "debug" and "stripped" versions of your container image ("debug" has a base image with a debugger, and "stripped" does not)?

Normally, your service just has "stripped" containers, but if there is an active bug, you deploy one or more extra containers for that service which are "debug images", and wait for the problem to happen again.

Doesn't help if the problem only happens once, but who has time to debug that kind of problem anyhow?

@erictune

This comment has been minimized.

Copy link
Member

commented Jul 8, 2016

The key question I think is whether you do this by making a new pod, and pods stay immutable, or if we make pods mutable.

@verb

This comment has been minimized.

Copy link
Contributor Author

commented Jul 8, 2016

@thockin I'll grant you scary, but I'm not yet willing to concede that pulling in a different userland for a binary is any more opaque than your run-of-the-mill kubectl exec. Both seem solvable.

I'd be happy with an inactive container as long as it (optionally) automatically updates prior to activating so I'm not tied to an old debug image. The downside here is the extra boilerplate config in every pod I run.

@smarterclayton

This comment has been minimized.

Copy link
Contributor

commented Jul 8, 2016

I should note that we've had very good feedback from the "debug" command
(which spawns a copy of the pod with a shell, or other command, as the
target). It doesn't address the "I created a pod that has nothing useful
in it to debug", but it does address the bulk of the practical "w.t.h. is
this not starting up correctly" problems.

On Fri, Jul 8, 2016 at 7:16 PM, verb notifications@github.com wrote:

@thockin https://github.com/thockin I'll grant you scary, but I'm not
willing to concede that pulling in a different userland for a binary is any
more opaque than your run-of-the-mill kubectl exec. Both seem solvable.

I'd be happy with an inactive container as long as it (optionally)
automatically updates prior to activating so I'm not tied to an old debug
image. The downside here is the extra boilerplate config in every pod I run.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#27140 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/ABG_p2uVpzBsO1U8z8rTGXRCBPFQimVuks5qTtpXgaJpZM4IyRHU
.

@smarterclayton

This comment has been minimized.

Copy link
Contributor

commented Jul 8, 2016

Debug also leads naturally to other hooks like
"--attach-and-mount=IMAGENAME" for getting access to debug tools.

On Fri, Jul 8, 2016 at 7:31 PM, Clayton Coleman ccoleman@redhat.com wrote:

I should note that we've had very good feedback from the "debug" command
(which spawns a copy of the pod with a shell, or other command, as the
target). It doesn't address the "I created a pod that has nothing useful
in it to debug", but it does address the bulk of the practical "w.t.h. is
this not starting up correctly" problems.

On Fri, Jul 8, 2016 at 7:16 PM, verb notifications@github.com wrote:

@thockin https://github.com/thockin I'll grant you scary, but I'm not
willing to concede that pulling in a different userland for a binary is any
more opaque than your run-of-the-mill kubectl exec. Both seem solvable.

I'd be happy with an inactive container as long as it (optionally)
automatically updates prior to activating so I'm not tied to an old debug
image. The downside here is the extra boilerplate config in every pod I run.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#27140 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/ABG_p2uVpzBsO1U8z8rTGXRCBPFQimVuks5qTtpXgaJpZM4IyRHU
.

@verb

This comment has been minimized.

Copy link
Contributor Author

commented Jul 8, 2016

@erictune Certainly workable, but I'm concerned about some downsides:

  1. We'd want use the same image for QA as in prod, but then how do we QA the debug image? What if the stripped and debug images differ somehow?
  2. We're coupled with the debug environment we had at build time rather than the ones available at debug time
  3. The goal is minimal dependencies, but I'd have to include the debug tools (and all of their ongoing updates) as dependencies, which would be hard to track. (i.e. I need to apply a security update for an image that's not currently running but could be running if I needed to debug something in the future)

Even if I can't think of it right now, I'm confident there will eventually be a reason that I'll need to connect to a stripped container and it seems like a bit of a gap in the toolbox.

@bgrant0607

This comment has been minimized.

Copy link
Member

commented Oct 26, 2016

Vaguely related to #831

@verb

This comment has been minimized.

Copy link
Contributor Author

commented Sep 12, 2017

/assign @verb

@fejta-bot

This comment has been minimized.

Copy link

commented Jan 5, 2018

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

Prevent issues from auto-closing with an /lifecycle frozen comment.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or @fejta.
/lifecycle stale

@radu-matei

This comment has been minimized.

Copy link

commented Jan 19, 2018

Hi!
Is there anyone actively working on this?

I would really like to start contributing on it (realistically starting next week or so).

@verb

This comment has been minimized.

Copy link
Contributor Author

commented Jan 19, 2018

@radu-matei Yes, I'm actively working on it. I have some PRs lined up but we haven't quite finalized the API yet, see kubernetes/community#1269.

I'd love to have some help here, of course. Was there a particular area to which you'd like to contribute?

k8s-github-robot pushed a commit that referenced this issue Jan 24, 2018

Kubernetes Submit Queue
Merge pull request #45442 from verb/pod-tshoot-1
Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Add a container type to the runtime manager's container status

**What this PR does / why we need it**:
This is Step 1 of the "Debug Containers" feature proposed in #35584 and is hidden behind a feature gate. Debug containers exist as container status with no associated spec, so this new runtime label allows the kubelet to treat containers differently without relying on spec.

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: cc #27140

**Special notes for your reviewer**:

**Release note**:

```release-note
NONE
```

**Integrating feedback**:
- [x] Remove Type field in favor of a help method

**Dependencies:**
- [x] #46261 Feature gate for Debug Containers
@fejta-bot

This comment has been minimized.

Copy link

commented Apr 19, 2018

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle stale

@verb

This comment has been minimized.

Copy link
Contributor Author

commented Apr 19, 2018

/remove-lifecycle stale

@fejta-bot

This comment has been minimized.

Copy link

commented Jul 18, 2018

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle stale

@verb

This comment has been minimized.

Copy link
Contributor Author

commented Jul 20, 2018

/remove-lifecycle stale

@fejta-bot

This comment has been minimized.

Copy link

commented Oct 18, 2018

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle stale

@fche

This comment has been minimized.

Copy link

commented Oct 19, 2018

/remove-lifecycle stale

@fejta-bot

This comment has been minimized.

Copy link

commented Jan 17, 2019

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle stale

@verb

This comment has been minimized.

Copy link
Contributor Author

commented Jan 24, 2019

/remove-lifecycle stale

@skydoctor

This comment has been minimized.

Copy link

commented Feb 13, 2019

This would be very useful IMO. @verb: Any recent work on getting debug containers in to running pods?

@verb

This comment has been minimized.

Copy link
Contributor Author

commented Feb 13, 2019

@skydoctor Yes, we've been working on the API in #59416 and I've just opened a KEP kubernetes/enhancements#830.

kubernetes/enhancements#277 would be a good issue to follow for updates.

@verb verb changed the title Support for troubleshooting running pods Support for troubleshooting distroless containers Apr 18, 2019

@kfox1111

This comment has been minimized.

Copy link

commented Apr 18, 2019

Until this support lands, I've been using this to debug:
https://github.com/pnnl-miscscripts/miscscripts/tree/master/bin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.