Monitor kubectl logs when port forwarding and retry on error #2543
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When
kubectl port-forward
encounters an error (most commonly from the container backing a resource being restarted), an error is logged to stderr, but the process does not actually return with an exit code, or notify the caller in any way than an error occurred. During port forwarding, skaffold verifies that a port is correctly forwarded by attempting to attach to the specified port and ensuring that a listening connection cannot be established, but since kubectl hangs onto the port and continues to run successfully when an error is actually encountered, this check succeeds erroneously.To handle this, the only indication we have from kubectl that something has gone wrong is from its logs to stderr, so we attach to these logs and search the stream for
"error forwarding port"
. AMonitor()
call is kicked off in a separate goroutine for each forwarded port, and on seeing this error string in the logs for the associatedkubectl port-forward
process, it will issue a callback to theEntryManager
to restart the port forwarding operation entirely.Additionally, kubectl itself will not actually log this error until the first failed connection to the forwarded port, so in theMonitor()
call we issue a ping to the port once per second, to tease out any errors that kubectl might encounter. This is very suboptimal, but the implementation (and shortcomings) ofkubectl port-forward
give us very little to work with here.update: I removed the ping from the monitor, since this could be really spammy for services where connection logs actually matter (e.g. nginx). after a redeploy, the first attempted connection to a forwarded service will fail, but skaffold will see this and trigger a reconnection. again, not great UX, but this is ultimately a workaround for a bug in kubectl.
Fixes #2523