diff --git a/pkg/bootstrap/docker/dockerhelper/helper.go b/pkg/bootstrap/docker/dockerhelper/helper.go index 7946d5499409..27edab70aae7 100644 --- a/pkg/bootstrap/docker/dockerhelper/helper.go +++ b/pkg/bootstrap/docker/dockerhelper/helper.go @@ -77,6 +77,14 @@ func (h *Helper) dockerInfo() (*dockertypes.Info, error) { return h.info, nil } +func (h *Helper) CgroupDriver() (string, error) { + info, err := h.dockerInfo() + if err != nil { + return "", err + } + return info.CgroupDriver, nil +} + // HasInsecureRegistryArg checks whether the docker daemon is configured with // the appropriate insecure registry argument func (h *Helper) HasInsecureRegistryArg() (bool, error) { diff --git a/pkg/bootstrap/docker/openshift/helper.go b/pkg/bootstrap/docker/openshift/helper.go index b382ed3d282b..e6c3eb022b26 100644 --- a/pkg/bootstrap/docker/openshift/helper.go +++ b/pkg/bootstrap/docker/openshift/helper.go @@ -116,10 +116,10 @@ type StartOptions struct { } // NewHelper creates a new OpenShift helper -func NewHelper(client *docker.Client, hostHelper *host.HostHelper, image, containerName, publicHostname, routingSuffix string) *Helper { +func NewHelper(client *docker.Client, dockerHelper *dockerhelper.Helper, hostHelper *host.HostHelper, image, containerName, publicHostname, routingSuffix string) *Helper { return &Helper{ client: client, - dockerHelper: dockerhelper.NewHelper(client, nil), + dockerHelper: dockerHelper, execHelper: dockerexec.NewExecHelper(client, containerName), hostHelper: hostHelper, runHelper: run.NewRunHelper(client), @@ -730,6 +730,19 @@ func (h *Helper) updateConfig(configDir string, opt *StartOptions) error { nodeCfg.DNSIP = "" } nodeCfg.DNSBindAddress = "" + + if h.supportsCgroupDriver() { + // Set the cgroup driver from the current docker + cgroupDriver, err := h.dockerHelper.CgroupDriver() + if err != nil { + return err + } + if nodeCfg.KubeletArguments == nil { + nodeCfg.KubeletArguments = configapi.ExtendedArguments{} + } + nodeCfg.KubeletArguments["cgroup-driver"] = []string{cgroupDriver} + } + cfgBytes, err = configapilatest.WriteYAML(nodeCfg) if err != nil { return err @@ -784,3 +797,25 @@ func getUsedPorts(data string) map[int]struct{} { glog.V(2).Infof("Used ports in container: %#v", ports) return ports } + +func (h *Helper) supportsCgroupDriver() bool { + script := `#!/bin/bash + +# Exit with an error +set -e + +# Ensure we have a link to the openshift binary named kubelet +if [[ ! -f /usr/bin/kubelet ]]; then + ln -s /usr/bin/openshift /usr/bin/kubelet +fi + +kubelet --help | grep -- "--cgroup-driver" +` + rc, err := h.runHelper.New().Image(h.image). + DiscardContainer(). + Entrypoint("/bin/bash"). + Command("-c", script). + Run() + + return rc == 0 && err == nil +} diff --git a/pkg/bootstrap/docker/up.go b/pkg/bootstrap/docker/up.go index c79ca42ca67d..65c48abe8027 100644 --- a/pkg/bootstrap/docker/up.go +++ b/pkg/bootstrap/docker/up.go @@ -1071,7 +1071,7 @@ func (c *ClientStartConfig) Clients() (*client.Client, kclientset.Interface, err // OpenShiftHelper returns a helper object to work with OpenShift on the server func (c *CommonStartConfig) OpenShiftHelper() *openshift.Helper { if c.openshiftHelper == nil { - c.openshiftHelper = openshift.NewHelper(c.dockerClient, c.HostHelper(), c.openshiftImage(), openshift.OpenShiftContainer, c.PublicHostname, c.RoutingSuffix) + c.openshiftHelper = openshift.NewHelper(c.dockerClient, c.DockerHelper(), c.HostHelper(), c.openshiftImage(), openshift.OpenShiftContainer, c.PublicHostname, c.RoutingSuffix) } return c.openshiftHelper } diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cgroup_manager_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cgroup_manager_linux.go index ba782d50dc70..e30d73bac764 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cgroup_manager_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cgroup_manager_linux.go @@ -227,8 +227,20 @@ func (m *cgroupManagerImpl) Exists(name CgroupName) bool { // Get map of all cgroup paths on the system for the particular cgroup cgroupPaths := m.buildCgroupPaths(name) + // the presence of alternative control groups not known to runc confuses + // the kubelet existence checks. + // ideally, we would have a mechaninsm in runc to support Exists() logic + // scoped to the set control groups it understands. this is being discussed + // in https://github.com/opencontainers/runc/issues/1440 + // once resolved, we can remove this code. + whitelistControllers := sets.NewString("cpu", "cpuacct", "cpuset", "memory", "hugetlb", "systemd") + // If even one cgroup path doesn't exist, then the cgroup doesn't exist. - for _, path := range cgroupPaths { + for controller, path := range cgroupPaths { + // ignore mounts we dont care about + if !whitelistControllers.Has(controller) { + continue + } if !libcontainercgroups.PathExists(path) { return false }