Skip to content

Commit

Permalink
KEP of pod affinity/anti-affinity supports Gt and Lt operators
Browse files Browse the repository at this point in the history
  • Loading branch information
wgliang committed Mar 12, 2019
1 parent a56b53a commit 9992bf0
Showing 1 changed file with 208 additions and 0 deletions.
@@ -0,0 +1,208 @@
---
title: Pod affinity/anti-affinity supports Gt and Lt operators
authors:
- "@wgliang"
owning-sig: sig-scheduling
reviewers:
- "@bsalamat"
- "@k82cn"
- "@Huang-Wei"
approvers:
- "@bsalamat"
- "@k82cn"
creation-date: 2019-02-22
last-updated: 2019-03-12
status: provisional
---

# Pod affinity/anti-affinity supports Gt and Lt operators

## Table of Contents

* [Summary](#summary)
* [Motivation](#motivation)
* [Goals](#goals)
* [Non-Goals](#non-goals)
* [Proposal](#proposal)
* [User Stories](#user-stories)
* [Risks and Mitigations](#risks-and-mitigations)
* [Design Details](#design-details)
* [Content](#content)
* [Test Plan](#test-plan)
* [Graduation Criteria](#graduation-criteria)
* [Implementation History](#implementation-history)

## Summary

Extend the `Pod` affinity/anti-affinity operators to support `Gt` and `Lt` to provide
users with more elegant Pod label selection capabilities.

## Motivation

We know that `Node` affinity/anti-affinity currently supports `In`, `NotIn`, `Exists`,
`DoesNotExist`, `Gt`, `Lt`. But Pod affinity/anti-affinity only works with regular
label selectors: `In`, `NotIn`, `Exists`, `DoesNotExist`.

This is not an ideal situation if users want to put pods based on the label range.
`Pod` affinity/anti-affinity support for `Gt` and `Lt` operators will give users more
control.

### Goals

- `Pod` affinity/anti-affinity support for `Gt` and `Lt` operators.
- `Gt` and `Lt` will have the same status and influence as the original operators (`In`,
`NotIn`, `Exists`, `DoesNotExist`).

### Non-Goals

- Just add `Gt` and `Lt` operator functions without changing their original definition.
- Not changing the behavior of other label selectors, such as `Replicases`, `Daemonsets`, etc.

## Proposal

### User Stories

As an application developer, I want my application pods to be scheduled onto
one node that has pod with the "foo" tag and the tag value between "20" and "30".

- if we use the original `Exists` operator to implement, then we will write affinity
like this:
```go
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: foo
operator: Exists
values:
- 20
- labelSelector:
matchExpressions:
- key: foo
operator: Exists
values:
- 21
- labelSelector:
matchExpressions:
- key: foo
operator: Exists
values:
- 22
...
- labelSelector:
matchExpressions:
- key: foo
operator: Exists
values:
- 29
- labelSelector:
matchExpressions:
- key: foo
operator: Exists
values:
- 30
topologyKey: failure-domain.beta.kubernetes.io/zone
```
- if we use the original `In` operator to implement, then we will write affinity
like this:
```go
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: foo
operator: In
values:
- 20
- 21
- 22
- 23
...
- 28
- 29
- 30
topologyKey: failure-domain.beta.kubernetes.io/zone
```

Both are not ideal solutions. A promising solution is to provide users with `Gt` and `Lt`
operators, giving users the ability to specify the scope of the tag. Users can achieve
this in this way:
```go
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: foo
operator: Gt
values:
- 20
- key: foo
operator: Lt
values:
- 30
topologyKey: failure-domain.beta.kubernetes.io/zone
```

### Risks and Mitigations

Along with this feature, the biggest risk should be performance. This may also be the reason
why the `Gt` and `Lt` operators are not supported when Pod affinity/anti-affinity is
first proposed. However, the performance of the entire scheduler has been greatly improved(https://github.com/kubernetes/kubernetes/pull/74041#issuecomment-466191359), and the processing of Pod affinity/anti-affinity has been surprisingly optimized(https://github.com/kubernetes/kubernetes/pull/67788).

## Design Details
### Content
We will change the `LabelSelector` of `PodAffinityTerm` to the newly implemented `PodSelector` instead
of `metav1.LabelSelector`:

```go
type PodAffinityTerm struct {
LabelSelector *PodSelector
...
}
```

API of `PodSelector` is defined as below:

```go
type PodSelector struct {
MatchLabels map[string]string `json:"matchLabels,omitempty" protobuf:"bytes,1,rep,name=matchLabels"`
// +optional
MatchExpressions []PodSelectorRequirement `json:"matchExpressions,omitempty" protobuf:"bytes,2,rep,name=matchExpressions"`
}

type PodSelectorRequirement struct {
Key string `json:"key" patchStrategy:"merge" patchMergeKey:"key" protobuf:"bytes,1,opt,name=key"`
Operator PodSelectorOperator `json:"operator" protobuf:"bytes,2,opt,name=operator,casttype=LabelSelectorOperator"`
// +optional
Values []string `json:"values,omitempty" protobuf:"bytes,3,rep,name=values"`
}

type PodSelectorOperator string

const (
PodSelectorOpIn PodSelectorOperator = "In"
PodSelectorOpNotIn PodSelectorOperator = "NotIn"
PodSelectorOpExists PodSelectorOperator = "Exists"
PodSelectorOpDoesNotExist PodSelectorOperator = "DoesNotExist"
PodSelectorOpGt PodSelectorOperator = "Gt"
PodSelectorOpLt PodSelectorOperator = "Lt"
)
```

### Test Plan

_To be filled until targeted at a release._

### Graduation Criteria

_To be filled until targeted at a release._

## Implementation History

- 2019-03-12: Initial KEP sent out for reviewing.

0 comments on commit 9992bf0

Please sign in to comment.