Add streaming subprotocol negotiation for exec, attach, and port
forwarding. Restore previous (buggy) exec functionality as an
unspecified/unversioned subprotocol so newer kubectl clients can work
against 1.0.x kubelets.
The current executor structure is too dependent on client.Request
and client.Config. In order to do an attach from the server, it needs
to be possible to create an Executor from crypto/tls#TLSConfig and to
bypassing having a client.Request.
Changes:
* remotecommand.spdyExecutor - handles upgrading a request to SPDY and getting a connection
* remotecommand.NewAttach / New - moved to exec / portforward / attach since they handle requests
* Remove request.Upgrade() - it's too coupled to SPDY, and can live with the spdyExecutor
* Add request.VersionedParams(runtime.Object, runtime.ObjectConvertor) to handle object -> query transform
Not all clients and systems can support SPDY protocols. This commit adds
support for two new websocket protocols, one to handle streaming of pod
logs from a pod, and the other to allow exec to be tunneled over
websocket.
Browser support for chunked encoding is still poor, and web consoles
that wish to show pod logs may need to make compromises to display the
output. The /pods/<name>/log endpoint now supports websocket upgrade to
the 'binary.k8s.io' subprotocol, which sends chunks of logs as binary to
the client. Messages are written as logs are streamed from the container
daemon, so flushing should be unaffected.
Browser support for raw communication over SDPY is not possible, and
some languages lack libraries for it and HTTP/2. The Kubelet supports
upgrade to WebSocket instead of SPDY, and will multiplex STDOUT/IN/ERR
over websockets by prepending each binary message with a single byte
representing the channel (0 for IN, 1 for OUT, and 2 for ERR). Because
framing on WebSockets suffers from head-of-line blocking, clients and
other server code should ensure that no particular stream blocks. An
alternative subprotocol 'base64.channel.k8s.io' base64 encodes the body
and uses '0'-'9' to represent the channel for ease of use in browsers.
Correct port-forward data copying logic so that the server closes its
half of the data stream when socat exits, and the client closes its half
of the data stream when it finishes writing.
Modify the client to wait for both copies (client->server,
server->client) to finish before it unblocks.
Fix race condition in the Kubelet's handling of incoming port forward
streams. Have the client generate a connectionID header to be used to
associate the error and data streams for a single connection, instead of
assuming that streams n and n+1 go together. Attempt to generate a
pseudo connectionID in the server in the event the connectionID header
isn't present (older clients); this is a best-effort approach that only
really works with 1 connection at a time, whereas multiple concurrent
connections will only work reliably with a newer client that is
generating connectionID.
Have poller() send to the channel once, immediately, before the ticker
starts. This way, Poll, PollInfinite, and WaitFor will check the
condition immediately, instead of waiting for the poller's interval to
elapse once before doing the initial condition check.
Increase the supported controls on pod logging. Add validaiton to pod
log options. Ensure the Kubelet is using a consistent, structured way to
process pod log arguments.
Add ?sinceSeconds=<durationInSeconds>, &sinceTime=<RFC3339>, ?timestamps=<bool>,
?tailLines=<number>, and ?limitBytes=<number>
The `file` command used here to check whether a device is formatted is not
available for CoreOS. The effect is that the mounter tries to mount an
unformatted volume which fails. This makes it quite tedious to use persistent
volumes in CoreOS.
This patch replaces the `file` command with `lsblk` which is available in
CoreOS. I checked that it's also available on RHEL, Debian, Ubuntu and SLES.
A lot of packages use StringSet, but they don't use anything else from
the util package. Moving StringSet into another package will shrink
their dependency trees significantly.
If stdin is noninteractive, the io.Copy from stdin to remoteStdin will
unblock when it finishes reading from stdin. In this case, make sure to
close remoteStdin so the server knows the client won't be sending any
more data. This ensures that the remote process terminates. For example:
echo foo | kubectl exec -i <pod> -- cat
Without this change, the `cat` process never terminates and `kubectl
exec` hangs.
Fix interactive exec sessions hanging after you type 'exit'.
Add e2e test to cover noninteractive stdin: `echo a | kubectl exec -i <pod>
cat`
Add e2e test to cover psuedo-interactive stdin: `kubectl exec -i <pod> bash`
Prep for sending multiple data frames over multiple streams in remote command
test, which is more likely to find flakes (requires bump of spdystream
once an issue with the frame worker queues not being fully drained when
a goaway frame is received).
Use iptables --wait (if available) to avoid race conditions with
util.iptables failing if it tries to modify the tables at the same
time as another process.
Also, reorganize the code a bit in preparation for checking for
another flag as well. And, if semver.NewVersion() returns an error, it
means there's a bug in the code somewhere (we should only ever be
passing it valid version strings), so just log that error rather than
returning it to the caller.
The GCE PD plugin uses safe_format_and_mount found on standard GCE images:
https://github.com/GoogleCloudPlatform/compute-image-packages/blob/master/google-startup-scripts/usr/share/google/safe_format_and_mount
On custom images where this is not available pods fail to format and
mount GCE PDs. This patch uses linux utilities in a similar way to the
safe_format_and_mount script to format and mount the GCE PD and AWS EBC
devices. That is first attempt a mount. If mount fails try to use file to
investigate the device. If 'file' fails to get any information about
the device and simply returns "data" then assume the device is not
formatted and format it and attempt to mount it again.
Signed-off-by: Sami Wagiaalla <swagiaal@redhat.com>
The API server will refuse to start if a link-local IP address is selected, however, ChooseNetworkInterface can still select link-local network routes. This causes a startup failure on platforms like DigitalOcean that use a link-local route to fetch metadata.
Signed-off-by: Christian Stewart <christian@paral.in>
With older iptables binary, kube-proxy generates duplicate
iptables rules in NAT table every few seconds.
This fixes the problem by properly unquoting && parsing
older iptables-save output.