docs-v2/design_proposals/debug-events.md
Note: implemented but there were some minor name changes.
Cloud Code for IntelliJ and VS Code currently launch skaffold debug --port-forward to start
an application in debugging mode. debug modifies the podspecs to explicitly expose the debug port used
by the underlying language runtime via containerPort definitions. Skaffold monitors the cluster
and initiated forwards to ports on any newly-started containers, and raises events once the
forwards are established. The IDEs establish debug launch configurations by examining these
port-forward events for ports with specific names to (e.g., jdwp for Java/JVM,
devtools for NodeJS, or dap for connections using the Debug Adapter Protocol).
When a new debuggable container is created, Skaffold will
attempt to forward the remote debug port, which should result in a port-forward event, and thus
spare the IDEs from having to actively watch the cluster.
But relying strictly on port-forward events carries some risk. Although the likelihood of a port-name clash is low, the IDE may require additional configuration information to establish a debugging connection. For example, there may be no indication of the underlying project’s location in the file-system, nor the relative path in the container.
Although such information is published by skaffold debug via pod annotations, obtaining this
information would require that the IDEs actively track new pods and containers. This tracking would
duplicate functionality already being performed by Skaffold, and also requiring this functionality to be
re-implemented in each IDE.
This design proposal recommends that Skaffold instead also watch and issue events when debuggable containers are started and terminated.
This design proposes that Skaffold issue events to inform the IDEs of the following conditions:
The appearance of a container that is debuggable. This event will provide:
debug.cloud.google.com/config configuration block for the container
(a JSON object) including (! indicates new items)
go, jvm, nodejs, python)skaffold.yaml)The disappearance of a container that was debuggable. This event will provide:
debug.cloud.google.com/config configuration block for the container
(a JSON object) including (! indicates new items)
go, jvm, nodejs, python)name (which should allow cross-referencing with the skaffold.yaml)Skaffold will also maintain state and report on the set of debuggable containers.
With this information, the IDE should be able to:
skaffold.yaml{
"result": {
"timestamp": "2019-10-23T18:50:38.916931Z",
"event": {
"deployEvent": {
"status": "In Progress"
}
},
"entry": "Deploy started"
}
}
{
"result": {
"timestamp": "2019-10-23T18:50:39.629826Z",
"event": {
"deployEvent": {
"status": "Complete"
}
},
"entry": "Deploy complete"
}
}
{
"result": {
"timestamp": "2019-10-23T18:50:41.004396Z",
"event": {
"debugEvent": {
"status": "Started",
"podName": "npm",
"containerName": "web",
"namespace": "default",
"runtime": "nodejs",
"configuration": "{\"name\":\"gcr.io/artifact/name/from/skaffold.yaml\",\"ports\":{\"devtools\":9229},\"runtime\":\"nodejs\",\"workingDir\":\"/app\"}"
}
},
"entry": "Debuggable container started pod/npm:web (default)"
}
}
{
"result": {
"timestamp": "2019-10-23T18:50:41.004551Z",
"event": {
"portEvent": {
"localPort": 3000,
"remotePort": 3000,
"podName": "npm",
"containerName": "web",
"namespace": "default",
"resourceType": "pod",
"resourceName": "npm"
}
},
"entry": "Forwarding container web to local port 3000"
}
}
{
"result": {
"timestamp": "2019-10-23T18:50:41.004792Z",
"event": {
"portEvent": {
"localPort": 9229,
"remotePort": 9229,
"podName": "npm",
"containerName": "web",
"namespace": "default",
"portName": "devtools",
"resourceType": "pod",
"resourceName": "npm"
}
},
"entry": "Forwarding container web to local port 9229"
}
}
$ curl -s localhost:50052/v1/state | jq .
{
"buildState": {
"artifacts": {
"gcr.io/k8s-skaffold/skaffold-jib": "Complete"
}
},
"deployState": {
"status": "Complete"
},
"statusCheckState": {
"status": "Not Started"
},
"fileSyncState": {
"status": "Not Started"
},
"debuggingContainers": [
{
"status": "Started",
"podName": "web-6d7c9db467-gqr5x",
"containerName": "web",
"namespace": "default",
"runtime": "jvm",
"configuration": "{\"name\":\"gcr.io/artifact/name/from/skaffold.yaml\",\"ports\":{\"jdwp\":5005},\"runtime\":\"jvm\",\"workingDir\":\"/app\"}"
}
]
}
<Why is a new Debug Event necessary?>
One alternative explored was to piggy-back the debug information into the existing port-forward events. This design was eliminated as:
kubectl exec to launch a process in the remote container.There may also be a desire for the IDEs to selectively initiate port-forwards on an as-needed basis. This may be useful for large microservice deployments. Indeed the debugging podspec transformations could be applied on-the-fly too.
The idea here is that skaffold debug internally configures a watcher that looks for and notifies
of pods with debuggable containers, similar to how the port-forwarding manager
listens for pods or services.
skaffold debug will set a DebugMode option to true. This value will be used in
SkaffoldRunner.Dev() to install the debug container watch manager.DebugEvent type to the protobuf definitions. The status field will be one
of "Started" or "Terminated".Tests will need to verify that pod- and container-start successfully raise debugging Started events, and container termination and pod-deletion raises Terminated events.