Skip to content
This repository has been archived by the owner on Aug 24, 2023. It is now read-only.

quickfix: propagate runtime #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cmd/cri/options/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ func NewContainerRuntimeOptions() *config.ContainerRuntimeOptions {
PodSandboxImage: defaultPodSandboxImage,
ImagePullProgressDeadline: metav1.Duration{Duration: 1 * time.Minute},
NetworkPluginName: "cni",
RuntimeHandler: []string{
"spin=io.containerd.spin.v1",
"wasmedge=io.containerd.wasmedge.v1",
},

CNIBinDir: cniBinDir,
CNIConfDir: cniConfDir,
Expand Down
15 changes: 15 additions & 0 deletions cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ package cmd

import (
"fmt"
"regexp"
"runtime"
"strings"

"github.com/Mirantis/cri-dockerd/backend"
"github.com/Mirantis/cri-dockerd/cmd/cri/options"
Expand Down Expand Up @@ -181,6 +183,18 @@ func RunCriDockerd(f *options.DockerCRIFlags, stopCh <-chan struct{}) error {
}
}

runtimeHandlerValidate := regexp.MustCompile(`^\w+=\w+\.[\w\.]+$`)
runtimeHandler := make(map[string]string)
for _, handler := range r.RuntimeHandler {
//TODO validate
valid := runtimeHandlerValidate.Match([]byte(handler))
if !valid {
logrus.Fatalf("Could not parse runtime handler \"%s\" parameter. Format shoud be \"runtimeClassName=io.containerd.runtime.v1\"", handler)
}
kv := strings.Split(handler, "=")
runtimeHandler[kv[0]] = kv[1]
}

