Bug 1311456

Summary: Should give proper message when create a limit resource with defaultLimit and Pod type specified
Product: OKD Reporter: Qixuan Wang <qixuan.wang>
Component: PodAssignee: Derek Carr <decarr>
Status: CLOSED NOTABUG QA Contact: DeShuai Ma <dma>
Severity: low Docs Contact:
Priority: medium    
Version: 3.xCC: aos-bugs, mmccomas
Target Milestone: ---Keywords: Reopened
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-04-07 14:49:09 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Qixuan Wang 2016-02-24 09:56:58 UTC
Description of problem:
Since default limit and request are not supported on limitrange resource if type is pod, so create a pod with these values should give proper message. Currently defaultRequest has a error message but defaultLimit doesn't.

Version-Release number of selected component (if applicable):
oc v3.1.1.905
kubernetes v1.2.0-alpha.7-703-gbc4550d

How reproducible:
Always

Steps to Reproduce:
1. Prepare a limitrange definition with defaultLimit specified for a Pod type
# cat limitrange-1.yaml 
apiVersion: v1
kind: LimitRange
metadata:
  name: limitrange-1
spec:
  limits:
  - max:
      cpu: 500m
      memory: 750Mi
    min:
      cpu: 10m
      memory: 5Mi
    defaultLimit:
      cpu: 200m
      memory: 400Mi
    maxLimitRequestRatio:
      cpu: 2
      memory: 5
    type: Pod
  - defaultLimit:
      cpu: 130m
      memory: 120Mi
    defaultRequest:
      cpu: 110m
      memory: 100Mi
    maxLimitRequestRatio:
      cpu: 10
      memory: 8
    max:
      cpu: 400m
      memory: 750Mi
    min:
      cpu: 10m
      memory: 5Mi
    type: Container

2. Create a limit resource
# oc create -f limitrange-1.yaml -n qwang2 --config=/home/qwang/admin.kubeconfig

3. Check limits
# oc describe limits limitrange-1
# oc get limits limitrange-1 -o yaml

Actual results:
2. [root@dhcp-136-211 us]# oc create -f limitrange-1.yaml -n qwang2 --config=/home/qwang/admin.kubeconfig
limitrange "limitrange-1" created

3. [root@dhcp-136-211 us]# oc describe limits limitrange-1
Name:		limitrange-1
Namespace:	qwang2
Type		Resource	Min	Max	Default Request	Default Limit	Max Limit/Request Ratio
----		--------	---	---	---------------	-------------	-----------------------
Pod		cpu		10m	500m	-		-		2
Pod		memory		5Mi	750Mi	-		-		5
Container	cpu		10m	400m	110m		400m		10
Container	memory		5Mi	750Mi	100Mi		750Mi		8

[root@dhcp-136-211 us]# oc get limits limitrange-1 -o yaml
apiVersion: v1
kind: LimitRange
metadata:
  creationTimestamp: 2016-02-24T09:15:32Z
  name: limitrange-1
  namespace: qwang2
  resourceVersion: "34719"
  selfLink: /api/v1/namespaces/qwang2/limitranges/limitrange-1
  uid: 27dd706d-dad7-11e5-80ba-fa163e76dd6a
spec:
  limits:
  - max:
      cpu: 500m
      memory: 750Mi
    maxLimitRequestRatio:
      cpu: "2"
      memory: "5"
    min:
      cpu: 10m
      memory: 5Mi
    type: Pod
  - default:
      cpu: 400m
      memory: 750Mi
    defaultRequest:
      cpu: 110m
      memory: 100Mi
    max:
      cpu: 400m
      memory: 750Mi
    maxLimitRequestRatio:
      cpu: "10"
      memory: "8"
    min:
      cpu: 10m
      memory: 5Mi
    type: Container


Expected results:
2. Since default limit is not supported as default request, when creating limit, should show message like defaultRequest:
The LimitRange "limitrange-1" is invalid.
spec.limits[0].defaultLimit: Forbidden: may not be specified when `type` is 'Pod'


Additional info:

Comment 1 Derek Carr 2016-02-24 23:11:02 UTC
The field name that defaults limits is called "default" and not "defaultLimit" for historical reasons because it actually pre-dates the presence of request and limit in the API.

As a result, the converter was just dropping fields it did not understand.

