-
Couldn't load subscription status.
- Fork 881
initial implementation of rkt fly as stage1 #1833
Changes from all commits
938cd3c
96c8677
aae2e4e
294d0d0
41edab8
e3e6cb6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| # Running rkt with the *fly* stage1 | ||
|
|
||
| The *fly* stage1 is an alternative stage1 that runs a single-application ACI with only `chroot`-isolation. | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could add a sentence about the motivation. Something like:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I stole that paragraph, thanks! |
||
|
|
||
| ## Motivation | ||
|
|
||
| The motivation of the fly feature is to add the ability to run applications with full privileges on the host but still benefit from the image management and discovery from rkt. | ||
| The Kubernetes kubelet is one candidate for rkt fly. | ||
|
|
||
|
|
||
| ## How does it work? | ||
|
|
||
| In comparison to the default stage1, there is no process manager involved in the stage1. | ||
|
|
||
| The rkt application sets up bind mounts for `/dev`, `/proc`, `/sys`, and the user-provided volumes. | ||
| In addition to the bind mounts, An additional *tmpfs* mount is done at `/tmp`. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An -> an |
||
| After the mounts are set up, rkt `chroot`s to the application's RootFS and finally executes the application. | ||
|
|
||
| Here's a comparison of the default and fly stage1: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this would be better on line 15 |
||
|
|
||
| stage1-coreos.aci: | ||
|
|
||
| ``` | ||
| host OS | ||
| └─ rkt | ||
| └─ systemd-nspawn | ||
| └─ systemd | ||
| └─ chroot | ||
| └─ user-app1 | ||
| ``` | ||
|
|
||
|
|
||
| stage1-fly.aci: | ||
|
|
||
| ``` | ||
| host OS | ||
| └─ rkt | ||
| └─ chroot | ||
| └─ user-app1 | ||
| ``` | ||
|
|
||
| ### Mount propagation modes | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing newline after this one |
||
| The *fly* stage1 makes use of Linux' [mount propagation modes](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt). | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Linux's or just Linux |
||
| If a volume source path is a mountpoint on the host, this mountpoint is made recursively shared before the host path is mounted on the target path in the container. | ||
| Hence, changes to the mounts on the target mount path inside the container will be propagated back to the host. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. " changes to the mounts on the target mount path inside the container " this is a mouthful - would " changes to the mounts inside the container" suffice? or maybe an example There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it still works ;) |
||
|
|
||
| The bind mounts for `/dev`, `/proc`, and `/sys` are done automatically and are recursive, because their hierarchy contains mounts which also need to be available for the container to function properly. | ||
| User provided volumes are not mounted recursively. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. User-provided |
||
| This is a safety measure to prevent system crashes when multiple containers are started that mount `/` into the container. | ||
|
|
||
|
|
||
| ## Getting started | ||
|
|
||
| You can either use `stage1-fly.aci` from the official release, or build rkt yourself with the right options: | ||
|
|
||
| ``` | ||
| $ ./autogen.sh && ./configure --with-stage1-flavors=fly && make | ||
| ``` | ||
|
|
||
| For more details about configure parameters, see [configure script parameters documentation](build-configure.md). | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you update the build-configure.md, by adding fly flavor to the list of flavors listed there? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Of course. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this has been done There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/see/see the/ |
||
| This will build the rkt binary and the stage1-fly.aci in `build-rkt-0.13.0+git/bin/`. | ||
|
|
||
| ### Selecting stage1 at runtime | ||
|
|
||
| Curious readers can read a whole document on how to [choose which stage1.aci to use at runtime](https://github.com/coreos/rkt/blob/master/Documentation/commands.md#use-a-custom-stage-1). | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The commands documentation describes how to choose which stage1.aci to use at runtime. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This sounds awkward, but I get the idea. |
||
|
|
||
| Here is a quick example of how to use a container stage1 named `stage1-fly.aci` in `/usr/local/rkt/`: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest to use Fedora packages stage1 in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then we need to update the LKVM stage1 doc too. I suggest to do this afterwards and all together. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fair enough. |
||
| ``` | ||
| # rkt run --stage1-image=/usr/local/rkt/stage1-fly.aci coreos.com/etcd:v2.0.9 | ||
| ``` | ||
|
|
||
|
|
||
| ## WARNING: missing isolation and security features | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm a little wary of this messaging - it's a BIG SCARY WARNING for something that's by design, right? |
||
|
|
||
| The *fly* stage1 does **NOT** support the isolators and security features as the default stage1 does. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that, by design, the fly stage1 does not provide the isolation and security features that standard Specifically, the following constraints are not available when using the fly stage1: |
||
|
|
||
| Here's an incomplete list of features that are missing: | ||
| - network namespace isolation | ||
| - CPU isolators | ||
| - Memory isolators | ||
| - CAPABILITY bounding | ||
| - SELinux | ||
|
|
||
| ### Winning missing features back with systemd | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps "Providing additional isolation with systemd" |
||
|
|
||
| If you run systemd on your host, you can [wrap rkt with a systemd unit file](using-rkt-with-systemd.md#advanced-unit-file). | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid the second person: |
||
| For more information please consult the systemd manual. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| The following should get you started: | ||
|
|
||
| * [systemd.resource-control](http://www.freedesktop.org/software/systemd/man/systemd.resource-control.html) | ||
| * [systemd.directives](http://www.freedesktop.org/software/systemd/man/systemd.directives.html) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| # rkt fly | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think just remove this document for now... |
||
|
|
||
| ***This subcommand does not exist yet.*** | ||
| It will be a synonym for `rkt run --stage1=/path/to/stage1-fly.aci`. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I actually don't want this to be synonymous, because then |
||
|
|
||
| For more information please read about [running the fly stage1](../running-fly-stage1.md). | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,7 +59,7 @@ AC_ARG_WITH([stage1-default-flavor], | |
|
|
||
| AC_ARG_WITH([stage1-flavors], | ||
| [AS_HELP_STRING([--with-stage1-flavors], | ||
| [comma-separated list of stage1 flavors; choose from 'src', 'coreos', 'host', 'kvm'; default: 'coreos,kvm'])], | ||
| [comma-separated list of stage1 flavors; choose from 'src', 'coreos', 'host', 'kvm', 'fly'; default: 'coreos,kvm,fly'])], | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there's another place in the file that you need to update the default; this is just the help text. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Search for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done (see below) |
||
| [RKT_STAGE1_FLAVORS="${withval}"], | ||
| [RKT_STAGE1_FLAVORS=auto]) | ||
|
|
||
|
|
@@ -153,7 +153,7 @@ AS_CASE([${RKT_STAGE1_SETUP_KIND}], | |
| dnl and set the first flavor in the list as a | ||
| dnl default unless specified. | ||
| [AS_VAR_IF([RKT_STAGE1_FLAVORS],[auto], | ||
| [RKT_STAGE1_FLAVORS='coreos,kvm']) | ||
| [RKT_STAGE1_FLAVORS='coreos,kvm,fly']) | ||
| AS_VAR_IF([RKT_STAGE1_DEFAULT_FLAVOR],[auto], | ||
| [RKT_STAGE1_DEFAULT_FLAVOR=`AS_ECHO([${RKT_STAGE1_FLAVORS}]) | cut -d, -f1`]) | ||
| RKT_STAGE1_DEFAULT_NAME='' | ||
|
|
@@ -172,7 +172,7 @@ AS_VAR_IF([RKT_STAGE1_FLAVORS_VERSION_OVERRIDE], [auto], | |
| ## Built stage1 flavors verification | ||
|
|
||
| dnl a list of all flavors | ||
| RKT_STAGE1_ALL_FLAVORS=coreos,kvm,host,src | ||
| RKT_STAGE1_ALL_FLAVORS=coreos,kvm,host,src,fly | ||
|
|
||
| dnl RKT_ITERATE_FLAVORS iterates all comma-separated flavors stored in | ||
| dnl $1 using an iterator variable $2 and executes body $3. | ||
|
|
@@ -188,7 +188,7 @@ dnl additional string to an error message. | |
| AC_DEFUN([RKT_IS_VALID_FLAVOR], | ||
| [AS_CASE([$1], | ||
| dnl Correct flavor, nothing to do. | ||
| [coreos|kvm|host|src], | ||
| [coreos|kvm|host|src|fly], | ||
| [], | ||
| dnl Bogus flavor, bail out. | ||
| [AC_MSG_ERROR([*** unknown stage1 flavor "$1" $2])])]) | ||
|
|
@@ -231,6 +231,8 @@ RKT_ITERATE_FLAVORS([${RKT_STAGE1_FLAVORS}],[flavor], | |
| RKT_REQ_PROG([BC],[bc],[bc])], | ||
| [host], | ||
| [], | ||
| [fly], | ||
| [AC_MSG_WARN([* fly is an experimental stage1 implementation with almost no isolation and less features])], | ||
| [AC_MSG_ERROR([*** Unhandled flavor "${flavor}", should not happen])])]) | ||
|
|
||
| dnl Validate passed default flavor, it should be one of the built | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| // Copyright 2015 The rkt Authors | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| package stage1_common | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/stage1_common/common/ |
||
|
|
||
| import ( | ||
| "fmt" | ||
| "io/ioutil" | ||
| "os" | ||
| "path/filepath" | ||
|
|
||
| "github.com/coreos/rkt/pkg/sys" | ||
| ) | ||
|
|
||
| func WithClearedCloExec(lfd int, f func() error) error { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. exported function needs docstring |
||
| err := sys.CloseOnExec(lfd, false) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| defer sys.CloseOnExec(lfd, true) | ||
|
|
||
| return f() | ||
| } | ||
|
|
||
| func WritePpid(pid int) error { | ||
| // write ppid file as specified in | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. now that this is an exported function can you promote this comment to being a docstring? |
||
| // Documentation/devel/stage1-implementors-guide.md | ||
| out, err := os.Getwd() | ||
| if err != nil { | ||
| return fmt.Errorf("cannot get current working directory: %v\n", err) | ||
| } | ||
| // we are the parent of the process that is PID 1 in the container so we write our PID to "ppid" | ||
| err = ioutil.WriteFile(filepath.Join(out, "ppid"), | ||
| []byte(fmt.Sprintf("%d\n", pid)), 0644) | ||
| if err != nil { | ||
| return fmt.Errorf("cannot write ppid file: %v\n", err) | ||
| } | ||
| return nil | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| // Copyright 2015 The rkt Authors | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| package types | ||
|
|
||
| import ( | ||
| "encoding/json" | ||
| "fmt" | ||
| "io/ioutil" | ||
|
|
||
| "github.com/coreos/rkt/common" | ||
|
|
||
| "github.com/coreos/rkt/Godeps/_workspace/src/github.com/appc/spec/schema" | ||
| "github.com/coreos/rkt/Godeps/_workspace/src/github.com/appc/spec/schema/types" | ||
| ) | ||
|
|
||
| // Pod encapsulates a PodManifest and ImageManifests | ||
| type Pod struct { | ||
| Root string // root directory where the pod will be located | ||
| UUID types.UUID | ||
| Manifest *schema.PodManifest | ||
| Images map[string]*schema.ImageManifest | ||
| MetadataServiceURL string | ||
| Networks []string | ||
| } | ||
|
|
||
| // LoadPod loads a Pod Manifest (as prepared by stage0) and | ||
| // its associated Application Manifests, under $root/stage1/opt/stage1/$apphash | ||
| func LoadPod(root string, uuid *types.UUID) (*Pod, error) { | ||
| p := &Pod{ | ||
| Root: root, | ||
| UUID: *uuid, | ||
| Images: make(map[string]*schema.ImageManifest), | ||
| } | ||
|
|
||
| buf, err := ioutil.ReadFile(common.PodManifestPath(p.Root)) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed reading pod manifest: %v", err) | ||
| } | ||
|
|
||
| pm := &schema.PodManifest{} | ||
| if err := json.Unmarshal(buf, pm); err != nil { | ||
| return nil, fmt.Errorf("failed unmarshalling pod manifest: %v", err) | ||
| } | ||
| p.Manifest = pm | ||
|
|
||
| for i, app := range p.Manifest.Apps { | ||
| ampath := common.ImageManifestPath(p.Root, app.Name) | ||
| buf, err := ioutil.ReadFile(ampath) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed reading app manifest %q: %v", ampath, err) | ||
| } | ||
|
|
||
| am := &schema.ImageManifest{} | ||
| if err = json.Unmarshal(buf, am); err != nil { | ||
| return nil, fmt.Errorf("failed unmarshalling app manifest %q: %v", ampath, err) | ||
| } | ||
|
|
||
| if _, ok := p.Images[app.Name.String()]; ok { | ||
| return nil, fmt.Errorf("got multiple definitions for app: %v", app.Name) | ||
| } | ||
| if app.App == nil { | ||
| p.Manifest.Apps[i].App = am.App | ||
| } | ||
| p.Images[app.Name.String()] = am | ||
| } | ||
|
|
||
| return p, nil | ||
| } |
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.
Does it worth mentioning in the top paragraph? ;)
No need to do it in this PR. I can add it in the release PR if you suggest something.
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.
Sounds good :-)