-
Notifications
You must be signed in to change notification settings - Fork 882
rkt: add experimental support for attachable applications #3396
Conversation
cb003e9
to
6052116
Compare
rkt/attach.go
Outdated
return nil, fmt.Errorf("mode must specify at least one endpoint to attach") | ||
} | ||
if (attachTTYIn || attachTTYOut) && (attachStdin || attachStdout || attachStderr) { | ||
return nil, fmt.Errorf("incompatibles endpoints %q", attachMode) |
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.
"Incompatible". Also, this could be clearer (e.g. "cannot attach TTY and stdIn/out/err")
Hm. |
Oh, nevermind, I get it! |
stage1/init/common/units.go
Outdated
@@ -179,6 +171,131 @@ func ImmutableEnv(p *stage1commontypes.Pod, interactive bool, privateUsers strin | |||
return w.Error() | |||
} | |||
|
|||
// SetupAppIO prepares all properties related to streams (stdin/stdout/stderr) and TTY | |||
// for an application service unit | |||
func (w *UnitWriter) SetupAppIO(p *stage1commontypes.Pod, ra *schema.RuntimeApp, binPath string, interactive bool, debug bool, opts ...*unit.UnitOption) []*unit.UnitOption { |
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.
I know this is a WIP but I would love this to have a really good docblock, plus a reference to whatever other docs you write. Being nice to the future programmer who comes and wonders what the heck we're doing.
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.
ack, and maybe split in separate smaller methods
stage1/iottymux/iottymux.go
Outdated
|
||
ec := make(chan error) | ||
for s, p := range eps { | ||
conn, err := net.Dial("tcp", fmt.Sprintf("127.0.0.1:%s", p)) |
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.
Why did you choose to use a network socket instead of a Unix socket?
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.
No strong design decision, but network sockets look more flexible here as they are already scoped per-pod, they are not tied to the overabundant mount-ns magic we have in place and can play nicely with nsenter (if needed).
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.
Slowly starting to re-consider this choice in favor of a stage1-namespaced file-backed unix socket 😊
add802e
to
682b3fd
Compare
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.
@lucab I left a couple of comments as a first pass.
common/apps/apps.go
Outdated
@@ -30,6 +30,21 @@ var ( | |||
ErrInvalidSeccompOverride = errors.New("invalid seccomp command-line override") | |||
) | |||
|
|||
// AppIOType describes the type of an application stream at runtime (stdin/stdout/stderr). | |||
type AppIOType string |
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.
type AppIO string
is sufficient?
rkt/rkt.go
Outdated
|
||
// getRktEnvExperiments returns annotations for rkt experimental/hidden | ||
// features | ||
func getRktEnvExperiments(annotations map[types.ACIdentifier]string) map[types.ACIdentifier]string { |
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.
rktEnvExperiments
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.
I removed this code, will reconsider these features later in a better way.
rkt/rkt.go
Outdated
if envVal == "" { | ||
continue | ||
} | ||
annotations[v] = envVal |
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.
we are modifying annotations
here. I suggest we either make a copy of it, or declare the method to be mutable and not return annotations
at all.
defer p.Close() | ||
|
||
if p.State() != pkgPod.Running { | ||
stderr.Printf("pod %q isn't currently running", p.UUID) |
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.
stderr.Fatalf
(implying os.Exit(254)
)?
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.
Everywhere else we bubble up the return code to the wrapper and I prefer to stick to it. It may make sense to return the error object instead of the exit code, but not in the scope of this PR.
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.
👍 for bubbling up so defers happen; I don't think it needs or should be an error object either necessarily since one step up won't have more info in this case ever.
rkt/attach.go
Outdated
attachArgs := []string{ | ||
fmt.Sprintf("--app=%s", appName), | ||
fmt.Sprintf("--debug=%t", debug), | ||
} |
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 a bit unexpected to be in a parseAttachMode
func, I'd expect only attach
related options in this method.
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.
Renaming to "createAttachFlags" might help
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.
You are right, this func is misleading. I'll split the concerns, move name and debug out of here, and rename it.
stage1/iottymux/iottymux.go
Outdated
if err != nil { | ||
break | ||
} | ||
_, err = stdin.Write(lineIn) |
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.
if err != nil
, we should probably close the connection to the client and log things too?
stage1/iottymux/iottymux.go
Outdated
} | ||
// Open FIFOs | ||
var endpoints = make([]*net.Listener, 3) | ||
var fifos = make([]*os.File, 3) |
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.
why do we need a slice here?
stage1/iottymux/iottymux.go
Outdated
func actionIOMux(statusFile *os.File) error { | ||
var err error | ||
var endpoints = make([]*net.Listener, 3) | ||
var fifos = make([]*os.File, 3) |
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.
let's document the nature of these slices -> stdin, stdout, stderr
stage1/iottymux/iottymux.go
Outdated
var logs []io.WriteCloser | ||
var alivel []bool | ||
var conns []io.WriteCloser | ||
var alivec []bool |
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.
instead of maintaining alivec
and alivel
slices, you could remove them simply from the logs
and conns
slices in cases errors occur.
stage1/iottymux/iottymux.go
Outdated
} | ||
|
||
// acceptConn accepts a single client and queues it for further proxying | ||
func acceptConn(socket *net.Listener, c chan *net.Conn, stream string) { |
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.
net.Listener
is an interface, please don't pass a pointer to it.
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.
net.Conn
is an interface, please don't send pointers of it via a channel, it boils down to being a two-word pair of a pointer and type already, see http://research.swtch.com/interfaces.
fb0d859
to
1f069cc
Compare
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.
First review pass. The documentation is nice and the code looks good overall
``` | ||
{ | ||
"name": "coreos.com/rkt/stage2/stdout", | ||
"value": "log" |
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.
Copy paste error? This should be null
defer p.Close() | ||
|
||
if p.State() != pkgPod.Running { | ||
stderr.Printf("pod %q isn't currently running", p.UUID) |
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.
👍 for bubbling up so defers happen; I don't think it needs or should be an error object either necessarily since one step up won't have more info in this case ever.
rkt/attach.go
Outdated
} | ||
|
||
if err = stage0.Attach(p.Path(), podPID, *appName, stage1RootFS, uuid, attachArgs); err != nil { | ||
stderr.PrintE("enter failed", err) |
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.
'attach' might be clearer here
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.
ack
rkt/attach.go
Outdated
attachArgs := []string{ | ||
fmt.Sprintf("--app=%s", appName), | ||
fmt.Sprintf("--debug=%t", debug), | ||
} |
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.
Renaming to "createAttachFlags" might help
rkt/attach.go
Outdated
return nil, fmt.Errorf("incompatible endpoints %q, cannot simultaneously attach TTY and streams", attachMode) | ||
} | ||
|
||
attachArgs = append(attachArgs, []string{ |
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.
we can drop the []string{}...
bit, right?
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.
Definitely, silly me :(
stage1/attach/attach.go
Outdated
} | ||
|
||
args := stage1common.PrepareEnterCmd(false) | ||
args = append(args, []string{ |
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.
The []string{}...
is redundant
1218b4d
to
3dddf85
Compare
PTAL. I've fixed the issues reported in previous reviews and cleaned up most of the the TODOs. There are still several in |
No, at the moment |
0f5cc70
to
ae2341b
Compare
@squeed I added a bunch of changes for your comments and a test for sandbox-attach (killing some bugs while at it). |
@lucab @s-urbaniak preparing a training for I tried to work with rkt in minikube. minikube start --vm-driver=kvm --container-runtime=rkt --network-plugin=cni The version rkt Version: 1.14.0 is quite outdated. Do you have some newer version, as the old one has I would like to use rkt as an alternative in demos and training, so it This command shoud work out of the box At the moment I work around this issue with and kubectl exec -it busybox-434806045-3qcgt sh This is ugly for demos. Any idea or hint? Thanks in advance! |
@thomasfricke have you filed an issue against minikube about this?
Thomas Fricke <notifications@github.com> schrieb am Mi., 25. Jan. 2017,
15:20:
… @lucab <https://github.com/lucab> @s-urbaniak
<https://github.com/s-urbaniak> preparing a training for I tried to work
with rkt in minikube.
minikube start --vm-driver=kvm --container-runtime=rkt --network-plugin=cni
The version
rkt Version: 1.14.0
is quite outdated. Do you have some newer version, as the old one has
the issue with attaching to the tty and the networking inside does not
work?
I would like to use rkt as an alternative in demos and training, so it
would be nice if the version coming with minikube would work at least.
This command shoud work out of the box
kubectl run busybox --image=busybox sh
At the moment I work around this issue with
kubectl run busybox --image=busybox sleep 1000
and
kubectl exec -it busybox-434806045-3qcgt sh
This is ugly for demos. Any idea or hint?
Thanks in advance!
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#3396 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ACewNwlV9QPMYUwSHqeCoZWfQf0rBNL-ks5rV1oUgaJpZM4K4aqg>
.
|
@thomasfricke I created kubernetes/minikube#1042 |
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.
LGTM, the test passes for me locally, I made another pass, and tried it locally; let's ship it.
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.
Sorry, I was just playing around with this a bit more, and attach doesn't play nice with restarting an app:
$ sudo -E rkt app add --debug $pod docker://busybox --stderr=stream --stdout=stream --name=echo --exec=/bin/sh -- -c 'while true; do echo "stdout" $(date); (>&2 echo "stderr" $(date)); sleep 1; done'
stage0: locking pod manifest
stage0: Loading image sha512-dec96773486195b575ff04628b8f816e3d7eceb608dd07f745513902d36ea82b
stage0: Writing image manifest
stage0: adding app to sandbox
stage0: stage0: app-add: systemctl daemon-reload output:
$ sudo -E rkt app start --debug $pod --app=echo
$ sudo -E rkt attach $pod
stdout Sat Jan 28 11:29:36 UTC 2017
stderr Sat Jan 28 11:29:36 UTC 2017
...
^C
$ sudo -E rkt app stop --debug $pod --app=echo
$ sudo -E rkt app start --debug $pod --app=echo
$ echo $?
0
$ sudo -E rkt attach $pod
iottymux: runtime failure: dial unix /rkt/iottymux/echo/sock-stdout: connect: connection refused
stage1-attach: error executing "iottymux": exit status 254
attach: attach failed: error executing stage1 entrypoint: exit status 254
In the sandbox I see:
[ OK ] Started Journal Service.
[ OK ] Reached target rkt apps target.
Starting rkt supervisor-ready signaling...
[ OK ] Started rkt supervisor-ready signaling.
[19486.122201] echo[12]: iottymux: Listening for stdout on /rkt/iottymux/echo/sock-stdout
[19486.122427] echo[12]: iottymux: Listening for stderr on /rkt/iottymux/echo/sock-stderr
[19493.574246] echo[49]: iottymux: runtime failure
[19493.574479] echo[49]: └─unable to open stdout listener: listen unix /rkt/iottymux/echo/sock-stdout: bind: address already in use
I think the above can also be encoded in a functional test.
Initial analysis:
When we stop the app using app stop
, the iomux@echo.service
is successfully stopped too, but the socket files are still present:
$ enterpod
entering pod 819a9dca echo registry-1.docker.io/library/busybox:latest running 38 seconds ago 38 seconds ago default:ip4=172.16.28.109
bash-4.3# systemctl status iomux@echo.service
● iomux@echo.service - Streaming I/O handler for echo
Loaded: loaded (/usr/lib/systemd/system/iomux@.service; static; vendor preset: enabled)
Active: inactive (dead) since Sat 2017-01-28 12:42:11 CET; 27s ago
Process: 13 ExecStart=/iottymux --action=iomux --app=%i (code=killed, signal=TERM)
Main PID: 13 (code=killed, signal=TERM)
Jan 28 12:41:59 rkt-819a9dca-9b56-48ed-9e7d-4b1ec93ce15a systemd[1]: Started Streaming I/O handler for echo.
Jan 28 12:41:59 rkt-819a9dca-9b56-48ed-9e7d-4b1ec93ce15a echo[13]: iottymux: Listening for stdout on /rkt/iottymux/echo/sock-stdout
Jan 28 12:41:59 rkt-819a9dca-9b56-48ed-9e7d-4b1ec93ce15a echo[13]: iottymux: Listening for stderr on /rkt/iottymux/echo/sock-stderr
Jan 28 12:42:11 rkt-819a9dca-9b56-48ed-9e7d-4b1ec93ce15a systemd[1]: Stopping Streaming I/O handler for echo...
Jan 28 12:42:11 rkt-819a9dca-9b56-48ed-9e7d-4b1ec93ce15a systemd[1]: Stopped Streaming I/O handler for echo.
bash-4.3# cd /rkt/iottymux/echo/
bash-4.3#
endpoints env sock-stderr sock-stdout
resource cleanup is not properly handled upon |
fix for the above is available under s-urbaniak@cb346c6 |
|
||
This component takes care of multiplexing TTY and receiving clients for attaching. | ||
|
||
It is started as an instance of the templatedd `ttymux@.service` service by a `After=` dependency from the application. |
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.
"of the templated"
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.
fixed.
ae2341b
to
b28afd4
Compare
@s-urbaniak Thanks, I picked up your commit in this branch. |
b3685f2
to
86a098f
Compare
ok to test |
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.
LGTM once green
This commit introduces experimental support for attachable applications. This consists of: * a new `attach` subcommand * a set of per-app flags to control stdin/stdout/stderr modes * a stage1 `iottymux` binary for multiplexing and attaching * two new templated stage1 services, `iomux` and `ttymux`
86a098f
to
5a3fc14
Compare
5a3fc14
to
73ef404
Compare
Green, merging. |
As rkt 1.24.0 supports an experimental attach command, minikube iso image should also contain the new version. See also rkt/rkt#3396 (comment) /cc @s-urbaniak
This commit introduces experimental support for attachable
applications. It consists of:
attach
subcommandiottymux
binary for multiplexing and attachingiomux
andttymux
Fixes #1799
TODO:
rkt attach
and--stdin
,--stdout
,--stderr
$RKT_EXPERIMENT_ATTACH
flag