move access/auth content to reference folder, add TOC (#8624)
This commit is contained in:
committed by
k8s-ci-robot
parent
f4158d642b
commit
1f557bde2c
@@ -1,158 +0,0 @@
|
||||
---
|
||||
reviewers:
|
||||
- bgrant0607
|
||||
- erictune
|
||||
- lavalamp
|
||||
title: Controlling Access to the Kubernetes API
|
||||
---
|
||||
|
||||
Users [access the API](docs/tasks/access-application-cluster/access-cluster/) using `kubectl`,
|
||||
client libraries, or by making REST requests. Both human users and
|
||||
[Kubernetes service accounts](/docs/tasks/configure-pod-container/configure-service-account/) can be
|
||||
authorized for API access.
|
||||
When a request reaches the API, it goes through several stages, illustrated in the
|
||||
following diagram:
|
||||
|
||||

|
||||
|
||||
## Transport Security
|
||||
|
||||
In a typical Kubernetes cluster, the API serves on port 443.
|
||||
The API server presents a certificate. This certificate is
|
||||
often self-signed, so `$USER/.kube/config` on the user's machine typically
|
||||
contains the root certificate for the API server's certificate, which when specified
|
||||
is used in place of the system default root certificate. This certificate is typically
|
||||
automatically written into your `$USER/.kube/config` when you create a cluster yourself
|
||||
using `kube-up.sh`. If the cluster has multiple users, then the creator needs to share
|
||||
the certificate with other users.
|
||||
|
||||
## Authentication
|
||||
|
||||
Once TLS is established, the HTTP request moves to the Authentication step.
|
||||
This is shown as step **1** in the diagram.
|
||||
The cluster creation script or cluster admin configures the API server to run
|
||||
one or more Authenticator Modules.
|
||||
Authenticators are described in more detail [here](/docs/admin/authentication/).
|
||||
|
||||
The input to the authentication step is the entire HTTP request, however, it typically
|
||||
just examines the headers and/or client certificate.
|
||||
|
||||
Authentication modules include Client Certificates, Password, and Plain Tokens,
|
||||
Bootstrap Tokens, and JWT Tokens (used for service accounts).
|
||||
|
||||
Multiple authentication modules can be specified, in which case each one is tried in sequence,
|
||||
until one of them succeeds.
|
||||
|
||||
On GCE, Client Certificates, Password, Plain Tokens, and JWT Tokens are all enabled.
|
||||
|
||||
If the request cannot be authenticated, it is rejected with HTTP status code 401.
|
||||
Otherwise, the user is authenticated as a specific `username`, and the user name
|
||||
is available to subsequent steps to use in their decisions. Some authenticators
|
||||
also provide the group memberships of the user, while other authenticators
|
||||
do not.
|
||||
|
||||
While Kubernetes uses "usernames" for access control decisions and in request logging,
|
||||
it does not have a `user` object nor does it store usernames or other information about
|
||||
users in its object store.
|
||||
|
||||
## Authorization
|
||||
|
||||
After the request is authenticated as coming from a specific user, the request must be authorized. This is shown as step **2** in the diagram.
|
||||
|
||||
A request must include the username of the requester, the requested action, and the object affected by the action. The request is authorized if an existing policy declares that the user has permissions to complete the requested action.
|
||||
|
||||
For example, if Bob has the policy below, then he can read pods only in the namespace `projectCaribou`:
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "abac.authorization.kubernetes.io/v1beta1",
|
||||
"kind": "Policy",
|
||||
"spec": {
|
||||
"user": "bob",
|
||||
"namespace": "projectCaribou",
|
||||
"resource": "pods",
|
||||
"readonly": true
|
||||
}
|
||||
}
|
||||
```
|
||||
If Bob makes the following request, the request is authorized because he is allowed to read objects in the `projectCaribou` namespace:
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "authorization.k8s.io/v1beta1",
|
||||
"kind": "SubjectAccessReview",
|
||||
"spec": {
|
||||
"resourceAttributes": {
|
||||
"namespace": "projectCaribou",
|
||||
"verb": "get",
|
||||
"group": "unicorn.example.org",
|
||||
"resource": "pods"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
If Bob makes a request to write (`create` or `update`) to the objects in the `projectCaribou` namespace, his authorization is denied. If Bob makes a request to read (`get`) objects in a different namespace such as `projectFish`, then his authorization is denied.
|
||||
|
||||
Kubernetes authorization requires that you use common REST attributes to interact with existing organization-wide or cloud-provider-wide access control systems. It is important to use REST formatting because these control systems might interact with other APIs besides the Kubernetes API.
|
||||
|
||||
Kubernetes supports multiple authorization modules, such as ABAC mode, RBAC Mode, and Webhook mode. When an administrator creates a cluster, they configured the authorization modules that should be used in the API server. If more than one authorization modules are configured, Kubernetes checks each module, and if any module authorizes the request, then the request can proceed. If all of the modules deny the request, then the request is denied (HTTP status code 403).
|
||||
|
||||
To learn more about Kubernetes authorization, including details about creating policies using the supported authorization modules, see [Authorization Overview](/docs/admin/authorization/).
|
||||
|
||||
|
||||
## Admission Control
|
||||
|
||||
Admission Control Modules are software modules that can modify or reject requests.
|
||||
In addition to the attributes available to Authorization Modules, Admission
|
||||
Control Modules can access the contents of the object that is being created or updated.
|
||||
They act on objects being created, deleted, updated or connected (proxy), but not reads.
|
||||
|
||||
Multiple admission controllers can be configured. Each is called in order.
|
||||
|
||||
This is shown as step **3** in the diagram.
|
||||
|
||||
Unlike Authentication and Authorization Modules, if any admission controller module
|
||||
rejects, then the request is immediately rejected.
|
||||
|
||||
In addition to rejecting objects, admission controllers can also set complex defaults for
|
||||
fields.
|
||||
|
||||
The available Admission Control Modules are described [here](/docs/admin/admission-controllers/).
|
||||
|
||||
Once a request passes all admission controllers, it is validated using the validation routines
|
||||
for the corresponding API object, and then written to the object store (shown as step **4**).
|
||||
|
||||
|
||||
## API Server Ports and IPs
|
||||
|
||||
The previous discussion applies to requests sent to the secure port of the API server
|
||||
(the typical case). The API server can actually serve on 2 ports:
|
||||
|
||||
By default the Kubernetes API server serves HTTP on 2 ports:
|
||||
|
||||
1. `Localhost Port`:
|
||||
|
||||
- is intended for testing and bootstrap, and for other components of the master node
|
||||
(scheduler, controller-manager) to talk to the API
|
||||
- no TLS
|
||||
- default is port 8080, change with `--insecure-port` flag.
|
||||
- default IP is localhost, change with `--insecure-bind-address` flag.
|
||||
- request **bypasses** authentication and authorization modules.
|
||||
- request handled by admission control module(s).
|
||||
- protected by need to have host access
|
||||
|
||||
2. `Secure Port`:
|
||||
|
||||
- use whenever possible
|
||||
- uses TLS. Set cert with `--tls-cert-file` and key with `--tls-private-key-file` flag.
|
||||
- default is port 6443, change with `--secure-port` flag.
|
||||
- default IP is first non-localhost network interface, change with `--bind-address` flag.
|
||||
- request handled by authentication and authorization modules.
|
||||
- request handled by admission control module(s).
|
||||
- authentication and authorization modules run.
|
||||
|
||||
When the cluster is created by `kube-up.sh`, on Google Compute Engine (GCE),
|
||||
and on several other cloud providers, the API server serves on port 443. On
|
||||
GCE, a firewall rule is configured on the project to allow external HTTPS
|
||||
access to the API. Other cluster setup methods vary.
|
||||
|
||||
@@ -1,645 +0,0 @@
|
||||
---
|
||||
reviewers:
|
||||
- lavalamp
|
||||
- davidopp
|
||||
- derekwaynecarr
|
||||
- erictune
|
||||
- janetkuo
|
||||
- thockin
|
||||
title: Using Admission Controllers
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## What are they?
|
||||
|
||||
An admission controller is a piece of code that intercepts requests to the
|
||||
Kubernetes API server prior to persistence of the object, but after the request
|
||||
is authenticated and authorized. The controllers consist of the
|
||||
[list](#what-does-each-admission-controller-do) below, are compiled into the
|
||||
`kube-apiserver` binary, and may only be configured by the cluster
|
||||
administrator. In that list, there are two special controllers:
|
||||
MutatingAdmissionWebhook and ValidatingAdmissionWebhook. These execute the
|
||||
mutating and validating (respectively) [admission control
|
||||
webhooks](/docs/admin/extensible-admission-controllers/#external-admission-webhooks)
|
||||
which are configured in the API.
|
||||
|
||||
Admission controllers may be "validating", "mutating", or both. Mutating
|
||||
controllers may modify the objects they admit; validating controllers may not.
|
||||
|
||||
The admission control process proceeds in two phases. In the first phase,
|
||||
mutating admission controllers are run. In the second phase, validating
|
||||
admission controllers are run. Note again that some of the controllers are
|
||||
both.
|
||||
|
||||
If any of the controllers in either phase reject the request, the entire
|
||||
request is rejected immediately and an error is returned to the end-user.
|
||||
|
||||
Finally, in addition to sometimes mutating the object in question, admission
|
||||
controllers may sometimes have side effects, that is, mutate related
|
||||
resources as part of request processing. Incrementing quota usage is the
|
||||
canonical example of why this is necessary. Any such side-effect needs a
|
||||
corresponding reclamation or reconciliation process, as a given admission
|
||||
controller does not know for sure that a given request will pass all of the
|
||||
other admission controllers.
|
||||
|
||||
## Why do I need them?
|
||||
|
||||
Many advanced features in Kubernetes require an admission controller to be enabled in order
|
||||
to properly support the feature. As a result, a Kubernetes API server that is not properly
|
||||
configured with the right set of admission controllers is an incomplete server and will not
|
||||
support all the features you expect.
|
||||
|
||||
## How do I turn on an admission controller?
|
||||
|
||||
The Kubernetes API server flag `enable-admission-plugins` takes a comma-delimited list of admission control plugins to invoke prior to modifying objects in the cluster.
|
||||
For example, the following command line enables the `NamespaceLifecycle` and the `LimitRanger`
|
||||
admission control plugins:
|
||||
|
||||
```shell
|
||||
kube-apiserver --enable-admission-plugins=NamespaceLifecyle,LimitRanger ...
|
||||
```
|
||||
|
||||
{{< note >}}
|
||||
**Note**: Depending on the way your Kubernetes cluster is deployed and how the
|
||||
API server is started, you may need to apply the settings in different ways.
|
||||
For example, you may have to modify the systemd unit file if the API server is
|
||||
deployed as a systemd service, you may modify the manifest file for the API
|
||||
server if Kubernetes is deployed in a self-hosted way.
|
||||
{{< /note >}}
|
||||
|
||||
## How do I turn off an admission controller?
|
||||
|
||||
The Kubernetes API server flag `disable-admission-plugins` takes a comma-delimited list of admission control plugins to be disabled, even if they are in the list of plugins enabled by default.
|
||||
|
||||
```shell
|
||||
kube-apiserver --disable-admission-plugins=PodNodeSelector,AlwaysDeny ...
|
||||
```
|
||||
|
||||
## What does each admission controller do?
|
||||
|
||||
### AlwaysAdmit (DEPRECATED)
|
||||
|
||||
Use this admission controller by itself to pass-through all requests. AlwaysAdmit is DEPRECATED as no real meaning.
|
||||
|
||||
### AlwaysPullImages
|
||||
|
||||
This admission controller modifies every new Pod to force the image pull policy to Always. This is useful in a
|
||||
multitenant cluster so that users can be assured that their private images can only be used by those
|
||||
who have the credentials to pull them. Without this admission controller, once an image has been pulled to a
|
||||
node, any pod from any user can use it simply by knowing the image's name (assuming the Pod is
|
||||
scheduled onto the right node), without any authorization check against the image. When this admission controller
|
||||
is enabled, images are always pulled prior to starting containers, which means valid credentials are
|
||||
required.
|
||||
|
||||
### AlwaysDeny (DEPRECATED)
|
||||
|
||||
Rejects all requests. AlwaysDeny is DEPRECATED as no real meaning.
|
||||
|
||||
### DefaultStorageClass
|
||||
|
||||
This admission controller observes creation of `PersistentVolumeClaim` objects that do not request any specific storage class
|
||||
and automatically adds a default storage class to them.
|
||||
This way, users that do not request any special storage class do not need to care about them at all and they
|
||||
will get the default one.
|
||||
|
||||
This admission controller does not do anything when no default storage class is configured. When more than one storage
|
||||
class is marked as default, it rejects any creation of `PersistentVolumeClaim` with an error and an administrator
|
||||
must revisit their `StorageClass` objects and mark only one as default.
|
||||
This admission controller ignores any `PersistentVolumeClaim` updates; it acts only on creation.
|
||||
|
||||
See [persistent volume](/docs/concepts/storage/persistent-volumes/) documentation about persistent volume claims and
|
||||
storage classes and how to mark a storage class as default.
|
||||
|
||||
### DefaultTolerationSeconds
|
||||
|
||||
This admission controller sets the default forgiveness toleration for pods to tolerate
|
||||
the taints `notready:NoExecute` and `unreachable:NoExecute` for 5 minutes,
|
||||
if the pods don't already have toleration for taints
|
||||
`node.kubernetes.io/not-ready:NoExecute` or
|
||||
`node.alpha.kubernetes.io/unreachable:NoExecute`.
|
||||
|
||||
### DenyExecOnPrivileged (deprecated)
|
||||
|
||||
This admission controller will intercept all requests to exec a command in a pod if that pod has a privileged container.
|
||||
|
||||
If your cluster supports privileged containers, and you want to restrict the ability of end-users to exec
|
||||
commands in those containers, we strongly encourage enabling this admission controller.
|
||||
|
||||
This functionality has been merged into [DenyEscalatingExec](#denyescalatingexec).
|
||||
|
||||
### DenyEscalatingExec
|
||||
|
||||
This admission controller will deny exec and attach commands to pods that run with escalated privileges that
|
||||
allow host access. This includes pods that run as privileged, have access to the host IPC namespace, and
|
||||
have access to the host PID namespace.
|
||||
|
||||
If your cluster supports containers that run with escalated privileges, and you want to
|
||||
restrict the ability of end-users to exec commands in those containers, we strongly encourage
|
||||
enabling this admission controller.
|
||||
|
||||
### EventRateLimit (alpha)
|
||||
|
||||
This admission controller mitigates the problem where the API server gets flooded by
|
||||
event requests. The cluster admin can specify event rate limits by:
|
||||
|
||||
* Enabling the `EventRateLimit` admission controller;
|
||||
* Referencing an `EventRateLimit` configuration file from the file provided to the API
|
||||
server's command line flag `--admission-control-config-file`:
|
||||
|
||||
```yaml
|
||||
kind: AdmissionConfiguration
|
||||
apiVersion: apiserver.k8s.io/v1alpha1
|
||||
plugins:
|
||||
- name: EventRateLimit
|
||||
path: eventconfig.yaml
|
||||
...
|
||||
```
|
||||
|
||||
There are four types of limits that can be specified in the configuration:
|
||||
|
||||
* `Server`: All event requests received by the API server share a single bucket.
|
||||
* `Namespace`: Each namespace has a dedicated bucket.
|
||||
* `User`: Each user is allocated a bucket.
|
||||
* `SourceAndObject`: A bucket is assigned by each combination of source and
|
||||
involved object of the event.
|
||||
|
||||
Below is a sample `eventconfig.yaml` for such a configuration:
|
||||
|
||||
```yaml
|
||||
kind: Configuration
|
||||
apiVersion: eventratelimit.admission.k8s.io/v1alpha1
|
||||
limits:
|
||||
- type: Namespace
|
||||
qps: 50
|
||||
burst: 100
|
||||
cacheSize: 2000
|
||||
- type: User
|
||||
qps: 10
|
||||
burst: 50
|
||||
```
|
||||
|
||||
See the [EventRateLimit proposal](https://git.k8s.io/community/contributors/design-proposals/api-machinery/admission_control_event_rate_limit.md)
|
||||
for more details.
|
||||
|
||||
### ExtendedResourceToleration
|
||||
|
||||
This plug-in facilitates creation of dedicated nodes with extended resources.
|
||||
If operators want to create dedicated nodes with extended resources (like GPUs, FPGAs etc.), they are expected to
|
||||
[taint the node](/docs/concepts/configuration/taint-and-toleration/#example-use-cases) with the extended resource
|
||||
name as the key. This admission controller, if enabled, automatically
|
||||
adds tolerations for such taints to pods requesting extended resources, so users don't have to manually
|
||||
add these tolerations.
|
||||
|
||||
### ImagePolicyWebhook
|
||||
|
||||
The ImagePolicyWebhook admission controller allows a backend webhook to make admission decisions.
|
||||
|
||||
#### Configuration File Format
|
||||
|
||||
ImagePolicyWebhook uses a configuration file to set options for the behavior of the backend.
|
||||
This file may be json or yaml and has the following format:
|
||||
|
||||
```yaml
|
||||
imagePolicy:
|
||||
kubeConfigFile: /path/to/kubeconfig/for/backend
|
||||
# time in s to cache approval
|
||||
allowTTL: 50
|
||||
# time in s to cache denial
|
||||
denyTTL: 50
|
||||
# time in ms to wait between retries
|
||||
retryBackoff: 500
|
||||
# determines behavior if the webhook backend fails
|
||||
defaultAllow: true
|
||||
```
|
||||
|
||||
Reference the ImagePolicyWebhook configuration file from the file provided to the API server's command line flag `--admission-control-config-file`:
|
||||
|
||||
```yaml
|
||||
kind: AdmissionConfiguration
|
||||
apiVersion: apiserver.k8s.io/v1alpha1
|
||||
plugins:
|
||||
- name: ImagePolicyWebhook
|
||||
path: imagepolicyconfig.yaml
|
||||
...
|
||||
```
|
||||
|
||||
The ImagePolicyWebhook config file must reference a [kubeconfig](docs/tasks/access-application-cluster/configure-access-multiple-clusters/)
|
||||
formatted file which sets up the connection to the backend. It is required that the backend communicate over TLS.
|
||||
|
||||
The kubeconfig file's cluster field must point to the remote service, and the user field must contain the returned authorizer.
|
||||
|
||||
```yaml
|
||||
# clusters refers to the remote service.
|
||||
clusters:
|
||||
- name: name-of-remote-imagepolicy-service
|
||||
cluster:
|
||||
certificate-authority: /path/to/ca.pem # CA for verifying the remote service.
|
||||
server: https://images.example.com/policy # URL of remote service to query. Must use 'https'.
|
||||
|
||||
# users refers to the API server's webhook configuration.
|
||||
users:
|
||||
- name: name-of-api-server
|
||||
user:
|
||||
client-certificate: /path/to/cert.pem # cert for the webhook admission controller to use
|
||||
client-key: /path/to/key.pem # key matching the cert
|
||||
```
|
||||
For additional HTTP configuration, refer to the [kubeconfig](docs/tasks/access-application-cluster/configure-access-multiple-clusters/) documentation.
|
||||
|
||||
#### Request Payloads
|
||||
|
||||
When faced with an admission decision, the API Server POSTs a JSON serialized `imagepolicy.k8s.io/v1alpha1` `ImageReview` object describing the action. This object contains fields describing the containers being admitted, as well as any pod annotations that match `*.image-policy.k8s.io/*`.
|
||||
|
||||
Note that webhook API objects are subject to the same versioning compatibility rules as other Kubernetes API objects. Implementers should be aware of looser compatibility promises for alpha objects and check the "apiVersion" field of the request to ensure correct deserialization. Additionally, the API Server must enable the imagepolicy.k8s.io/v1alpha1 API extensions group (`--runtime-config=imagepolicy.k8s.io/v1alpha1=true`).
|
||||
|
||||
An example request body:
|
||||
|
||||
```
|
||||
{
|
||||
"apiVersion":"imagepolicy.k8s.io/v1alpha1",
|
||||
"kind":"ImageReview",
|
||||
"spec":{
|
||||
"containers":[
|
||||
{
|
||||
"image":"myrepo/myimage:v1"
|
||||
},
|
||||
{
|
||||
"image":"myrepo/myimage@sha256:beb6bd6a68f114c1dc2ea4b28db81bdf91de202a9014972bec5e4d9171d90ed"
|
||||
}
|
||||
],
|
||||
"annotations":[
|
||||
"mycluster.image-policy.k8s.io/ticket-1234": "break-glass"
|
||||
],
|
||||
"namespace":"mynamespace"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The remote service is expected to fill the ImageReviewStatus field of the request and respond to either allow or disallow access. The response body's "spec" field is ignored and may be omitted. A permissive response would return:
|
||||
|
||||
```
|
||||
{
|
||||
"apiVersion": "imagepolicy.k8s.io/v1alpha1",
|
||||
"kind": "ImageReview",
|
||||
"status": {
|
||||
"allowed": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To disallow access, the service would return:
|
||||
|
||||
```
|
||||
{
|
||||
"apiVersion": "imagepolicy.k8s.io/v1alpha1",
|
||||
"kind": "ImageReview",
|
||||
"status": {
|
||||
"allowed": false,
|
||||
"reason": "image currently blacklisted"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For further documentation refer to the `imagepolicy.v1alpha1` API objects and `plugin/pkg/admission/imagepolicy/admission.go`.
|
||||
|
||||
#### Extending with Annotations
|
||||
|
||||
All annotations on a Pod that match `*.image-policy.k8s.io/*` are sent to the webhook. Sending annotations allows users who are aware of the image policy backend to send extra information to it, and for different backends implementations to accept different information.
|
||||
|
||||
Examples of information you might put here are:
|
||||
|
||||
* request to "break glass" to override a policy, in case of emergency.
|
||||
* a ticket number from a ticket system that documents the break-glass request
|
||||
* provide a hint to the policy server as to the imageID of the image being provided, to save it a lookup
|
||||
|
||||
In any case, the annotations are provided by the user and are not validated by Kubernetes in any way. In the future, if an annotation is determined to be widely useful, it may be promoted to a named field of ImageReviewSpec.
|
||||
|
||||
### Initializers (alpha)
|
||||
|
||||
The admission controller determines the initializers of a resource based on the existing
|
||||
`InitializerConfiguration`s. It sets the pending initializers by modifying the
|
||||
metadata of the resource to be created.
|
||||
For more information, please check [Dynamic Admission Control](/docs/admin/extensible-admission-controllers/).
|
||||
|
||||
### InitialResources (experimental)
|
||||
|
||||
This admission controller observes pod creation requests. If a container omits compute resource requests and limits,
|
||||
then the admission controller auto-populates a compute resource request based on historical usage of containers running the same image.
|
||||
If there is not enough data to make a decision the Request is left unchanged.
|
||||
When the admission controller sets a compute resource request, it does this by *annotating*
|
||||
the pod spec rather than mutating the `container.resources` fields.
|
||||
The annotations added contain the information on what compute resources were auto-populated.
|
||||
|
||||
See the [InitialResources proposal](https://git.k8s.io/community/contributors/design-proposals/autoscaling/initial-resources.md) for more details.
|
||||
|
||||
### LimitPodHardAntiAffinityTopology
|
||||
|
||||
This admission controller denies any pod that defines `AntiAffinity` topology key other than
|
||||
`kubernetes.io/hostname` in `requiredDuringSchedulingRequiredDuringExecution`.
|
||||
|
||||
### LimitRanger
|
||||
|
||||
This admission controller will observe the incoming request and ensure that it does not violate any of the constraints
|
||||
enumerated in the `LimitRange` object in a `Namespace`. If you are using `LimitRange` objects in
|
||||
your Kubernetes deployment, you MUST use this admission controller to enforce those constraints. LimitRanger can also
|
||||
be used to apply default resource requests to Pods that don't specify any; currently, the default LimitRanger
|
||||
applies a 0.1 CPU requirement to all Pods in the `default` namespace.
|
||||
|
||||
See the [limitRange design doc](https://git.k8s.io/community/contributors/design-proposals/resource-management/admission_control_limit_range.md) and the [example of Limit Range](/docs/tasks/administer-cluster/memory-default-namespace/) for more details.
|
||||
|
||||
### MutatingAdmissionWebhook (beta in 1.9)
|
||||
|
||||
This admission controller calls any mutating webhooks which match the request. Matching
|
||||
webhooks are called in serial; each one may modify the object if it desires.
|
||||
|
||||
This admission controller (as implied by the name) only runs in the mutating phase.
|
||||
|
||||
If a webhook called by this has side effects (for example, decrementing quota) it
|
||||
*must* have a reconciliation system, as it is not guaranteed that subsequent
|
||||
webhooks or validating admission controllers will permit the request to finish.
|
||||
|
||||
If you disable the MutatingAdmissionWebhook, you must also disable the
|
||||
`MutatingWebhookConfiguration` object in the `admissionregistration.k8s.io/v1beta1`
|
||||
group/version via the `--runtime-config` flag (both are on by default in
|
||||
versions >= 1.9).
|
||||
|
||||
#### Use caution when authoring and installing mutating webhooks
|
||||
|
||||
* Users may be confused when the objects they try to create are different from
|
||||
what they get back.
|
||||
* Built in control loops may break when the objects they try to create are
|
||||
different when read back.
|
||||
* Setting originally unset fields is less likely to cause problems than
|
||||
overwriting fields set in the original request. Avoid doing the latter.
|
||||
* This is a beta feature. Future versions of Kubernetes may restrict the types of
|
||||
mutations these webhooks can make.
|
||||
* Future changes to control loops for built-in resources or third-party resources
|
||||
may break webhooks that work well today. Even when the webhook installation API
|
||||
is finalized, not all possible webhook behaviors will be guaranteed to be supported
|
||||
indefinitely.
|
||||
|
||||
### NamespaceAutoProvision
|
||||
|
||||
This admission controller examines all incoming requests on namespaced resources and checks
|
||||
if the referenced namespace does exist.
|
||||
It creates a namespace if it cannot be found.
|
||||
This admission controller is useful in deployments that do not want to restrict creation of
|
||||
a namespace prior to its usage.
|
||||
|
||||
### NamespaceExists
|
||||
|
||||
This admission controller checks all requests on namespaced resources other than `Namespace` itself.
|
||||
If the namespace referenced from a request doesn't exist, the request is rejected.
|
||||
|
||||
### NamespaceLifecycle
|
||||
|
||||
This admission controller enforces that a `Namespace` that is undergoing termination cannot have new objects created in it,
|
||||
and ensures that requests in a non-existent `Namespace` are rejected. This admission controller also prevents deletion of
|
||||
three system reserved namespaces `default`, `kube-system`, `kube-public`.
|
||||
|
||||
A `Namespace` deletion kicks off a sequence of operations that remove all objects (pods, services, etc.) in that
|
||||
namespace. In order to enforce integrity of that process, we strongly recommend running this admission controller.
|
||||
|
||||
### NodeRestriction
|
||||
|
||||
This admission controller limits the `Node` and `Pod` objects a kubelet can modify. In order to be limited by this admission controller,
|
||||
kubelets must use credentials in the `system:nodes` group, with a username in the form `system:node:<nodeName>`.
|
||||
Such kubelets will only be allowed to modify their own `Node` API object, and only modify `Pod` API objects that are bound to their node.
|
||||
Future versions may add additional restrictions to ensure kubelets have the minimal set of permissions required to operate correctly.
|
||||
|
||||
### OwnerReferencesPermissionEnforcement
|
||||
|
||||
This admission controller protects the access to the `metadata.ownerReferences` of an object
|
||||
so that only users with "delete" permission to the object can change it.
|
||||
This admission controller also protects the access to `metadata.ownerReferences[x].blockOwnerDeletion`
|
||||
of an object, so that only users with "update" permission to the `finalizers`
|
||||
subresource of the referenced *owner* can change it.
|
||||
|
||||
### PersistentVolumeLabel (DEPRECATED)
|
||||
|
||||
This admission controller automatically attaches region or zone labels to PersistentVolumes
|
||||
as defined by the cloud provider (for example, GCE or AWS).
|
||||
It helps ensure the Pods and the PersistentVolumes mounted are in the same
|
||||
region and/or zone.
|
||||
If the admission controller doesn't support automatic labelling your PersistentVolumes, you
|
||||
may need to add the labels manually to prevent pods from mounting volumes from
|
||||
a different zone. PersistentVolumeLabel is DEPRECATED and labeling persistent volumes has been taken over by [cloud controller manager](/docs/tasks/administer-cluster/running-cloud-controller/).
|
||||
|
||||
### PodNodeSelector
|
||||
|
||||
This admission controller defaults and limits what node selectors may be used within a namespace by reading a namespace annotation and a global configuration.
|
||||
|
||||
#### Configuration File Format
|
||||
|
||||
`PodNodeSelector` uses a configuration file to set options for the behavior of the backend.
|
||||
Note that the configuration file format will move to a versioned file in a future release.
|
||||
This file may be json or yaml and has the following format:
|
||||
|
||||
```yaml
|
||||
podNodeSelectorPluginConfig:
|
||||
clusterDefaultNodeSelector: <node-selectors-labels>
|
||||
namespace1: <node-selectors-labels>
|
||||
namespace2: <node-selectors-labels>
|
||||
```
|
||||
|
||||
Reference the `PodNodeSelector` configuration file from the file provided to the API server's command line flag `--admission-control-config-file`:
|
||||
|
||||
```yaml
|
||||
kind: AdmissionConfiguration
|
||||
apiVersion: apiserver.k8s.io/v1alpha1
|
||||
plugins:
|
||||
- name: PodNodeSelector
|
||||
path: podnodeselector.yaml
|
||||
...
|
||||
```
|
||||
|
||||
#### Configuration Annotation Format
|
||||
`PodNodeSelector` uses the annotation key `scheduler.alpha.kubernetes.io/node-selector` to assign node selectors to namespaces.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
scheduler.alpha.kubernetes.io/node-selector: <node-selectors-labels>
|
||||
name: namespace3
|
||||
```
|
||||
|
||||
#### Internal Behavior
|
||||
This admission controller has the following behavior:
|
||||
|
||||
1. If the `Namespace` has an annotation with a key `scheduler.alpha.kubernetes.io/node-selector`, use its value as the
|
||||
node selector.
|
||||
1. If the namespace lacks such an annotation, use the `clusterDefaultNodeSelector` defined in the `PodNodeSelector`
|
||||
plugin configuration file as the node selector.
|
||||
1. Evaluate the pod's node selector against the namespace node selector for conflicts. Conflicts result in rejection.
|
||||
1. Evaluate the pod's node selector against the namespace-specific whitelist defined the plugin configuration file.
|
||||
Conflicts result in rejection.
|
||||
|
||||
{{< note >}}
|
||||
**Note:** PodNodeSelector allows forcing pods to run on specifically labeled nodes. Also see the PodTolerationRestriction
|
||||
admission plugin, which allows preventing pods from running on specifically tainted nodes.
|
||||
{{< /note >}}
|
||||
|
||||
### PersistentVolumeClaimResize
|
||||
|
||||
This admission controller implements additional validations for checking incoming `PersistentVolumeClaim` resize requests.
|
||||
|
||||
{{< note >}}
|
||||
**Note:** Support for volume resizing is available as an alpha feature. Admins must set the feature gate `ExpandPersistentVolumes`
|
||||
to `true` to enable resizing.
|
||||
{{< /note >}}
|
||||
|
||||
After enabling the `ExpandPersistentVolumes` feature gate, enabling the `PersistentVolumeClaimResize` admission
|
||||
controller is recommended, too. This admission controller prevents resizing of all claims by default unless a claim's `StorageClass`
|
||||
explicitly enables resizing by setting `allowVolumeExpansion` to `true`.
|
||||
|
||||
For example: all `PersistentVolumeClaim`s created from the following `StorageClass` support volume expansion:
|
||||
|
||||
```yaml
|
||||
kind: StorageClass
|
||||
apiVersion: storage.k8s.io/v1
|
||||
metadata:
|
||||
name: gluster-vol-default
|
||||
provisioner: kubernetes.io/glusterfs
|
||||
parameters:
|
||||
resturl: "http://192.168.10.100:8080"
|
||||
restuser: ""
|
||||
secretNamespace: ""
|
||||
secretName: ""
|
||||
allowVolumeExpansion: true
|
||||
```
|
||||
|
||||
For more information about persistent volume claims, see ["PersistentVolumeClaims"](/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims).
|
||||
|
||||
### PodPreset
|
||||
|
||||
This admission controller injects a pod with the fields specified in a matching PodPreset.
|
||||
See also [PodPreset concept](/docs/concepts/workloads/pods/podpreset/) and
|
||||
[Inject Information into Pods Using a PodPreset](/docs/tasks/inject-data-application/podpreset)
|
||||
for more information.
|
||||
|
||||
### PodSecurityPolicy
|
||||
|
||||
This admission controller acts on creation and modification of the pod and determines if it should be admitted
|
||||
based on the requested security context and the available Pod Security Policies.
|
||||
|
||||
For Kubernetes < 1.6.0, the API Server must enable the extensions/v1beta1/podsecuritypolicy API
|
||||
extensions group (`--runtime-config=extensions/v1beta1/podsecuritypolicy=true`).
|
||||
|
||||
See also [Pod Security Policy documentation](/docs/concepts/policy/pod-security-policy/)
|
||||
for more information.
|
||||
|
||||
### PodTolerationRestriction
|
||||
|
||||
This admission controller first verifies any conflict between a pod's tolerations and its
|
||||
namespace's tolerations, and rejects the pod request if there is a conflict.
|
||||
It then merges the namespace's tolerations into the pod's tolerations.
|
||||
The resulting tolerations are checked against the namespace's whitelist of
|
||||
tolerations. If the check succeeds, the pod request is admitted otherwise
|
||||
rejected.
|
||||
|
||||
If the pod's namespace does not have any associated default or whitelist of
|
||||
tolerations, then the cluster-level default or whitelist of tolerations are used
|
||||
instead if specified.
|
||||
|
||||
Tolerations to a namespace are assigned via the
|
||||
`scheduler.alpha.kubernetes.io/defaultTolerations` and
|
||||
`scheduler.alpha.kubernetes.io/tolerationsWhitelist`
|
||||
annotation keys.
|
||||
|
||||
### Priority
|
||||
|
||||
The priority admission controller uses the `priorityClassName` field and populates the integer value of the priority. If the priority class is not found, the Pod is rejected.
|
||||
|
||||
### ResourceQuota
|
||||
|
||||
This admission controller will observe the incoming request and ensure that it does not violate any of the constraints
|
||||
enumerated in the `ResourceQuota` object in a `Namespace`. If you are using `ResourceQuota`
|
||||
objects in your Kubernetes deployment, you MUST use this admission controller to enforce quota constraints.
|
||||
|
||||
See the [resourceQuota design doc](https://git.k8s.io/community/contributors/design-proposals/resource-management/admission_control_resource_quota.md) and the [example of Resource Quota](/docs/concepts/policy/resource-quotas/) for more details.
|
||||
|
||||
|
||||
### SecurityContextDeny
|
||||
|
||||
This admission controller will deny any pod that attempts to set certain escalating [SecurityContext](/docs/tasks/configure-pod-container/security-context/) fields. This should be enabled if a cluster doesn't utilize [pod security policies](/docs/concepts/policy/pod-security-policy/) to restrict the set of values a security context can take.
|
||||
|
||||
### ServiceAccount
|
||||
|
||||
This admission controller implements automation for [serviceAccounts](/docs/tasks/configure-pod-container/configure-service-account/).
|
||||
We strongly recommend using this admission controller if you intend to make use of Kubernetes `ServiceAccount` objects.
|
||||
|
||||
### Storage Object in Use Protection (beta)
|
||||
{{< feature-state for_k8s_version="v1.10" state="beta" >}}
|
||||
The `StorageObjectInUseProtection` plugin adds the `kubernetes.io/pvc-protection` or `kubernetes.io/pv-protection` finalizers to newly created Persistent Volume Claims (PVCs) or Persistent Volumes (PV). In case a user deletes a PVC or PV the PVC or PV is not removed until the finalizer is removed from the PVC or PV by PVC or PV Protection Controller. Refer to the [Storage Object in Use Protection](/docs/concepts/storage/persistent-volumes/#storage-object-in-use-protection) for more detailed information.
|
||||
|
||||
### ValidatingAdmissionWebhook (alpha in 1.8; beta in 1.9)
|
||||
|
||||
This admission controller calls any validating webhooks which match the request. Matching
|
||||
webhooks are called in parallel; if any of them rejects the request, the request
|
||||
fails. This admission controller only runs in the validation phase; the webhooks it calls may not
|
||||
mutate the object, as opposed to the webhooks called by the `MutatingAdmissionWebhook` admission controller.
|
||||
|
||||
If a webhook called by this has side effects (for example, decrementing quota) it
|
||||
*must* have a reconciliation system, as it is not guaranteed that subsequent
|
||||
webhooks or other validating admission controllers will permit the request to finish.
|
||||
|
||||
If you disable the ValidatingAdmissionWebhook, you must also disable the
|
||||
`ValidatingWebhookConfiguration` object in the `admissionregistration.k8s.io/v1beta1`
|
||||
group/version via the `--runtime-config` flag (both are on by default in
|
||||
versions 1.9 and later).
|
||||
|
||||
|
||||
## Is there a recommended set of admission controllers to use?
|
||||
|
||||
Yes.
|
||||
|
||||
For Kubernetes version 1.10 and later, we recommend running the following set of admission controllers using the ```--enable-admission-plugins``` flag (**order doesn't matter**).
|
||||
|
||||
Note: ```--admission-control``` was deprecated in 1.10 and replaced with ```--enable-admission-plugins```.
|
||||
|
||||
```shell
|
||||
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota
|
||||
```
|
||||
|
||||
For Kubernetes 1.9 and earlier, we recommend running the following set of admission controllers using the ```--admission-control``` flag (**order matters**).
|
||||
|
||||
* v1.9
|
||||
|
||||
```shell
|
||||
--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota
|
||||
```
|
||||
|
||||
* It's worth reiterating that in 1.9, these happen in a mutating phase
|
||||
and a validating phase, and that e.g. `ResourceQuota` runs in the validating
|
||||
phase, and therefore is the last admission controller to run.
|
||||
`MutatingAdmissionWebhook` appears before it in this list, because it runs
|
||||
in the mutating phase.
|
||||
|
||||
For earlier versions, there was no concept of validating vs mutating and the
|
||||
admission controllers ran in the exact order specified.
|
||||
|
||||
* v1.6 - v1.8
|
||||
|
||||
```shell
|
||||
--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds
|
||||
```
|
||||
|
||||
* v1.4 - v1.5
|
||||
|
||||
```shell
|
||||
--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota
|
||||
```
|
||||
|
||||
* v1.2 - v1.3
|
||||
|
||||
```shell
|
||||
--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota
|
||||
```
|
||||
|
||||
* v1.0 - v1.1
|
||||
|
||||
```shell
|
||||
--admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,PersistentVolumeLabel,ResourceQuota
|
||||
```
|
||||
@@ -1,819 +0,0 @@
|
||||
---
|
||||
reviewers:
|
||||
- erictune
|
||||
- lavalamp
|
||||
- ericchiang
|
||||
- deads2k
|
||||
- liggitt
|
||||
title: Authenticating
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## Users in Kubernetes
|
||||
|
||||
All Kubernetes clusters have two categories of users: service accounts managed
|
||||
by Kubernetes, and normal users.
|
||||
|
||||
Normal users are assumed to be managed by an outside, independent service. An
|
||||
admin distributing private keys, a user store like Keystone or Google Accounts,
|
||||
even a file with a list of usernames and passwords. In this regard, _Kubernetes
|
||||
does not have objects which represent normal user accounts._ Regular users
|
||||
cannot be added to a cluster through an API call.
|
||||
|
||||
In contrast, service accounts are users managed by the Kubernetes API. They are
|
||||
bound to specific namespaces, and created automatically by the API server or
|
||||
manually through API calls. Service accounts are tied to a set of credentials
|
||||
stored as `Secrets`, which are mounted into pods allowing in-cluster processes
|
||||
to talk to the Kubernetes API.
|
||||
|
||||
API requests are tied to either a normal user or a service account, or are treated
|
||||
as anonymous requests. This means every process inside or outside the cluster, from
|
||||
a human user typing `kubectl` on a workstation, to `kubelets` on nodes, to members
|
||||
of the control plane, must authenticate when making requests to the API server,
|
||||
or be treated as an anonymous user.
|
||||
|
||||
## Authentication strategies
|
||||
|
||||
Kubernetes uses client certificates, bearer tokens, an authenticating proxy, or HTTP basic auth to
|
||||
authenticate API requests through authentication plugins. As HTTP requests are
|
||||
made to the API server, plugins attempt to associate the following attributes
|
||||
with the request:
|
||||
|
||||
* Username: a string which identifies the end user. Common values might be `kube-admin` or `jane@example.com`.
|
||||
* UID: a string which identifies the end user and attempts to be more consistent and unique than username.
|
||||
* Groups: a set of strings which associate users with a set of commonly grouped users.
|
||||
* Extra fields: a map of strings to list of strings which holds additional information authorizers may find useful.
|
||||
|
||||
All values are opaque to the authentication system and only hold significance
|
||||
when interpreted by an [authorizer](/docs/admin/authorization/).
|
||||
|
||||
You can enable multiple authentication methods at once. You should usually use at least two methods:
|
||||
|
||||
- service account tokens for service accounts
|
||||
- at least one other method for user authentication.
|
||||
|
||||
When multiple authenticator modules are enabled, the first module
|
||||
to successfully authenticate the request short-circuits evaluation.
|
||||
The API server does not guarantee the order authenticators run in.
|
||||
|
||||
The `system:authenticated` group is included in the list of groups for all authenticated users.
|
||||
|
||||
Integrations with other authentication protocols (LDAP, SAML, Kerberos, alternate x509 schemes, etc)
|
||||
can be accomplished using an [authenticating proxy](#authenticating-proxy) or the
|
||||
[authentication webhook](#webhook-token-authentication).
|
||||
|
||||
### X509 Client Certs
|
||||
|
||||
Client certificate authentication is enabled by passing the `--client-ca-file=SOMEFILE`
|
||||
option to API server. The referenced file must contain one or more certificates authorities
|
||||
to use to validate client certificates presented to the API server. If a client certificate
|
||||
is presented and verified, the common name of the subject is used as the user name for the
|
||||
request. As of Kubernetes 1.4, client certificates can also indicate a user's group memberships
|
||||
using the certificate's organization fields. To include multiple group memberships for a user,
|
||||
include multiple organization fields in the certificate.
|
||||
|
||||
For example, using the `openssl` command line tool to generate a certificate signing request:
|
||||
|
||||
``` bash
|
||||
openssl req -new -key jbeda.pem -out jbeda-csr.pem -subj "/CN=jbeda/O=app1/O=app2"
|
||||
```
|
||||
|
||||
This would create a CSR for the username "jbeda", belonging to two groups, "app1" and "app2".
|
||||
|
||||
See [Managing Certificates](/docs/concepts/cluster-administration/certificates/) for how to generate a client cert.
|
||||
|
||||
### Static Token File
|
||||
|
||||
The API server reads bearer tokens from a file when given the `--token-auth-file=SOMEFILE` option on the command line. Currently, tokens last indefinitely, and the token list cannot be
|
||||
changed without restarting API server.
|
||||
|
||||
The token file is a csv file with a minimum of 3 columns: token, user name, user uid,
|
||||
followed by optional group names. Note, if you have more than one group the column must be
|
||||
double quoted e.g.
|
||||
|
||||
```conf
|
||||
token,user,uid,"group1,group2,group3"
|
||||
```
|
||||
|
||||
#### Putting a Bearer Token in a Request
|
||||
|
||||
When using bearer token authentication from an http client, the API
|
||||
server expects an `Authorization` header with a value of `Bearer
|
||||
THETOKEN`. The bearer token must be a character sequence that can be
|
||||
put in an HTTP header value using no more than the encoding and
|
||||
quoting facilities of HTTP. For example: if the bearer token is
|
||||
`31ada4fd-adec-460c-809a-9e56ceb75269` then it would appear in an HTTP
|
||||
header as shown below.
|
||||
|
||||
```http
|
||||
Authorization: Bearer 31ada4fd-adec-460c-809a-9e56ceb75269
|
||||
```
|
||||
|
||||
### Bootstrap Tokens
|
||||
|
||||
This feature is currently in **alpha**.
|
||||
|
||||
To allow for streamlined bootstrapping for new clusters, Kubernetes includes a
|
||||
dynamically-managed Bearer token type called a *Bootstrap Token*. These tokens
|
||||
are stored as Secrets in the `kube-system` namespace, where they can be
|
||||
dynamically managed and created. Controller Manager contains a TokenCleaner
|
||||
controller that deletes bootstrap tokens as they expire.
|
||||
|
||||
The tokens are of the form `[a-z0-9]{6}.[a-z0-9]{16}`. The first component is a
|
||||
Token ID and the second component is the Token Secret. You specify the token
|
||||
in an HTTP header as follows:
|
||||
|
||||
```http
|
||||
Authorization: Bearer 781292.db7bc3a58fc5f07e
|
||||
```
|
||||
|
||||
You must enable the Bootstrap Token Authenticator with the
|
||||
`--experimental-bootstrap-token-auth` flag on the API Server. You must enable
|
||||
the TokenCleaner controller via the `--controllers` flag on the Controller
|
||||
Manager. This is done with something like `--controllers=*,tokencleaner`.
|
||||
`kubeadm` will do this for you if you are using it to bootstrapping a cluster.
|
||||
|
||||
The authenticator authenticates as `system:bootstrap:<Token ID>`. It is
|
||||
included in the `system:bootstrappers` group. The naming and groups are
|
||||
intentionally limited to discourage users from using these tokens past
|
||||
bootstrapping. The user names and group can be used (and are used by `kubeadm`)
|
||||
to craft the appropriate authorization policies to support bootstrapping a
|
||||
cluster.
|
||||
|
||||
Please see [Bootstrap Tokens](/docs/admin/bootstrap-tokens/) for in depth
|
||||
documentation on the Bootstrap Token authenticator and controllers along with
|
||||
how to manage these tokens with `kubeadm`.
|
||||
|
||||
### Static Password File
|
||||
|
||||
Basic authentication is enabled by passing the `--basic-auth-file=SOMEFILE`
|
||||
option to API server. Currently, the basic auth credentials last indefinitely,
|
||||
and the password cannot be changed without restarting API server. Note that basic
|
||||
authentication is currently supported for convenience while we finish making the
|
||||
more secure modes described above easier to use.
|
||||
|
||||
The basic auth file is a csv file with a minimum of 3 columns: password, user name, user id.
|
||||
In Kubernetes version 1.6 and later, you can specify an optional fourth column containing
|
||||
comma-separated group names. If you have more than one group, you must enclose the fourth
|
||||
column value in double quotes ("). See the following example:
|
||||
|
||||
```conf
|
||||
password,user,uid,"group1,group2,group3"
|
||||
```
|
||||
|
||||
When using basic authentication from an http client, the API server expects an `Authorization` header
|
||||
with a value of `Basic BASE64ENCODED(USER:PASSWORD)`.
|
||||
|
||||
### Service Account Tokens
|
||||
|
||||
A service account is an automatically enabled authenticator that uses signed
|
||||
bearer tokens to verify requests. The plugin takes two optional flags:
|
||||
|
||||
* `--service-account-key-file` A file containing a PEM encoded key for signing bearer tokens.
|
||||
If unspecified, the API server's TLS private key will be used.
|
||||
* `--service-account-lookup` If enabled, tokens which are deleted from the API will be revoked.
|
||||
|
||||
Service accounts are usually created automatically by the API server and
|
||||
associated with pods running in the cluster through the `ServiceAccount`
|
||||
[Admission Controller](/docs/admin/admission-controllers/). Bearer tokens are
|
||||
mounted into pods at well-known locations, and allow in-cluster processes to
|
||||
talk to the API server. Accounts may be explicitly associated with pods using the
|
||||
`serviceAccountName` field of a `PodSpec`.
|
||||
|
||||
NOTE: `serviceAccountName` is usually omitted because this is done automatically.
|
||||
|
||||
```
|
||||
apiVersion: apps/v1 # this apiVersion is relevant as of Kubernetes 1.9
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
namespace: default
|
||||
spec:
|
||||
replicas: 3
|
||||
template:
|
||||
metadata:
|
||||
# ...
|
||||
spec:
|
||||
serviceAccountName: bob-the-bot
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.7.9
|
||||
```
|
||||
|
||||
Service account bearer tokens are perfectly valid to use outside the cluster and
|
||||
can be used to create identities for long standing jobs that wish to talk to the
|
||||
Kubernetes API. To manually create a service account, simply use the `kubectl
|
||||
create serviceaccount (NAME)` command. This creates a service account in the
|
||||
current namespace and an associated secret.
|
||||
|
||||
```
|
||||
$ kubectl create serviceaccount jenkins
|
||||
serviceaccount "jenkins" created
|
||||
$ kubectl get serviceaccounts jenkins -o yaml
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
# ...
|
||||
secrets:
|
||||
- name: jenkins-token-1yvwg
|
||||
```
|
||||
|
||||
The created secret holds the public CA of the API server and a signed JSON Web
|
||||
Token (JWT).
|
||||
|
||||
```
|
||||
$ kubectl get secret jenkins-token-1yvwg -o yaml
|
||||
apiVersion: v1
|
||||
data:
|
||||
ca.crt: (APISERVER'S CA BASE64 ENCODED)
|
||||
namespace: ZGVmYXVsdA==
|
||||
token: (BEARER TOKEN BASE64 ENCODED)
|
||||
kind: Secret
|
||||
metadata:
|
||||
# ...
|
||||
type: kubernetes.io/service-account-token
|
||||
```
|
||||
|
||||
Note: values are base64 encoded because secrets are always base64 encoded.
|
||||
|
||||
The signed JWT can be used as a bearer token to authenticate as the given service
|
||||
account. See [above](#putting-a-bearer-token-in-a-request) for how the token is included
|
||||
in a request. Normally these secrets are mounted into pods for in-cluster access to
|
||||
the API server, but can be used from outside the cluster as well.
|
||||
|
||||
Service accounts authenticate with the username `system:serviceaccount:(NAMESPACE):(SERVICEACCOUNT)`,
|
||||
and are assigned to the groups `system:serviceaccounts` and `system:serviceaccounts:(NAMESPACE)`.
|
||||
|
||||
WARNING: Because service account tokens are stored in secrets, any user with
|
||||
read access to those secrets can authenticate as the service account. Be cautious
|
||||
when granting permissions to service accounts and read capabilities for secrets.
|
||||
|
||||
### OpenID Connect Tokens
|
||||
|
||||
[OpenID Connect](https://openid.net/connect/) is a flavor of OAuth2 supported by
|
||||
some OAuth2 providers, notably Azure Active Directory, Salesforce, and Google.
|
||||
The protocol's main extension of OAuth2 is an additional field returned with
|
||||
the access token called an [ID Token](https://openid.net/specs/openid-connect-core-1_0.html#IDToken).
|
||||
This token is a JSON Web Token (JWT) with well known fields, such as a user's
|
||||
email, signed by the server.
|
||||
|
||||
To identify the user, the authenticator uses the `id_token` (not the `access_token`)
|
||||
from the OAuth2 [token response](https://openid.net/specs/openid-connect-core-1_0.html#TokenResponse)
|
||||
as a bearer token. See [above](#putting-a-bearer-token-in-a-request) for how the token
|
||||
is included in a request.
|
||||
|
||||

|
||||
|
||||
1. Login to your identity provider
|
||||
2. Your identity provider will provide you with an `access_token`, `id_token` and a `refresh_token`
|
||||
3. When using `kubectl`, use your `id_token` with the `--token` flag or add it directly to your `kubeconfig`
|
||||
4. `kubectl` sends your `id_token` in a header called Authorization to the API server
|
||||
5. The API server will make sure the JWT signature is valid by checking against the certificate named in the configuration
|
||||
6. Check to make sure the `id_token` hasn't expired
|
||||
7. Make sure the user is authorized
|
||||
8. Once authorized the API server returns a response to `kubectl`
|
||||
9. `kubectl` provides feedback to the user
|
||||
|
||||
Since all of the data needed to validate who you are is in the `id_token`, Kubernetes doesn't need to
|
||||
"phone home" to the identity provider. In a model where every request is stateless this provides a very scalable
|
||||
solution for authentication. It does offer a few challenges:
|
||||
|
||||
1. Kubernetes has no "web interface" to trigger the authentication process. There is no browser or interface to collect credentials which is why you need to authenticate to your identity provider first.
|
||||
2. The `id_token` can't be revoked, it's like a certificate so it should be short-lived (only a few minutes) so it can be very annoying to have to get a new token every few minutes.
|
||||
3. There's no easy way to authenticate to the Kubernetes dashboard without using the `kubectl proxy` command or a reverse proxy that injects the `id_token`.
|
||||
|
||||
|
||||
#### Configuring the API Server
|
||||
|
||||
To enable the plugin, configure the following flags on the API server:
|
||||
|
||||
| Parameter | Description | Example | Required |
|
||||
| --------- | ----------- | ------- | ------- |
|
||||
| `--oidc-issuer-url` | URL of the provider which allows the API server to discover public signing keys. Only URLs which use the `https://` scheme are accepted. This is typically the provider's discovery URL without a path, for example "https://accounts.google.com" or "https://login.salesforce.com". This URL should point to the level below .well-known/openid-configuration | If the discovery URL is `https://accounts.google.com/.well-known/openid-configuration`, the value should be `https://accounts.google.com` | Yes |
|
||||
| `--oidc-client-id` | A client id that all tokens must be issued for. | kubernetes | Yes |
|
||||
| `--oidc-username-claim` | JWT claim to use as the user name. By default `sub`, which is expected to be a unique identifier of the end user. Admins can choose other claims, such as `email` or `name`, depending on their provider. However, claims other than `email` will be prefixed with the issuer URL to prevent naming clashes with other plugins. | sub | No |
|
||||
| `--oidc-username-prefix` | Prefix prepended to username claims to prevent clashes with existing names (such as `system:` users). For example, the value `oidc:` will create usernames like `oidc:jane.doe`. If this flag isn't provided and `--oidc-user-claim` is a value other than `email` the prefix defaults to `( Issuer URL )#` where `( Issuer URL )` is the value of `--oidc-issuer-url`. The value `-` can be used to disable all prefixing. | `oidc:` | No |
|
||||
| `--oidc-groups-claim` | JWT claim to use as the user's group. If the claim is present it must be an array of strings. | groups | No |
|
||||
| `--oidc-groups-prefix` | Prefix prepended to group claims to prevent clashes with existing names (such as `system:` groups). For example, the value `oidc:` will create group names like `oidc:engineering` and `oidc:infra`. | `oidc:` | No |
|
||||
| `--oidc-ca-file` | The path to the certificate for the CA that signed your identity provider's web certificate. Defaults to the host's root CAs. | `/etc/kubernetes/ssl/kc-ca.pem` | No |
|
||||
|
||||
Importantly, the API server is not an OAuth2 client, rather it can only be
|
||||
configured to trust a single issuer. This allows the use of public providers,
|
||||
such as Google, without trusting credentials issued to third parties. Admins who
|
||||
wish to utilize multiple OAuth clients should explore providers which support the
|
||||
`azp` (authorized party) claim, a mechanism for allowing one client to issue
|
||||
tokens on behalf of another.
|
||||
|
||||
Kubernetes does not provide an OpenID Connect Identity Provider.
|
||||
You can use an existing public OpenID Connect Identity Provider (such as Google, or [others](http://connect2id.com/products/nimbus-oauth-openid-connect-sdk/openid-connect-providers)).
|
||||
Or, you can run your own Identity Provider, such as CoreOS [dex](https://github.com/coreos/dex), [Keycloak](https://github.com/keycloak/keycloak), CloudFoundry [UAA](https://github.com/cloudfoundry/uaa), or Tremolo Security's [OpenUnison](https://github.com/tremolosecurity/openunison).
|
||||
|
||||
For an identity provider to work with Kubernetes it must:
|
||||
|
||||
1. Support [OpenID connect discovery](https://openid.net/specs/openid-connect-discovery-1_0.html); not all do.
|
||||
2. Run in TLS with non-obsolete ciphers
|
||||
3. Have a CA signed certificate (even if the CA is not a commercial CA or is self signed)
|
||||
|
||||
A note about requirement #3 above, requiring a CA signed certificate. If you deploy your own identity provider (as opposed to one of the cloud providers like Google or Microsoft) you MUST have your identity provider's web server certificate signed by a certificate with the `CA` flag set to `TRUE`, even if it is self signed. This is due to GoLang's TLS client implementation being very strict to the standards around certificate validation. If you don't have a CA handy, you can use [this script](https://github.com/coreos/dex/blob/1ee5920c54f5926d6468d2607c728b71cfe98092/examples/k8s/gencert.sh) from the CoreOS team to create a simple CA and a signed certificate and key pair.
|
||||
Or you can use [this similar script](https://raw.githubusercontent.com/TremoloSecurity/openunison-qs-kubernetes/master/src/main/bash/makessl.sh) that generates SHA256 certs with a longer life and larger key size.
|
||||
|
||||
Setup instructions for specific systems:
|
||||
|
||||
- [UAA](http://apigee.com/about/blog/engineering/kubernetes-authentication-enterprise)
|
||||
- [Dex](https://speakerdeck.com/ericchiang/kubernetes-access-control-with-dex)
|
||||
- [OpenUnison](https://github.com/TremoloSecurity/openunison-qs-kubernetes)
|
||||
|
||||
#### Using kubectl
|
||||
|
||||
##### Option 1 - OIDC Authenticator
|
||||
|
||||
The first option is to use the kubectl `oidc` authenticator, which sets the `id_token` as a bearer token for all requests and refreshes the token once it expires. After you've logged into your provider, use kubectl to add your `id_token`, `refresh_token`, `client_id`, and `client_secret` to configure the plugin.
|
||||
|
||||
Providers that don't return an `id_token` as part of their refresh token response (e.g. [Okta](https://developer.okta.com/docs/api/resources/oidc.html#response-parameters-4)) aren't supported by this plugin and should use "Option 2" below.
|
||||
|
||||
```bash
|
||||
kubectl config set-credentials USER_NAME \
|
||||
--auth-provider=oidc \
|
||||
--auth-provider-arg=idp-issuer-url=( issuer url ) \
|
||||
--auth-provider-arg=client-id=( your client id ) \
|
||||
--auth-provider-arg=client-secret=( your client secret ) \
|
||||
--auth-provider-arg=refresh-token=( your refresh token ) \
|
||||
--auth-provider-arg=idp-certificate-authority=( path to your ca certificate ) \
|
||||
--auth-provider-arg=id-token=( your id_token )
|
||||
```
|
||||
|
||||
As an example, running the below command after authenticating to your identity provider:
|
||||
|
||||
```bash
|
||||
kubectl config set-credentials mmosley \
|
||||
--auth-provider=oidc \
|
||||
--auth-provider-arg=idp-issuer-url=https://oidcidp.tremolo.lan:8443/auth/idp/OidcIdP \
|
||||
--auth-provider-arg=client-id=kubernetes \
|
||||
--auth-provider-arg=client-secret=1db158f6-177d-4d9c-8a8b-d36869918ec5 \
|
||||
--auth-provider-arg=refresh-token=q1bKLFOyUiosTfawzA93TzZIDzH2TNa2SMm0zEiPKTUwME6BkEo6Sql5yUWVBSWpKUGphaWpxSVAfekBOZbBhaEW+VlFUeVRGcluyVF5JT4+haZmPsluFoFu5XkpXk5BXqHega4GAXlF+ma+vmYpFcHe5eZR+slBFpZKtQA= \
|
||||
--auth-provider-arg=idp-certificate-authority=/root/ca.pem \
|
||||
--auth-provider-arg=id-token=eyJraWQiOiJDTj1vaWRjaWRwLnRyZW1vbG8ubGFuLCBPVT1EZW1vLCBPPVRybWVvbG8gU2VjdXJpdHksIEw9QXJsaW5ndG9uLCBTVD1WaXJnaW5pYSwgQz1VUy1DTj1rdWJlLWNhLTEyMDIxNDc5MjEwMzYwNzMyMTUyIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL29pZGNpZHAudHJlbW9sby5sYW46ODQ0My9hdXRoL2lkcC9PaWRjSWRQIiwiYXVkIjoia3ViZXJuZXRlcyIsImV4cCI6MTQ4MzU0OTUxMSwianRpIjoiMm96US15TXdFcHV4WDlHZUhQdy1hZyIsImlhdCI6MTQ4MzU0OTQ1MSwibmJmIjoxNDgzNTQ5MzMxLCJzdWIiOiI0YWViMzdiYS1iNjQ1LTQ4ZmQtYWIzMC0xYTAxZWU0MWUyMTgifQ.w6p4J_6qQ1HzTG9nrEOrubxIMb9K5hzcMPxc9IxPx2K4xO9l-oFiUw93daH3m5pluP6K7eOE6txBuRVfEcpJSwlelsOsW8gb8VJcnzMS9EnZpeA0tW_p-mnkFc3VcfyXuhe5R3G7aa5d8uHv70yJ9Y3-UhjiN9EhpMdfPAoEB9fYKKkJRzF7utTTIPGrSaSU6d2pcpfYKaxIwePzEkT4DfcQthoZdy9ucNvvLoi1DIC-UocFD8HLs8LYKEqSxQvOcvnThbObJ9af71EwmuE21fO5KzMW20KtAeget1gnldOosPtz1G5EwvaQ401-RPQzPGMVBld0_zMCAwZttJ4knw
|
||||
```
|
||||
|
||||
Which would produce the below configuration:
|
||||
|
||||
```yaml
|
||||
users:
|
||||
- name: mmosley
|
||||
user:
|
||||
auth-provider:
|
||||
config:
|
||||
client-id: kubernetes
|
||||
client-secret: 1db158f6-177d-4d9c-8a8b-d36869918ec5
|
||||
id-token: eyJraWQiOiJDTj1vaWRjaWRwLnRyZW1vbG8ubGFuLCBPVT1EZW1vLCBPPVRybWVvbG8gU2VjdXJpdHksIEw9QXJsaW5ndG9uLCBTVD1WaXJnaW5pYSwgQz1VUy1DTj1rdWJlLWNhLTEyMDIxNDc5MjEwMzYwNzMyMTUyIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL29pZGNpZHAudHJlbW9sby5sYW46ODQ0My9hdXRoL2lkcC9PaWRjSWRQIiwiYXVkIjoia3ViZXJuZXRlcyIsImV4cCI6MTQ4MzU0OTUxMSwianRpIjoiMm96US15TXdFcHV4WDlHZUhQdy1hZyIsImlhdCI6MTQ4MzU0OTQ1MSwibmJmIjoxNDgzNTQ5MzMxLCJzdWIiOiI0YWViMzdiYS1iNjQ1LTQ4ZmQtYWIzMC0xYTAxZWU0MWUyMTgifQ.w6p4J_6qQ1HzTG9nrEOrubxIMb9K5hzcMPxc9IxPx2K4xO9l-oFiUw93daH3m5pluP6K7eOE6txBuRVfEcpJSwlelsOsW8gb8VJcnzMS9EnZpeA0tW_p-mnkFc3VcfyXuhe5R3G7aa5d8uHv70yJ9Y3-UhjiN9EhpMdfPAoEB9fYKKkJRzF7utTTIPGrSaSU6d2pcpfYKaxIwePzEkT4DfcQthoZdy9ucNvvLoi1DIC-UocFD8HLs8LYKEqSxQvOcvnThbObJ9af71EwmuE21fO5KzMW20KtAeget1gnldOosPtz1G5EwvaQ401-RPQzPGMVBld0_zMCAwZttJ4knw
|
||||
idp-certificate-authority: /root/ca.pem
|
||||
idp-issuer-url: https://oidcidp.tremolo.lan:8443/auth/idp/OidcIdP
|
||||
refresh-token: q1bKLFOyUiosTfawzA93TzZIDzH2TNa2SMm0zEiPKTUwME6BkEo6Sql5yUWVBSWpKUGphaWpxSVAfekBOZbBhaEW+VlFUeVRGcluyVF5JT4+haZmPsluFoFu5XkpXk5BXq
|
||||
name: oidc
|
||||
```
|
||||
Once your `id_token` expires, `kubectl` will attempt to refresh your `id_token` using your `refresh_token` and `client_secret` storing the new values for the `refresh_token` and `id_token` in your `.kube/config`.
|
||||
|
||||
|
||||
##### Option 2 - Use the `--token` Option
|
||||
|
||||
The `kubectl` command lets you pass in a token using the `--token` option. Simply copy and paste the `id_token` into this option:
|
||||
|
||||
```
|
||||
kubectl --token=eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL21sYi50cmVtb2xvLmxhbjo4MDQzL2F1dGgvaWRwL29pZGMiLCJhdWQiOiJrdWJlcm5ldGVzIiwiZXhwIjoxNDc0NTk2NjY5LCJqdGkiOiI2RDUzNXoxUEpFNjJOR3QxaWVyYm9RIiwiaWF0IjoxNDc0NTk2MzY5LCJuYmYiOjE0NzQ1OTYyNDksInN1YiI6Im13aW5kdSIsInVzZXJfcm9sZSI6WyJ1c2VycyIsIm5ldy1uYW1lc3BhY2Utdmlld2VyIl0sImVtYWlsIjoibXdpbmR1QG5vbW9yZWplZGkuY29tIn0.f2As579n9VNoaKzoF-dOQGmXkFKf1FMyNV0-va_B63jn-_n9LGSCca_6IVMP8pO-Zb4KvRqGyTP0r3HkHxYy5c81AnIh8ijarruczl-TK_yF5akjSTHFZD-0gRzlevBDiH8Q79NAr-ky0P4iIXS8lY9Vnjch5MF74Zx0c3alKJHJUnnpjIACByfF2SCaYzbWFMUNat-K1PaUk5-ujMBG7yYnr95xD-63n8CO8teGUAAEMx6zRjzfhnhbzX-ajwZLGwGUBT4WqjMs70-6a7_8gZmLZb2az1cZynkFRj2BaCkVT3A2RrjeEwZEtGXlMqKJ1_I2ulrOVsYx01_yD35-rw get nodes
|
||||
```
|
||||
|
||||
|
||||
### Webhook Token Authentication
|
||||
|
||||
Webhook authentication is a hook for verifying bearer tokens.
|
||||
|
||||
* `--authentication-token-webhook-config-file` a kubeconfig file describing how to access the remote webhook service.
|
||||
* `--authentication-token-webhook-cache-ttl` how long to cache authentication decisions. Defaults to two minutes.
|
||||
|
||||
The configuration file uses the [kubeconfig](/docs/concepts/cluster-administration/authenticate-across-clusters-kubeconfig/)
|
||||
file format. Within the file "users" refers to the API server webhook and
|
||||
"clusters" refers to the remote service. An example would be:
|
||||
|
||||
```yaml
|
||||
# clusters refers to the remote service.
|
||||
clusters:
|
||||
- name: name-of-remote-authn-service
|
||||
cluster:
|
||||
certificate-authority: /path/to/ca.pem # CA for verifying the remote service.
|
||||
server: https://authn.example.com/authenticate # URL of remote service to query. Must use 'https'.
|
||||
|
||||
# users refers to the API server's webhook configuration.
|
||||
users:
|
||||
- name: name-of-api-server
|
||||
user:
|
||||
client-certificate: /path/to/cert.pem # cert for the webhook plugin to use
|
||||
client-key: /path/to/key.pem # key matching the cert
|
||||
|
||||
# kubeconfig files require a context. Provide one for the API server.
|
||||
current-context: webhook
|
||||
contexts:
|
||||
- context:
|
||||
cluster: name-of-remote-authn-service
|
||||
user: name-of-api-sever
|
||||
name: webhook
|
||||
```
|
||||
|
||||
When a client attempts to authenticate with the API server using a bearer token
|
||||
as discussed [above](#putting-a-bearer-token-in-a-request),
|
||||
the authentication webhook POSTs a JSON-serialized `authentication.k8s.io/v1beta1` `TokenReview` object containing the token
|
||||
to the remote service. Kubernetes will not challenge a request that lacks such a header.
|
||||
|
||||
Note that webhook API objects are subject to the same [versioning compatibility rules](/docs/concepts/overview/kubernetes-api/)
|
||||
as other Kubernetes API objects. Implementers should be aware of looser
|
||||
compatibility promises for beta objects and check the "apiVersion" field of the
|
||||
request to ensure correct deserialization. Additionally, the API server must
|
||||
enable the `authentication.k8s.io/v1beta1` API extensions group (`--runtime-config=authentication.k8s.io/v1beta1=true`).
|
||||
|
||||
The POST body will be of the following format:
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "authentication.k8s.io/v1beta1",
|
||||
"kind": "TokenReview",
|
||||
"spec": {
|
||||
"token": "(BEARERTOKEN)"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The remote service is expected to fill the `status` field of
|
||||
the request to indicate the success of the login. The response body's `spec`
|
||||
field is ignored and may be omitted. A successful validation of the bearer
|
||||
token would return:
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "authentication.k8s.io/v1beta1",
|
||||
"kind": "TokenReview",
|
||||
"status": {
|
||||
"authenticated": true,
|
||||
"user": {
|
||||
"username": "janedoe@example.com",
|
||||
"uid": "42",
|
||||
"groups": [
|
||||
"developers",
|
||||
"qa"
|
||||
],
|
||||
"extra": {
|
||||
"extrafield1": [
|
||||
"extravalue1",
|
||||
"extravalue2"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
An unsuccessful request would return:
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "authentication.k8s.io/v1beta1",
|
||||
"kind": "TokenReview",
|
||||
"status": {
|
||||
"authenticated": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
HTTP status codes can be used to supply additional error context.
|
||||
|
||||
|
||||
### Authenticating Proxy
|
||||
|
||||
The API server can be configured to identify users from request header values, such as `X-Remote-User`.
|
||||
It is designed for use in combination with an authenticating proxy, which sets the request header value.
|
||||
|
||||
* `--requestheader-username-headers` Required, case-insensitive. Header names to check, in order, for the user identity. The first header containing a value is used as the username.
|
||||
* `--requestheader-group-headers` 1.6+. Optional, case-insensitive. "X-Remote-Group" is suggested. Header names to check, in order, for the user's groups. All values in all specified headers are used as group names.
|
||||
* `--requestheader-extra-headers-prefix` 1.6+. Optional, case-insensitive. "X-Remote-Extra-" is suggested. Header prefixes to look for to determine extra information about the user (typically used by the configured authorization plugin). Any headers beginning with any of the specified prefixes have the prefix removed, the remainder of the header name becomes the extra key, and the header value is the extra value.
|
||||
|
||||
For example, with this configuration:
|
||||
|
||||
```
|
||||
--requestheader-username-headers=X-Remote-User
|
||||
--requestheader-group-headers=X-Remote-Group
|
||||
--requestheader-extra-headers-prefix=X-Remote-Extra-
|
||||
```
|
||||
|
||||
this request:
|
||||
|
||||
```
|
||||
GET / HTTP/1.1
|
||||
X-Remote-User: fido
|
||||
X-Remote-Group: dogs
|
||||
X-Remote-Group: dachshunds
|
||||
X-Remote-Extra-Scopes: openid
|
||||
X-Remote-Extra-Scopes: profile
|
||||
```
|
||||
|
||||
would result in this user info:
|
||||
|
||||
```yaml
|
||||
name: fido
|
||||
groups:
|
||||
- dogs
|
||||
- dachshunds
|
||||
extra:
|
||||
scopes:
|
||||
- openid
|
||||
- profile
|
||||
```
|
||||
|
||||
|
||||
In order to prevent header spoofing, the authenticating proxy is required to present a valid client
|
||||
certificate to the API server for validation against the specified CA before the request headers are
|
||||
checked.
|
||||
|
||||
* `--requestheader-client-ca-file` Required. PEM-encoded certificate bundle. A valid client certificate must be presented and validated against the certificate authorities in the specified file before the request headers are checked for user names.
|
||||
* `--requestheader-allowed-names` Optional. List of common names (cn). If set, a valid client certificate with a Common Name (cn) in the specified list must be presented before the request headers are checked for user names. If empty, any Common Name is allowed.
|
||||
|
||||
|
||||
## Anonymous requests
|
||||
|
||||
When enabled, requests that are not rejected by other configured authentication methods are
|
||||
treated as anonymous requests, and given a username of `system:anonymous` and a group of
|
||||
`system:unauthenticated`.
|
||||
|
||||
For example, on a server with token authentication configured, and anonymous access enabled,
|
||||
a request providing an invalid bearer token would receive a `401 Unauthorized` error.
|
||||
A request providing no bearer token would be treated as an anonymous request.
|
||||
|
||||
In 1.5.1-1.5.x, anonymous access is disabled by default, and can be enabled by
|
||||
passing the `--anonymous-auth=true` option to the API server.
|
||||
|
||||
In 1.6+, anonymous access is enabled by default if an authorization mode other than `AlwaysAllow`
|
||||
is used, and can be disabled by passing the `--anonymous-auth=false` option to the API server.
|
||||
Starting in 1.6, the ABAC and RBAC authorizers require explicit authorization of the
|
||||
`system:anonymous` user or the `system:unauthenticated` group, so legacy policy rules
|
||||
that grant access to the `*` user or `*` group do not include anonymous users.
|
||||
|
||||
## User impersonation
|
||||
|
||||
A user can act as another user through impersonation headers. These let requests
|
||||
manually override the user info a request authenticates as. For example, an admin
|
||||
could use this feature to debug an authorization policy by temporarily
|
||||
impersonating another user and seeing if a request was denied.
|
||||
|
||||
Impersonation requests first authenticate as the requesting user, then switch
|
||||
to the impersonated user info.
|
||||
|
||||
* A user makes an API call with their credentials _and_ impersonation headers.
|
||||
* API server authenticates the user.
|
||||
* API server ensures the authenticated users has impersonation privileges.
|
||||
* Request user info is replaced with impersonation values.
|
||||
* Request is evaluated, authorization acts on impersonated user info.
|
||||
|
||||
The following HTTP headers can be used to performing an impersonation request:
|
||||
|
||||
* `Impersonate-User`: The username to act as.
|
||||
* `Impersonate-Group`: A group name to act as. Can be provided multiple times to set multiple groups. Optional. Requires "Impersonate-User"
|
||||
* `Impersonate-Extra-( extra name )`: A dynamic header used to associate extra fields with the user. Optional. Requires "Impersonate-User"
|
||||
|
||||
An example set of headers:
|
||||
|
||||
```http
|
||||
Impersonate-User: jane.doe@example.com
|
||||
Impersonate-Group: developers
|
||||
Impersonate-Group: admins
|
||||
Impersonate-Extra-dn: cn=jane,ou=engineers,dc=example,dc=com
|
||||
Impersonate-Extra-scopes: view
|
||||
Impersonate-Extra-scopes: development
|
||||
```
|
||||
|
||||
When using `kubectl` set the `--as` flag to configure the `Impersonate-User`
|
||||
header, set the `--as-group` flag to configure the `Impersonate-Group` header.
|
||||
|
||||
```shell
|
||||
$ kubectl drain mynode
|
||||
Error from server (Forbidden): User "clark" cannot get nodes at the cluster scope. (get nodes mynode)
|
||||
|
||||
$ kubectl drain mynode --as=superman --as-group=system:masters
|
||||
node "mynode" cordoned
|
||||
node "mynode" drained
|
||||
```
|
||||
|
||||
To impersonate a user, group, or set extra fields, the impersonating user must
|
||||
have the ability to perform the "impersonate" verb on the kind of attribute
|
||||
being impersonated ("user", "group", etc.). For clusters that enable the RBAC
|
||||
authorization plugin, the following ClusterRole encompasses the rules needed to
|
||||
set user and group impersonation headers:
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: impersonator
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["users", "groups", "serviceaccounts"]
|
||||
verbs: ["impersonate"]
|
||||
```
|
||||
|
||||
Extra fields are evaluated as sub-resources of the resource "userextras". To
|
||||
allow a user to use impersonation headers for the extra field "scopes," a user
|
||||
should be granted the following role:
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: scopes-impersonator
|
||||
rules:
|
||||
# Can set "Impersonate-Extra-scopes" header.
|
||||
- apiGroups: ["authentication.k8s.io"]
|
||||
resources: ["userextras/scopes"]
|
||||
verbs: ["impersonate"]
|
||||
```
|
||||
|
||||
The values of impersonation headers can also be restricted by limiting the set
|
||||
of `resourceNames` a resource can take.
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: limited-impersonator
|
||||
rules:
|
||||
# Can impersonate the user "jane.doe@example.com"
|
||||
- apiGroups: [""]
|
||||
resources: ["users"]
|
||||
verbs: ["impersonate"]
|
||||
resourceNames: ["jane.doe@example.com"]
|
||||
|
||||
# Can impersonate the groups "developers" and "admins"
|
||||
- apiGroups: [""]
|
||||
resources: ["groups"]
|
||||
verbs: ["impersonate"]
|
||||
resourceNames: ["developers","admins"]
|
||||
|
||||
# Can impersonate the extras field "scopes" with the values "view" and "development"
|
||||
- apiGroups: ["authentication.k8s.io"]
|
||||
resources: ["userextras/scopes"]
|
||||
verbs: ["impersonate"]
|
||||
resourceNames: ["view", "development"]
|
||||
```
|
||||
|
||||
## client-go credential plugins
|
||||
|
||||
{{< feature-state for_k8s_version="v1.10" state="alpha" >}}
|
||||
|
||||
`k8s.io/client-go` and tools using it such as `kubectl` and `kubelet` are able to execute an
|
||||
external command to receive user credentials.
|
||||
|
||||
This feature is intended for client side integrations with authentication protocols not natively
|
||||
supported by `k8s.io/client-go` (LDAP, Kerberos, OAuth2, SAML, etc.). The plugin implements the
|
||||
protocol specific logic, then returns opaque credentials to use. Almost all credential plugin
|
||||
use cases require a server side component with support for the [webhook token authenticator](#webhook-token-authentication)
|
||||
to interpret the credential format produced by the client plugin.
|
||||
|
||||
As of 1.10 only bearer tokens are supported. Support for client certs may be added in a future release.
|
||||
|
||||
### Example use case
|
||||
|
||||
In a hypothetical use case, an organization would run an external service that exchanges LDAP credentials
|
||||
for user specific, signed tokens. The service would also be capable of responding to [webhook token
|
||||
authenticator](#webhook-token-authentication) requests to validate the tokens. Users would be required
|
||||
to install a credential plugin on their workstation.
|
||||
|
||||
To authenticate against the API:
|
||||
|
||||
* The user issues a `kubectl` command.
|
||||
* Credential plugin prompts the user for LDAP credentials, exchanges credentials with external service for a token.
|
||||
* Credential plugin returns token to client-go, which uses it as a bearer token against the API server.
|
||||
* API server uses the [webhook token authenticator](#webhook-token-authentication) to submit a `TokenReview` to the external service.
|
||||
* External service verifies the signature on the token and returns the user's username and groups.
|
||||
|
||||
### Configuration
|
||||
|
||||
Credential plugins are configured through [`kubectl` config files](/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)
|
||||
as part of the user fields.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Config
|
||||
users:
|
||||
- name: my-user
|
||||
user:
|
||||
exec:
|
||||
# Command to execute. Required.
|
||||
command: "example-client-go-exec-plugin"
|
||||
|
||||
# API version to use when encoding and decoding the ExecCredentials
|
||||
# resource. Required.
|
||||
#
|
||||
# The API version returned by the plugin MUST match the version encoded.
|
||||
apiVersion: "client.authentication.k8s.io/v1alpha1"
|
||||
|
||||
# Environment variables to set when executing the plugin. Optional.
|
||||
env:
|
||||
- name: "FOO"
|
||||
value: "bar"
|
||||
|
||||
# Arguments to pass when executing the plugin. Optional.
|
||||
args:
|
||||
- "arg1"
|
||||
- "arg2"
|
||||
clusters:
|
||||
- name: my-cluster
|
||||
cluster:
|
||||
server: "https://172.17.4.100:6443"
|
||||
certificate-authority: "/etc/kubernetes/ca.pem"
|
||||
contexts:
|
||||
- name: my-cluster
|
||||
context:
|
||||
cluster: my-cluster
|
||||
user: my-user
|
||||
current-context: my-cluster
|
||||
```
|
||||
|
||||
Relative command paths are interpreted as relative to the directory of the config file. If
|
||||
KUBECONFIG is set to `/home/jane/kubeconfig` and the exec command is `./bin/example-client-go-exec-plugin`,
|
||||
the binary `/home/jane/bin/example-client-go-exec-plugin` is executed.
|
||||
|
||||
```yaml
|
||||
- name: my-user
|
||||
user:
|
||||
exec:
|
||||
# Path relative to the directory of the kubeconfig
|
||||
command: "./bin/example-client-go-exec-plugin"
|
||||
apiVersion: "client.authentication.k8s.io/v1alpha1"
|
||||
```
|
||||
|
||||
### Input and output formats
|
||||
|
||||
When executing the command, `k8s.io/client-go` sets the `KUBERNETES_EXEC_INFO` environment
|
||||
variable to a JSON serialized [`ExecCredential`](
|
||||
https://github.com/kubernetes/client-go/blob/master/pkg/apis/clientauthentication/v1alpha1/types.go)
|
||||
resource.
|
||||
|
||||
```
|
||||
KUBERNETES_EXEC_INFO='{
|
||||
"apiVersion": "client.authentication.k8s.io/v1alpha1",
|
||||
"kind": "ExecCredential",
|
||||
"spec": {
|
||||
"interactive": true
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
When plugins are executed from an interactive session, `stdin` and `stderr` are directly
|
||||
exposed to the plugin so it can prompt the user for input for interactive logins.
|
||||
|
||||
When responding to a 401 HTTP status code (indicating invalid credentials), this object will
|
||||
include metadata about the response.
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "client.authentication.k8s.io/v1alpha1",
|
||||
"kind": "ExecCredential",
|
||||
"spec": {
|
||||
"response": {
|
||||
"code": 401,
|
||||
"header": {
|
||||
"WWW-Authenticate": [
|
||||
"Bearer realm=ldap.example.com"
|
||||
]
|
||||
},
|
||||
},
|
||||
"interactive": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The executed command is expected to print an `ExceCredential` to `stdout`. `k8s.io/client-go`
|
||||
will then use the returned bearer token in the `status` when authenticating against the
|
||||
Kubernetes API.
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "client.authentication.k8s.io/v1alpha1",
|
||||
"kind": "ExecCredential",
|
||||
"status": {
|
||||
"token": "my-bearer-token"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Optionally, this output can include the expiry of the token formatted as a RFC3339 timestamp.
|
||||
If an expiry is omitted, the bearer token is cached until the server responds with a 401 HTTP
|
||||
status code. Note that this caching is only for the duration of process and therefore the plugin
|
||||
is triggered each time the tool using the plugin is invoked.
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "client.authentication.k8s.io/v1alpha1",
|
||||
"kind": "ExecCredential",
|
||||
"status": {
|
||||
"token": "my-bearer-token",
|
||||
"expirationTimestamp": "2018-03-05T17:30:20-08:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -1,184 +0,0 @@
|
||||
---
|
||||
reviewers:
|
||||
- erictune
|
||||
- lavalamp
|
||||
- deads2k
|
||||
- liggitt
|
||||
title: Overview
|
||||
content_template: templates/concept
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
Learn more about Kubernetes authorization, including details about creating
|
||||
policies using the supported authorization modules.
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
In Kubernetes, you must be authenticated (logged in) before your request can be
|
||||
authorized (granted permission to access). For information about authentication,
|
||||
see [Accessing Control Overview](/docs/admin/accessing-the-api/).
|
||||
|
||||
Kubernetes expects attributes that are common to REST API requests. This means
|
||||
that Kubernetes authorization works with existing organization-wide or
|
||||
cloud-provider-wide access control systems which may handle other APIs besides
|
||||
the Kubernetes API.
|
||||
|
||||
## Determine Whether a Request is Allowed or Denied
|
||||
Kubernetes authorizes API requests using the API server. It evaluates all of the
|
||||
request attributes against all policies and allows or denies the request. All
|
||||
parts of an API request must be allowed by some policy in order to proceed. This
|
||||
means that permissions are denied by default.
|
||||
|
||||
(Although Kubernetes uses the API server, access controls and policies that
|
||||
depend on specific fields of specific kinds of objects are handled by Admission
|
||||
Controllers.)
|
||||
|
||||
When multiple authorization modules are configured, each is checked in sequence.
|
||||
If any authorizer approves or denies a request, that decision is immediately
|
||||
returned and no other authorizer is consulted. If all modules have no opinion on
|
||||
the request, then the request is denied. A deny returns an HTTP status code 403.
|
||||
|
||||
## Review Your Request Attributes
|
||||
Kubernetes reviews only the following API request attributes:
|
||||
|
||||
* **user** - The `user` string provided during authentication.
|
||||
* **group** - The list of group names to which the authenticated user belongs.
|
||||
* **"extra"** - A map of arbitrary string keys to string values, provided by the authentication layer.
|
||||
* **API** - Indicates whether the request is for an API resource.
|
||||
* **Request path** - Path to miscellaneous non-resource endpoints like `/api` or `/healthz`.
|
||||
* **API request verb** - API verbs `get`, `list`, `create`, `update`, `patch`, `watch`, `proxy`, `redirect`, `delete`, and `deletecollection` are used for resource requests. To determine the request verb for a resource API endpoint, see **Determine the request verb** below.
|
||||
* **HTTP request verb** - HTTP verbs `get`, `post`, `put`, and `delete` are used for non-resource requests.
|
||||
* **Resource** - The ID or name of the resource that is being accessed (for resource requests only) -- For resource requests using `get`, `update`, `patch`, and `delete` verbs, you must provide the resource name.
|
||||
* **Subresource** - The subresource that is being accessed (for resource requests only).
|
||||
* **Namespace** - The namespace of the object that is being accessed (for namespaced resource requests only).
|
||||
* **API group** - The API group being accessed (for resource requests only). An empty string designates the [core API group](/docs/concepts/overview/kubernetes-api/).
|
||||
|
||||
## Determine the Request Verb
|
||||
To determine the request verb for a resource API endpoint, review the HTTP verb
|
||||
used and whether or not the request acts on an individual resource or a
|
||||
collection of resources:
|
||||
|
||||
HTTP verb | request verb
|
||||
----------|---------------
|
||||
POST | create
|
||||
GET, HEAD | get (for individual resources), list (for collections)
|
||||
PUT | update
|
||||
PATCH | patch
|
||||
DELETE | delete (for individual resources), deletecollection (for collections)
|
||||
|
||||
Kubernetes sometimes checks authorization for additional permissions using specialized verbs. For example:
|
||||
|
||||
* [PodSecurityPolicy](/docs/concepts/policy/pod-security-policy/) checks for authorization of the `use` verb on `podsecuritypolicies` resources in the `policy` API group.
|
||||
* [RBAC](/docs/admin/authorization/rbac/#privilege-escalation-prevention-and-bootstrapping) checks for authorization
|
||||
of the `bind` verb on `roles` and `clusterroles` resources in the `rbac.authorization.k8s.io` API group.
|
||||
* [Authentication](/docs/admin/authentication/) layer checks for authorization of the `impersonate` verb on `users`, `groups`, and `serviceaccounts` in the core API group, and the `userextras` in the `authentication.k8s.io` API group.
|
||||
|
||||
## Authorization Modules
|
||||
* **Node** - A special-purpose authorizer that grants permissions to kubelets based on the pods they are scheduled to run. To learn more about using the Node authorization mode, see [Node Authorization](/docs/admin/authorization/node/).
|
||||
* **ABAC** - Attribute-based access control (ABAC) defines an access control paradigm whereby access rights are granted to users through the use of policies which combine attributes together. The policies can use any type of attributes (user attributes, resource attributes, object, environment attributes, etc). To learn more about using the ABAC mode, see [ABAC Mode](/docs/admin/authorization/abac/).
|
||||
* **RBAC** - Role-based access control (RBAC) is a method of regulating access to computer or network resources based on the roles of individual users within an enterprise. In this context, access is the ability of an individual user to perform a specific task, such as view, create, or modify a file. To learn more about using the RBAC mode, see [RBAC Mode](/docs/admin/authorization/rbac/)
|
||||
* When specified "RBAC" (Role-Based Access Control) uses the "rbac.authorization.k8s.io" API group to drive authorization decisions, allowing admins to dynamically configure permission policies through the Kubernetes API.
|
||||
* To enable RBAC, start the apiserver with `--authorization-mode=RBAC`.
|
||||
* **Webhook** - A WebHook is an HTTP callback: an HTTP POST that occurs when something happens; a simple event-notification via HTTP POST. A web application implementing WebHooks will POST a message to a URL when certain things happen. To learn more about using the Webhook mode, see [Webhook Mode](/docs/admin/authorization/webhook/).
|
||||
|
||||
#### Checking API Access
|
||||
|
||||
`kubectl` provides the `auth can-i` subcommand for quickly querying the API authorization layer.
|
||||
The command uses the `SelfSubjectAccessReview` API to determine if the current user can perform
|
||||
a given action, and works regardless of the authorization mode used.
|
||||
|
||||
|
||||
```bash
|
||||
$ kubectl auth can-i create deployments --namespace dev
|
||||
yes
|
||||
$ kubectl auth can-i create deployments --namespace prod
|
||||
no
|
||||
```
|
||||
|
||||
Administrators can combine this with ["user impersonation"](/docs/admin/authentication/#user-impersonation)
|
||||
to determine what action other users can perform.
|
||||
|
||||
```bash
|
||||
$ kubectl auth can-i list secrets --namespace dev --as dave
|
||||
no
|
||||
```
|
||||
|
||||
`SelfSubjectAccessReview` is part of the `authorization.k8s.io` API group, which
|
||||
exposes the API server authorization to external services. Other resources in
|
||||
this group include:
|
||||
|
||||
* `SubjectAccessReview` - Access review for any user, not just the current one. Useful for delegating authorization decisions to the API server. For example, the kubelet and extension API servers use this to determine user access to their own APIs.
|
||||
* `LocalSubjectAccessReview` - Like `SubjectAccessReview` but restricted to a specific namespace.
|
||||
* `SelfSubjectRulesReview` - A review which returns the set of actions a user can perform within a namespace. Useful for users to quickly summarize their own access, or for UIs to hide/show actions.
|
||||
|
||||
These APIs can be queried by creating normal Kubernetes resources, where the response "status"
|
||||
field of the returned object is the result of the query.
|
||||
|
||||
```bash
|
||||
$ kubectl create -f - -o yaml << EOF
|
||||
apiVersion: authorization.k8s.io/v1
|
||||
kind: SelfSubjectAccessReview
|
||||
spec:
|
||||
resourceAttributes:
|
||||
group: apps
|
||||
name: deployments
|
||||
verb: create
|
||||
namespace: dev
|
||||
EOF
|
||||
|
||||
apiVersion: authorization.k8s.io/v1
|
||||
kind: SelfSubjectAccessReview
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
spec:
|
||||
resourceAttributes:
|
||||
group: apps
|
||||
name: deployments
|
||||
namespace: dev
|
||||
verb: create
|
||||
status:
|
||||
allowed: true
|
||||
denied: false
|
||||
```
|
||||
|
||||
## Using Flags for Your Authorization Module
|
||||
|
||||
You must include a flag in your policy to indicate which authorization module
|
||||
your policies include:
|
||||
|
||||
The following flags can be used:
|
||||
|
||||
* `--authorization-mode=ABAC` Attribute-Based Access Control (ABAC) mode allows you to configure policies using local files.
|
||||
* `--authorization-mode=RBAC` Role-based access control (RBAC) mode allows you to create and store policies using the Kubernetes API.
|
||||
* `--authorization-mode=Webhook` WebHook is an HTTP callback mode that allows you to manage authorization using a remote REST endpoint.
|
||||
* `--authorization-mode=Node` Node authorization is a special-purpose authorization mode that specifically authorizes API requests made by kubelets.
|
||||
* `--authorization-mode=AlwaysDeny` This flag blocks all requests. Use this flag only for testing.
|
||||
* `--authorization-mode=AlwaysAllow` This flag allows all requests. Use this flag only if you do not require authorization for your API requests.
|
||||
|
||||
You can choose more than one authorization module. Modules are checked in order
|
||||
so an earlier module has higher priority to allow or deny a request.
|
||||
|
||||
{{% /capture %}}
|
||||
{{% capture whatsnext %}}
|
||||
* To learn more about Authentication, see **Authentication** in [Controlling Access to the Kubernetes API](/docs/admin/accessing-the-api/).
|
||||
* To learn more about Admission Control, see [Using Admission Controllers](/docs/admin/admission-controllers/).
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
|
||||
## Privilege escalation via pod creation
|
||||
|
||||
Users who have the ability to create pods in a namespace can potentially
|
||||
escalate their privileges within that namespace. They can create pods that
|
||||
access their privileges within that namespace. They can create pods that access
|
||||
secrets the user cannot themselves read, or that run under a service account
|
||||
with different/greater permissions.
|
||||
|
||||
{{< caution >}}
|
||||
**Caution:** System administrators, use care when granting access to pod
|
||||
creation. A user granted permission to create pods (or controllers that create
|
||||
pods) in the namespace can: read all secrets in the namespace; read all config
|
||||
maps in the namespace; and impersonate any service account in the namespace and
|
||||
take any action the account could take. This applies regardless of authorization
|
||||
mode.
|
||||
{{< /caution >}}
|
||||
@@ -1,156 +0,0 @@
|
||||
---
|
||||
reviewers:
|
||||
- erictune
|
||||
- lavalamp
|
||||
- deads2k
|
||||
- liggitt
|
||||
title: ABAC Mode
|
||||
content_template: templates/concept
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
Attribute-based access control (ABAC) defines an access control paradigm whereby access rights are granted to users through the use of policies which combine attributes together.
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
## Policy File Format
|
||||
|
||||
For mode `ABAC`, also specify `--authorization-policy-file=SOME_FILENAME`.
|
||||
|
||||
The file format is [one JSON object per line](http://jsonlines.org/). There
|
||||
should be no enclosing list or map, just one map per line.
|
||||
|
||||
Each line is a "policy object". A policy object is a map with the following
|
||||
properties:
|
||||
|
||||
- Versioning properties:
|
||||
- `apiVersion`, type string; valid values are "abac.authorization.kubernetes.io/v1beta1". Allows versioning and conversion of the policy format.
|
||||
- `kind`, type string: valid values are "Policy". Allows versioning and conversion of the policy format.
|
||||
- `spec` property set to a map with the following properties:
|
||||
- Subject-matching properties:
|
||||
- `user`, type string; the user-string from `--token-auth-file`. If you specify `user`, it must match the username of the authenticated user.
|
||||
- `group`, type string; if you specify `group`, it must match one of the groups of the authenticated user. `system:authenticated` matches all authenticated requests. `system:unauthenticated` matches all unauthenticated requests.
|
||||
- Resource-matching properties:
|
||||
- `apiGroup`, type string; an API group.
|
||||
- Ex: `extensions`
|
||||
- Wildcard: `*` matches all API groups.
|
||||
- `namespace`, type string; a namespace.
|
||||
- Ex: `kube-system`
|
||||
- Wildcard: `*` matches all resource requests.
|
||||
- `resource`, type string; a resource type
|
||||
- Ex: `pods`
|
||||
- Wildcard: `*` matches all resource requests.
|
||||
- Non-resource-matching properties:
|
||||
- `nonResourcePath`, type string; non-resource request paths.
|
||||
- Ex: `/version` or `/apis`
|
||||
- Wildcard:
|
||||
- `*` matches all non-resource requests.
|
||||
- `/foo/*` matches all subpaths of `/foo/`.
|
||||
- `readonly`, type boolean, when true, means that the Resource-matching policy only applies to get, list, and watch operations, Non-resource-matching policy only applies to get operation.
|
||||
|
||||
**NOTES:** An unset property is the same as a property set to the zero value for its type
|
||||
(e.g. empty string, 0, false). However, unset should be preferred for
|
||||
readability.
|
||||
|
||||
In the future, policies may be expressed in a JSON format, and managed via a
|
||||
REST interface.
|
||||
|
||||
## Authorization Algorithm
|
||||
|
||||
A request has attributes which correspond to the properties of a policy object.
|
||||
|
||||
When a request is received, the attributes are determined. Unknown attributes
|
||||
are set to the zero value of its type (e.g. empty string, 0, false).
|
||||
|
||||
A property set to `"*"` will match any value of the corresponding attribute.
|
||||
|
||||
The tuple of attributes is checked for a match against every policy in the
|
||||
policy file. If at least one line matches the request attributes, then the
|
||||
request is authorized (but may fail later validation).
|
||||
|
||||
To permit any authenticated user to do something, write a policy with the
|
||||
group property set to `"system:authenticated"`.
|
||||
|
||||
To permit any unauthenticated user to do something, write a policy with the
|
||||
group property set to `"system:unauthenticated"`.
|
||||
|
||||
To permit a user to do anything, write a policy with the apiGroup, namespace,
|
||||
resource, and nonResourcePath properties set to `"*"`.
|
||||
|
||||
## Kubectl
|
||||
|
||||
Kubectl uses the `/api` and `/apis` endpoints of api-server to negotiate
|
||||
client/server versions. To validate objects sent to the API by create/update
|
||||
operations, kubectl queries certain swagger resources. For API version `v1`
|
||||
those would be `/swaggerapi/api/v1` & `/swaggerapi/experimental/v1`.
|
||||
|
||||
When using ABAC authorization, those special resources have to be explicitly
|
||||
exposed via the `nonResourcePath` property in a policy (see [examples](#examples) below):
|
||||
|
||||
* `/api`, `/api/*`, `/apis`, and `/apis/*` for API version negotiation.
|
||||
* `/version` for retrieving the server version via `kubectl version`.
|
||||
* `/swaggerapi/*` for create/update operations.
|
||||
|
||||
To inspect the HTTP calls involved in a specific kubectl operation you can turn
|
||||
up the verbosity:
|
||||
|
||||
kubectl --v=8 version
|
||||
|
||||
## Examples
|
||||
|
||||
1. Alice can do anything to all resources:
|
||||
|
||||
```json
|
||||
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "alice", "namespace": "*", "resource": "*", "apiGroup": "*"}}
|
||||
```
|
||||
2. Kubelet can read any pods:
|
||||
|
||||
```json
|
||||
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "kubelet", "namespace": "*", "resource": "pods", "readonly": true}}
|
||||
```
|
||||
3. Kubelet can read and write events:
|
||||
|
||||
```json
|
||||
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "kubelet", "namespace": "*", "resource": "events"}}
|
||||
```
|
||||
4. Bob can just read pods in namespace "projectCaribou":
|
||||
|
||||
```json
|
||||
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "bob", "namespace": "projectCaribou", "resource": "pods", "readonly": true}}
|
||||
```
|
||||
5. Anyone can make read-only requests to all non-resource paths:
|
||||
|
||||
```json
|
||||
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group": "system:authenticated", "readonly": true, "nonResourcePath": "*"}}
|
||||
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"group": "system:unauthenticated", "readonly": true, "nonResourcePath": "*"}}
|
||||
```
|
||||
|
||||
[Complete file example](http://releases.k8s.io/{{< param "githubbranch" >}}/pkg/auth/authorizer/abac/example_policy_file.jsonl)
|
||||
|
||||
## A quick note on service accounts
|
||||
|
||||
A service account automatically generates a user. The user's name is generated
|
||||
according to the naming convention:
|
||||
|
||||
```shell
|
||||
system:serviceaccount:<namespace>:<serviceaccountname>
|
||||
```
|
||||
Creating a new namespace also causes a new service account to be created, of
|
||||
this form:
|
||||
|
||||
```shell
|
||||
system:serviceaccount:<namespace>:default
|
||||
```
|
||||
|
||||
For example, if you wanted to grant the default service account in the
|
||||
kube-system full privilege to the API, you would add this line to your policy
|
||||
file:
|
||||
|
||||
```json
|
||||
{"apiVersion":"abac.authorization.kubernetes.io/v1beta1","kind":"Policy","spec":{"user":"system:serviceaccount:kube-system:default","namespace":"*","resource":"*","apiGroup":"*"}}
|
||||
```
|
||||
|
||||
The apiserver will need to be restarted to pickup the new policy lines.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
---
|
||||
reviewers:
|
||||
- timstclair
|
||||
- deads2k
|
||||
- liggitt
|
||||
- ericchiang
|
||||
title: Using Node Authorization
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
Node authorization is a special-purpose authorization mode that specifically authorizes API requests made by kubelets.
|
||||
|
||||
## Overview
|
||||
|
||||
The Node authorizer allows a kubelet to perform API operations. This includes:
|
||||
|
||||
Read operations:
|
||||
|
||||
* services
|
||||
* endpoints
|
||||
* nodes
|
||||
* pods
|
||||
* secrets, configmaps, persistent volume claims and persistent volumes related to pods bound to the kubelet's node
|
||||
|
||||
Write operations:
|
||||
|
||||
* nodes and node status (enable the `NodeRestriction` admission plugin to limit a kubelet to modify its own node)
|
||||
* pods and pod status (enable the `NodeRestriction` admission plugin to limit a kubelet to modify pods bound to itself)
|
||||
* events
|
||||
|
||||
Auth-related operations:
|
||||
|
||||
* read/write access to the certificationsigningrequests API for TLS bootstrapping
|
||||
* the ability to create tokenreviews and subjectaccessreviews for delegated authentication/authorization checks
|
||||
|
||||
In future releases, the node authorizer may add or remove permissions to ensure kubelets
|
||||
have the minimal set of permissions required to operate correctly.
|
||||
|
||||
In order to be authorized by the Node authorizer, kubelets must use a credential that identifies them as
|
||||
being in the `system:nodes` group, with a username of `system:node:<nodeName>`.
|
||||
This group and user name format match the identity created for each kubelet as part of
|
||||
[kubelet TLS bootstrapping](/docs/admin/kubelet-tls-bootstrapping/).
|
||||
|
||||
To enable the Node authorizer, start the apiserver with `--authorization-mode=Node`.
|
||||
|
||||
To limit the API objects kubelets are able to write, enable the [NodeRestriction](/docs/admin/admission-controllers#NodeRestriction) admission plugin by starting the apiserver with `--enable-admission-plugins=...,NodeRestriction,...`
|
||||
|
||||
## Migration considerations
|
||||
|
||||
### Kubelets outside the `system:nodes` group
|
||||
|
||||
Kubelets outside the `system:nodes` group would not be authorized by the `Node` authorization mode,
|
||||
and would need to continue to be authorized via whatever mechanism currently authorizes them.
|
||||
The node admission plugin would not restrict requests from these kubelets.
|
||||
|
||||
### Kubelets with undifferentiated usernames
|
||||
|
||||
In some deployments, kubelets have credentials that place them in the `system:nodes` group,
|
||||
but do not identify the particular node they are associated with,
|
||||
because they do not have a username in the `system:node:...` format.
|
||||
These kubelets would not be authorized by the `Node` authorization mode,
|
||||
and would need to continue to be authorized via whatever mechanism currently authorizes them.
|
||||
|
||||
The `NodeRestriction` admission plugin would ignore requests from these kubelets,
|
||||
since the default node identifier implementation would not consider that a node identity.
|
||||
|
||||
### Upgrades from previous versions using RBAC
|
||||
|
||||
Upgraded pre-1.7 clusters using [RBAC](/docs/admin/authorization/rbac/) will continue functioning as-is because the `system:nodes` group binding will already exist.
|
||||
|
||||
If a cluster admin wishes to start using the `Node` authorizer and `NodeRestriction` admission plugin
|
||||
to limit node access to the API, that can be done non-disruptively:
|
||||
|
||||
1. Enable the `Node` authorization mode (`--authorization-mode=Node,RBAC`) and the `NodeRestriction` admission plugin
|
||||
2. Ensure all kubelets' credentials conform to the group/username requirements
|
||||
3. Audit apiserver logs to ensure the `Node` authorizer is not rejecting requests from kubelets (no persistent `NODE DENY` messages logged)
|
||||
4. Delete the `system:node` cluster role binding
|
||||
|
||||
### RBAC Node Permissions
|
||||
|
||||
In 1.6, the `system:node` cluster role was automatically bound to the `system:nodes` group when using the [RBAC Authorization mode](/docs/admin/authorization/rbac/).
|
||||
|
||||
In 1.7, the automatic binding of the `system:nodes` group to the `system:node` role is deprecated
|
||||
because the node authorizer accomplishes the same purpose with the benefit of additional restrictions
|
||||
on secret and configmap access. If the `Node` and `RBAC` authorization modes are both enabled,
|
||||
the automatic binding of the `system:nodes` group to the `system:node` role is not created in 1.7.
|
||||
|
||||
In 1.8, the binding will not be created at all.
|
||||
|
||||
When using RBAC, the `system:node` cluster role will continue to be created,
|
||||
for compatibility with deployment methods that bind other users or groups to that role.
|
||||
@@ -1,885 +0,0 @@
|
||||
---
|
||||
reviewers:
|
||||
- erictune
|
||||
- deads2k
|
||||
- liggitt
|
||||
title: Using RBAC Authorization
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
Role-Based Access Control ("RBAC") uses the "rbac.authorization.k8s.io" API group
|
||||
to drive authorization decisions, allowing admins to dynamically configure policies
|
||||
through the Kubernetes API.
|
||||
|
||||
As of 1.8, RBAC mode is stable and backed by the rbac.authorization.k8s.io/v1 API.
|
||||
|
||||
To enable RBAC, start the apiserver with `--authorization-mode=RBAC`.
|
||||
|
||||
## API Overview
|
||||
|
||||
The RBAC API declares four top-level types which will be covered in this
|
||||
section. Users can interact with these resources as they would with any other
|
||||
API resource (via `kubectl`, API calls, etc.). For instance,
|
||||
`kubectl create -f (resource).yml` can be used with any of these examples,
|
||||
though readers who wish to follow along should review the section on
|
||||
bootstrapping first.
|
||||
|
||||
### Role and ClusterRole
|
||||
|
||||
In the RBAC API, a role contains rules that represent a set of permissions.
|
||||
Permissions are purely additive (there are no "deny" rules).
|
||||
A role can be defined within a namespace with a `Role`, or cluster-wide with a `ClusterRole`.
|
||||
|
||||
A `Role` can only be used to grant access to resources within a single namespace.
|
||||
Here's an example `Role` in the "default" namespace that can be used to grant read access to pods:
|
||||
|
||||
```yaml
|
||||
kind: Role
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
namespace: default
|
||||
name: pod-reader
|
||||
rules:
|
||||
- apiGroups: [""] # "" indicates the core API group
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "watch", "list"]
|
||||
```
|
||||
|
||||
A `ClusterRole` can be used to grant the same permissions as a `Role`,
|
||||
but because they are cluster-scoped, they can also be used to grant access to:
|
||||
|
||||
* cluster-scoped resources (like nodes)
|
||||
* non-resource endpoints (like "/healthz")
|
||||
* namespaced resources (like pods) across all namespaces (needed to run `kubectl get pods --all-namespaces`, for example)
|
||||
|
||||
The following `ClusterRole` can be used to grant read access to secrets in any particular namespace,
|
||||
or across all namespaces (depending on how it is [bound](#rolebinding-and-clusterrolebinding)):
|
||||
|
||||
```yaml
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
# "namespace" omitted since ClusterRoles are not namespaced
|
||||
name: secret-reader
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get", "watch", "list"]
|
||||
```
|
||||
|
||||
### RoleBinding and ClusterRoleBinding
|
||||
|
||||
A role binding grants the permissions defined in a role to a user or set of users.
|
||||
It holds a list of subjects (users, groups, or service accounts), and a reference to the role being granted.
|
||||
Permissions can be granted within a namespace with a `RoleBinding`, or cluster-wide with a `ClusterRoleBinding`.
|
||||
|
||||
A `RoleBinding` may reference a `Role` in the same namespace.
|
||||
The following `RoleBinding` grants the "pod-reader" role to the user "jane" within the "default" namespace.
|
||||
This allows "jane" to read pods in the "default" namespace.
|
||||
|
||||
`roleRef` is how you will actually create the binding. The `kind` will be either `Role` or `ClusterRole`, and the `name` will reference the name of the specific `Role` or `ClusterRole` you want. In the example below, this RoleBinding is using `roleRef` to bind the user "jane" to the `Role` created above named `pod-reader`.
|
||||
|
||||
```yaml
|
||||
# This role binding allows "jane" to read pods in the "default" namespace.
|
||||
kind: RoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: read-pods
|
||||
namespace: default
|
||||
subjects:
|
||||
- kind: User
|
||||
name: jane # Name is case sensitive
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
roleRef:
|
||||
kind: Role #this must be Role or ClusterRole
|
||||
name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
A `RoleBinding` may also reference a `ClusterRole` to grant the permissions to namespaced
|
||||
resources defined in the `ClusterRole` within the `RoleBinding`'s namespace.
|
||||
This allows administrators to define a set of common roles for the entire cluster,
|
||||
then reuse them within multiple namespaces.
|
||||
|
||||
For instance, even though the following `RoleBinding` refers to a `ClusterRole`,
|
||||
"dave" (the subject, case sensitive) will only be able to read secrets in the "development"
|
||||
namespace (the namespace of the `RoleBinding`).
|
||||
|
||||
```yaml
|
||||
# This role binding allows "dave" to read secrets in the "development" namespace.
|
||||
kind: RoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: read-secrets
|
||||
namespace: development # This only grants permissions within the "development" namespace.
|
||||
subjects:
|
||||
- kind: User
|
||||
name: dave # Name is case sensitive
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: secret-reader
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
Finally, a `ClusterRoleBinding` may be used to grant permission at the cluster level and in all
|
||||
namespaces. The following `ClusterRoleBinding` allows any user in the group "manager" to read
|
||||
secrets in any namespace.
|
||||
|
||||
```yaml
|
||||
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: read-secrets-global
|
||||
subjects:
|
||||
- kind: Group
|
||||
name: manager # Name is case sensitive
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: secret-reader
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
### Referring to Resources
|
||||
|
||||
Most resources are represented by a string representation of their name, such as "pods", just as it
|
||||
appears in the URL for the relevant API endpoint. However, some Kubernetes APIs involve a
|
||||
"subresource", such as the logs for a pod. The URL for the pods logs endpoint is:
|
||||
|
||||
```
|
||||
GET /api/v1/namespaces/{namespace}/pods/{name}/log
|
||||
```
|
||||
|
||||
In this case, "pods" is the namespaced resource, and "log" is a subresource of pods. To represent
|
||||
this in an RBAC role, use a slash to delimit the resource and subresource. To allow a subject
|
||||
to read both pods and pod logs, you would write:
|
||||
|
||||
```yaml
|
||||
kind: Role
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
namespace: default
|
||||
name: pod-and-pod-logs-reader
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods", "pods/log"]
|
||||
verbs: ["get", "list"]
|
||||
```
|
||||
|
||||
Resources can also be referred to by name for certain requests through the `resourceNames` list.
|
||||
When specified, requests using the "get", "delete", "update", and "patch" verbs can be restricted
|
||||
to individual instances of a resource. To restrict a subject to only "get" and "update" a single
|
||||
configmap, you would write:
|
||||
|
||||
```yaml
|
||||
kind: Role
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
namespace: default
|
||||
name: configmap-updater
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps"]
|
||||
resourceNames: ["my-configmap"]
|
||||
verbs: ["update", "get"]
|
||||
```
|
||||
|
||||
Notably, if `resourceNames` are set, then the verb must not be list, watch, create, or deletecollection.
|
||||
Because resource names are not present in the URL for create, list, watch, and deletecollection API requests,
|
||||
those verbs would not be allowed by a rule with `resourceNames` set, since the `resourceNames` portion of the
|
||||
rule would not match the request.
|
||||
|
||||
### Aggregated ClusterRoles
|
||||
|
||||
As of 1.9, ClusterRoles can be created by combining other ClusterRoles using an `aggregationRule`. The
|
||||
permissions of aggregated ClusterRoles are controller-managed, and filled in by unioning the rules of any
|
||||
ClusterRole that matches the provided label selector. An example aggregated ClusterRole:
|
||||
|
||||
```yaml
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: monitoring
|
||||
aggregationRule:
|
||||
clusterRoleSelectors:
|
||||
- matchLabels:
|
||||
rbac.example.com/aggregate-to-monitoring: "true"
|
||||
rules: [] # Rules are automatically filled in by the controller manager.
|
||||
```
|
||||
|
||||
Creating a ClusterRole that matches the label selector will add rules to the aggregated ClusterRole. In this case
|
||||
rules can be added to the "monitoring" ClusterRole by creating another ClusterRole that has the label
|
||||
`rbac.example.com/aggregate-to-monitoring: true`.
|
||||
|
||||
```yaml
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: monitoring-endpoints
|
||||
labels:
|
||||
rbac.example.com/aggregate-to-monitoring: "true"
|
||||
# These rules will be added to the "monitoring" role.
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["services", "endpoints", "pods"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
```
|
||||
|
||||
The default user-facing roles (described below) use ClusterRole aggregation. This lets admins include rules
|
||||
for custom resources, such as those served by CustomResourceDefinitions or Aggregated API servers, on the
|
||||
default roles.
|
||||
|
||||
For example, the following ClusterRoles let the "admin" and "edit" default roles manage the custom resource
|
||||
"CronTabs" and the "view" role perform read-only actions on the resource.
|
||||
|
||||
```yaml
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: aggregate-cron-tabs-edit
|
||||
labels:
|
||||
# Add these permissions to the "admin" and "edit" default roles.
|
||||
rbac.authorization.k8s.io/aggregate-to-admin: "true"
|
||||
rbac.authorization.k8s.io/aggregate-to-edit: "true"
|
||||
rules:
|
||||
- apiGroups: ["stable.example.com"]
|
||||
resources: ["crontabs"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
---
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: aggregate-cron-tabs-view
|
||||
labels:
|
||||
# Add these permissions to the "view" default role.
|
||||
rbac.authorization.k8s.io/aggregate-to-view: "true"
|
||||
rules:
|
||||
- apiGroups: ["stable.example.com"]
|
||||
resources: ["crontabs"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
```
|
||||
|
||||
#### Role Examples
|
||||
|
||||
Only the `rules` section is shown in the following examples.
|
||||
|
||||
Allow reading the resource "pods" in the core API group:
|
||||
|
||||
```yaml
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
```
|
||||
|
||||
Allow reading/writing "deployments" in both the "extensions" and "apps" API groups:
|
||||
|
||||
```yaml
|
||||
rules:
|
||||
- apiGroups: ["extensions", "apps"]
|
||||
resources: ["deployments"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
```
|
||||
|
||||
Allow reading "pods" and reading/writing "jobs":
|
||||
|
||||
```yaml
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups: ["batch", "extensions"]
|
||||
resources: ["jobs"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
```
|
||||
|
||||
Allow reading a `ConfigMap` named "my-config" (must be bound with a `RoleBinding` to limit to a single `ConfigMap` in a single namespace):
|
||||
|
||||
```yaml
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps"]
|
||||
resourceNames: ["my-config"]
|
||||
verbs: ["get"]
|
||||
```
|
||||
|
||||
Allow reading the resource "nodes" in the core group (because a `Node` is cluster-scoped, this must be in a `ClusterRole` bound with a `ClusterRoleBinding` to be effective):
|
||||
|
||||
```yaml
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["nodes"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
```
|
||||
|
||||
Allow "GET" and "POST" requests to the non-resource endpoint "/healthz" and all subpaths (must be in a `ClusterRole` bound with a `ClusterRoleBinding` to be effective):
|
||||
|
||||
```yaml
|
||||
rules:
|
||||
- nonResourceURLs: ["/healthz", "/healthz/*"] # '*' in a nonResourceURL is a suffix glob match
|
||||
verbs: ["get", "post"]
|
||||
```
|
||||
|
||||
### Referring to Subjects
|
||||
|
||||
A `RoleBinding` or `ClusterRoleBinding` binds a role to *subjects*.
|
||||
Subjects can be groups, users or service accounts.
|
||||
|
||||
Users are represented by strings. These can be plain usernames, like
|
||||
"alice", email-style names, like "bob@example.com", or numeric IDs
|
||||
represented as a string. It is up to the Kubernetes admin to configure
|
||||
the [authentication modules](/docs/admin/authentication/) to produce
|
||||
usernames in the desired format. The RBAC authorization system does
|
||||
not require any particular format. However, the prefix `system:` is
|
||||
reserved for Kubernetes system use, and so the admin should ensure
|
||||
usernames do not contain this prefix by accident.
|
||||
|
||||
Group information in Kubernetes is currently provided by the Authenticator
|
||||
modules. Groups, like users, are represented as strings, and that string
|
||||
has no format requirements, other than that the prefix `system:` is reserved.
|
||||
|
||||
[Service Accounts](/docs/tasks/configure-pod-container/configure-service-account/) have usernames with the `system:serviceaccount:` prefix and belong
|
||||
to groups with the `system:serviceaccounts:` prefix.
|
||||
|
||||
#### Role Binding Examples
|
||||
|
||||
Only the `subjects` section of a `RoleBinding` is shown in the following examples.
|
||||
|
||||
For a user named "alice@example.com":
|
||||
|
||||
```yaml
|
||||
subjects:
|
||||
- kind: User
|
||||
name: "alice@example.com"
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
For a group named "frontend-admins":
|
||||
|
||||
```yaml
|
||||
subjects:
|
||||
- kind: Group
|
||||
name: "frontend-admins"
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
For the default service account in the kube-system namespace:
|
||||
|
||||
```yaml
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: default
|
||||
namespace: kube-system
|
||||
```
|
||||
|
||||
For all service accounts in the "qa" namespace:
|
||||
|
||||
```yaml
|
||||
subjects:
|
||||
- kind: Group
|
||||
name: system:serviceaccounts:qa
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
For all service accounts everywhere:
|
||||
|
||||
```yaml
|
||||
subjects:
|
||||
- kind: Group
|
||||
name: system:serviceaccounts
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
For all authenticated users (version 1.5+):
|
||||
|
||||
```yaml
|
||||
subjects:
|
||||
- kind: Group
|
||||
name: system:authenticated
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
For all unauthenticated users (version 1.5+):
|
||||
|
||||
```yaml
|
||||
subjects:
|
||||
- kind: Group
|
||||
name: system:unauthenticated
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
For all users (version 1.5+):
|
||||
|
||||
```yaml
|
||||
subjects:
|
||||
- kind: Group
|
||||
name: system:authenticated
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
- kind: Group
|
||||
name: system:unauthenticated
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
## Default Roles and Role Bindings
|
||||
|
||||
API servers create a set of default `ClusterRole` and `ClusterRoleBinding` objects.
|
||||
Many of these are `system:` prefixed, which indicates that the resource is "owned" by the infrastructure.
|
||||
Modifications to these resources can result in non-functional clusters. One example is the `system:node` ClusterRole.
|
||||
This role defines permissions for kubelets. If the role is modified, it can prevent kubelets from working.
|
||||
|
||||
All of the default cluster roles and rolebindings are labeled with `kubernetes.io/bootstrapping=rbac-defaults`.
|
||||
|
||||
### Auto-reconciliation
|
||||
|
||||
At each start-up, the API server updates default cluster roles with any missing permissions,
|
||||
and updates default cluster role bindings with any missing subjects.
|
||||
This allows the cluster to repair accidental modifications,
|
||||
and to keep roles and rolebindings up-to-date as permissions and subjects change in new releases.
|
||||
|
||||
To opt out of this reconciliation, set the `rbac.authorization.kubernetes.io/autoupdate`
|
||||
annotation on a default cluster role or rolebinding to `false`.
|
||||
Be aware that missing default permissions and subjects can result in non-functional clusters.
|
||||
|
||||
Auto-reconciliation is enabled in Kubernetes version 1.6+ when the RBAC authorizer is active.
|
||||
|
||||
### Discovery Roles
|
||||
|
||||
<table>
|
||||
<colgroup><col width="25%"><col width="25%"><col></colgroup>
|
||||
<tr>
|
||||
<th>Default ClusterRole</th>
|
||||
<th>Default ClusterRoleBinding</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>system:basic-user</b></td>
|
||||
<td><b>system:authenticated</b> and <b>system:unauthenticated</b> groups</td>
|
||||
<td>Allows a user read-only access to basic information about themselves.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>system:discovery</b></td>
|
||||
<td><b>system:authenticated</b> and <b>system:unauthenticated</b> groups</td>
|
||||
<td>Allows read-only access to API discovery endpoints needed to discover and negotiate an API level.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### User-facing Roles
|
||||
|
||||
Some of the default roles are not `system:` prefixed. These are intended to be user-facing roles.
|
||||
They include super-user roles (`cluster-admin`),
|
||||
roles intended to be granted cluster-wide using ClusterRoleBindings (`cluster-status`),
|
||||
and roles intended to be granted within particular namespaces using RoleBindings (`admin`, `edit`, `view`).
|
||||
|
||||
As of 1.9, user-facing roles use [ClusterRole Aggregation](#aggregated-clusterroles) to allow admins to include
|
||||
rules for custom resources on these roles. To add rules to the "admin", "edit", or "view" role, create a
|
||||
ClusterRole with one or more of the following labels:
|
||||
|
||||
```yaml
|
||||
metadata:
|
||||
labels:
|
||||
rbac.authorization.k8s.io/aggregate-to-admin: "true"
|
||||
rbac.authorization.k8s.io/aggregate-to-edit: "true"
|
||||
rbac.authorization.k8s.io/aggregate-to-view: "true"
|
||||
```
|
||||
|
||||
<table>
|
||||
<colgroup><col width="25%"><col width="25%"><col></colgroup>
|
||||
<tr>
|
||||
<th>Default ClusterRole</th>
|
||||
<th>Default ClusterRoleBinding</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>cluster-admin</b></td>
|
||||
<td><b>system:masters</b> group</td>
|
||||
<td>Allows super-user access to perform any action on any resource.
|
||||
When used in a <b>ClusterRoleBinding</b>, it gives full control over every resource in the cluster and in all namespaces.
|
||||
When used in a <b>RoleBinding</b>, it gives full control over every resource in the rolebinding's namespace, including the namespace itself.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>admin</b></td>
|
||||
<td>None</td>
|
||||
<td>Allows admin access, intended to be granted within a namespace using a <b>RoleBinding</b>.
|
||||
If used in a <b>RoleBinding</b>, allows read/write access to most resources in a namespace,
|
||||
including the ability to create roles and rolebindings within the namespace.
|
||||
It does not allow write access to resource quota or to the namespace itself.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>edit</b></td>
|
||||
<td>None</td>
|
||||
<td>Allows read/write access to most objects in a namespace.
|
||||
It does not allow viewing or modifying roles or rolebindings.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>view</b></td>
|
||||
<td>None</td>
|
||||
<td>Allows read-only access to see most objects in a namespace.
|
||||
It does not allow viewing roles or rolebindings.
|
||||
It does not allow viewing secrets, since those are escalating.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Core Component Roles
|
||||
|
||||
<table>
|
||||
<colgroup><col width="25%"><col width="25%"><col></colgroup>
|
||||
<tr>
|
||||
<th>Default ClusterRole</th>
|
||||
<th>Default ClusterRoleBinding</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>system:kube-scheduler</b></td>
|
||||
<td><b>system:kube-scheduler</b> user</td>
|
||||
<td>Allows access to the resources required by the kube-scheduler component.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>system:kube-controller-manager</b></td>
|
||||
<td><b>system:kube-controller-manager</b> user</td>
|
||||
<td>Allows access to the resources required by the kube-controller-manager component.
|
||||
The permissions required by individual control loops are contained in the <a href="#controller-roles">controller roles</a>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>system:node</b></td>
|
||||
<td>None in 1.8+</td>
|
||||
<td>Allows access to resources required by the kubelet component, <b>including read access to all secrets, and write access to all pod status objects</b>.
|
||||
As of 1.7, use of the <a href="/docs/admin/authorization/node/">Node authorizer</a> and <a href="/docs/admin/admission-controllers/#noderestriction">NodeRestriction admission plugin</a> is recommended instead of this role, and allow granting API access to kubelets based on the pods scheduled to run on them.
|
||||
Prior to 1.7, this role was automatically bound to the `system:nodes` group.
|
||||
In 1.7, this role was automatically bound to the `system:nodes` group if the `Node` authorization mode is not enabled.
|
||||
In 1.8+, no binding is automatically created.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>system:node-proxier</b></td>
|
||||
<td><b>system:kube-proxy</b> user</td>
|
||||
<td>Allows access to the resources required by the kube-proxy component.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Other Component Roles
|
||||
|
||||
<table>
|
||||
<colgroup><col width="25%"><col width="25%"><col></colgroup>
|
||||
<tr>
|
||||
<th>Default ClusterRole</th>
|
||||
<th>Default ClusterRoleBinding</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>system:auth-delegator</b></td>
|
||||
<td>None</td>
|
||||
<td>Allows delegated authentication and authorization checks.
|
||||
This is commonly used by add-on API servers for unified authentication and authorization.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>system:heapster</b></td>
|
||||
<td>None</td>
|
||||
<td>Role for the <a href="https://github.com/kubernetes/heapster">Heapster</a> component.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>system:kube-aggregator</b></td>
|
||||
<td>None</td>
|
||||
<td>Role for the <a href="https://github.com/kubernetes/kube-aggregator">kube-aggregator</a> component.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>system:kube-dns</b></td>
|
||||
<td><b>kube-dns</b> service account in the <b>kube-system</b> namespace</td>
|
||||
<td>Role for the <a href="/docs/concepts/services-networking/dns-pod-service/">kube-dns</a> component.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>system:kubelet-api-admin</b></td>
|
||||
<td>None</td>
|
||||
<td>Allows full access to the kubelet API.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>system:node-bootstrapper</b></td>
|
||||
<td>None</td>
|
||||
<td>Allows access to the resources required to perform <a href="/docs/admin/kubelet-tls-bootstrapping/">Kubelet TLS bootstrapping</a>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>system:node-problem-detector</b></td>
|
||||
<td>None</td>
|
||||
<td>Role for the <a href="https://github.com/kubernetes/node-problem-detector">node-problem-detector</a> component.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>system:persistent-volume-provisioner</b></td>
|
||||
<td>None</td>
|
||||
<td>Allows access to the resources required by most <a href="/docs/concepts/storage/persistent-volumes/#provisioner">dynamic volume provisioners</a>.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Controller Roles
|
||||
|
||||
The [Kubernetes controller manager](/docs/admin/kube-controller-manager/) runs core control loops.
|
||||
When invoked with `--use-service-account-credentials`, each control loop is started using a separate service account.
|
||||
Corresponding roles exist for each control loop, prefixed with `system:controller:`.
|
||||
If the controller manager is not started with `--use-service-account-credentials`,
|
||||
it runs all control loops using its own credential, which must be granted all the relevant roles.
|
||||
These roles include:
|
||||
|
||||
* system:controller:attachdetach-controller
|
||||
* system:controller:certificate-controller
|
||||
* system:controller:cronjob-controller
|
||||
* system:controller:daemon-set-controller
|
||||
* system:controller:deployment-controller
|
||||
* system:controller:disruption-controller
|
||||
* system:controller:endpoint-controller
|
||||
* system:controller:generic-garbage-collector
|
||||
* system:controller:horizontal-pod-autoscaler
|
||||
* system:controller:job-controller
|
||||
* system:controller:namespace-controller
|
||||
* system:controller:node-controller
|
||||
* system:controller:persistent-volume-binder
|
||||
* system:controller:pod-garbage-collector
|
||||
* system:controller:pv-protection-controller
|
||||
* system:controller:pvc-protection-controller
|
||||
* system:controller:replicaset-controller
|
||||
* system:controller:replication-controller
|
||||
* system:controller:resourcequota-controller
|
||||
* system:controller:route-controller
|
||||
* system:controller:service-account-controller
|
||||
* system:controller:service-controller
|
||||
* system:controller:statefulset-controller
|
||||
* system:controller:ttl-controller
|
||||
|
||||
## Privilege Escalation Prevention and Bootstrapping
|
||||
|
||||
The RBAC API prevents users from escalating privileges by editing roles or role bindings.
|
||||
Because this is enforced at the API level, it applies even when the RBAC authorizer is not in use.
|
||||
|
||||
A user can only create/update a role if they already have all the permissions contained in the role,
|
||||
at the same scope as the role (cluster-wide for a `ClusterRole`, within the same namespace or cluster-wide for a `Role`).
|
||||
For example, if "user-1" does not have the ability to list secrets cluster-wide, they cannot create a `ClusterRole`
|
||||
containing that permission. To allow a user to create/update roles:
|
||||
|
||||
1. Grant them a role that allows them to create/update `Role` or `ClusterRole` objects, as desired.
|
||||
2. Grant them roles containing the permissions you would want them to be able to set in a `Role` or `ClusterRole`. If they attempt to create or modify a `Role` or `ClusterRole` with permissions they themselves have not been granted, the API request will be forbidden.
|
||||
|
||||
A user can only create/update a role binding if they already have all the permissions contained in the referenced role
|
||||
(at the same scope as the role binding) *or* if they've been given explicit permission to perform the `bind` verb on the referenced role.
|
||||
For example, if "user-1" does not have the ability to list secrets cluster-wide, they cannot create a `ClusterRoleBinding`
|
||||
to a role that grants that permission. To allow a user to create/update role bindings:
|
||||
|
||||
1. Grant them a role that allows them to create/update `RoleBinding` or `ClusterRoleBinding` objects, as desired.
|
||||
2. Grant them permissions needed to bind a particular role:
|
||||
* implicitly, by giving them the permissions contained in the role.
|
||||
* explicitly, by giving them permission to perform the `bind` verb on the particular role (or cluster role).
|
||||
|
||||
For example, this cluster role and role binding would allow "user-1" to grant other users the `admin`, `edit`, and `view` roles in the "user-1-namespace" namespace:
|
||||
|
||||
```yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: role-grantor
|
||||
rules:
|
||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["rolebindings"]
|
||||
verbs: ["create"]
|
||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["clusterroles"]
|
||||
verbs: ["bind"]
|
||||
resourceNames: ["admin","edit","view"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: role-grantor-binding
|
||||
namespace: user-1-namespace
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: role-grantor
|
||||
subjects:
|
||||
- apiGroup: rbac.authorization.k8s.io
|
||||
kind: User
|
||||
name: user-1
|
||||
```
|
||||
|
||||
When bootstrapping the first roles and role bindings, it is necessary for the initial user to grant permissions they do not yet have.
|
||||
To bootstrap initial roles and role bindings:
|
||||
|
||||
* Use a credential with the `system:masters` group, which is bound to the `cluster-admin` super-user role by the default bindings.
|
||||
* If your API server runs with the insecure port enabled (`--insecure-port`), you can also make API calls via that port, which does not enforce authentication or authorization.
|
||||
|
||||
## Command-line Utilities
|
||||
|
||||
Two `kubectl` commands exist to grant roles within a namespace or across the entire cluster.
|
||||
|
||||
### `kubectl create rolebinding`
|
||||
|
||||
Grants a `Role` or `ClusterRole` within a specific namespace. Examples:
|
||||
|
||||
* Grant the `admin` `ClusterRole` to a user named "bob" in the namespace "acme":
|
||||
|
||||
`kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=bob --namespace=acme`
|
||||
|
||||
* Grant the `view` `ClusterRole` to a service account named "myapp" in the namespace "acme":
|
||||
|
||||
`kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=acme`
|
||||
|
||||
### `kubectl create clusterrolebinding`
|
||||
|
||||
Grants a `ClusterRole` across the entire cluster, including all namespaces. Examples:
|
||||
|
||||
* Grant the `cluster-admin` `ClusterRole` to a user named "root" across the entire cluster:
|
||||
|
||||
`kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root`
|
||||
|
||||
* Grant the `system:node` `ClusterRole` to a user named "kubelet" across the entire cluster:
|
||||
|
||||
`kubectl create clusterrolebinding kubelet-node-binding --clusterrole=system:node --user=kubelet`
|
||||
|
||||
* Grant the `view` `ClusterRole` to a service account named "myapp" in the namespace "acme" across the entire cluster:
|
||||
|
||||
`kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp`
|
||||
|
||||
See the CLI help for detailed usage.
|
||||
|
||||
## Service Account Permissions
|
||||
|
||||
Default RBAC policies grant scoped permissions to control-plane components, nodes,
|
||||
and controllers, but grant *no permissions* to service accounts outside the "kube-system" namespace
|
||||
(beyond discovery permissions given to all authenticated users).
|
||||
|
||||
This allows you to grant particular roles to particular service accounts as needed.
|
||||
Fine-grained role bindings provide greater security, but require more effort to administrate.
|
||||
Broader grants can give unnecessary (and potentially escalating) API access to service accounts, but are easier to administrate.
|
||||
|
||||
In order from most secure to least secure, the approaches are:
|
||||
|
||||
1. Grant a role to an application-specific service account (best practice)
|
||||
|
||||
This requires the application to specify a `serviceAccountName` in its pod spec,
|
||||
and for the service account to be created (via the API, application manifest, `kubectl create serviceaccount`, etc.).
|
||||
|
||||
For example, grant read-only permission within "my-namespace" to the "my-sa" service account:
|
||||
|
||||
```shell
|
||||
kubectl create rolebinding my-sa-view \
|
||||
--clusterrole=view \
|
||||
--serviceaccount=my-namespace:my-sa \
|
||||
--namespace=my-namespace
|
||||
```
|
||||
|
||||
2. Grant a role to the "default" service account in a namespace
|
||||
|
||||
If an application does not specify a `serviceAccountName`, it uses the "default" service account.
|
||||
|
||||
{{< note >}}**NOTE:** Permissions given to the "default" service
|
||||
account are available to any pod in the namespace that does not
|
||||
specify a `serviceAccountName`.{{< /note >}}
|
||||
|
||||
For example, grant read-only permission within "my-namespace" to the "default" service account:
|
||||
|
||||
```shell
|
||||
kubectl create rolebinding default-view \
|
||||
--clusterrole=view \
|
||||
--serviceaccount=my-namespace:default \
|
||||
--namespace=my-namespace
|
||||
```
|
||||
|
||||
Many [add-ons](/docs/concepts/cluster-administration/addons/) currently run as the "default" service account in the "kube-system" namespace.
|
||||
To allow those add-ons to run with super-user access, grant cluster-admin permissions to the "default" service account in the "kube-system" namespace.
|
||||
|
||||
{{< note >}}**NOTE:** Enabling this means the "kube-system"
|
||||
namespace contains secrets that grant super-user access to the
|
||||
API.{{< /note >}}
|
||||
|
||||
```shell
|
||||
kubectl create clusterrolebinding add-on-cluster-admin \
|
||||
--clusterrole=cluster-admin \
|
||||
--serviceaccount=kube-system:default
|
||||
```
|
||||
|
||||
3. Grant a role to all service accounts in a namespace
|
||||
|
||||
If you want all applications in a namespace to have a role, no matter what service account they use,
|
||||
you can grant a role to the service account group for that namespace.
|
||||
|
||||
For example, grant read-only permission within "my-namespace" to all service accounts in that namespace:
|
||||
|
||||
```shell
|
||||
kubectl create rolebinding serviceaccounts-view \
|
||||
--clusterrole=view \
|
||||
--group=system:serviceaccounts:my-namespace \
|
||||
--namespace=my-namespace
|
||||
```
|
||||
|
||||
4. Grant a limited role to all service accounts cluster-wide (discouraged)
|
||||
|
||||
If you don't want to manage permissions per-namespace, you can grant a cluster-wide role to all service accounts.
|
||||
|
||||
For example, grant read-only permission across all namespaces to all service accounts in the cluster:
|
||||
|
||||
```shell
|
||||
kubectl create clusterrolebinding serviceaccounts-view \
|
||||
--clusterrole=view \
|
||||
--group=system:serviceaccounts
|
||||
```
|
||||
|
||||
5. Grant super-user access to all service accounts cluster-wide (strongly discouraged)
|
||||
|
||||
If you don't care about partitioning permissions at all, you can grant super-user access to all service accounts.
|
||||
|
||||
{{< warning >}}**WARNING:** This allows any user with read access
|
||||
to secrets or the ability to create a pod to access super-user
|
||||
credentials.{{< /warning >}}
|
||||
|
||||
```shell
|
||||
kubectl create clusterrolebinding serviceaccounts-cluster-admin \
|
||||
--clusterrole=cluster-admin \
|
||||
--group=system:serviceaccounts
|
||||
```
|
||||
|
||||
## Upgrading from 1.5
|
||||
|
||||
Prior to Kubernetes 1.6, many deployments used very permissive ABAC policies,
|
||||
including granting full API access to all service accounts.
|
||||
|
||||
Default RBAC policies grant scoped permissions to control-plane components, nodes,
|
||||
and controllers, but grant *no permissions* to service accounts outside the "kube-system" namespace
|
||||
(beyond discovery permissions given to all authenticated users).
|
||||
|
||||
While far more secure, this can be disruptive to existing workloads expecting to automatically receive API permissions.
|
||||
Here are two approaches for managing this transition:
|
||||
|
||||
### Parallel Authorizers
|
||||
|
||||
Run both the RBAC and ABAC authorizers, and specify a policy file that contains
|
||||
[the legacy ABAC policy](/docs/admin/authorization/abac#policy-file-format):
|
||||
|
||||
```
|
||||
--authorization-mode=RBAC,ABAC --authorization-policy-file=mypolicy.json
|
||||
```
|
||||
|
||||
The RBAC authorizer will attempt to authorize requests first. If it denies an API request,
|
||||
the ABAC authorizer is then run. This means that any request allowed by *either* the RBAC
|
||||
or ABAC policies is allowed.
|
||||
|
||||
When run with a log level of 2 or higher (`--v=2`), you can see RBAC denials in the apiserver log (prefixed with `RBAC DENY:`).
|
||||
You can use that information to determine which roles need to be granted to which users, groups, or service accounts.
|
||||
Once you have [granted roles to service accounts](#service-account-permissions) and workloads are running with no RBAC denial messages
|
||||
in the server logs, you can remove the ABAC authorizer.
|
||||
|
||||
## Permissive RBAC Permissions
|
||||
|
||||
You can replicate a permissive policy using RBAC role bindings.
|
||||
|
||||
{{< warning >}}
|
||||
**WARNING:** The following policy allows **ALL** service accounts to act as cluster administrators.
|
||||
Any application running in a container receives service account credentials automatically,
|
||||
and could perform any action against the API, including viewing secrets and modifying permissions.
|
||||
This is not a recommended policy.
|
||||
{{< /warning >}}
|
||||
|
||||
```
|
||||
kubectl create clusterrolebinding permissive-binding \
|
||||
--clusterrole=cluster-admin \
|
||||
--user=admin \
|
||||
--user=kubelet \
|
||||
--group=system:serviceaccounts
|
||||
```
|
||||
@@ -1,151 +0,0 @@
|
||||
---
|
||||
reviewers:
|
||||
- erictune
|
||||
- lavalamp
|
||||
- deads2k
|
||||
- liggitt
|
||||
title: Webhook Mode
|
||||
content_template: templates/concept
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
A WebHook is an HTTP callback: an HTTP POST that occurs when something happens; a simple event-notification via HTTP POST. A web application implementing WebHooks will POST a message to a URL when certain things happen.
|
||||
{{% /capture %}}
|
||||
|
||||
{{% capture body %}}
|
||||
When specified, mode `Webhook` causes Kubernetes to query an outside REST
|
||||
service when determining user privileges.
|
||||
|
||||
## Configuration File Format
|
||||
|
||||
Mode `Webhook` requires a file for HTTP configuration, specify by the
|
||||
`--authorization-webhook-config-file=SOME_FILENAME` flag.
|
||||
|
||||
The configuration file uses the [kubeconfig](/docs/tasks/access-application-cluster/configure-access-multiple-clusters/)
|
||||
file format. Within the file "users" refers to the API Server webhook and
|
||||
"clusters" refers to the remote service.
|
||||
|
||||
A configuration example which uses HTTPS client auth:
|
||||
|
||||
```yaml
|
||||
# clusters refers to the remote service.
|
||||
clusters:
|
||||
- name: name-of-remote-authz-service
|
||||
cluster:
|
||||
# CA for verifying the remote service.
|
||||
certificate-authority: /path/to/ca.pem
|
||||
# URL of remote service to query. Must use 'https'. May not include parameters.
|
||||
server: https://authz.example.com/authorize
|
||||
|
||||
# users refers to the API Server's webhook configuration.
|
||||
users:
|
||||
- name: name-of-api-server
|
||||
user:
|
||||
client-certificate: /path/to/cert.pem # cert for the webhook plugin to use
|
||||
client-key: /path/to/key.pem # key matching the cert
|
||||
|
||||
# kubeconfig files require a context. Provide one for the API Server.
|
||||
current-context: webhook
|
||||
contexts:
|
||||
- context:
|
||||
cluster: name-of-remote-authz-service
|
||||
user: name-of-api-server
|
||||
name: webhook
|
||||
```
|
||||
|
||||
## Request Payloads
|
||||
|
||||
When faced with an authorization decision, the API Server POSTs a JSON-
|
||||
serialized `authorization.k8s.io/v1beta1` `SubjectAccessReview` object describing the
|
||||
action. This object contains fields describing the user attempting to make the
|
||||
request, and either details about the resource being accessed or requests
|
||||
attributes.
|
||||
|
||||
Note that webhook API objects are subject to the same [versioning compatibility rules](/docs/concepts/overview/kubernetes-api/)
|
||||
as other Kubernetes API objects. Implementers should be aware of looser
|
||||
compatibility promises for beta objects and check the "apiVersion" field of the
|
||||
request to ensure correct deserialization. Additionally, the API Server must
|
||||
enable the `authorization.k8s.io/v1beta1` API extensions group (`--runtime-config=authorization.k8s.io/v1beta1=true`).
|
||||
|
||||
An example request body:
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "authorization.k8s.io/v1beta1",
|
||||
"kind": "SubjectAccessReview",
|
||||
"spec": {
|
||||
"resourceAttributes": {
|
||||
"namespace": "kittensandponies",
|
||||
"verb": "get",
|
||||
"group": "unicorn.example.org",
|
||||
"resource": "pods"
|
||||
},
|
||||
"user": "jane",
|
||||
"group": [
|
||||
"group1",
|
||||
"group2"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The remote service is expected to fill the `status` field of
|
||||
the request and respond to either allow or disallow access. The response body's
|
||||
`spec` field is ignored and may be omitted. A permissive response would return:
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "authorization.k8s.io/v1beta1",
|
||||
"kind": "SubjectAccessReview",
|
||||
"status": {
|
||||
"allowed": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To disallow access, the remote service would return:
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "authorization.k8s.io/v1beta1",
|
||||
"kind": "SubjectAccessReview",
|
||||
"status": {
|
||||
"allowed": false,
|
||||
"reason": "user does not have read access to the namespace"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Access to non-resource paths are sent as:
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "authorization.k8s.io/v1beta1",
|
||||
"kind": "SubjectAccessReview",
|
||||
"spec": {
|
||||
"nonResourceAttributes": {
|
||||
"path": "/debug",
|
||||
"verb": "get"
|
||||
},
|
||||
"user": "jane",
|
||||
"group": [
|
||||
"group1",
|
||||
"group2"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Non-resource paths include: `/api`, `/apis`, `/metrics`, `/resetMetrics`,
|
||||
`/logs`, `/debug`, `/healthz`, `/swagger-ui/`, `/swaggerapi/`, `/ui`, and
|
||||
`/version.` Clients require access to `/api`, `/api/*`, `/apis`, `/apis/*`,
|
||||
and `/version` to discover what resources and versions are present on the server.
|
||||
Access to other non-resource paths can be disallowed without restricting access
|
||||
to the REST api.
|
||||
|
||||
For further documentation refer to the authorization.v1beta1 API objects and
|
||||
[webhook.go](https://github.com/kubernetes/kubernetes/blob/{{< param "githubbranch" >}}/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go).
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
---
|
||||
reviewers:
|
||||
- jbeda
|
||||
title: Authenticating with Bootstrap Tokens
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## Overview
|
||||
|
||||
Bootstrap tokens are a simple bearer token that is meant to be used when
|
||||
creating new clusters or joining new nodes to an existing cluster. It was built
|
||||
to support [`kubeadm`](/docs/admin/kubeadm/), but can be used in other contexts
|
||||
for users that wish to start clusters without `kubeadm`. It is also built to
|
||||
work, via RBAC policy, with the [Kubelet TLS
|
||||
Bootstrapping](/docs/admin/kubelet-tls-bootstrapping/) system.
|
||||
|
||||
Bootstrap Tokens are defined with a specific type
|
||||
(`bootstrap.kubernetes.io/token`) of secrets that lives in the `kube-system`
|
||||
namespace. These Secrets are then read by the Bootstrap Authenticator in the
|
||||
API Server. Expired tokens are removed with the TokenCleaner controller in the
|
||||
Controller Manager. The tokens are also used to create a signature for a
|
||||
specific ConfigMap used in a "discovery" process through a BootstrapSigner
|
||||
controller.
|
||||
|
||||
{{< feature-state state="beta" >}}
|
||||
|
||||
## Token Format
|
||||
|
||||
Bootstrap Tokens take the form of `abcdef.0123456789abcdef`. More formally,
|
||||
they must match the regular expression `[a-z0-9]{6}\.[a-z0-9]{16}`.
|
||||
|
||||
The first part of the token is the "Token ID" and is considered public
|
||||
information. It is used when referring to a token without leaking the secret
|
||||
part used for authentication. The second part is the "Token Secret" and should
|
||||
only be shared with trusted parties.
|
||||
|
||||
## Enabling Bootstrap Token Authentication
|
||||
|
||||
The Bootstrap Token authenticator can be enabled using the following flag on the
|
||||
API server:
|
||||
|
||||
```
|
||||
--enable-bootstrap-token-auth
|
||||
```
|
||||
|
||||
When enabled, bootstrapping tokens can be used as bearer token credentials to
|
||||
authenticate requests against the API server.
|
||||
|
||||
```http
|
||||
Authorization: Bearer 07401b.f395accd246ae52d
|
||||
```
|
||||
|
||||
Tokens authenticate as the username `system:bootstrap:<token id>` and are members
|
||||
of the group `system:bootstrappers`. Additional groups may be specified in the
|
||||
token's Secret.
|
||||
|
||||
Expired tokens can be deleted automatically by enabling the `tokencleaner`
|
||||
controller on the controller manager.
|
||||
|
||||
```
|
||||
--controllers=*,tokencleaner
|
||||
```
|
||||
|
||||
## Bootstrap Token Secret Format
|
||||
|
||||
Each valid token is backed by a secret in the `kube-system` namespace. You can
|
||||
find the full design doc
|
||||
[here](https://github.com/kubernetes/community/blob/{{< param "githubbranch" >}}/contributors/design-proposals/cluster-lifecycle/bootstrap-discovery.md).
|
||||
|
||||
Here is what the secret looks like.
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
# Name MUST be of form "bootstrap-token-<token id>"
|
||||
name: bootstrap-token-07401b
|
||||
namespace: kube-system
|
||||
|
||||
# Type MUST be 'bootstrap.kubernetes.io/token'
|
||||
type: bootstrap.kubernetes.io/token
|
||||
stringData:
|
||||
# Human readable description. Optional.
|
||||
description: "The default bootstrap token generated by 'kubeadm init'."
|
||||
|
||||
# Token ID and secret. Required.
|
||||
token-id: 07401b
|
||||
token-secret: f395accd246ae52d
|
||||
|
||||
# Expiration. Optional.
|
||||
expiration: 2017-03-10T03:22:11Z
|
||||
|
||||
# Allowed usages.
|
||||
usage-bootstrap-authentication: "true"
|
||||
usage-bootstrap-signing: "true"
|
||||
|
||||
# Extra groups to authenticate the token as. Must start with "system:bootstrappers:"
|
||||
auth-extra-groups: system:bootstrappers:worker,system:bootstrappers:ingress
|
||||
```
|
||||
|
||||
The type of the secret must be `bootstrap.kubernetes.io/token` and the name must
|
||||
be `bootstrap-token-<token id>`. It must also exist in the `kube-system`
|
||||
namespace.
|
||||
|
||||
The `usage-bootstrap-*` members indicate what this secret is intended to be used
|
||||
for. A value must be set to `true` to be enabled.
|
||||
|
||||
* `usage-bootstrap-authentication` indicates that the token can be used to
|
||||
authenticate to the API server as a bearer token.
|
||||
* `usage-bootstrap-signing` indicates that the token may be used to sign the
|
||||
`cluster-info` ConfigMap as described below.
|
||||
|
||||
The `expiration` field controls the expiry of the token. Expired tokens are
|
||||
rejected when used for authentication and ignored during ConfigMap signing.
|
||||
The expiry value is encoded as an absolute UTC time using RFC3339. Enable the
|
||||
`tokencleaner` controller to automatically delete expired tokens.
|
||||
|
||||
## Token Management with `kubeadm`
|
||||
|
||||
You can use the `kubeadm` tool to manage tokens on a running cluster. See the
|
||||
[`kubeadm token` docs](/docs/admin/kubeadm/#manage-tokens) for details.
|
||||
|
||||
## ConfigMap Signing
|
||||
|
||||
In addition to authentication, the tokens can be used to sign a ConfigMap. This
|
||||
is used early in a cluster bootstrap process before the client trusts the API
|
||||
server. The signed ConfigMap can be authenticated by the shared token.
|
||||
|
||||
Enable ConfigMap signing by enabling the `bootstrapsigner` controller on the
|
||||
Controller Manager.
|
||||
|
||||
```
|
||||
--controllers=*,bootstrapsigner
|
||||
```
|
||||
|
||||
The ConfigMap that is signed is `cluster-info` in the `kube-public` namespace.
|
||||
The typical flow is that a client reads this ConfigMap while unauthenticated and
|
||||
ignoring TLS errors. It then validates the payload of the ConfigMap by looking
|
||||
at a signature embedded in the ConfigMap.
|
||||
|
||||
The ConfigMap may look like this:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: cluster-info
|
||||
namespace: kube-public
|
||||
data:
|
||||
jws-kubeconfig-07401b: eyJhbGciOiJIUzI1NiIsImtpZCI6IjA3NDAxYiJ9..tYEfbo6zDNo40MQE07aZcQX2m3EB2rO3NuXtxVMYm9U
|
||||
kubeconfig: |
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: <really long certificate data>
|
||||
server: https://10.138.0.2:6443
|
||||
name: ""
|
||||
contexts: []
|
||||
current-context: ""
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users: []
|
||||
```
|
||||
|
||||
The `kubeconfig` member of the ConfigMap is a config file with just the cluster
|
||||
information filled out. The key thing being communicated here is the
|
||||
`certificate-authority-data`. This may be expanded in the future.
|
||||
|
||||
The signature is a JWS signature using the "detached" mode. To validate the
|
||||
signature, the user should encode the `kubeconfig` payload according to JWS
|
||||
rules (base64 encoded while discarding any trailing `=`). That encoded payload
|
||||
is then used to form a whole JWS by inserting it between the 2 dots. You can
|
||||
verify the JWS using the `HS256` scheme (HMAC-SHA256) with the full token (e.g.
|
||||
`07401b.f395accd246ae52d`) as the shared secret. Users _must_ verify that HS256
|
||||
is used.
|
||||
|
||||
WARNING: Any party with a bootstrapping token can create a valid signature for that
|
||||
token. When using ConfigMap signing it's discouraged to share the same token with
|
||||
many clients, since a compromised client can potentially man-in-the middle another
|
||||
client relying on the signature to bootstrap TLS trust.
|
||||
|
||||
Consult the [kubeadm security model](/docs/reference/generated/kubeadm/#security-model)
|
||||
section for more information.
|
||||
@@ -1,305 +0,0 @@
|
||||
---
|
||||
reviewers:
|
||||
- smarterclayton
|
||||
- lavalamp
|
||||
- whitlockjc
|
||||
- caesarxuchao
|
||||
- deads2k
|
||||
title: Dynamic Admission Control
|
||||
---
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## Overview
|
||||
|
||||
The [admission controllers documentation](/docs/admin/admission-controllers/)
|
||||
introduces how to use standard, plugin-style admission controllers. However,
|
||||
plugin admission controllers are not flexible enough for all use cases, due to
|
||||
the following:
|
||||
|
||||
* They need to be compiled into kube-apiserver.
|
||||
* They are only configurable when the apiserver starts up.
|
||||
|
||||
Two features, *Admission Webhooks* (beta in 1.9) and *Initializers* (alpha),
|
||||
address these limitations. They allow admission controllers to be developed
|
||||
out-of-tree and configured at runtime.
|
||||
|
||||
This page describes how to use Admission Webhooks and Initializers.
|
||||
|
||||
## Admission Webhooks
|
||||
|
||||
### What are admission webhooks?
|
||||
|
||||
Admission webhooks are HTTP callbacks that receive admission requests and do
|
||||
something with them. You can define two types of admission webhooks,
|
||||
[validating admission Webhook](/docs/admin/admission-controllers.md#validatingadmissionwebhook-alpha-in-18-beta-in-19)
|
||||
and
|
||||
[mutating admission webhook](/docs/admin/admission-controllers.md#mutatingadmissionwebhook-beta-in-19).
|
||||
With validating admission Webhooks, you may reject requests to enforce custom
|
||||
admission policies. With mutating admission Webhooks, you may change requests to
|
||||
enforce custom defaults.
|
||||
|
||||
### Experimenting with admission webhooks
|
||||
|
||||
Admission webhooks are essentially part of the cluster control-plane. You should
|
||||
write and deploy them with great caution. Please read the [user
|
||||
guides](https://github.com/kubernetes/website/pull/6836/files)(WIP) for
|
||||
instructions if you intend to write/deploy production-grade admission webhooks.
|
||||
In the following, we describe how to quickly experiment with admission webhooks.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
* Ensure that the Kubernetes cluster is at least as new as v1.9.
|
||||
|
||||
* Ensure that MutatingAdmissionWebhook and ValidatingAdmissionWebhook
|
||||
admission controllers are enabled.
|
||||
[Here](/docs/admin/admission-controllers.md#is-there-a-recommended-set-of-admission-controllers-to-use)
|
||||
is a recommended set of admission controllers to enable in general.
|
||||
|
||||
* Ensure that the admissionregistration.k8s.io/v1beta1 API is enabled.
|
||||
|
||||
### Write an admission webhook server
|
||||
|
||||
Please refer to the implementation of the [admission webhook
|
||||
server](https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.1/test/images/webhook/main.go)
|
||||
that is validated in a Kubernetes e2e test. The webhook handles the
|
||||
`admissionReview` requests sent by the apiservers, and sends back its decision
|
||||
wrapped in `admissionResponse`.
|
||||
|
||||
The example admission webhook server leaves the `ClientAuth` field
|
||||
[empty](https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.1/test/images/webhook/config.go#L48-L49),
|
||||
which defaults to `NoClientCert`. This means that the webhook server does not
|
||||
authenticate the identity of the clients, supposedly apiservers. If you need
|
||||
mutual TLS or other ways to authenticate the clients, see
|
||||
how to [authenticate apiservers](#authenticate-apiservers).
|
||||
|
||||
### Deploy the admission webhook service
|
||||
|
||||
The webhook server in the e2e test is deployed in the Kubernetes cluster, via
|
||||
the [deployment API](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#deployment-v1beta1-apps).
|
||||
The test also creates a [service](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#service-v1-core)
|
||||
as the front-end of the webhook server. See
|
||||
[code](https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.1/test/e2e/apimachinery/webhook.go#L196).
|
||||
|
||||
You may also deploy your webhooks outside of the cluster. You will need to update
|
||||
your [webhook client configurations](https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.1/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go#L218) accordingly.
|
||||
|
||||
### Configure admission webhooks on the fly
|
||||
|
||||
You can dynamically configure what resources are subject to what admission
|
||||
webhooks via
|
||||
[ValidatingWebhookConfiguration](https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.1/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go#L68)
|
||||
or
|
||||
[MutatingWebhookConifuration](https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.1/staging/src/k8s.io/api/admissionregistration/v1beta1/types.go#L98).
|
||||
|
||||
The following is an example `validatingWebhookConfiguration`, a mutating webhook
|
||||
configuration is similar.
|
||||
|
||||
```yaml
|
||||
apiVersion: admissionregistration.k8s.io/v1beta1
|
||||
kind: ValidatingWebhookConfiguration
|
||||
metadata:
|
||||
name: <name of this configuration object>
|
||||
webhooks:
|
||||
- name: <webhook name, e.g., pod-policy.example.io>
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
apiVersions:
|
||||
- v1
|
||||
operations:
|
||||
- CREATE
|
||||
resources:
|
||||
- pods
|
||||
clientConfig:
|
||||
service:
|
||||
namespace: <namespace of the front-end service>
|
||||
name: <name of the front-end service>
|
||||
caBundle: <pem encoded ca cert that signs the server cert used by the webhook>
|
||||
```
|
||||
|
||||
*Note*: When using `clientConfig.service`, the server cert must be valid for
|
||||
`<svc_name>.<svc_namespace>.svc`.
|
||||
|
||||
When an apiserver receives a request that matches one of the `rules`, the
|
||||
apiserver sends an `admissionReview` request to webhook as specified in the
|
||||
`clientConfig`.
|
||||
|
||||
After you create the webhook configuration, the system will take a few seconds
|
||||
to honor the new configuration.
|
||||
|
||||
{{< note >}}
|
||||
**Note** When the webhook plugin is deployed into the Kubernetes cluster as a
|
||||
service, it has to expose its service on the 443 port. The communication
|
||||
between the API server and the webhook service may fail if a different port
|
||||
is used.
|
||||
{{< /note >}}
|
||||
|
||||
### Authenticate apiservers
|
||||
|
||||
If your admission webhooks require authentication, you can configure the
|
||||
apiservers to use basic auth, bearer token, or a cert to authenticate itself to
|
||||
the webhooks. There are three steps to complete the configuration.
|
||||
|
||||
* When starting the apiserver, specify the location of the admission control
|
||||
configuration file via the `--admission-control-config-file` flag.
|
||||
|
||||
* In the admission control configuration file, specify where the
|
||||
MutatingAdmissionWebhook controller and ValidatingAdmissionWebhook controller
|
||||
should read the credentials. The credentials are stored in kubeConfig files
|
||||
(yes, the same schema that's used by kubectl), so the field name is
|
||||
`kubeConfigFile`. Here is an example admission control configuration file:
|
||||
|
||||
```yaml
|
||||
apiVersion: apiserver.k8s.io/v1alpha1
|
||||
kind: AdmissionConfiguration
|
||||
plugins:
|
||||
- name: ValidatingAdmissionWebhook
|
||||
configuration:
|
||||
apiVersion: apiserver.config.k8s.io/v1alpha1
|
||||
kind: WebhookAdmission
|
||||
kubeConfigFile: <path-to-kubeconfig-file>
|
||||
- name: MutatingAdmissionWebhook
|
||||
configuration:
|
||||
apiVersion: apiserver.config.k8s.io/v1alpha1
|
||||
kind: WebhookAdmission
|
||||
kubeConfigFile: <path-to-kubeconfig-file>
|
||||
```
|
||||
|
||||
The schema of `admissionConfiguration` is defined
|
||||
[here](https://github.com/kubernetes/kubernetes/blob/v1.10.0-beta.0/staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1alpha1/types.go#L27).
|
||||
|
||||
* In the kubeConfig file, provide the credentials:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Config
|
||||
users:
|
||||
# DNS name of webhook service, i.e., <service name>.<namespace>.svc, or the URL
|
||||
# of the webhook server.
|
||||
- name: 'webhook1.ns1.svc'
|
||||
user:
|
||||
client-certificate-data: <pem encoded certificate>
|
||||
client-key-data: <pem encoded key>
|
||||
# The `name` supports using * to wildmatch prefixing segments.
|
||||
- name: '*.webhook-company.org'
|
||||
user:
|
||||
password: <password>
|
||||
username: <name>
|
||||
# '*' is the default match.
|
||||
- name: '*'
|
||||
user:
|
||||
token: <token>
|
||||
```
|
||||
|
||||
Of course you need to set up the webhook server to handle these authentications.
|
||||
|
||||
## Initializers
|
||||
|
||||
### What are initializers?
|
||||
|
||||
*Initializer* has two meanings:
|
||||
|
||||
* A list of pending pre-initialization tasks, stored in every object's metadata
|
||||
(e.g., "AddMyCorporatePolicySidecar").
|
||||
|
||||
* A user customized controller, which actually performs those tasks. The name of the task
|
||||
corresponds to the controller which performs the task. For clarity, we call
|
||||
them *initializer controllers* in this page.
|
||||
|
||||
Once the controller has performed its assigned task, it removes its name from
|
||||
the list. For example, it may send a PATCH that inserts a container in a pod and
|
||||
also removes its name from `metadata.initializers.pending`. Initializers may make
|
||||
mutations to objects.
|
||||
|
||||
Objects which have a non-empty initializer list are considered uninitialized,
|
||||
and are not visible in the API unless specifically requested by using the query parameter,
|
||||
`?includeUninitialized=true`.
|
||||
|
||||
### When to use initializers?
|
||||
|
||||
Initializers are useful for admins to force policies (e.g., the
|
||||
[AlwaysPullImages](/docs/admin/admission-controllers/#alwayspullimages)
|
||||
admission controller), or to inject defaults (e.g., the
|
||||
[DefaultStorageClass](/docs/admin/admission-controllers/#defaultstorageclass)
|
||||
admission controller), etc.
|
||||
|
||||
**Note:** If your use case does not involve mutating objects, consider using
|
||||
external admission webhooks, as they have better performance.
|
||||
|
||||
### How are initializers triggered?
|
||||
|
||||
When an object is POSTed, it is checked against all existing
|
||||
`initializerConfiguration` objects (explained below). For all that it matches,
|
||||
all `spec.initializers[].name`s are appended to the new object's
|
||||
`metadata.initializers.pending` field.
|
||||
|
||||
An initializer controller should list and watch for uninitialized objects, by
|
||||
using the query parameter `?includeUninitialized=true`. If using client-go, just
|
||||
set
|
||||
[listOptions.includeUninitialized](https://github.com/kubernetes/kubernetes/blob/v1.7.0-rc.1/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go#L315)
|
||||
to true.
|
||||
|
||||
For the observed uninitialized objects, an initializer controller should first
|
||||
check if its name matches `metadata.initializers.pending[0]`. If so, it should then
|
||||
perform its assigned task and remove its name from the list.
|
||||
|
||||
### Enable initializers alpha feature
|
||||
|
||||
*Initializers* is an alpha feature, so it is disabled by default. To turn it on,
|
||||
you need to:
|
||||
|
||||
* Include "Initializers" in the `--enable-admission-plugins` flag when starting
|
||||
`kube-apiserver`. If you have multiple `kube-apiserver` replicas, all should
|
||||
have the same flag setting.
|
||||
|
||||
* Enable the dynamic admission controller registration API by adding
|
||||
`admissionregistration.k8s.io/v1alpha1` to the `--runtime-config` flag passed
|
||||
to `kube-apiserver`, e.g.
|
||||
`--runtime-config=admissionregistration.k8s.io/v1alpha1`. Again, all replicas
|
||||
should have the same flag setting.
|
||||
|
||||
### Deploy an initializer controller
|
||||
|
||||
You should deploy an initializer controller via the [deployment
|
||||
API](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#deployment-v1beta1-apps).
|
||||
|
||||
### Configure initializers on the fly
|
||||
|
||||
You can configure what initializers are enabled and what resources are subject
|
||||
to the initializers by creating `initializerConfiguration` resources.
|
||||
|
||||
You should first deploy the initializer controller and make sure that it is
|
||||
working properly before creating the `initializerConfiguration`. Otherwise, any
|
||||
newly created resources will be stuck in an uninitialized state.
|
||||
|
||||
The following is an example `initializerConfiguration`:
|
||||
|
||||
```yaml
|
||||
apiVersion: admissionregistration.k8s.io/v1alpha1
|
||||
kind: InitializerConfiguration
|
||||
metadata:
|
||||
name: example-config
|
||||
initializers:
|
||||
# the name needs to be fully qualified, i.e., containing at least two "."
|
||||
- name: podimage.example.com
|
||||
rules:
|
||||
# apiGroups, apiVersion, resources all support wildcard "*".
|
||||
# "*" cannot be mixed with non-wildcard.
|
||||
- apiGroups:
|
||||
- ""
|
||||
apiVersions:
|
||||
- v1
|
||||
resources:
|
||||
- pods
|
||||
```
|
||||
|
||||
After you create the `initializerConfiguration`, the system will take a few
|
||||
seconds to honor the new configuration. Then, `"podimage.example.com"` will be
|
||||
appended to the `metadata.initializers.pending` field of newly created pods. You
|
||||
should already have a ready "podimage" initializer controller that handles pods
|
||||
whose `metadata.initializers.pending[0].name="podimage.example.com"`. Otherwise
|
||||
the pods will be stuck in an uninitialized state.
|
||||
|
||||
Make sure that all expansions of the `<apiGroup, apiVersions, resources>` tuple
|
||||
in a `rule` are valid. If they are not, separate them in different `rules`.
|
||||
@@ -1,109 +0,0 @@
|
||||
---
|
||||
reviewers:
|
||||
- bprashanth
|
||||
- davidopp
|
||||
- lavalamp
|
||||
- liggitt
|
||||
title: Managing Service Accounts
|
||||
---
|
||||
|
||||
*This is a Cluster Administrator guide to service accounts. It assumes knowledge of
|
||||
the [User Guide to Service Accounts](/docs/user-guide/service-accounts).*
|
||||
|
||||
*Support for authorization and user accounts is planned but incomplete. Sometimes
|
||||
incomplete features are referred to in order to better describe service accounts.*
|
||||
|
||||
## User accounts vs service accounts
|
||||
|
||||
Kubernetes distinguishes between the concept of a user account and a service account
|
||||
for a number of reasons:
|
||||
|
||||
- User accounts are for humans. Service accounts are for processes, which
|
||||
run in pods.
|
||||
- User accounts are intended to be global. Names must be unique across all
|
||||
namespaces of a cluster, future user resource will not be namespaced.
|
||||
Service accounts are namespaced.
|
||||
- Typically, a cluster's User accounts might be synced from a corporate
|
||||
database, where new user account creation requires special privileges and
|
||||
is tied to complex business processes. Service account creation is intended
|
||||
to be more lightweight, allowing cluster users to create service accounts for
|
||||
specific tasks (i.e. principle of least privilege).
|
||||
- Auditing considerations for humans and service accounts may differ.
|
||||
- A config bundle for a complex system may include definition of various service
|
||||
accounts for components of that system. Because service accounts can be created
|
||||
ad-hoc and have namespaced names, such config is portable.
|
||||
|
||||
## Service account automation
|
||||
|
||||
Three separate components cooperate to implement the automation around service accounts:
|
||||
|
||||
- A Service account admission controller
|
||||
- A Token controller
|
||||
- A Service account controller
|
||||
|
||||
### Service Account Admission Controller
|
||||
|
||||
The modification of pods is implemented via a plugin
|
||||
called an [Admission Controller](/docs/admin/admission-controllers). It is part of the apiserver.
|
||||
It acts synchronously to modify pods as they are created or updated. When this plugin is active
|
||||
(and it is by default on most distributions), then it does the following when a pod is created or modified:
|
||||
|
||||
1. If the pod does not have a `ServiceAccount` set, it sets the `ServiceAccount` to `default`.
|
||||
2. It ensures that the `ServiceAccount` referenced by the pod exists, and otherwise rejects it.
|
||||
4. If the pod does not contain any `ImagePullSecrets`, then `ImagePullSecrets` of the
|
||||
`ServiceAccount` are added to the pod.
|
||||
5. It adds a `volume` to the pod which contains a token for API access.
|
||||
6. It adds a `volumeSource` to each container of the pod mounted at `/var/run/secrets/kubernetes.io/serviceaccount`.
|
||||
|
||||
### Token Controller
|
||||
|
||||
TokenController runs as part of controller-manager. It acts asynchronously. It:
|
||||
|
||||
- observes serviceAccount creation and creates a corresponding Secret to allow API access.
|
||||
- observes serviceAccount deletion and deletes all corresponding ServiceAccountToken Secrets.
|
||||
- observes secret addition, and ensures the referenced ServiceAccount exists, and adds a token to the secret if needed.
|
||||
- observes secret deletion and removes a reference from the corresponding ServiceAccount if needed.
|
||||
|
||||
You must pass a service account private key file to the token controller in the controller-manager by using
|
||||
the `--service-account-private-key-file` option. The private key will be used to sign generated service account tokens.
|
||||
Similarly, you must pass the corresponding public key to the kube-apiserver using the `--service-account-key-file`
|
||||
option. The public key will be used to verify the tokens during authentication.
|
||||
|
||||
#### To create additional API tokens
|
||||
|
||||
A controller loop ensures a secret with an API token exists for each service
|
||||
account. To create additional API tokens for a service account, create a secret
|
||||
of type `ServiceAccountToken` with an annotation referencing the service
|
||||
account, and the controller will update it with a generated token:
|
||||
|
||||
secret.json:
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "Secret",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "mysecretname",
|
||||
"annotations": {
|
||||
"kubernetes.io/service-account.name": "myserviceaccount"
|
||||
}
|
||||
},
|
||||
"type": "kubernetes.io/service-account-token"
|
||||
}
|
||||
```
|
||||
|
||||
```shell
|
||||
kubectl create -f ./secret.json
|
||||
kubectl describe secret mysecretname
|
||||
```
|
||||
|
||||
#### To delete/invalidate a service account token
|
||||
|
||||
```shell
|
||||
kubectl delete secret mysecretname
|
||||
```
|
||||
|
||||
### Service Account Controller
|
||||
|
||||
Service Account Controller manages ServiceAccount inside namespaces, and ensures
|
||||
a ServiceAccount named "default" exists in every active namespace.
|
||||
Reference in New Issue
Block a user