interface.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. Copyright 2019 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. // This file defines the scheduling framework plugin interfaces.
  14. package v1alpha1
  15. import (
  16. "errors"
  17. "time"
  18. "k8s.io/api/core/v1"
  19. "k8s.io/apimachinery/pkg/types"
  20. internalcache "k8s.io/kubernetes/pkg/scheduler/internal/cache"
  21. )
  22. // Code is the Status code/type which is returned from plugins.
  23. type Code int
  24. // These are predefined codes used in a Status.
  25. const (
  26. // Success means that plugin ran correctly and found pod schedulable.
  27. // NOTE: A nil status is also considered as "Success".
  28. Success Code = iota
  29. // Error is used for internal plugin errors, unexpected input, etc.
  30. Error
  31. // Unschedulable is used when a plugin finds a pod unschedulable.
  32. // The accompanying status message should explain why the pod is unschedulable.
  33. Unschedulable
  34. // Wait is used when a permit plugin finds a pod scheduling should wait.
  35. Wait
  36. )
  37. // Status indicates the result of running a plugin. It consists of a code and a
  38. // message. When the status code is not `Success`, the status message should
  39. // explain why.
  40. // NOTE: A nil Status is also considered as Success.
  41. type Status struct {
  42. code Code
  43. message string
  44. }
  45. // Code returns code of the Status.
  46. func (s *Status) Code() Code {
  47. if s == nil {
  48. return Success
  49. }
  50. return s.code
  51. }
  52. // Message returns message of the Status.
  53. func (s *Status) Message() string {
  54. return s.message
  55. }
  56. // IsSuccess returns true if and only if "Status" is nil or Code is "Success".
  57. func (s *Status) IsSuccess() bool {
  58. if s == nil || s.code == Success {
  59. return true
  60. }
  61. return false
  62. }
  63. // AsError returns an "error" object with the same message as that of the Status.
  64. func (s *Status) AsError() error {
  65. if s.IsSuccess() {
  66. return nil
  67. }
  68. return errors.New(s.message)
  69. }
  70. // NewStatus makes a Status out of the given arguments and returns its pointer.
  71. func NewStatus(code Code, msg string) *Status {
  72. return &Status{
  73. code: code,
  74. message: msg,
  75. }
  76. }
  77. // WaitingPod represents a pod currently waiting in the permit phase.
  78. type WaitingPod interface {
  79. // GetPod returns a reference to the waiting pod.
  80. GetPod() *v1.Pod
  81. // Allow the waiting pod to be scheduled. Returns true if the allow signal was
  82. // successfully delivered, false otherwise.
  83. Allow() bool
  84. // Reject declares the waiting pod unschedulable. Returns true if the allow signal
  85. // was successfully delivered, false otherwise.
  86. Reject(msg string) bool
  87. }
  88. // Plugin is the parent type for all the scheduling framework plugins.
  89. type Plugin interface {
  90. Name() string
  91. }
  92. // PodInfo is minimum cell in the scheduling queue.
  93. type PodInfo struct {
  94. Pod *v1.Pod
  95. // The time pod added to the scheduling queue.
  96. Timestamp time.Time
  97. }
  98. // LessFunc is the function to sort pod info
  99. type LessFunc func(podInfo1, podInfo2 *PodInfo) bool
  100. // QueueSortPlugin is an interface that must be implemented by "QueueSort" plugins.
  101. // These plugins are used to sort pods in the scheduling queue. Only one queue sort
  102. // plugin may be enabled at a time.
  103. type QueueSortPlugin interface {
  104. Plugin
  105. // Less are used to sort pods in the scheduling queue.
  106. Less(*PodInfo, *PodInfo) bool
  107. }
  108. // ReservePlugin is an interface for Reserve plugins. These plugins are called
  109. // at the reservation point. These are meant to update the state of the plugin.
  110. // This concept used to be called 'assume' in the original scheduler.
  111. // These plugins should return only Success or Error in Status.code. However,
  112. // the scheduler accepts other valid codes as well. Anything other than Success
  113. // will lead to rejection of the pod.
  114. type ReservePlugin interface {
  115. Plugin
  116. // Reserve is called by the scheduling framework when the scheduler cache is
  117. // updated.
  118. Reserve(pc *PluginContext, p *v1.Pod, nodeName string) *Status
  119. }
  120. // PrebindPlugin is an interface that must be implemented by "prebind" plugins.
  121. // These plugins are called before a pod being scheduled.
  122. type PrebindPlugin interface {
  123. Plugin
  124. // Prebind is called before binding a pod. All prebind plugins must return
  125. // success or the pod will be rejected and won't be sent for binding.
  126. Prebind(pc *PluginContext, p *v1.Pod, nodeName string) *Status
  127. }
  128. // PostbindPlugin is an interface that must be implemented by "postbind" plugins.
  129. // These plugins are called after a pod is successfully bound to a node.
  130. type PostbindPlugin interface {
  131. Plugin
  132. // Postbind is called after a pod is successfully bound. These plugins are
  133. // informational. A common application of this extension point is for cleaning
  134. // up. If a plugin needs to clean-up its state after a pod is scheduled and
  135. // bound, Postbind is the extension point that it should register.
  136. Postbind(pc *PluginContext, p *v1.Pod, nodeName string)
  137. }
  138. // UnreservePlugin is an interface for Unreserve plugins. This is an informational
  139. // extension point. If a pod was reserved and then rejected in a later phase, then
  140. // un-reserve plugins will be notified. Un-reserve plugins should clean up state
  141. // associated with the reserved Pod.
  142. type UnreservePlugin interface {
  143. Plugin
  144. // Unreserve is called by the scheduling framework when a reserved pod was
  145. // rejected in a later phase.
  146. Unreserve(pc *PluginContext, p *v1.Pod, nodeName string)
  147. }
  148. // PermitPlugin is an interface that must be implemented by "permit" plugins.
  149. // These plugins are called before a pod is bound to a node.
  150. type PermitPlugin interface {
  151. Plugin
  152. // Permit is called before binding a pod (and before prebind plugins). Permit
  153. // plugins are used to prevent or delay the binding of a Pod. A permit plugin
  154. // must return success or wait with timeout duration, or the pod will be rejected.
  155. // The pod will also be rejected if the wait timeout or the pod is rejected while
  156. // waiting. Note that if the plugin returns "wait", the framework will wait only
  157. // after running the remaining plugins given that no other plugin rejects the pod.
  158. Permit(pc *PluginContext, p *v1.Pod, nodeName string) (*Status, time.Duration)
  159. }
  160. // Framework manages the set of plugins in use by the scheduling framework.
  161. // Configured plugins are called at specified points in a scheduling context.
  162. type Framework interface {
  163. FrameworkHandle
  164. // QueueSortFunc returns the function to sort pods in scheduling queue
  165. QueueSortFunc() LessFunc
  166. // RunPrebindPlugins runs the set of configured prebind plugins. It returns
  167. // *Status and its code is set to non-success if any of the plugins returns
  168. // anything but Success. If the Status code is "Unschedulable", it is
  169. // considered as a scheduling check failure, otherwise, it is considered as an
  170. // internal error. In either case the pod is not going to be bound.
  171. RunPrebindPlugins(pc *PluginContext, pod *v1.Pod, nodeName string) *Status
  172. // RunPostbindPlugins runs the set of configured postbind plugins.
  173. RunPostbindPlugins(pc *PluginContext, pod *v1.Pod, nodeName string)
  174. // RunReservePlugins runs the set of configured reserve plugins. If any of these
  175. // plugins returns an error, it does not continue running the remaining ones and
  176. // returns the error. In such case, pod will not be scheduled.
  177. RunReservePlugins(pc *PluginContext, pod *v1.Pod, nodeName string) *Status
  178. // RunUnreservePlugins runs the set of configured unreserve plugins.
  179. RunUnreservePlugins(pc *PluginContext, pod *v1.Pod, nodeName string)
  180. // RunPermitPlugins runs the set of configured permit plugins. If any of these
  181. // plugins returns a status other than "Success" or "Wait", it does not continue
  182. // running the remaining plugins and returns an error. Otherwise, if any of the
  183. // plugins returns "Wait", then this function will block for the timeout period
  184. // returned by the plugin, if the time expires, then it will return an error.
  185. // Note that if multiple plugins asked to wait, then we wait for the minimum
  186. // timeout duration.
  187. RunPermitPlugins(pc *PluginContext, pod *v1.Pod, nodeName string) *Status
  188. }
  189. // FrameworkHandle provides data and some tools that plugins can use. It is
  190. // passed to the plugin factories at the time of plugin initialization. Plugins
  191. // must store and use this handle to call framework functions.
  192. type FrameworkHandle interface {
  193. // NodeInfoSnapshot return the latest NodeInfo snapshot. The snapshot
  194. // is taken at the beginning of a scheduling cycle and remains unchanged until
  195. // a pod finishes "Reserve" point. There is no guarantee that the information
  196. // remains unchanged in the binding phase of scheduling.
  197. NodeInfoSnapshot() *internalcache.NodeInfoSnapshot
  198. // IterateOverWaitingPods acquires a read lock and iterates over the WaitingPods map.
  199. IterateOverWaitingPods(callback func(WaitingPod))
  200. // GetWaitingPod returns a waiting pod given its UID.
  201. GetWaitingPod(uid types.UID) WaitingPod
  202. }