mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-13 11:25:19 +00:00
Include security options in the container created event
This commit is contained in:
@@ -18,6 +18,7 @@ package dockertools
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -111,7 +112,7 @@ var (
|
||||
podInfraContainerImagePullPolicy = api.PullIfNotPresent
|
||||
|
||||
// Default set of seccomp security options.
|
||||
defaultSeccompOpt = []dockerOpt{{"seccomp", "unconfined"}}
|
||||
defaultSeccompOpt = []dockerOpt{{"seccomp", "unconfined", ""}}
|
||||
)
|
||||
|
||||
type DockerManager struct {
|
||||
@@ -579,6 +580,10 @@ func (dm *DockerManager) runContainer(
|
||||
if err != nil {
|
||||
return kubecontainer.ContainerID{}, err
|
||||
}
|
||||
fmtSecurityOpts, err := dm.fmtDockerOpts(securityOpts)
|
||||
if err != nil {
|
||||
return kubecontainer.ContainerID{}, err
|
||||
}
|
||||
|
||||
// Pod information is recorded on the container as labels to preserve it in the event the pod is deleted
|
||||
// while the Kubelet is down and there is no information available to recover the pod.
|
||||
@@ -658,7 +663,7 @@ func (dm *DockerManager) runContainer(
|
||||
CPUShares: cpuShares,
|
||||
Devices: devices,
|
||||
},
|
||||
SecurityOpt: securityOpts,
|
||||
SecurityOpt: fmtSecurityOpts,
|
||||
}
|
||||
|
||||
// Set sysctls if requested
|
||||
@@ -733,7 +738,21 @@ func (dm *DockerManager) runContainer(
|
||||
if len(createResp.Warnings) != 0 {
|
||||
glog.V(2).Infof("Container %q of pod %q created with warnings: %v", container.Name, format.Pod(pod), createResp.Warnings)
|
||||
}
|
||||
dm.recorder.Eventf(ref, api.EventTypeNormal, events.CreatedContainer, "Created container with docker id %v", utilstrings.ShortenString(createResp.ID, 12))
|
||||
|
||||
createdEventMsg := fmt.Sprintf("Created container with docker id %v", utilstrings.ShortenString(createResp.ID, 12))
|
||||
if len(securityOpts) > 0 {
|
||||
var msgs []string
|
||||
for _, opt := range securityOpts {
|
||||
glog.Errorf("Logging security options: %+v", opt)
|
||||
msg := opt.msg
|
||||
if msg == "" {
|
||||
msg = opt.value
|
||||
}
|
||||
msgs = append(msgs, fmt.Sprintf("%s=%s", opt.key, truncateMsg(msg, 256)))
|
||||
}
|
||||
createdEventMsg = fmt.Sprintf("%s; Security:[%s]", createdEventMsg, strings.Join(msgs, " "))
|
||||
}
|
||||
dm.recorder.Eventf(ref, api.EventTypeNormal, events.CreatedContainer, createdEventMsg)
|
||||
|
||||
if err = dm.client.StartContainer(createResp.ID); err != nil {
|
||||
dm.recorder.Eventf(ref, api.EventTypeWarning, events.FailedToStartContainer,
|
||||
@@ -1056,25 +1075,12 @@ func (dm *DockerManager) checkVersionCompatibility() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dm *DockerManager) getSecurityOpts(pod *api.Pod, ctrName string) ([]string, error) {
|
||||
func (dm *DockerManager) fmtDockerOpts(opts []dockerOpt) ([]string, error) {
|
||||
version, err := dm.APIVersion()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var securityOpts []dockerOpt
|
||||
if seccompOpts, err := dm.getSeccompOpts(pod, ctrName, version); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
securityOpts = append(securityOpts, seccompOpts...)
|
||||
}
|
||||
|
||||
if appArmorOpts, err := dm.getAppArmorOpts(pod, ctrName); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
securityOpts = append(securityOpts, appArmorOpts...)
|
||||
}
|
||||
|
||||
const (
|
||||
// Docker changed the API for specifying options in v1.11
|
||||
optSeparatorChangeVersion = "1.23" // Corresponds to docker 1.11.x
|
||||
@@ -1089,19 +1095,44 @@ func (dm *DockerManager) getSecurityOpts(pod *api.Pod, ctrName string) ([]string
|
||||
sep = optSeparatorOld
|
||||
}
|
||||
|
||||
opts := make([]string, len(securityOpts))
|
||||
for i, opt := range securityOpts {
|
||||
opts[i] = fmt.Sprintf("%s%c%s", opt.key, sep, opt.value)
|
||||
fmtOpts := make([]string, len(opts))
|
||||
for i, opt := range opts {
|
||||
fmtOpts[i] = fmt.Sprintf("%s%c%s", opt.key, sep, opt.value)
|
||||
}
|
||||
return opts, nil
|
||||
return fmtOpts, nil
|
||||
}
|
||||
|
||||
func (dm *DockerManager) getSecurityOpts(pod *api.Pod, ctrName string) ([]dockerOpt, error) {
|
||||
var securityOpts []dockerOpt
|
||||
if seccompOpts, err := dm.getSeccompOpts(pod, ctrName); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
securityOpts = append(securityOpts, seccompOpts...)
|
||||
}
|
||||
|
||||
if appArmorOpts, err := dm.getAppArmorOpts(pod, ctrName); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
securityOpts = append(securityOpts, appArmorOpts...)
|
||||
}
|
||||
|
||||
return securityOpts, nil
|
||||
}
|
||||
|
||||
type dockerOpt struct {
|
||||
// The key-value pair passed to docker.
|
||||
key, value string
|
||||
// The alternative value to use in log/event messages.
|
||||
msg string
|
||||
}
|
||||
|
||||
// Get the docker security options for seccomp.
|
||||
func (dm *DockerManager) getSeccompOpts(pod *api.Pod, ctrName string, version kubecontainer.Version) ([]dockerOpt, error) {
|
||||
func (dm *DockerManager) getSeccompOpts(pod *api.Pod, ctrName string) ([]dockerOpt, error) {
|
||||
version, err := dm.APIVersion()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// seccomp is only on docker versions >= v1.10
|
||||
if result, err := version.Compare(dockerV110APIVersion); err != nil {
|
||||
return nil, err
|
||||
@@ -1144,8 +1175,10 @@ func (dm *DockerManager) getSeccompOpts(pod *api.Pod, ctrName string, version ku
|
||||
if err := json.Compact(b, file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Rather than the full profile, just put the filename & md5sum in the event log.
|
||||
msg := fmt.Sprintf("%s(md5:%x)", name, md5.Sum(file))
|
||||
|
||||
return []dockerOpt{{"seccomp", b.String()}}, nil
|
||||
return []dockerOpt{{"seccomp", b.String(), msg}}, nil
|
||||
}
|
||||
|
||||
// Get the docker security options for AppArmor.
|
||||
@@ -1158,7 +1191,7 @@ func (dm *DockerManager) getAppArmorOpts(pod *api.Pod, ctrName string) ([]docker
|
||||
|
||||
// Assume validation has already happened.
|
||||
profileName := strings.TrimPrefix(profile, apparmor.ProfileNamePrefix)
|
||||
return []dockerOpt{{"apparmor", profileName}}, nil
|
||||
return []dockerOpt{{"apparmor", profileName, ""}}, nil
|
||||
}
|
||||
|
||||
type dockerExitError struct {
|
||||
@@ -2557,3 +2590,15 @@ func (dm *DockerManager) getVersionInfo() (versionInfo, error) {
|
||||
daemonVersion: daemonVersion,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Truncate the message if it exceeds max length.
|
||||
func truncateMsg(msg string, max int) string {
|
||||
if len(msg) <= max {
|
||||
return msg
|
||||
}
|
||||
glog.V(2).Infof("Truncated %s", msg)
|
||||
const truncatedMsg = "..TRUNCATED.."
|
||||
begin := (max - len(truncatedMsg)) / 2
|
||||
end := len(msg) - (max - (len(truncatedMsg) + begin))
|
||||
return msg[:begin] + truncatedMsg + msg[end:]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user