Related PR:
Topic | Link |
---|---|
Separate validation from RESTStorage | http://issue.k8s.io/2977 |
High level goals:
- Enable an easy-to-use mechanism to provide admission control to cluster.
- Enable a provider to support multiple admission control strategies or author their own.
- Ensure any rejected request can propagate errors back to the caller with why the request failed.
Authorization via policy is focused on answering if a user is authorized to perform an action.
Admission Control is focused on if the system will accept an authorized action.
Kubernetes may choose to dismiss an authorized action based on any number of admission control strategies.
This proposal documents the basic design, and describes how any number of admission control plug-ins could be injected.
Implementation of specific admission control strategies are handled in separate documents.
The kube-apiserver takes the following OPTIONAL arguments to enable admission control:
Option | Behavior |
---|---|
admission-control | Comma-delimited, ordered list of admission control choices to invoke prior to modifying or deleting an object. |
admission-control-config-file | File with admission control configuration parameters to boot-strap plug-in. |
An AdmissionControl plug-in is an implementation of the following interface:
package admission
// Attributes is an interface used by a plug-in to make an admission decision
// on a individual request.
type Attributes interface {
GetNamespace() string
GetKind() string
GetOperation() string
GetObject() runtime.Object
}
// Interface is an abstract, pluggable interface for Admission Control decisions.
type Interface interface {
// Admit makes an admission decision based on the request attributes
// An error is returned if it denies the request.
Admit(a Attributes) (err error)
}
A plug-in must be compiled with the binary, and is registered as an available option by providing a name, and implementation of admission.Interface.
func init() {
admission.RegisterPlugin("AlwaysDeny", func(client client.Interface, config io.Reader) (admission.Interface, error) { return NewAlwaysDeny(), nil })
}
A plug-in must be added to the imports in plugins.go
// Admission policies
_ "k8s.io/kubernetes/plugin/pkg/admission/admit"
_ "k8s.io/kubernetes/plugin/pkg/admission/alwayspullimages"
_ "k8s.io/kubernetes/plugin/pkg/admission/antiaffinity"
...
_ "<YOUR NEW PLUGIN>"
Invocation of admission control is handled by the APIServer and not individual RESTStorage implementations.
This design assumes that Issue 297 is adopted, and as a consequence, the general framework of the APIServer request/response flow will ensure the following:
- Incoming request
- Authenticate user
- Authorize user
- If operation=create|update|delete|connect, then admission.Admit(requestAttributes)
- invoke each admission.Interface object in sequence
- Case on the operation:
- If operation=create|update, then validate(object) and persist
- If operation=delete, delete the object
- If operation=connect, exec
If at any step, there is an error, the request is canceled.