diff --git a/pkg/kubelet/dockershim/docker_container.go b/pkg/kubelet/dockershim/docker_container.go index 36d91009419..08022326db0 100644 --- a/pkg/kubelet/dockershim/docker_container.go +++ b/pkg/kubelet/dockershim/docker_container.go @@ -126,6 +126,13 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi Privileged: config.GetPrivileged(), } + // Set sysctls if requested + sysctls, err := getSysctlsFromAnnotations(config.Annotations) + if err != nil { + return "", fmt.Errorf("failed to get sysctls from annotations %v for container %q: %v", config.Annotations, config.Metadata.GetName(), err) + } + hc.Sysctls = sysctls + // Apply options derived from the sandbox config. if lc := sandboxConfig.GetLinux(); lc != nil { // Apply Cgroup options. @@ -170,7 +177,6 @@ func (ds *dockerService) CreateContainer(podSandboxID string, config *runtimeApi // Note: ShmSize is handled in kube_docker_client.go } - var err error hc.SecurityOpt, err = getContainerSecurityOpts(config.Metadata.GetName(), sandboxConfig, ds.seccompProfileRoot) if err != nil { return "", fmt.Errorf("failed to generate container security options for container %q: %v", config.Metadata.GetName(), err) diff --git a/pkg/kubelet/dockershim/docker_sandbox.go b/pkg/kubelet/dockershim/docker_sandbox.go index a0e3ab33672..14860b10043 100644 --- a/pkg/kubelet/dockershim/docker_sandbox.go +++ b/pkg/kubelet/dockershim/docker_sandbox.go @@ -224,6 +224,13 @@ func (ds *dockerService) makeSandboxDockerConfig(c *runtimeApi.PodSandboxConfig, HostConfig: hc, } + // Set sysctls if requested + sysctls, err := getSysctlsFromAnnotations(c.Annotations) + if err != nil { + return nil, fmt.Errorf("failed to get sysctls from annotations %v for sandbox %q: %v", c.Annotations, c.Metadata.GetName(), err) + } + hc.Sysctls = sysctls + // Apply linux-specific options. if lc := c.GetLinux(); lc != nil { // Apply Cgroup options. @@ -265,7 +272,6 @@ func (ds *dockerService) makeSandboxDockerConfig(c *runtimeApi.PodSandboxConfig, setSandboxResources(hc) // Set security options. - var err error hc.SecurityOpt, err = getSandboxSecurityOpts(c, ds.seccompProfileRoot) if err != nil { return nil, fmt.Errorf("failed to generate sandbox security options for sandbox %q: %v", c.Metadata.GetName(), err) diff --git a/pkg/kubelet/dockershim/helpers.go b/pkg/kubelet/dockershim/helpers.go index e7e3c31ed8c..0b67c650625 100644 --- a/pkg/kubelet/dockershim/helpers.go +++ b/pkg/kubelet/dockershim/helpers.go @@ -27,6 +27,7 @@ import ( dockernat "github.com/docker/go-connections/nat" "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api" runtimeApi "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime" "k8s.io/kubernetes/pkg/kubelet/dockertools" "k8s.io/kubernetes/pkg/kubelet/types" @@ -222,6 +223,27 @@ func getNetworkNamespace(c *dockertypes.ContainerJSON) string { return fmt.Sprintf(dockerNetNSFmt, c.State.Pid) } +// getSysctlsFromAnnotations gets sysctls from annotations. +func getSysctlsFromAnnotations(annotations map[string]string) (map[string]string, error) { + var results map[string]string + + sysctls, unsafeSysctls, err := api.SysctlsFromPodAnnotations(annotations) + if err != nil { + return nil, err + } + if len(sysctls)+len(unsafeSysctls) > 0 { + results = make(map[string]string, len(sysctls)+len(unsafeSysctls)) + for _, c := range sysctls { + results[c.Name] = c.Value + } + for _, c := range unsafeSysctls { + results[c.Name] = c.Value + } + } + + return results, nil +} + // dockerFilter wraps around dockerfilters.Args and provides methods to modify // the filter easily. type dockerFilter struct { diff --git a/pkg/kubelet/dockershim/helpers_test.go b/pkg/kubelet/dockershim/helpers_test.go index f2793627c23..0312e22e670 100644 --- a/pkg/kubelet/dockershim/helpers_test.go +++ b/pkg/kubelet/dockershim/helpers_test.go @@ -147,3 +147,43 @@ func TestGetSandboxSecurityOpts(t *testing.T) { } } } + +// TestGetSystclsFromAnnotations tests the logic of getting sysctls from annotations. +func TestGetSystclsFromAnnotations(t *testing.T) { + tests := []struct { + annotations map[string]string + expectedSysctls map[string]string + }{{ + annotations: map[string]string{ + api.SysctlsPodAnnotationKey: "kernel.shmmni=32768,kernel.shmmax=1000000000", + api.UnsafeSysctlsPodAnnotationKey: "knet.ipv4.route.min_pmtu=1000", + }, + expectedSysctls: map[string]string{ + "kernel.shmmni": "32768", + "kernel.shmmax": "1000000000", + "knet.ipv4.route.min_pmtu": "1000", + }, + }, { + annotations: map[string]string{ + api.SysctlsPodAnnotationKey: "kernel.shmmni=32768,kernel.shmmax=1000000000", + }, + expectedSysctls: map[string]string{ + "kernel.shmmni": "32768", + "kernel.shmmax": "1000000000", + }, + }, { + annotations: map[string]string{ + api.UnsafeSysctlsPodAnnotationKey: "knet.ipv4.route.min_pmtu=1000", + }, + expectedSysctls: map[string]string{ + "knet.ipv4.route.min_pmtu": "1000", + }, + }} + + for i, test := range tests { + actual, err := getSysctlsFromAnnotations(test.annotations) + assert.NoError(t, err, "TestCase[%d]", i) + assert.Len(t, actual, len(test.expectedSysctls), "TestCase[%d]", i) + assert.Equal(t, test.expectedSysctls, actual, "TestCase[%d]", i) + } +}