KubeCon NA 19 - Sig API Machinery Deep Dive
KubeCon NA 19 - Sig API Machinery Deep Dive
• CRDs
• Immutability
• Equality
• x-kubernetes-list-type / x-kubernetes-map-type
• Server-Side Apply
• Priority & Fairness
WIP: Immutability
type: object {“slice”: [“a”,”b”]} → {“slice”: [“a”,”b”]} ✓
properties: {“slice”: [“a”,”b”]} → {“slice”: [“b”,”a”]} 𐄂
slice:
type: array {“slice”: []} → {“slice”: null} ?
x-kubernetes-mutability: Immutable {“slice”: []} → {} ?
items:
type: string
valid → invalid
Equality
JSON
When are objects equal?
Corollary:
Native types:
type Foo struct {
Slice []string `json:”slice,omitempty”`
}
json.Unmarshal(`{“slice”: []`, &Foo{}} → Foo{Slice: nil}
Native types:
type Foo struct {
Slice []string `json:”slice,omitempty”`
}
json.Unmarshal(`{“slice”: []`, &Foo{}} → Foo{Slice: nil}
apiextensions-apiserver
CR handlers
CR handlers
CR handlers encoding
GET
admission REST logic
conversion
conversion &
CREATE
decoding
defaulting
LIST
request
result
404
validation
UPDATE
HTTP request storage DELETE
conversion & WATCH
defaulting PATCH
decoding / encoding
etcd
logic that is strict today
Request normalization
HTTP response
apiextensions-apiserver
CR handlers
CR handlers
CR handlers encoding
GET
admission REST logic
conversion
conversion &
CREATE
decoding
defaulting
LIST
request
result
404
validation
UPDATE
HTTP request storage DELETE
conversion & WATCH
defaulting PATCH
decoding / encoding
etcd
logic that is strict today
normalization
Request normalization
HTTP response
apiextensions-apiserver
CR handlers
CR handlers
CR handlers encoding
GET
admission REST logic
conversion
conversion &
CREATE
decoding
defaulting
LIST
request
result
404
validation
UPDATE
HTTP request storage DELETE
conversion & WATCH
defaulting PATCH
decoding / encoding
etcd
logic that is strict today
normalization
List-type / map-type
{“array”: [
{“name”:”a”, “value”:42},
unique keys
{“name”:”b”, “value”:1} map
]}
{“array”: [
{“a”:”x”, “b”:42},
unique items {“a”:”y”, “b”:1}, set
{“a”:”y”, “c”:[1,2,3]}
]}
Maps
default
x-kubernetes-map-type: atomic | granular
It doesn’t support:
- multi-keys associative lists
- unions
- multiple appliers
- multiple versions
Server-side Apply: Overview
- Server-side Apply tracks which actors manage which fields for all
operations
- Update: The intent is computed from the fields that have changed.
Apply and Update workflows
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
...
Fields Sets
- Set is a trie of fields owned:
"f:metadata":{"f:labels":{"f:sidecar_version": {}}},
"f:spec":{"f:template":{"f:spec":{"f:containers":{
"k:{\"name\":\"sidecar\"}":{".": {},"f:image": {}}
}}}}
We then remove list or map items that were formerly owned by that
manager, and not owned by any other applyer.
What’s missing?
• Goals:
• Reserve capacity for self-maintenance
• Protection against buggy controllers
• Protection against buggy/greedy parts of workload
• What to regulate:
• The product of dispatch rate X execution duration
• … that is, the number executing
• Approach:
• Divide server’s capacity among priority levels
• Concurrency limit and optionally queuing at each priority level
• Classify request to flow, associate flow to priority level
• This is a more sophisticated version of the max-in-flight limit
API Priority and Fairness
Earlier
handlers
429
Dispatch
Flow Schema 2
API
Priority
and
Fairness Priority Level N
Flow Schema N-1
Dispatch
Flow Schema N
Later
handlers
API Priority and Fairness
• Example • PriorityLevelConfiguration
PriorityLevelConfiguration: with no queuing:
kind: PriorityLevelConfiguration kind: PriorityLevelConfiguration
spec: spec:
type: Limited type: Limited
limited: limited:
assuredConcurrencyShares: 30 assuredConcurrencyShares: 30
limitResponse: limitResponse:
type: Queue type: Reject
queuing:
queues: 50 • PriorityLevelConfiguration
handSize: 3 with no concurrency limit:
queueLengthLimit: 10 kind: PriorityLevelConfiguration
spec:
type: Exempt
API Priority and Fairness
• Example FlowSchema:
kind: FlowSchema
spec:
priorityLevelConfiguration: {name: system-high}
matchingPrecedence: 1500
distinguisherMethod: {type: ByUser}
rules:
- subjects:
- kind: Group
- group: {name: "system:nodes"}
- resourceRules:
- verbs: [get, list]
apiGroups: [""]
resources: [pods, services, nodes/status]
namespaces: ["*"]
- nonResourceRules:
- verbs: [get, list]
nonResourceURLs: ["*"]
API Priority and Fairness
• Match request from system service account to read anything:
kind: FlowSchema
spec:
priorityLevelConfiguration: {name: system-high}
matchingPrecedence: 1500
distinguisherMethod: {type: ByNamespace}
rules:
- subjects:
- kind: ServiceAcount
- serviceAccount: {namespace: kube-system, name: "*"}
- resourceRules:
- verbs: [get, list]
apiGroups: ["*"]
resources: ["*"]
clusterScope: true
namespaces: ["*"]