-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Add debugging support for Skaffold: skaffold debug
#1702
Add debugging support for Skaffold: skaffold debug
#1702
Conversation
- always attempts to apply debugging transform - assumes all containers are JVM - fixed JDWP port of 5005: will only work for a single container within a podspec
Ensures we don't apply debugging transforms on `skaffold dev`.
port = portAlloc(5005) | ||
|
||
javaToolOptions := v1.EnvVar{ | ||
Name: "JAVA_TOOL_OPTIONS", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shd we make these constants?
Great PR!! Looking forward to see this in. |
- Pod - Deployment - StatefulSet - DaemonSet - Job - ReplicaSet - ReplicationController
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking great!
I tried it and now it works nicely too!
I have mostly nits and some refactoring + docs comments.
Some other observations:
- It is a little bit annoying how the multiple containers can race for ports so sometimes web1 gets the 8081 sometimes web2.
- sync and rebuild would be actually nice - now the iteration requires restarting
skaffold debug
- which I usually do by changing the yaml file :)
Thanks Brian. The logic lgtm. I’ll defer to the Skaffold folks for the golang specifics. |
Thanks @balopat for the thorough review.
IIUC, this is related to the port-forwarding of declared container ports to the local host, right?
+1 |
PTAL @balopat |
This PR adds a new command to Skaffold called
debug
.debug
provides a zero configuration solution for setting up containers for debugging. It is a mix ofrun
anddev
in that it builds and deploys artifacts similar torun
, but monitors and cleans-up likedev
.debug
transforms the Kubernetes manifests to setup a container for debugging as required for the container's runtime technology.Comments and suggestions are welcome. I'm know my Go is terrible and can be improved.
About
skaffold debug
skaffold debug
is likeskaffold dev
with the following differences:JAVA_TOOL_OPTIONS
environment variable added/adjusted to configure the JDWP agent to listen for a specific port--inspect=port
added to configure a DevTools connectionPodSpec
metadata to describe the JDWP/DevTools port nameddebug.cloud.google.com/config
which points to a string containing a JSON object mapping container-name → a debug runtime configuration object. Each debug configuration object has at least aruntime
field that points to a simple ID describing the underlying language runtime technology (e.g.,jvm
,nodejs
); other fields specify any configuration specific to that language runtime technology. For example , a pod with two containers namedmicroservice
andweb
(line breaks added for legibility)Example transforms
For NodeJS, involving a PodSpec from
examples/hot-reload
. The changes in this example:debug.cloud.google.com/config
has a JSON object that describes the connection configuration details. As Kubernetes container objects don't carry metadata, we have to put this metadata on the container's parent; as a pod/podspec can have multiple containers, we use a key-value map, keyed by the container name.--inspect=9229
is added to the node command lineNote that we identify this artifact as Node based on the container attempting to run
nodemon
. (npm run xxx
is not handled as it doesn't support passing through--inspect
.)For Java (a deployment from
examples/jib
). The changes in this example:debug.cloud.google.com/config
has a JSON object that describes the connection configuration details. As Kubernetes container objects don't carry metadata, we have to put this metadata on the container's parent; as a pod/podspec can have multiple containers, we use a key-value map, keyed by the container name.JAVA_TOOL_OPTIONS
is added; this is picked up by the JVM at launch.Change Overview
This implementation happens entirely at deploy time. When I initially starting writing this code, my plan was to implement it as a mutating admission controller, where the code only had access to the images. So this code walks the manifests to be deployed and examines and transforms any containers referenced in a pod/podspec that use a supported language runtime.
We guess the runtime technology for an image container by examining the referenced image container configuration, specifically looking at the environment variables and command-line. It turns out that most of the language runtime base images define a
XXXX_VERSION
environment variable or use a well-known command-name (java
ornode
ornodemon
).pkg/skaffold/debugging
deploy/kubectl.go
to configure a manifest transformer (ManifestList
)ApplyDebuggingTransforms
inpkg/skaffold/debugging/debug.go
) walks the Kubernetes objects and applies changes to podspecs based on the guessed runtime technologyskaffold/build/Artifact
alone isn't enough to introspect on the corresponding container image as it may have been loaded into the local docker daemon or pushed to a registry. I changedskaffold/build/Artifact
to include aLocation
enum, and changed the Builder interface to return an Artifact with the location, rather than just return the built tag.-~~ the container image's config (
go-containerregistry/pkg/v1/config/Config
) is contained by re-defining theskaffold/build/Artifact
to also provide a configuration retriever function.~~ Update: now entirely hidden inside thedebugging
package. There are two retriever implementations, one that fetches from a registry and the other from the Docker daemon. This must be determined at build-time as it depends on the local-push.Follow-ups
I'd prefer to leave these follow-ups to separate PRs:
initContainer
that copies files into anemptyDir
volume.skaffold debug
#2173)skaffold debug
#2174)skaffold debug
#2175)skaffold debug
should allow specifying imagePullPolicy for debug helpers #2191)cmd/debug.go
. (Shouldskaffold debug
be configurable per artifact? #2184)skaffold.yaml
and associated objects? or perhaps just leverage the debug annotations (Provide mechanism to indicate language runtime type for an artifact #2203)