Merge pull request #206 from Crazykev/add-sysctls
Add support for sysctls
This commit is contained in:
commit
19b11293f6
4 changed files with 116 additions and 1 deletions
|
@ -188,6 +188,18 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest
|
|||
g.AddAnnotation(k, v)
|
||||
}
|
||||
|
||||
// extract linux sysctls from annotations and pass down to oci runtime
|
||||
safe, unsafe, err := SysctlsFromPodAnnotations(annotations)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, sysctl := range safe {
|
||||
g.AddLinuxSysctl(sysctl.Name, sysctl.Value)
|
||||
}
|
||||
for _, sysctl := range unsafe {
|
||||
g.AddLinuxSysctl(sysctl.Name, sysctl.Value)
|
||||
}
|
||||
|
||||
// setup cgroup settings
|
||||
cgroupParent := req.GetConfig().GetLinux().GetCgroupParent()
|
||||
if cgroupParent != "" {
|
||||
|
|
|
@ -95,3 +95,64 @@ func parseDNSOptions(servers, searches, options []string, path string) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: remove sysctl extraction related code here, instead we import from k8s directly.
|
||||
|
||||
const (
|
||||
// SysctlsPodAnnotationKey represents the key of sysctls which are set for the infrastructure
|
||||
// container of a pod. The annotation value is a comma separated list of sysctl_name=value
|
||||
// key-value pairs. Only a limited set of whitelisted and isolated sysctls is supported by
|
||||
// the kubelet. Pods with other sysctls will fail to launch.
|
||||
SysctlsPodAnnotationKey string = "security.alpha.kubernetes.io/sysctls"
|
||||
|
||||
// UnsafeSysctlsPodAnnotationKey represents the key of sysctls which are set for the infrastructure
|
||||
// container of a pod. The annotation value is a comma separated list of sysctl_name=value
|
||||
// key-value pairs. Unsafe sysctls must be explicitly enabled for a kubelet. They are properly
|
||||
// namespaced to a pod or a container, but their isolation is usually unclear or weak. Their use
|
||||
// is at-your-own-risk. Pods that attempt to set an unsafe sysctl that is not enabled for a kubelet
|
||||
// will fail to launch.
|
||||
UnsafeSysctlsPodAnnotationKey string = "security.alpha.kubernetes.io/unsafe-sysctls"
|
||||
)
|
||||
|
||||
// Sysctl defines a kernel parameter to be set
|
||||
type Sysctl struct {
|
||||
// Name of a property to set
|
||||
Name string `json:"name"`
|
||||
// Value of a property to set
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// SysctlsFromPodAnnotations parses the sysctl annotations into a slice of safe Sysctls
|
||||
// and a slice of unsafe Sysctls. This is only a convenience wrapper around
|
||||
// SysctlsFromPodAnnotation.
|
||||
func SysctlsFromPodAnnotations(a map[string]string) ([]Sysctl, []Sysctl, error) {
|
||||
safe, err := SysctlsFromPodAnnotation(a[SysctlsPodAnnotationKey])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
unsafe, err := SysctlsFromPodAnnotation(a[UnsafeSysctlsPodAnnotationKey])
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return safe, unsafe, nil
|
||||
}
|
||||
|
||||
// SysctlsFromPodAnnotation parses an annotation value into a slice of Sysctls.
|
||||
func SysctlsFromPodAnnotation(annotation string) ([]Sysctl, error) {
|
||||
if len(annotation) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
kvs := strings.Split(annotation, ",")
|
||||
sysctls := make([]Sysctl, len(kvs))
|
||||
for i, kv := range kvs {
|
||||
cs := strings.Split(kv, "=")
|
||||
if len(cs) != 2 || len(cs[0]) == 0 {
|
||||
return nil, fmt.Errorf("sysctl %q not of the format sysctl_name=value", kv)
|
||||
}
|
||||
sysctls[i].Name = cs[0]
|
||||
sysctls[i].Value = cs[1]
|
||||
}
|
||||
return sysctls, nil
|
||||
}
|
||||
|
|
|
@ -187,3 +187,43 @@ function teardown() {
|
|||
cleanup_pods
|
||||
stop_ocid
|
||||
}
|
||||
|
||||
@test "pass pod sysctls to runtime" {
|
||||
# this test requires docker, thus it can't yet be run in a container
|
||||
if [ "$TRAVIS" = "true" ]; then # instead of $TRAVIS, add a function is_containerized to skip here
|
||||
skip "cannot yet run this test in a container, use sudo make localintegration"
|
||||
fi
|
||||
|
||||
start_ocid
|
||||
run ocic pod create --config "$TESTDATA"/sandbox_config.json
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
pod_id="$output"
|
||||
|
||||
run ocic ctr create --pod "$pod_id" --config "$TESTDATA"/container_redis.json
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
container_id="$output"
|
||||
|
||||
run ocic ctr start --id "$container_id"
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run ocic ctr execsync --id "$container_id" sysctl kernel.shm_rmid_forced
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "kernel.shm_rmid_forced = 1" ]]
|
||||
|
||||
run ocic ctr execsync --id "$container_id" sysctl kernel.msgmax
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "kernel.msgmax = 8192" ]]
|
||||
|
||||
run ocic ctr execsync --id "$container_id" sysctl net.ipv4.ip_local_port_range
|
||||
echo "$output"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "net.ipv4.ip_local_port_range = 1024 65000" ]]
|
||||
|
||||
cleanup_pods
|
||||
stop_ocid
|
||||
}
|
||||
|
|
4
test/testdata/sandbox_config.json
vendored
4
test/testdata/sandbox_config.json
vendored
|
@ -46,7 +46,9 @@
|
|||
"group": "test"
|
||||
},
|
||||
"annotations": {
|
||||
"owner": "hmeng"
|
||||
"owner": "hmeng",
|
||||
"security.alpha.kubernetes.io/sysctls": "kernel.shm_rmid_forced=1,net.ipv4.ip_local_port_range=1024 65000",
|
||||
"security.alpha.kubernetes.io/unsafe-sysctls": "kernel.msgmax=8192"
|
||||
},
|
||||
"linux": {
|
||||
"cgroup_parent": "podsandbox1.slice:container:infra",
|
||||
|
|
Loading…
Reference in a new issue