mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 22:46:12 +00:00
Merge pull request #29356 from smarterclayton/init_containers
Automatic merge from submit-queue LimitRanger and PodSecurityPolicy need to check more on init containers Container limits not applied to init containers. HostPorts not checked on podsecuritypolicy @pweil- @derekwaynecarr
This commit is contained in:
commit
3301f6d14f
@ -250,6 +250,12 @@ func (s *simpleProvider) ValidateContainerSecurityContext(pod *api.Pod, containe
|
|||||||
allErrs = append(allErrs, s.hasInvalidHostPort(&c, idxPath)...)
|
allErrs = append(allErrs, s.hasInvalidHostPort(&c, idxPath)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
containersPath = fldPath.Child("initContainers")
|
||||||
|
for idx, c := range pod.Spec.InitContainers {
|
||||||
|
idxPath := containersPath.Index(idx)
|
||||||
|
allErrs = append(allErrs, s.hasInvalidHostPort(&c, idxPath)...)
|
||||||
|
}
|
||||||
|
|
||||||
if !s.psp.Spec.HostPID && pod.Spec.SecurityContext.HostPID {
|
if !s.psp.Spec.HostPID && pod.Spec.SecurityContext.HostPID {
|
||||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("hostPID"), pod.Spec.SecurityContext.HostPID, "Host PID is not allowed to be used"))
|
allErrs = append(allErrs, field.Invalid(fldPath.Child("hostPID"), pod.Spec.SecurityContext.HostPID, "Host PID is not allowed to be used"))
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ package initialresources
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
@ -89,9 +90,24 @@ func (ir initialResources) Admit(a admission.Attributes) (err error) {
|
|||||||
// The method veryfies whether resources should be set for the given pod and
|
// The method veryfies whether resources should be set for the given pod and
|
||||||
// if there is estimation available the method fills Request field.
|
// if there is estimation available the method fills Request field.
|
||||||
func (ir initialResources) estimateAndFillResourcesIfNotSet(pod *api.Pod) {
|
func (ir initialResources) estimateAndFillResourcesIfNotSet(pod *api.Pod) {
|
||||||
annotations := []string{}
|
var annotations []string
|
||||||
|
for i := range pod.Spec.InitContainers {
|
||||||
|
annotations = append(annotations, ir.estimateContainer(pod, &pod.Spec.InitContainers[i], "init container")...)
|
||||||
|
}
|
||||||
for i := range pod.Spec.Containers {
|
for i := range pod.Spec.Containers {
|
||||||
c := &pod.Spec.Containers[i]
|
annotations = append(annotations, ir.estimateContainer(pod, &pod.Spec.Containers[i], "container")...)
|
||||||
|
}
|
||||||
|
if len(annotations) > 0 {
|
||||||
|
if pod.ObjectMeta.Annotations == nil {
|
||||||
|
pod.ObjectMeta.Annotations = make(map[string]string)
|
||||||
|
}
|
||||||
|
val := "Initial Resources plugin set: " + strings.Join(annotations, "; ")
|
||||||
|
pod.ObjectMeta.Annotations[initialResourcesAnnotation] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ir initialResources) estimateContainer(pod *api.Pod, c *api.Container, message string) []string {
|
||||||
|
var annotations []string
|
||||||
req := c.Resources.Requests
|
req := c.Resources.Requests
|
||||||
lim := c.Resources.Limits
|
lim := c.Resources.Limits
|
||||||
var cpu, mem *resource.Quantity
|
var cpu, mem *resource.Quantity
|
||||||
@ -120,28 +136,21 @@ func (ir initialResources) estimateAndFillResourcesIfNotSet(pod *api.Pod) {
|
|||||||
}
|
}
|
||||||
setRes := []string{}
|
setRes := []string{}
|
||||||
if cpu != nil {
|
if cpu != nil {
|
||||||
glog.Infof("CPU estimation for container %v in pod %v/%v is %v", c.Name, pod.ObjectMeta.Namespace, pod.ObjectMeta.Name, cpu.String())
|
glog.Infof("CPU estimation for %s %v in pod %v/%v is %v", message, c.Name, pod.ObjectMeta.Namespace, pod.ObjectMeta.Name, cpu.String())
|
||||||
setRes = append(setRes, string(api.ResourceCPU))
|
setRes = append(setRes, string(api.ResourceCPU))
|
||||||
req[api.ResourceCPU] = *cpu
|
req[api.ResourceCPU] = *cpu
|
||||||
}
|
}
|
||||||
if mem != nil {
|
if mem != nil {
|
||||||
glog.Infof("Memory estimation for container %v in pod %v/%v is %v", c.Name, pod.ObjectMeta.Namespace, pod.ObjectMeta.Name, mem.String())
|
glog.Infof("Memory estimation for %s %v in pod %v/%v is %v", message, c.Name, pod.ObjectMeta.Namespace, pod.ObjectMeta.Name, mem.String())
|
||||||
setRes = append(setRes, string(api.ResourceMemory))
|
setRes = append(setRes, string(api.ResourceMemory))
|
||||||
req[api.ResourceMemory] = *mem
|
req[api.ResourceMemory] = *mem
|
||||||
}
|
}
|
||||||
if len(setRes) > 0 {
|
if len(setRes) > 0 {
|
||||||
sort.Strings(setRes)
|
sort.Strings(setRes)
|
||||||
a := strings.Join(setRes, ", ") + " request for container " + c.Name
|
a := strings.Join(setRes, ", ") + fmt.Sprintf(" request for %s %s", message, c.Name)
|
||||||
annotations = append(annotations, a)
|
annotations = append(annotations, a)
|
||||||
}
|
}
|
||||||
}
|
return annotations
|
||||||
if len(annotations) > 0 {
|
|
||||||
if pod.ObjectMeta.Annotations == nil {
|
|
||||||
pod.ObjectMeta.Annotations = make(map[string]string)
|
|
||||||
}
|
|
||||||
val := "Initial Resources plugin set: " + strings.Join(annotations, "; ")
|
|
||||||
pod.ObjectMeta.Annotations[initialResourcesAnnotation] = val
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ir initialResources) getEstimation(kind api.ResourceName, c *api.Container, ns string) (*resource.Quantity, error) {
|
func (ir initialResources) getEstimation(kind api.ResourceName, c *api.Container, ns string) (*resource.Quantity, error) {
|
||||||
|
@ -61,6 +61,9 @@ func createPod(name string, image string, request api.ResourceList) *api.Pod {
|
|||||||
Spec: api.PodSpec{},
|
Spec: api.PodSpec{},
|
||||||
}
|
}
|
||||||
pod.Spec.Containers = []api.Container{}
|
pod.Spec.Containers = []api.Container{}
|
||||||
|
addContainer(pod, "i0", image, request)
|
||||||
|
pod.Spec.InitContainers = pod.Spec.Containers
|
||||||
|
pod.Spec.Containers = []api.Container{}
|
||||||
addContainer(pod, "c0", image, request)
|
addContainer(pod, "c0", image, request)
|
||||||
return pod
|
return pod
|
||||||
}
|
}
|
||||||
@ -86,6 +89,7 @@ func verifyContainer(t *testing.T, c *api.Container, cpu, mem int64) {
|
|||||||
|
|
||||||
func verifyPod(t *testing.T, pod *api.Pod, cpu, mem int64) {
|
func verifyPod(t *testing.T, pod *api.Pod, cpu, mem int64) {
|
||||||
verifyContainer(t, &pod.Spec.Containers[0], cpu, mem)
|
verifyContainer(t, &pod.Spec.Containers[0], cpu, mem)
|
||||||
|
verifyContainer(t, &pod.Spec.InitContainers[0], cpu, mem)
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyAnnotation(t *testing.T, pod *api.Pod, expected string) {
|
func verifyAnnotation(t *testing.T, pod *api.Pod, expected string) {
|
||||||
@ -94,13 +98,13 @@ func verifyAnnotation(t *testing.T, pod *api.Pod, expected string) {
|
|||||||
t.Errorf("No annotation but expected %v", expected)
|
t.Errorf("No annotation but expected %v", expected)
|
||||||
}
|
}
|
||||||
if a != expected {
|
if a != expected {
|
||||||
t.Errorf("Wrong annatation set by Initial Resources: got %v, expected %v", a, expected)
|
t.Errorf("Wrong annotation set by Initial Resources: got %v, expected %v", a, expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func expectNoAnnotation(t *testing.T, pod *api.Pod) {
|
func expectNoAnnotation(t *testing.T, pod *api.Pod) {
|
||||||
if a, ok := pod.ObjectMeta.Annotations[initialResourcesAnnotation]; ok {
|
if a, ok := pod.ObjectMeta.Annotations[initialResourcesAnnotation]; ok {
|
||||||
t.Errorf("Expected no annatation but got %v", a)
|
t.Errorf("Expected no annotation but got %v", a)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,9 +126,9 @@ func performTest(t *testing.T, ir admission.Interface) {
|
|||||||
verifyPod(t, pods[2], 300, 100)
|
verifyPod(t, pods[2], 300, 100)
|
||||||
verifyPod(t, pods[3], 300, 300)
|
verifyPod(t, pods[3], 300, 300)
|
||||||
|
|
||||||
verifyAnnotation(t, pods[0], "Initial Resources plugin set: cpu, memory request for container c0")
|
verifyAnnotation(t, pods[0], "Initial Resources plugin set: cpu, memory request for init container i0; cpu, memory request for container c0")
|
||||||
verifyAnnotation(t, pods[1], "Initial Resources plugin set: cpu request for container c0")
|
verifyAnnotation(t, pods[1], "Initial Resources plugin set: cpu request for init container i0")
|
||||||
verifyAnnotation(t, pods[2], "Initial Resources plugin set: memory request for container c0")
|
verifyAnnotation(t, pods[2], "Initial Resources plugin set: memory request for init container i0")
|
||||||
expectNoAnnotation(t, pods[3])
|
expectNoAnnotation(t, pods[3])
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +233,7 @@ func TestManyContainers(t *testing.T) {
|
|||||||
verifyContainer(t, &pod.Spec.Containers[2], 300, 100)
|
verifyContainer(t, &pod.Spec.Containers[2], 300, 100)
|
||||||
verifyContainer(t, &pod.Spec.Containers[3], 300, 300)
|
verifyContainer(t, &pod.Spec.Containers[3], 300, 300)
|
||||||
|
|
||||||
verifyAnnotation(t, pod, "Initial Resources plugin set: cpu, memory request for container c0; cpu request for container c1; memory request for container c2")
|
verifyAnnotation(t, pod, "Initial Resources plugin set: cpu, memory request for init container i0; cpu, memory request for container c0; cpu request for container c1; memory request for container c2")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNamespaceAware(t *testing.T) {
|
func TestNamespaceAware(t *testing.T) {
|
||||||
|
@ -448,6 +448,24 @@ func PodLimitFunc(limitRange *api.LimitRange, pod *api.Pod) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for j := range pod.Spec.InitContainers {
|
||||||
|
container := &pod.Spec.InitContainers[j]
|
||||||
|
for k, v := range limit.Min {
|
||||||
|
if err := minConstraint(limitType, k, v, container.Resources.Requests, container.Resources.Limits); err != nil {
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for k, v := range limit.Max {
|
||||||
|
if err := maxConstraint(limitType, k, v, container.Resources.Requests, container.Resources.Limits); err != nil {
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for k, v := range limit.MaxLimitRequestRatio {
|
||||||
|
if err := limitRequestRatioConstraint(limitType, k, v, container.Resources.Requests, container.Resources.Limits); err != nil {
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// enforce pod limits on init containers
|
// enforce pod limits on init containers
|
||||||
|
@ -394,9 +394,12 @@ func TestAdmitHostPorts(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for i := 0; i < 2; i++ {
|
||||||
for k, v := range tests {
|
for k, v := range tests {
|
||||||
|
v.pod.Spec.Containers, v.pod.Spec.InitContainers = v.pod.Spec.InitContainers, v.pod.Spec.Containers
|
||||||
testPSPAdmit(k, v.psps, v.pod, v.shouldPass, v.expectedPSP, t)
|
testPSPAdmit(k, v.psps, v.pod, v.shouldPass, v.expectedPSP, t)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAdmitHostPID(t *testing.T) {
|
func TestAdmitHostPID(t *testing.T) {
|
||||||
|
Loading…
Reference in New Issue
Block a user