mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 04:33:26 +00:00
Merge pull request #25324 from jfrazelle/add-seccomp
Add Seccomp to Annotations
This commit is contained in:
commit
4357b8a0a6
@ -19,6 +19,7 @@ package options
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
_ "net/http/pprof"
|
_ "net/http/pprof"
|
||||||
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -132,6 +133,7 @@ func NewKubeletServer() *KubeletServer {
|
|||||||
RootDirectory: defaultRootDir,
|
RootDirectory: defaultRootDir,
|
||||||
RuntimeCgroups: "",
|
RuntimeCgroups: "",
|
||||||
SerializeImagePulls: true,
|
SerializeImagePulls: true,
|
||||||
|
SeccompProfileRoot: filepath.Join(defaultRootDir, "seccomp"),
|
||||||
StreamingConnectionIdleTimeout: unversioned.Duration{Duration: 4 * time.Hour},
|
StreamingConnectionIdleTimeout: unversioned.Duration{Duration: 4 * time.Hour},
|
||||||
SyncFrequency: unversioned.Duration{Duration: 1 * time.Minute},
|
SyncFrequency: unversioned.Duration{Duration: 1 * time.Minute},
|
||||||
SystemCgroups: "",
|
SystemCgroups: "",
|
||||||
@ -171,6 +173,7 @@ func (s *KubeletServer) AddFlags(fs *pflag.FlagSet) {
|
|||||||
fs.StringVar(&s.PodInfraContainerImage, "pod-infra-container-image", s.PodInfraContainerImage, "The image whose network/ipc namespaces containers in each pod will use.")
|
fs.StringVar(&s.PodInfraContainerImage, "pod-infra-container-image", s.PodInfraContainerImage, "The image whose network/ipc namespaces containers in each pod will use.")
|
||||||
fs.StringVar(&s.DockerEndpoint, "docker-endpoint", s.DockerEndpoint, "If non-empty, use this for the docker endpoint to communicate with")
|
fs.StringVar(&s.DockerEndpoint, "docker-endpoint", s.DockerEndpoint, "If non-empty, use this for the docker endpoint to communicate with")
|
||||||
fs.StringVar(&s.RootDirectory, "root-dir", s.RootDirectory, "Directory path for managing kubelet files (volume mounts,etc).")
|
fs.StringVar(&s.RootDirectory, "root-dir", s.RootDirectory, "Directory path for managing kubelet files (volume mounts,etc).")
|
||||||
|
fs.StringVar(&s.SeccompProfileRoot, "seccomp-profile-root", s.SeccompProfileRoot, "Directory path for seccomp profiles.")
|
||||||
fs.BoolVar(&s.AllowPrivileged, "allow-privileged", s.AllowPrivileged, "If true, allow containers to request privileged mode. [default=false]")
|
fs.BoolVar(&s.AllowPrivileged, "allow-privileged", s.AllowPrivileged, "If true, allow containers to request privileged mode. [default=false]")
|
||||||
fs.StringVar(&s.HostNetworkSources, "host-network-sources", s.HostNetworkSources, "Comma-separated list of sources from which the Kubelet allows pods to use of host network. [default=\"*\"]")
|
fs.StringVar(&s.HostNetworkSources, "host-network-sources", s.HostNetworkSources, "Comma-separated list of sources from which the Kubelet allows pods to use of host network. [default=\"*\"]")
|
||||||
fs.StringVar(&s.HostPIDSources, "host-pid-sources", s.HostPIDSources, "Comma-separated list of sources from which the Kubelet allows pods to use the host pid namespace. [default=\"*\"]")
|
fs.StringVar(&s.HostPIDSources, "host-pid-sources", s.HostPIDSources, "Comma-separated list of sources from which the Kubelet allows pods to use the host pid namespace. [default=\"*\"]")
|
||||||
|
@ -261,6 +261,7 @@ func UnsecuredKubeletConfig(s *options.KubeletServer) (*KubeletConfig, error) {
|
|||||||
RktAPIEndpoint: s.RktAPIEndpoint,
|
RktAPIEndpoint: s.RktAPIEndpoint,
|
||||||
RktStage1Image: s.RktStage1Image,
|
RktStage1Image: s.RktStage1Image,
|
||||||
RootDirectory: s.RootDirectory,
|
RootDirectory: s.RootDirectory,
|
||||||
|
SeccompProfileRoot: s.SeccompProfileRoot,
|
||||||
Runonce: s.RunOnce,
|
Runonce: s.RunOnce,
|
||||||
SerializeImagePulls: s.SerializeImagePulls,
|
SerializeImagePulls: s.SerializeImagePulls,
|
||||||
StandaloneMode: (len(s.APIServerList) == 0),
|
StandaloneMode: (len(s.APIServerList) == 0),
|
||||||
@ -831,6 +832,7 @@ type KubeletConfig struct {
|
|||||||
RktStage1Image string
|
RktStage1Image string
|
||||||
RootDirectory string
|
RootDirectory string
|
||||||
Runonce bool
|
Runonce bool
|
||||||
|
SeccompProfileRoot string
|
||||||
SerializeImagePulls bool
|
SerializeImagePulls bool
|
||||||
StandaloneMode bool
|
StandaloneMode bool
|
||||||
StreamingConnectionIdleTimeout time.Duration
|
StreamingConnectionIdleTimeout time.Duration
|
||||||
@ -882,6 +884,7 @@ func CreateAndInitKubelet(kc *KubeletConfig) (k KubeletBootstrap, pc *config.Pod
|
|||||||
kc.DockerClient,
|
kc.DockerClient,
|
||||||
kubeClient,
|
kubeClient,
|
||||||
kc.RootDirectory,
|
kc.RootDirectory,
|
||||||
|
kc.SeccompProfileRoot,
|
||||||
kc.PodInfraContainerImage,
|
kc.PodInfraContainerImage,
|
||||||
kc.SyncFrequency,
|
kc.SyncFrequency,
|
||||||
float32(kc.RegistryPullQPS),
|
float32(kc.RegistryPullQPS),
|
||||||
|
@ -149,6 +149,7 @@ kubelet
|
|||||||
--root-dir="/var/lib/kubelet": Directory path for managing kubelet files (volume mounts,etc).
|
--root-dir="/var/lib/kubelet": Directory path for managing kubelet files (volume mounts,etc).
|
||||||
--runonce[=false]: If true, exit after spawning pods from local manifests or remote urls. Exclusive with --api-servers, and --enable-server
|
--runonce[=false]: If true, exit after spawning pods from local manifests or remote urls. Exclusive with --api-servers, and --enable-server
|
||||||
--runtime-cgroups="": Optional absolute name of cgroups to create and run the runtime in.
|
--runtime-cgroups="": Optional absolute name of cgroups to create and run the runtime in.
|
||||||
|
--seccomp-profile-root="/var/lib/kubelet/seccomp": Directory path for seccomp profiles.
|
||||||
--serialize-image-pulls[=true]: Pull images one at a time. We recommend *not* changing the default value on nodes that run docker daemon with version < 1.9 or an Aufs storage backend. Issue #10959 has more details. [default=true]
|
--serialize-image-pulls[=true]: Pull images one at a time. We recommend *not* changing the default value on nodes that run docker daemon with version < 1.9 or an Aufs storage backend. Issue #10959 has more details. [default=true]
|
||||||
--streaming-connection-idle-timeout=4h0m0s: Maximum time a streaming connection can be idle before the connection is automatically closed. 0 indicates no timeout. Example: '5m'
|
--streaming-connection-idle-timeout=4h0m0s: Maximum time a streaming connection can be idle before the connection is automatically closed. 0 indicates no timeout. Example: '5m'
|
||||||
--sync-frequency=1m0s: Max period between synchronizing running containers and config
|
--sync-frequency=1m0s: Max period between synchronizing running containers and config
|
||||||
@ -160,7 +161,7 @@ kubelet
|
|||||||
--volume-stats-agg-period=1m0s: Specifies interval for kubelet to calculate and cache the volume disk usage for all pods and volumes. To disable volume calculations, set to 0. Default: '1m'
|
--volume-stats-agg-period=1m0s: Specifies interval for kubelet to calculate and cache the volume disk usage for all pods and volumes. To disable volume calculations, set to 0. Default: '1m'
|
||||||
```
|
```
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra on 21-May-2016
|
###### Auto generated by spf13/cobra on 24-May-2016
|
||||||
|
|
||||||
|
|
||||||
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
||||||
|
@ -385,6 +385,7 @@ save-config
|
|||||||
scheduler-config
|
scheduler-config
|
||||||
scheduler-name
|
scheduler-name
|
||||||
schema-cache-dir
|
schema-cache-dir
|
||||||
|
seccomp-profile-root
|
||||||
secure-port
|
secure-port
|
||||||
serialize-image-pulls
|
serialize-image-pulls
|
||||||
server-start-timeout
|
server-start-timeout
|
||||||
|
@ -223,6 +223,7 @@ func DeepCopy_componentconfig_KubeletConfiguration(in KubeletConfiguration, out
|
|||||||
out.PodInfraContainerImage = in.PodInfraContainerImage
|
out.PodInfraContainerImage = in.PodInfraContainerImage
|
||||||
out.DockerEndpoint = in.DockerEndpoint
|
out.DockerEndpoint = in.DockerEndpoint
|
||||||
out.RootDirectory = in.RootDirectory
|
out.RootDirectory = in.RootDirectory
|
||||||
|
out.SeccompProfileRoot = in.SeccompProfileRoot
|
||||||
out.AllowPrivileged = in.AllowPrivileged
|
out.AllowPrivileged = in.AllowPrivileged
|
||||||
out.HostNetworkSources = in.HostNetworkSources
|
out.HostNetworkSources = in.HostNetworkSources
|
||||||
out.HostPIDSources = in.HostPIDSources
|
out.HostPIDSources = in.HostPIDSources
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -151,6 +151,8 @@ type KubeletConfiguration struct {
|
|||||||
// rootDirectory is the directory path to place kubelet files (volume
|
// rootDirectory is the directory path to place kubelet files (volume
|
||||||
// mounts,etc).
|
// mounts,etc).
|
||||||
RootDirectory string `json:"rootDirectory"`
|
RootDirectory string `json:"rootDirectory"`
|
||||||
|
// seccompProfileRoot is the directory path for seccomp profiles.
|
||||||
|
SeccompProfileRoot string `json:"seccompProfileRoot"`
|
||||||
// allowPrivileged enables containers to request privileged mode.
|
// allowPrivileged enables containers to request privileged mode.
|
||||||
// Defaults to false.
|
// Defaults to false.
|
||||||
AllowPrivileged bool `json:"allowPrivileged"`
|
AllowPrivileged bool `json:"allowPrivileged"`
|
||||||
|
@ -51,7 +51,7 @@ func NewFakeDockerManager(
|
|||||||
fakePodGetter := &fakePodGetter{}
|
fakePodGetter := &fakePodGetter{}
|
||||||
dm := NewDockerManager(client, recorder, livenessManager, containerRefManager, fakePodGetter, machineInfo, podInfraContainerImage, qps,
|
dm := NewDockerManager(client, recorder, livenessManager, containerRefManager, fakePodGetter, machineInfo, podInfraContainerImage, qps,
|
||||||
burst, containerLogsDir, osInterface, networkPlugin, runtimeHelper, httpClient, &NativeExecHandler{},
|
burst, containerLogsDir, osInterface, networkPlugin, runtimeHelper, httpClient, &NativeExecHandler{},
|
||||||
fakeOOMAdjuster, fakeProcFs, false, imageBackOff, false, false, true)
|
fakeOOMAdjuster, fakeProcFs, false, imageBackOff, false, false, true, "/var/lib/kubelet/seccomp")
|
||||||
dm.dockerPuller = &FakeDockerPuller{}
|
dm.dockerPuller = &FakeDockerPuller{}
|
||||||
|
|
||||||
// ttl of version cache is set to 0 so we always call version api directly in tests.
|
// ttl of version cache is set to 0 so we always call version api directly in tests.
|
||||||
|
@ -18,6 +18,7 @@ package dockertools
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@ -25,6 +26,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -102,8 +104,7 @@ var (
|
|||||||
// TODO: make this a TTL based pull (if image older than X policy, pull)
|
// TODO: make this a TTL based pull (if image older than X policy, pull)
|
||||||
podInfraContainerImagePullPolicy = api.PullIfNotPresent
|
podInfraContainerImagePullPolicy = api.PullIfNotPresent
|
||||||
|
|
||||||
// Default set of security options. Seccomp is disabled by default until
|
// Default set of security options.
|
||||||
// github issue #20870 is resolved.
|
|
||||||
defaultSecurityOpt = []string{"seccomp:unconfined"}
|
defaultSecurityOpt = []string{"seccomp:unconfined"}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -172,6 +173,9 @@ type DockerManager struct {
|
|||||||
|
|
||||||
// The version cache of docker daemon.
|
// The version cache of docker daemon.
|
||||||
versionCache *cache.ObjectCache
|
versionCache *cache.ObjectCache
|
||||||
|
|
||||||
|
// Directory to host local seccomp profiles.
|
||||||
|
seccompProfileRoot string
|
||||||
}
|
}
|
||||||
|
|
||||||
// A subset of the pod.Manager interface extracted for testing purposes.
|
// A subset of the pod.Manager interface extracted for testing purposes.
|
||||||
@ -214,6 +218,7 @@ func NewDockerManager(
|
|||||||
serializeImagePulls bool,
|
serializeImagePulls bool,
|
||||||
enableCustomMetrics bool,
|
enableCustomMetrics bool,
|
||||||
hairpinMode bool,
|
hairpinMode bool,
|
||||||
|
seccompProfileRoot string,
|
||||||
options ...kubecontainer.Option) *DockerManager {
|
options ...kubecontainer.Option) *DockerManager {
|
||||||
// Wrap the docker client with instrumentedDockerInterface
|
// Wrap the docker client with instrumentedDockerInterface
|
||||||
client = newInstrumentedDockerInterface(client)
|
client = newInstrumentedDockerInterface(client)
|
||||||
@ -250,6 +255,7 @@ func NewDockerManager(
|
|||||||
enableCustomMetrics: enableCustomMetrics,
|
enableCustomMetrics: enableCustomMetrics,
|
||||||
configureHairpinMode: hairpinMode,
|
configureHairpinMode: hairpinMode,
|
||||||
imageStatsProvider: &imageStatsProvider{client},
|
imageStatsProvider: &imageStatsProvider{client},
|
||||||
|
seccompProfileRoot: seccompProfileRoot,
|
||||||
}
|
}
|
||||||
dm.runner = lifecycle.NewHandlerRunner(httpClient, dm, dm)
|
dm.runner = lifecycle.NewHandlerRunner(httpClient, dm, dm)
|
||||||
if serializeImagePulls {
|
if serializeImagePulls {
|
||||||
@ -552,7 +558,7 @@ func (dm *DockerManager) runContainer(
|
|||||||
ContainerName: container.Name,
|
ContainerName: container.Name,
|
||||||
}
|
}
|
||||||
|
|
||||||
securityOpts, err := dm.getDefaultSecurityOpt()
|
securityOpts, err := dm.getSecurityOpt(pod, container.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return kubecontainer.ContainerID{}, err
|
return kubecontainer.ContainerID{}, err
|
||||||
}
|
}
|
||||||
@ -971,20 +977,57 @@ func (dm *DockerManager) checkVersionCompatibility() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dm *DockerManager) getDefaultSecurityOpt() ([]string, error) {
|
func (dm *DockerManager) getSecurityOpt(pod *api.Pod, ctrName string) ([]string, error) {
|
||||||
version, err := dm.APIVersion()
|
version, err := dm.APIVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// seccomp is to be disabled on docker versions >= v1.10
|
|
||||||
|
// seccomp is only on docker versions >= v1.10
|
||||||
result, err := version.Compare(dockerV110APIVersion)
|
result, err := version.Compare(dockerV110APIVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if result >= 0 {
|
if result < 0 {
|
||||||
|
// return early for old versions
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
profile, profileOK := pod.ObjectMeta.Annotations["security.alpha.kubernetes.io/seccomp/container/"+ctrName]
|
||||||
|
if !profileOK {
|
||||||
|
// try the pod profile
|
||||||
|
profile, profileOK = pod.ObjectMeta.Annotations["security.alpha.kubernetes.io/seccomp/pod"]
|
||||||
|
if !profileOK {
|
||||||
|
// return early the default
|
||||||
|
return defaultSecurityOpt, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if profile == "unconfined" {
|
||||||
|
// return early the default
|
||||||
return defaultSecurityOpt, nil
|
return defaultSecurityOpt, nil
|
||||||
}
|
}
|
||||||
return nil, nil
|
|
||||||
|
if profile == "docker/default" {
|
||||||
|
// return nil so docker will load the default seccomp profile
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.HasPrefix(profile, "localhost") {
|
||||||
|
return nil, fmt.Errorf("unknown seccomp profile option: %s", profile)
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := ioutil.ReadFile(filepath.Join(dm.seccompProfileRoot, strings.TrimPrefix(profile, "localhost/")))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
b := bytes.NewBuffer(nil)
|
||||||
|
if err := json.Compact(b, file); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return []string{fmt.Sprintf("seccomp=%s", b.Bytes())}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type dockerExitError struct {
|
type dockerExitError struct {
|
||||||
|
@ -1714,7 +1714,7 @@ func verifySyncResults(t *testing.T, expectedResults []*kubecontainer.SyncResult
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSeccompIsDisabledWithDockerV110(t *testing.T) {
|
func TestSeccompIsUnconfinedByDefaultWithDockerV110(t *testing.T) {
|
||||||
dm, fakeDocker := newTestDockerManagerWithVersion("1.10.1", "1.22")
|
dm, fakeDocker := newTestDockerManagerWithVersion("1.10.1", "1.22")
|
||||||
pod := &api.Pod{
|
pod := &api.Pod{
|
||||||
ObjectMeta: api.ObjectMeta{
|
ObjectMeta: api.ObjectMeta{
|
||||||
@ -1750,7 +1750,134 @@ func TestSeccompIsDisabledWithDockerV110(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error %v", err)
|
t.Fatalf("unexpected error %v", err)
|
||||||
}
|
}
|
||||||
assert.Contains(t, newContainer.HostConfig.SecurityOpt, "seccomp:unconfined", "Pods with Docker versions >= 1.10 must have seccomp disabled.")
|
assert.Contains(t, newContainer.HostConfig.SecurityOpt, "seccomp:unconfined", "Pods with Docker versions >= 1.10 must not have seccomp disabled by default")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnconfinedSeccompProfileWithDockerV110(t *testing.T) {
|
||||||
|
dm, fakeDocker := newTestDockerManagerWithVersion("1.10.1", "1.22")
|
||||||
|
pod := &api.Pod{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
UID: "12345678",
|
||||||
|
Name: "foo4",
|
||||||
|
Namespace: "new",
|
||||||
|
Annotations: map[string]string{
|
||||||
|
"security.alpha.kubernetes.io/seccomp/pod": "unconfined",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: api.PodSpec{
|
||||||
|
Containers: []api.Container{
|
||||||
|
{Name: "bar4"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
runSyncPod(t, dm, fakeDocker, pod, nil, false)
|
||||||
|
|
||||||
|
verifyCalls(t, fakeDocker, []string{
|
||||||
|
// Create pod infra container.
|
||||||
|
"create", "start", "inspect_container", "inspect_container",
|
||||||
|
// Create container.
|
||||||
|
"create", "start", "inspect_container",
|
||||||
|
})
|
||||||
|
|
||||||
|
fakeDocker.Lock()
|
||||||
|
if len(fakeDocker.Created) != 2 ||
|
||||||
|
!matchString(t, "/k8s_POD\\.[a-f0-9]+_foo4_new_", fakeDocker.Created[0]) ||
|
||||||
|
!matchString(t, "/k8s_bar4\\.[a-f0-9]+_foo4_new_", fakeDocker.Created[1]) {
|
||||||
|
t.Errorf("unexpected containers created %v", fakeDocker.Created)
|
||||||
|
}
|
||||||
|
fakeDocker.Unlock()
|
||||||
|
|
||||||
|
newContainer, err := fakeDocker.InspectContainer(fakeDocker.Created[1])
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error %v", err)
|
||||||
|
}
|
||||||
|
assert.Contains(t, newContainer.HostConfig.SecurityOpt, "seccomp:unconfined", "Pods created with a secccomp annotation of unconfined should have seccomp:unconfined.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDefaultSeccompProfileWithDockerV110(t *testing.T) {
|
||||||
|
dm, fakeDocker := newTestDockerManagerWithVersion("1.10.1", "1.22")
|
||||||
|
pod := &api.Pod{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
UID: "12345678",
|
||||||
|
Name: "foo1",
|
||||||
|
Namespace: "new",
|
||||||
|
Annotations: map[string]string{
|
||||||
|
"security.alpha.kubernetes.io/seccomp/pod": "docker/default",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: api.PodSpec{
|
||||||
|
Containers: []api.Container{
|
||||||
|
{Name: "bar1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
runSyncPod(t, dm, fakeDocker, pod, nil, false)
|
||||||
|
|
||||||
|
verifyCalls(t, fakeDocker, []string{
|
||||||
|
// Create pod infra container.
|
||||||
|
"create", "start", "inspect_container", "inspect_container",
|
||||||
|
// Create container.
|
||||||
|
"create", "start", "inspect_container",
|
||||||
|
})
|
||||||
|
|
||||||
|
fakeDocker.Lock()
|
||||||
|
if len(fakeDocker.Created) != 2 ||
|
||||||
|
!matchString(t, "/k8s_POD\\.[a-f0-9]+_foo1_new_", fakeDocker.Created[0]) ||
|
||||||
|
!matchString(t, "/k8s_bar1\\.[a-f0-9]+_foo1_new_", fakeDocker.Created[1]) {
|
||||||
|
t.Errorf("unexpected containers created %v", fakeDocker.Created)
|
||||||
|
}
|
||||||
|
fakeDocker.Unlock()
|
||||||
|
|
||||||
|
newContainer, err := fakeDocker.InspectContainer(fakeDocker.Created[1])
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error %v", err)
|
||||||
|
}
|
||||||
|
assert.NotContains(t, newContainer.HostConfig.SecurityOpt, "seccomp:unconfined", "Pods created with a secccomp annotation of docker/default should have empty security opt.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSeccompContainerAnnotationTrumpsPod(t *testing.T) {
|
||||||
|
dm, fakeDocker := newTestDockerManagerWithVersion("1.10.1", "1.22")
|
||||||
|
pod := &api.Pod{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
UID: "12345678",
|
||||||
|
Name: "foo2",
|
||||||
|
Namespace: "new",
|
||||||
|
Annotations: map[string]string{
|
||||||
|
"security.alpha.kubernetes.io/seccomp/pod": "unconfined",
|
||||||
|
"security.alpha.kubernetes.io/seccomp/container/bar2": "docker/default",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: api.PodSpec{
|
||||||
|
Containers: []api.Container{
|
||||||
|
{Name: "bar2"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
runSyncPod(t, dm, fakeDocker, pod, nil, false)
|
||||||
|
|
||||||
|
verifyCalls(t, fakeDocker, []string{
|
||||||
|
// Create pod infra container.
|
||||||
|
"create", "start", "inspect_container", "inspect_container",
|
||||||
|
// Create container.
|
||||||
|
"create", "start", "inspect_container",
|
||||||
|
})
|
||||||
|
|
||||||
|
fakeDocker.Lock()
|
||||||
|
if len(fakeDocker.Created) != 2 ||
|
||||||
|
!matchString(t, "/k8s_POD\\.[a-f0-9]+_foo2_new_", fakeDocker.Created[0]) ||
|
||||||
|
!matchString(t, "/k8s_bar2\\.[a-f0-9]+_foo2_new_", fakeDocker.Created[1]) {
|
||||||
|
t.Errorf("unexpected containers created %v", fakeDocker.Created)
|
||||||
|
}
|
||||||
|
fakeDocker.Unlock()
|
||||||
|
|
||||||
|
newContainer, err := fakeDocker.InspectContainer(fakeDocker.Created[1])
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error %v", err)
|
||||||
|
}
|
||||||
|
assert.NotContains(t, newContainer.HostConfig.SecurityOpt, "seccomp:unconfined", "Container annotation should trump the pod annotation for seccomp.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSecurityOptsAreNilWithDockerV19(t *testing.T) {
|
func TestSecurityOptsAreNilWithDockerV19(t *testing.T) {
|
||||||
|
@ -177,6 +177,7 @@ func NewMainKubelet(
|
|||||||
dockerClient dockertools.DockerInterface,
|
dockerClient dockertools.DockerInterface,
|
||||||
kubeClient clientset.Interface,
|
kubeClient clientset.Interface,
|
||||||
rootDirectory string,
|
rootDirectory string,
|
||||||
|
seccompProfileRoot string,
|
||||||
podInfraContainerImage string,
|
podInfraContainerImage string,
|
||||||
resyncInterval time.Duration,
|
resyncInterval time.Duration,
|
||||||
pullQPS float32,
|
pullQPS float32,
|
||||||
@ -423,6 +424,7 @@ func NewMainKubelet(
|
|||||||
serializeImagePulls,
|
serializeImagePulls,
|
||||||
enableCustomMetrics,
|
enableCustomMetrics,
|
||||||
klet.hairpinMode == componentconfig.HairpinVeth,
|
klet.hairpinMode == componentconfig.HairpinVeth,
|
||||||
|
seccompProfileRoot,
|
||||||
containerRuntimeOptions...,
|
containerRuntimeOptions...,
|
||||||
)
|
)
|
||||||
case "rkt":
|
case "rkt":
|
||||||
|
@ -47,7 +47,7 @@ func dockerRuntime() kubecontainer.Runtime {
|
|||||||
nil, nil, nil, pm, nil,
|
nil, nil, nil, pm, nil,
|
||||||
"", 0, 0, "",
|
"", 0, 0, "",
|
||||||
nil, nil, nil, nil, nil, nil, nil,
|
nil, nil, nil, nil, nil, nil, nil,
|
||||||
false, nil, true, false, false,
|
false, nil, true, false, false, "",
|
||||||
)
|
)
|
||||||
|
|
||||||
return dm
|
return dm
|
||||||
|
Loading…
Reference in New Issue
Block a user