$ cat limitrange-1.yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: limitrange-1
spec:
  limits:
  - max:
      cpu: 500m
      memory: 750Mi
    min:
      cpu: 10m
      memory: 5Mi
    default:
      cpu: 200m
      memory: 400Mi
    maxLimitRequestRatio:
      cpu: 2
      memory: 5
    type: Pod
  - default:
      cpu: 130m
      memory: 120Mi
    defaultRequest:
      cpu: 110m
      memory: 100Mi
    maxLimitRequestRatio:
      cpu: 10
      memory: 8
    max:
      cpu: 400m
      memory: 750Mi
    min:
      cpu: 10m
      memory: 5Mi
    type: Container
$ cluster/kubectl.sh create -f limitrange-1.yaml 
The LimitRange "limitrange-1" is invalid.
spec.limits[0].default: Forbidden: may not be specified when `type` is 'Pod'

If you drop the field from limitType=pod, you get the following:

$ cat limitrange-1.yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: limitrange-1
spec:
  limits:
  - max:
      cpu: 500m
      memory: 750Mi
    min:
      cpu: 10m
      memory: 5Mi
    maxLimitRequestRatio:
      cpu: 2
      memory: 5
    type: Pod
  - default:
      cpu: 130m
      memory: 120Mi
    defaultRequest:
      cpu: 110m
      memory: 100Mi
    maxLimitRequestRatio:
      cpu: 10
      memory: 8
    max:
      cpu: 400m
      memory: 750Mi
    min:
      cpu: 10m
      memory: 5Mi
    type: Container
$ cluster/kubectl.sh create -f limitrange-1.yaml 
limitrange "limitrange-1" created
$ cluster/kubectl.sh describe limits/limitrange-1
Name:		limitrange-1
Namespace:	default
Type		Resource	Min	Max	Default Request	Default Limit	Max Limit/Request Ratio
----		--------	---	---	---------------	-------------	-----------------------
Pod		cpu		10m	500m	-		-		2
Pod		memory		5Mi	750Mi	-		-		5
Container	cpu		10m	400m	110m		130m		10
Container	memory		5Mi	750Mi	100Mi		120Mi		8

Comment 2 Qixuan Wang 2016-02-25 03:25:20 UTC
Thanks for your detailed explanation.  
If limitType=Container and set DefaultLimit, the value of course is ignored, but the new value is the same with value of Max. Why does it get from Max(Default request and limit are all from Max if didn't set them, probably it's by design)? Should it has a clear message indicates that DefaultLimit is incorrect?

# cat limitrange-2.yaml 
apiVersion: v1
kind: LimitRange
metadata:
  name: limitrange-2
spec:
  limits:
  - defaultLimit:
      cpu: 130m
      memory: 120Mi
    defaultRequest:
      cpu: 110m
      memory: 100Mi
    maxLimitRequestRatio:
      cpu: 10
      memory: 8
    max:
      cpu: 400m
      memory: 750Mi
    min:
      cpu: 10m
      memory: 5Mi
    type: Container


# oc describe limits limitrange-2
Name:		limitrange-2
Namespace:	qwang3
Type		Resource	Min	Max	Default Request	Default Limit	Max Limit/Request Ratio
----		--------	---	---	---------------	-------------	-----------------------
Container	memory		5Mi	750Mi	100Mi		750Mi		8
Container	cpu		10m	400m	110m		400m		10


# oc get limits limitrange-2 -o yaml
apiVersion: v1
kind: LimitRange
metadata:
  creationTimestamp: 2016-02-25T03:14:00Z
  name: limitrange-2
  namespace: qwang3
  resourceVersion: "62696"
  selfLink: /api/v1/namespaces/qwang3/limitranges/limitrange-2
  uid: d0ef10f3-db6d-11e5-80ba-fa163e76dd6a
spec:
  limits:
  - default:
      cpu: 400m
      memory: 750Mi
    defaultRequest:
      cpu: 110m
      memory: 100Mi
    max:
      cpu: 400m
      memory: 750Mi
    maxLimitRequestRatio:
      cpu: "10"
      memory: "8"
    min:
      cpu: 10m
      memory: 5Mi
    type: Container

Comment 3 Derek Carr 2016-04-07 14:49:09 UTC
This is working as designed:

see https://github.com/kubernetes/kubernetes/blob/master/docs/design/admission_control_limit_range.md#default-value-behavior

Let me explain the rationale behind the current behavior.

If you specify a MAX[memory] for a container of 500Mi, then every container must make an explicit resources.limit[memory] <= 500Mi.  To make that convenient for users, we will default the default LIMIT[memory] for a container to match the MAX if not specified.