Skip to content

RFC: runtime: enable kata as optional runtime#42986

Closed
jongwu wants to merge 1 commit intomoby:masterfrom
jongwu:kata_enable
Closed

RFC: runtime: enable kata as optional runtime#42986
jongwu wants to merge 1 commit intomoby:masterfrom
jongwu:kata_enable

Conversation

@jongwu
Copy link
Copy Markdown
Contributor

@jongwu jongwu commented Nov 3, 2021

After kata move to 2.x, "--add-runtime" is no longer working as kata runtime changed into a containerd-shim. People enjoy starting kata using docker, but it seems there is no way to go. Here is just a proposal to enable kata as an optional runtime. It's not good enough but deserve a try.

Currently, containerd-shim-v2 is adopt by dockerd, thus we can easily
add containerd-shim-kata-v2 as docker runtime.
we can get it by just exporting shim config to user and people can add containerd kata shim through the config.

Signed-off-by: Jianyong Wu jianyong.wu@arm.com

- What I did
enable containerd-shim based runtime like kata as docker optional runtime

- How I did it
export shim config to user
- How to verify it
add kata runtime in dockerd config like:
{
"runtimes":{
"io.containerd.kata.v2":{
"shim":{
"binary":"io.containerd.kata.v2"
}
}
}
}
and specify runtime using "--runtime io.containerd.kata.v2" when start kata using docker

- Description for the changelog

- A picture of a cute animal (not mandatory but encouraged)

🐭