// Initialize streaming configuration. (Not using TLS now)
streamingConfig := &streaming.Config{
// Use a relative redirect (no scheme or host).
Expand All @@ -196,6 +210,7 @@ func RunCriDockerd(f *options.DockerCRIFlags, stopCh <-chan struct{}) error {
ds, err := core.NewDockerService(
dockerClientConfig,
r.PodSandboxImage,
runtimeHandler,
streamingConfig,
&pluginSettings,
f.RuntimeCgroups,
Expand Down
9 changes: 9 additions & 0 deletions config/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ type ContainerRuntimeOptions struct {
// HairpinMode is the mode used to allow endpoints of a Service to load
// balance back to themselves if they should try to access their own Service
HairpinMode HairpinMode
// RuntimeHandler is a slice of runtime handler mappings e.g. runc=iocontainerd.runc.v2
RuntimeHandler []string
}

// AddFlags has the set of flags needed by cri-dockerd
Expand Down Expand Up @@ -139,6 +141,13 @@ func (s *ContainerRuntimeOptions) AddFlags(fs *pflag.FlagSet) {
"The address to bind the CRI streaming server to. If not specified, it will bind to all addresses.",
),
)

fs.StringSliceVar(
&s.RuntimeHandler,
"runtime-handler",
s.RuntimeHandler,
"Additional runtimes e.g. runc=io.containerd.runc.v2",
)
// Network plugin settings for Docker.
fs.StringVar(
&s.PodCIDR,
Expand Down
2 changes: 2 additions & 0 deletions core/container_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func (ds *dockerService) CreateContainer(
}
containerName := makeContainerName(sandboxConfig, config)
terminationMessagePath, _ := config.Annotations["io.kubernetes.container.terminationMessagePath"]
json, _, err := ds.getPodSandboxDetails(podSandboxID)
createConfig := types.ContainerCreateConfig{
Name: containerName,
Config: &container.Config{
Expand All @@ -89,6 +90,7 @@ func (ds *dockerService) CreateContainer(
RestartPolicy: container.RestartPolicy{
Name: "no",
},
Runtime: json.Config.Labels[runtimeLabelName],
},
}

Expand Down
3 changes: 3 additions & 0 deletions core/docker_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ var internalLabelKeys = []string{containerTypeLabelKey, containerLogPathLabelKey
func NewDockerService(
clientConfig *config.ClientConfig,
podSandboxImage string,
runtimeHandler map[string]string,
streamingConfig *streaming.Config,
pluginSettings *config.NetworkPluginSettings,
cgroupsName string,
Expand All @@ -145,6 +146,7 @@ func NewDockerService(
client: c,
os: config.RealOS{},
podSandboxImage: podSandboxImage,
runtimeHandler: runtimeHandler,
streamingRuntime: &streaming.StreamingRuntime{
Client: client,
ExecHandler: &NativeExecHandler{},
Expand Down Expand Up @@ -256,6 +258,7 @@ type dockerService struct {
client libdocker.DockerClientInterface
os config.OSInterface
podSandboxImage string
runtimeHandler map[string]string
streamingRuntime *streaming.StreamingRuntime
streamingServer streaming.Server

Expand Down
22 changes: 18 additions & 4 deletions core/sandbox_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ package core

import (
"fmt"
"os"
"strings"
"time"

"github.com/Mirantis/cri-dockerd/libdocker"
"github.com/Mirantis/cri-dockerd/utils"
"github.com/Mirantis/cri-dockerd/utils/errors"
"k8s.io/kubernetes/pkg/credentialprovider"
"os"
"strings"
"time"

"github.com/Mirantis/cri-dockerd/config"
dockertypes "github.com/docker/docker/api/types"
Expand All @@ -47,14 +48,27 @@ const (
defaultSandboxOOMAdj int = -998

// Name of the underlying container runtime
runtimeName = "docker"
runtimeName = "docker"
runtimeLabelName = "pod.spec.runtimeClassName"
)

var (
// Termination grace period
defaultSandboxGracePeriod = time.Duration(10) * time.Second
)

func (ds *dockerService) getRuntimeFromRuntimeClassName(runtimeClassName string) (string, error) {
if runtimeClassName == "" || runtimeClassName == runtimeName {
return runtimeClassName, nil
}
runtimeHandler, ok := ds.runtimeHandler[runtimeClassName]
if ok {
return runtimeHandler, nil
} else {
return "", fmt.Errorf("RuntimeHandler %q not supported", runtimeClassName)
}
}

// Returns whether the sandbox network is ready, and whether the sandbox is known
func (ds *dockerService) getNetworkReady(podSandboxID string) (bool, bool) {
ds.networkReadyLock.Lock()
Expand Down
11 changes: 8 additions & 3 deletions core/sandbox_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"encoding/json"
"fmt"

"github.com/Mirantis/cri-dockerd/config"
"github.com/Mirantis/cri-dockerd/utils/errors"
v1 "k8s.io/cri-api/pkg/apis/runtime/v1"
Expand Down Expand Up @@ -51,9 +52,6 @@ func (ds *dockerService) RunPodSandbox(
}

// Step 2: Create the sandbox container.
if r.GetRuntimeHandler() != "" && r.GetRuntimeHandler() != runtimeName {
return nil, fmt.Errorf("RuntimeHandler %q not supported", r.GetRuntimeHandler())
}
createConfig, err := ds.makeSandboxDockerConfig(containerConfig, image)
if err != nil {
return nil, fmt.Errorf(
Expand All @@ -62,6 +60,13 @@ func (ds *dockerService) RunPodSandbox(
err,
)
}
// Map Kubernetes runtimeClassName to Docker runtime.
runtimeHandler, err := ds.getRuntimeFromRuntimeClassName(r.GetRuntimeHandler())
if err != nil {
return nil, err
}
// TODO: find a better way to pass runtime from K8s Pod to containers
createConfig.Config.Labels[runtimeLabelName] = runtimeHandler
createResp, err := ds.client.CreateContainer(*createConfig)
if err != nil {
createResp, err = recoverFromCreationConflictIfNeeded(ds.client, *createConfig, err)
Expand Down