Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions pkg/kubelet/rkt/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
24 changes: 24 additions & 0 deletions pkg/kubelet/rkt/rkt.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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))
Expand Down
51 changes: 51 additions & 0 deletions pkg/kubelet/rkt/rkt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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))
}
}
}