func kataV2ShimConfig(conf *config.Config, runtimePath string) *types.ShimConfig {
return &types.ShimConfig{
Binary: linuxKataShimV2,
Opts: &v2runcoptions.Options{
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does kata really support this struct?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @AkihiroSuda -, I think that kata doesn't support the opts part. I have removed these lines.

@AkihiroSuda AkihiroSuda added area/runtime Runtime kind/feature Functionality or other elements that the project doesn't currently have. Features are new and shiny labels Nov 3, 2021
@thaJeztah
Copy link
Copy Markdown
Member

What would be needed to allow this to be configured in the daemon configuration without having to add special handling / code in this repository?

Basically, my ideal would be that new runtimes could be configured by the user (without us having to maintain special code for each of them)

@jongwu
Copy link
Copy Markdown
Contributor Author

jongwu commented Nov 6, 2021

What would be needed to allow this to be configured in the daemon configuration without having to add special handling / code in this repository?

Basically, my ideal would be that new runtimes could be configured by the user (without us having to maintain special code for each of them)

Thanks @thaJeztah -, Agree. docker should not maintain runtime list. I have changed the way to support kata that just exporting the shim config to user.

type ShimConfig struct {
Binary string
Binary string `json:"binary,omitempty`
Opts interface{}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a *ptypes.Any here.
Or perhaps define our own equivalent w/o importing proto libs which we can convert internally.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @cpuguy83 -, I'm not sure why we need proto type here? How we used it for? Is it enough to transfer "shim" info through grpc by just seting the binary type to "ptypes.Any"?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, we don't want to handle the type in dockerd, especially since it's just passed off to shim anyway.

The *Any type is just a proper encoding of interface{}.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @cpuguy83 -, I try to set binary to *ptypes.Any but I don't know how to test it using local json file to specify the runtime (I'm not familiar with the proto language) thus I don't know if the code is correctly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @cpuguy83 -, I twist the code again, now it works well.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand the change you added.

What we should be able to do is:

  1. Tell containerd which shim to use
    • Note that containerd only currently supports resolving a reference name like io.containerd.runc.v2 to containerd-shim-runc-v2, it does not support custom paths
  2. Pass along a config to the shim on create.
    • This is specific to each shim, eg runctypes.RuncOptions

To do 2, we either need to have explicit knowledge of every shim we ever want to support OR we should just be passing through configs.
In order to pass through those configs we need a place for users to encode them.
In this case we are looking to do that in the daemon config that gets stored in /etc/docker/daemon.json.
An interface{} does allow us to do this, but then we are passing around untyped data, and the containerd API is expecting to fill a types.Any (from the protobuf lib).
A types.Any has a type URL (i.e. full path of type... e.g. github.com/my/shim.Options) and some data.
https://github.com/gogo/protobuf/blob/master/protobuf/google/protobuf/any.proto

To understand how this is consumed, check out https://github.com/containerd/typeurl

These options get passed along to shims when containerd calls Create against the shim.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for my poor code. I have never touched these proto things before. Thanks for your guidance, I begin to aware how to deal with these. Really appreciated @cpuguy83

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @cpuguy83 -, I set shim.opts to types.Any and keep binary as string, thus let opts to convey the config. Is it right?

@jongwu
Copy link
Copy Markdown
Contributor Author

jongwu commented Nov 9, 2021

Hello @AkihiroSuda @thaJeztah -, help review this PR, thanks.

@jongwu jongwu force-pushed the kata_enable branch 2 times, most recently from 64175f5 to f81601b Compare November 10, 2021 13:26
@jongwu jongwu requested a review from cpuguy83 November 11, 2021 02:53
@thaJeztah
Copy link
Copy Markdown
Member

thaJeztah commented Nov 15, 2021

Looks like something isn't happy in CI; I see various tests fail with a similar error, like:

=== RUN   TestAuthZPluginV2Disable
    authz_plugin_v2_test.go:73: assertion failed: error is not nil: Error response from daemon: invalid task create option for io.containerd.runc.v2: unknown
--- FAIL: TestAuthZPluginV2Disable (1.67s)

Seems to come from https://github.com/containerd/containerd/blob/b5b83e0512458afd1ef75e778dfdbde2f88d424c/services/tasks/local.go#L771-L791

@jongwu
Copy link
Copy Markdown
Contributor Author

jongwu commented Nov 16, 2021

Looks like something isn't happy in CI; I see various tests fail with a similar error, like:

=== RUN   TestAuthZPluginV2Disable
    authz_plugin_v2_test.go:73: assertion failed: error is not nil: Error response from daemon: invalid task create option for io.containerd.runc.v2: unknown
--- FAIL: TestAuthZPluginV2Disable (1.67s)

Seems to come from https://github.com/containerd/containerd/blob/b5b83e0512458afd1ef75e778dfdbde2f88d424c/services/tasks/local.go#L771-L791

Hi @thaJeztah -, I'm not sure if I should do something here to save the CI or it's no business of this PR.

@thaJeztah
Copy link
Copy Markdown
Member

Hi @thaJeztah -, I'm not sure if I should do something here to save the CI or it's no business of this PR.

From the looks of it, I suspect it's related to the changes in this PR (invalid task create option for io.containerd.runc.v2: unknown). I must admit I'm not too familiar with this part of the code though. Hoping @cpuguy83 or @AkihiroSuda may be able to assist if needed 😅

Copy link
Copy Markdown
Member

@cpuguy83 cpuguy83 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing we are passing the wrong thing to containerd on the create call.

if rt.Shim == nil {
rt.Shim = defaultV2ShimConfig(daemon.configStore, rt.Path)
}
if rt.Shim.Opts == nil {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only the runc shims takes these default options, if the options are nil then we need to leave it nil unless we are using a runc shim.

package daemon // import "github.com/docker/docker/daemon"

import (
types1 "github.com/containerd/typeurl"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we keep all of these as typeurl?

"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/go-connections/nat"
types1 "github.com/gogo/protobuf/types"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit ptypes

@cpuguy83
Copy link
Copy Markdown
Member

I think one more issue with this is, we likely don't want those shim options to be protobuf in our json config.
I'm not exactly sure what to do here. Maybe instead of embedding the options in the daemon config like this we need to have a specific file, like /etc/docker/runtimes/<name>/shimopts. Maybe type url can go into the daemon config, though?

I can't really think of a way to do this that's not a pain to deal with as a user.
Open to suggestions here.

@struanb
Copy link
Copy Markdown

struanb commented Dec 17, 2021

Hi @jongwu @cpuguy83. I've been trying to get Docker to launch Kata v2 containers too. I'm unsure what the shim options are you're referring to, and so don't know if it helps, but Kata proposes using a wrapper executable, allowing any needed options to be added to the wrapper, like this:

/usr/local/bin/containerd-shim-katafc-v2 (on Ubuntu, with kata-containers 2.3.0 installed via Snap):

#!/bin/bash
KATA_CONF_FILE=/snap/kata-containers/current/usr/share/defaults/kata-containers/configuration.toml /snap/kata-containers/current/usr/bin/containerd-shim-kata-v2 "$@"

Is this a workable approach that would allow the daemon.json to contain only a path to the /usr/local/bin/containerd-shim-katafc-v2 wrapper?

N.B. In tests, if I copy this /usr/local/bin/containerd-shim-katafc-v2 wrapper over /usr/bin/containerd-shim-runc-v2 then unconfigured docker succeeds in launching kata v2 containers. So it really doesn't seem like much is needed to enable this.

@jongwu
Copy link
Copy Markdown
Contributor Author

jongwu commented Dec 20, 2021

Hi @jongwu @cpuguy83. I've been trying to get Docker to launch Kata v2 containers too. I'm unsure what the shim options are you're referring to, and so don't know if it helps, but Kata proposes using a wrapper executable, allowing any needed options to be added to the wrapper, like this:

/usr/local/bin/containerd-shim-katafc-v2 (on Ubuntu, with kata-containers 2.3.0 installed via Snap):

#!/bin/bash
KATA_CONF_FILE=/snap/kata-containers/current/usr/share/defaults/kata-containers/configuration.toml /snap/kata-containers/current/usr/bin/containerd-shim-kata-v2 "$@"

Is this a workable approach that would allow the daemon.json to contain only a path to the /usr/local/bin/containerd-shim-katafc-v2 wrapper?

N.B. In tests, if I copy this /usr/local/bin/containerd-shim-katafc-v2 wrapper over /usr/bin/containerd-shim-runc-v2 then unconfigured docker succeeds in launching kata v2 containers. So it really doesn't seem like much is needed to enable this.

Hi, @struanb -, what we want is let docker recognize and launch different runtimes. eg. using "--runtime " to specify runtime. IMO, docker has not prepared to accept other runtimes than "containerd-shim-runc-*" now. Replacing "shim" is not the normal way to launch a docker.

Some runtimes, e.g. Kata Containers, has no OCI runtime binary but a
containerd-shim based runtime. To support these kind of things, shim
config must be export to user config.

For example, if user want to add kata as its runtime, there are 2 steps to
go:
First, add kata runtime to daemon config file like:

{
   "runtimes":{
      "io.containerd.kata.v2":{
         "shim":{
            "binary": "io.containerd.kata.v2"
         }
      }
   }
}

Second, specify kata runtime using "--runtime io.containerd.kata.v2" in
command line.

Signed-off-by: Jianyong Wu <jianyong.wu@arm.com>
@jongwu
Copy link
Copy Markdown
Contributor Author

jongwu commented Dec 20, 2021

I think one more issue with this is, we likely don't want those shim options to be protobuf in our json config. I'm not exactly sure what to do here. Maybe instead of embedding the options in the daemon config like this we need to have a specific file, like /etc/docker/runtimes/<name>/shimopts. Maybe type url can go into the daemon config, though?

Sorry to replay so late. IMO adding a new config file is a little complicated for user and users are used to configurate dockerd in daemon config.

I can't really think of a way to do this that's not a pain to deal with as a user. Open to suggestions here.

We can do it here this way and may improve it later if there is a better way composed.

@cpuguy83
Copy link
Copy Markdown
Member

Discussed this on the maintainers meeting today with @thaJeztah, @tonistiigi, @samuelkarp, and @chris-crone.
The approach to use a separate config for shim specific options is what we'd like to do.
This means the user shove the options in protobuf or whatever encoding is easiest that the shim supports into the file on disk if they need to configure the shim.

If we ask the user to add the type url in the daemon.json, then docker can construct the ptypes.Any itself.
Later on we could add support for inline config if needed, e.g. maybe the shim supports json or... base64 encoded toml(?)... which may be friendly to put into a json document.

Should this config file be implicit based on the name of the runtime or explicit in the runtime config?

@jongwu
Copy link
Copy Markdown
Contributor Author

jongwu commented Jan 29, 2022

Discussed this on the maintainers meeting today with @thaJeztah, @tonistiigi, @samuelkarp, and @chris-crone. The approach to use a separate config for shim specific options is what we'd like to do. This means the user shove the options in protobuf or whatever encoding is easiest that the shim supports into the file on disk if they need to configure the shim.

OK.

If we ask the user to add the type url in the daemon.json, then docker can construct the ptypes.Any itself. Later on we could add support for inline config if needed, e.g. maybe the shim supports json or... base64 encoded toml(?)... which may be friendly to put into a json document.

Er, what's the format of the shim config file in the initial plan?

Should this config file be implicit based on the name of the runtime or explicit in the runtime config?

So, the config file for kata can be "/etc/docker/runtimes/kata-containers/shimopts.json"? In this commit, the value of "--runtime" is "io.containerd.kata.v2". Base on this separated shim config file, shall we start a kata using "--runtime kata-containers"?
what do you mean by "runtime config" ? I'm not sure there is a config file for "kata-shim".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/runtime Runtime kind/feature Functionality or other elements that the project doesn't currently have. Features are new and shiny

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants