mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-10 20:42:26 +00:00
use sysctl utils to do pod spec validation
Signed-off-by: Paco Xu <paco.xu@daocloud.io>
This commit is contained in:
parent
11de9543ee
commit
9a8ccdebc5
@ -44,6 +44,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
utilsysctl "k8s.io/component-helpers/node/util/sysctl"
|
||||
schedulinghelper "k8s.io/component-helpers/scheduling/corev1"
|
||||
kubeletapis "k8s.io/kubelet/pkg/apis"
|
||||
apiservice "k8s.io/kubernetes/pkg/api/service"
|
||||
@ -4575,11 +4576,8 @@ func validateSysctls(sysctls []core.Sysctl, fldPath *field.Path, hostNetwork, ho
|
||||
}
|
||||
// The parameters hostNet and hostIPC are used to forbid sysctls for pod sharing the
|
||||
// respective namespaces with the host.
|
||||
if hostNetwork && strings.HasPrefix(s.Name, "net") {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("name"), s.Name, "sysctl not allowed with host net enabled"))
|
||||
}
|
||||
if hostIPC && strings.HasPrefix(s.Name, "ipc") {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("name"), s.Name, "sysctl not allowed with host ipc enabled"))
|
||||
if !isValidSysctlWithHostNetIPC(s.Name, hostNetwork, hostIPC) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Index(i).Child("name"), s.Name, "sysctl not allowed with host net/ipc enabled"))
|
||||
}
|
||||
|
||||
names[s.Name] = struct{}{}
|
||||
@ -4587,6 +4585,32 @@ func validateSysctls(sysctls []core.Sysctl, fldPath *field.Path, hostNetwork, ho
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func isValidSysctlWithHostNetIPC(sysctl string, hostNet, hostIPC bool) bool {
|
||||
sysctl = utilsysctl.ConvertSysctlVariableToDotsSeparator(sysctl)
|
||||
var ns utilsysctl.Namespace
|
||||
if strings.HasSuffix(sysctl, "*") {
|
||||
prefix := sysctl[:len(sysctl)-1]
|
||||
ns = utilsysctl.NamespacedBy(prefix)
|
||||
if ns == utilsysctl.UnknownNamespace {
|
||||
// don't handle unknown namespace here
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
ns = utilsysctl.NamespacedBy(sysctl)
|
||||
if ns == utilsysctl.UnknownNamespace {
|
||||
// don't handle unknown namespace here
|
||||
return true
|
||||
}
|
||||
}
|
||||
if ns == utilsysctl.IpcNamespace && hostIPC {
|
||||
return false
|
||||
}
|
||||
if ns == utilsysctl.NetNamespace && hostNet {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// validatePodSpecSecurityContext verifies the SecurityContext of a PodSpec,
|
||||
// whether that is defined in a Pod or in an embedded PodSpec (e.g. a
|
||||
// Deployment's pod template).
|
||||
|
@ -21491,6 +21491,16 @@ func TestValidateSysctls(t *testing.T) {
|
||||
"_invalid",
|
||||
}
|
||||
|
||||
invalidWithHostNet := []string{
|
||||
"net.ipv4.conf.enp3s0/200.forwarding",
|
||||
"net/ipv4/conf/enp3s0.200/forwarding",
|
||||
}
|
||||
|
||||
invalidWithHostIPC := []string{
|
||||
"kernel.shmmax",
|
||||
"kernel.msgmax",
|
||||
}
|
||||
|
||||
duplicates := []string{
|
||||
"kernel.shmmax",
|
||||
"kernel.shmmax",
|
||||
@ -21500,7 +21510,7 @@ func TestValidateSysctls(t *testing.T) {
|
||||
for i, sysctl := range valid {
|
||||
sysctls[i].Name = sysctl
|
||||
}
|
||||
errs := validateSysctls(sysctls, field.NewPath("foo"))
|
||||
errs := validateSysctls(sysctls, field.NewPath("foo"), false, false)
|
||||
if len(errs) != 0 {
|
||||
t.Errorf("unexpected validation errors: %v", errs)
|
||||
}
|
||||
@ -21509,7 +21519,7 @@ func TestValidateSysctls(t *testing.T) {
|
||||
for i, sysctl := range invalid {
|
||||
sysctls[i].Name = sysctl
|
||||
}
|
||||
errs = validateSysctls(sysctls, field.NewPath("foo"))
|
||||
errs = validateSysctls(sysctls, field.NewPath("foo"), false, false)
|
||||
if len(errs) != 2 {
|
||||
t.Errorf("expected 2 validation errors. Got: %v", errs)
|
||||
} else {
|
||||
@ -21525,12 +21535,30 @@ func TestValidateSysctls(t *testing.T) {
|
||||
for i, sysctl := range duplicates {
|
||||
sysctls[i].Name = sysctl
|
||||
}
|
||||
errs = validateSysctls(sysctls, field.NewPath("foo"))
|
||||
errs = validateSysctls(sysctls, field.NewPath("foo"), false, false)
|
||||
if len(errs) != 1 {
|
||||
t.Errorf("unexpected validation errors: %v", errs)
|
||||
} else if errs[0].Type != field.ErrorTypeDuplicate {
|
||||
t.Errorf("expected error type %v, got %v", field.ErrorTypeDuplicate, errs[0].Type)
|
||||
}
|
||||
|
||||
sysctls = make([]core.Sysctl, len(invalidWithHostNet))
|
||||
for i, sysctl := range invalidWithHostNet {
|
||||
sysctls[i].Name = sysctl
|
||||
}
|
||||
errs = validateSysctls(sysctls, field.NewPath("foo"), true, false)
|
||||
if len(errs) != 2 {
|
||||
t.Errorf("unexpected validation errors: %v", errs)
|
||||
}
|
||||
|
||||
sysctls = make([]core.Sysctl, len(invalidWithHostIPC))
|
||||
for i, sysctl := range invalidWithHostIPC {
|
||||
sysctls[i].Name = sysctl
|
||||
}
|
||||
errs = validateSysctls(sysctls, field.NewPath("foo"), false, true)
|
||||
if len(errs) != 2 {
|
||||
t.Errorf("unexpected validation errors: %v", errs)
|
||||
}
|
||||
}
|
||||
|
||||
func newNodeNameEndpoint(nodeName string) *core.Endpoints {
|
||||
|
@ -6,6 +6,7 @@ go 1.21.3
|
||||
|
||||
require (
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
k8s.io/api v0.0.0
|
||||
k8s.io/apimachinery v0.0.0
|
||||
k8s.io/client-go v0.0.0
|
||||
@ -33,6 +34,7 @@ require (
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/oauth2 v0.10.0 // indirect
|
||||
golang.org/x/sys v0.13.0 // indirect
|
||||
|
@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@ -13,11 +13,13 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package sysctl
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// TestConvertSysctlVariableToDotsSeparator tests whether the sysctl variable
|
||||
|
Loading…
Reference in New Issue
Block a user