Provide a way to setup the limit NO files for rkt Pods

This commit is contained in:
JulienBalestra 2017-06-17 12:43:15 +02:00
parent 5eccc7ae80
commit 9f37efcf7e
3 changed files with 76 additions and 0 deletions

View File

@ -82,6 +82,7 @@ go_test(
"//vendor/github.com/appc/spec/schema:go_default_library",
"//vendor/github.com/appc/spec/schema/types:go_default_library",
"//vendor/github.com/coreos/go-systemd/dbus:go_default_library",
"//vendor/github.com/coreos/go-systemd/unit:go_default_library",
"//vendor/github.com/coreos/rkt/api/v1alpha:go_default_library",
"//vendor/github.com/golang/mock/gomock:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library",

View File

@ -95,6 +95,8 @@ const (
k8sRktRestartCountAnno = "rkt.kubernetes.io/restart-count"
k8sRktTerminationMessagePathAnno = "rkt.kubernetes.io/termination-message-path"
k8sRktLimitNoFileAnno = "systemd-unit-option.rkt.kubernetes.io/LimitNOFILE"
// TODO(euank): This has significant security concerns as a stage1 image is
// effectively root.
// Furthermore, this (using an annotation) is a hack to pass an extra
@ -1148,6 +1150,23 @@ func constructSyslogIdentifier(generateName string, podName string) string {
return podName
}
// Setup additional systemd field specified in the Pod Annotation
func setupSystemdCustomFields(annotations map[string]string, unitOptionArray []*unit.UnitOption) ([]*unit.UnitOption, error) {
// LimitNOFILE
if strSize := annotations[k8sRktLimitNoFileAnno]; strSize != "" {
size, err := strconv.Atoi(strSize)
if err != nil {
return unitOptionArray, err
}
if size < 1 {
return unitOptionArray, fmt.Errorf("invalid value for %s: %s", k8sRktLimitNoFileAnno, strSize)
}
unitOptionArray = append(unitOptionArray, newUnitOption("Service", "LimitNOFILE", strSize))
}
return unitOptionArray, nil
}
// preparePod will:
//
// 1. Invoke 'rkt prepare' to prepare the pod, and get the rkt pod uuid.
@ -1235,6 +1254,11 @@ func (r *Runtime) preparePod(pod *v1.Pod, podIP string, pullSecrets []v1.Secret,
units = append(units, newUnitOption("Service", "SELinuxContext", selinuxContext))
}
units, err = setupSystemdCustomFields(pod.Annotations, units)
if err != nil {
glog.Warningf("fail to add custom systemd fields provided by pod Annotations: %q", err)
}
serviceName := makePodServiceFileName(uuid)
glog.V(4).Infof("rkt: Creating service file %q for pod %q", serviceName, format.Pod(pod))
serviceFile, err := r.os.Create(serviceFilePath(serviceName))

View File

@ -28,6 +28,7 @@ import (
appcschema "github.com/appc/spec/schema"
appctypes "github.com/appc/spec/schema/types"
"github.com/coreos/go-systemd/unit"
rktapi "github.com/coreos/rkt/api/v1alpha"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
@ -2075,3 +2076,53 @@ func TestGetPodSystemdServiceFiles(t *testing.T) {
}
}
}
func TestSetupSystemdCustomFields(t *testing.T) {
testCases := []struct {
unitOpts []*unit.UnitOption
podAnnotations map[string]string
expectedValues []string
raiseErr bool
}{
// without annotation
{
[]*unit.UnitOption{
{Section: "Service", Name: "ExecStart", Value: "/bin/true"},
},
map[string]string{},
[]string{"/bin/true"},
false,
},
// with valid annotation for LimitNOFile
{
[]*unit.UnitOption{
{Section: "Service", Name: "ExecStart", Value: "/bin/true"},
},
map[string]string{k8sRktLimitNoFileAnno: "1024"},
[]string{"/bin/true", "1024"},
false,
},
// with invalid annotation for LimitNOFile
{
[]*unit.UnitOption{
{Section: "Service", Name: "ExecStart", Value: "/bin/true"},
},
map[string]string{k8sRktLimitNoFileAnno: "-1"},
[]string{"/bin/true"},
true,
},
}
for i, tt := range testCases {
raiseErr := false
newUnitsOpts, err := setupSystemdCustomFields(tt.podAnnotations, tt.unitOpts)
if err != nil {
raiseErr = true
}
assert.Equal(t, tt.raiseErr, raiseErr, fmt.Sprintf("Test case #%d", i))
for _, opt := range newUnitsOpts {
assert.Equal(t, "Service", opt.Section, fmt.Sprintf("Test case #%d", i))
assert.Contains(t, tt.expectedValues, opt.Value, fmt.Sprintf("Test case #%d", i))
}
}
}