2015-07-12 04:04:52 +00:00
|
|
|
<!-- BEGIN MUNGE: UNVERSIONED_WARNING -->
|
|
|
|
|
2016-06-10 23:46:46 +00:00
|
|
|
<!-- BEGIN STRIP_FOR_RELEASE -->
|
|
|
|
|
2016-07-15 09:44:58 +00:00
|
|
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
2016-06-10 23:46:46 +00:00
|
|
|
width="25" height="25">
|
2016-07-15 09:44:58 +00:00
|
|
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
2016-06-10 23:46:46 +00:00
|
|
|
width="25" height="25">
|
2016-07-15 09:44:58 +00:00
|
|
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
2016-06-10 23:46:46 +00:00
|
|
|
width="25" height="25">
|
2016-07-15 09:44:58 +00:00
|
|
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
2016-06-10 23:46:46 +00:00
|
|
|
width="25" height="25">
|
2016-07-15 09:44:58 +00:00
|
|
|
<img src="http://kubernetes.io/kubernetes/img/warning.png" alt="WARNING"
|
2016-06-10 23:46:46 +00:00
|
|
|
width="25" height="25">
|
|
|
|
|
|
|
|
<h2>PLEASE NOTE: This document applies to the HEAD of the source tree</h2>
|
|
|
|
|
|
|
|
If you are using a released version of Kubernetes, you should
|
|
|
|
refer to the docs that go with that version.
|
|
|
|
|
|
|
|
<!-- TAG RELEASE_LINK, added by the munger automatically -->
|
|
|
|
<strong>
|
|
|
|
The latest release of this document can be found
|
2016-09-01 21:40:55 +00:00
|
|
|
[here](http://releases.k8s.io/release-1.4/docs/design/security_context.md).
|
2016-06-10 23:46:46 +00:00
|
|
|
|
|
|
|
Documentation for other releases can be found at
|
|
|
|
[releases.k8s.io](http://releases.k8s.io).
|
|
|
|
</strong>
|
|
|
|
--
|
|
|
|
|
|
|
|
<!-- END STRIP_FOR_RELEASE -->
|
2015-07-12 04:04:52 +00:00
|
|
|
|
|
|
|
<!-- END MUNGE: UNVERSIONED_WARNING -->
|
2015-07-17 22:35:41 +00:00
|
|
|
|
2015-01-22 14:32:30 +00:00
|
|
|
# Security Contexts
|
2015-07-17 22:35:41 +00:00
|
|
|
|
2015-01-22 14:32:30 +00:00
|
|
|
## Abstract
|
2015-07-17 22:35:41 +00:00
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
A security context is a set of constraints that are applied to a container in
|
|
|
|
order to achieve the following goals (from [security design](security.md)):
|
2015-01-22 14:32:30 +00:00
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
1. Ensure a clear isolation between container and the underlying host it runs
|
|
|
|
on
|
|
|
|
2. Limit the ability of the container to negatively impact the infrastructure
|
|
|
|
or other containers
|
2015-01-22 14:32:30 +00:00
|
|
|
|
|
|
|
## Background
|
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
The problem of securing containers in Kubernetes has come up
|
|
|
|
[before](http://issue.k8s.io/398) and the potential problems with container
|
|
|
|
security are [well known](http://opensource.com/business/14/7/docker-security-selinux).
|
|
|
|
Although it is not possible to completely isolate Docker containers from their
|
|
|
|
hosts, new features like [user namespaces](https://github.com/docker/libcontainer/pull/304)
|
|
|
|
make it possible to greatly reduce the attack surface.
|
2015-01-22 14:32:30 +00:00
|
|
|
|
|
|
|
## Motivation
|
|
|
|
|
|
|
|
### Container isolation
|
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
In order to improve container isolation from host and other containers running
|
|
|
|
on the host, containers should only be granted the access they need to perform
|
|
|
|
their work. To this end it should be possible to take advantage of Docker
|
|
|
|
features such as the ability to
|
|
|
|
[add or remove capabilities](https://docs.docker.com/reference/run/#runtime-privilege-linux-capabilities-and-lxc-configuration)
|
|
|
|
and [assign MCS labels](https://docs.docker.com/reference/run/#security-configuration)
|
2015-01-22 14:32:30 +00:00
|
|
|
to the container process.
|
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
Support for user namespaces has recently been
|
|
|
|
[merged](https://github.com/docker/libcontainer/pull/304) into Docker's
|
|
|
|
libcontainer project and should soon surface in Docker itself. It will make it
|
|
|
|
possible to assign a range of unprivileged uids and gids from the host to each
|
|
|
|
container, improving the isolation between host and container and between
|
|
|
|
containers.
|
2015-01-22 14:32:30 +00:00
|
|
|
|
|
|
|
### External integration with shared storage
|
2015-07-17 22:35:41 +00:00
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
In order to support external integration with shared storage, processes running
|
|
|
|
in a Kubernetes cluster should be able to be uniquely identified by their Unix
|
|
|
|
UID, such that a chain of ownership can be established. Processes in pods will
|
|
|
|
need to have consistent UID/GID/SELinux category labels in order to access
|
|
|
|
shared disks.
|
2015-01-22 14:32:30 +00:00
|
|
|
|
|
|
|
## Constraints and Assumptions
|
2015-07-17 22:35:41 +00:00
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
* It is out of the scope of this document to prescribe a specific set of
|
|
|
|
constraints to isolate containers from their host. Different use cases need
|
|
|
|
different settings.
|
|
|
|
* The concept of a security context should not be tied to a particular security
|
|
|
|
mechanism or platform (ie. SELinux, AppArmor)
|
|
|
|
* Applying a different security context to a scope (namespace or pod) requires
|
|
|
|
a solution such as the one proposed for [service accounts](service_accounts.md).
|
2015-01-22 14:32:30 +00:00
|
|
|
|
|
|
|
## Use Cases
|
|
|
|
|
2015-07-24 21:52:18 +00:00
|
|
|
In order of increasing complexity, following are example use cases that would
|
2015-01-22 14:32:30 +00:00
|
|
|
be addressed with security contexts:
|
|
|
|
|
|
|
|
1. Kubernetes is used to run a single cloud application. In order to protect
|
2016-04-14 00:55:22 +00:00
|
|
|
nodes from containers:
|
2015-01-22 14:32:30 +00:00
|
|
|
* All containers run as a single non-root user
|
|
|
|
* Privileged containers are disabled
|
2015-07-24 21:52:18 +00:00
|
|
|
* All containers run with a particular MCS label
|
2015-01-22 14:32:30 +00:00
|
|
|
* Kernel capabilities like CHOWN and MKNOD are removed from containers
|
2015-07-24 21:52:18 +00:00
|
|
|
|
2015-01-22 14:32:30 +00:00
|
|
|
2. Just like case #1, except that I have more than one application running on
|
2016-04-14 00:55:22 +00:00
|
|
|
the Kubernetes cluster.
|
2015-01-22 14:32:30 +00:00
|
|
|
* Each application is run in its own namespace to avoid name collisions
|
|
|
|
* For each application a different uid and MCS label is used
|
2015-07-24 21:52:18 +00:00
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
3. Kubernetes is used as the base for a PAAS with multiple projects, each
|
|
|
|
project represented by a namespace.
|
2015-01-22 14:32:30 +00:00
|
|
|
* Each namespace is associated with a range of uids/gids on the node that
|
2016-04-14 00:55:22 +00:00
|
|
|
are mapped to uids/gids on containers using linux user namespaces.
|
2015-01-22 14:32:30 +00:00
|
|
|
* Certain pods in each namespace have special privileges to perform system
|
2016-04-14 00:55:22 +00:00
|
|
|
actions such as talking back to the server for deployment, run docker builds,
|
|
|
|
etc.
|
2015-01-22 14:32:30 +00:00
|
|
|
* External NFS storage is assigned to each namespace and permissions set
|
2016-04-14 00:55:22 +00:00
|
|
|
using the range of uids/gids assigned to that namespace.
|
2015-01-22 14:32:30 +00:00
|
|
|
|
|
|
|
## Proposed Design
|
|
|
|
|
|
|
|
### Overview
|
2015-07-17 22:35:41 +00:00
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
A *security context* consists of a set of constraints that determine how a
|
|
|
|
container is secured before getting created and run. A security context resides
|
|
|
|
on the container and represents the runtime parameters that will be used to
|
|
|
|
create and run the container via container APIs. A *security context provider*
|
|
|
|
is passed to the Kubelet so it can have a chance to mutate Docker API calls in
|
|
|
|
order to apply the security context.
|
2015-01-22 14:32:30 +00:00
|
|
|
|
|
|
|
It is recommended that this design be implemented in two phases:
|
|
|
|
|
2015-07-24 21:52:18 +00:00
|
|
|
1. Implement the security context provider extension point in the Kubelet
|
2016-04-14 00:55:22 +00:00
|
|
|
so that a default security context can be applied on container run and creation.
|
2015-01-22 14:32:30 +00:00
|
|
|
2. Implement a security context structure that is part of a service account. The
|
2016-04-14 00:55:22 +00:00
|
|
|
default context provider can then be used to apply a security context based on
|
|
|
|
the service account associated with the pod.
|
2015-07-20 16:45:58 +00:00
|
|
|
|
2015-01-22 14:32:30 +00:00
|
|
|
### Security Context Provider
|
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
The Kubelet will have an interface that points to a `SecurityContextProvider`.
|
|
|
|
The `SecurityContextProvider` is invoked before creating and running a given
|
|
|
|
container:
|
2015-01-22 14:32:30 +00:00
|
|
|
|
|
|
|
```go
|
|
|
|
type SecurityContextProvider interface {
|
2015-03-16 12:20:03 +00:00
|
|
|
// ModifyContainerConfig is called before the Docker createContainer call.
|
|
|
|
// The security context provider can make changes to the Config with which
|
|
|
|
// the container is created.
|
|
|
|
// An error is returned if it's not possible to secure the container as
|
|
|
|
// requested with a security context.
|
2015-05-08 20:38:28 +00:00
|
|
|
ModifyContainerConfig(pod *api.Pod, container *api.Container, config *docker.Config)
|
2015-01-22 14:32:30 +00:00
|
|
|
|
|
|
|
// ModifyHostConfig is called before the Docker runContainer call.
|
|
|
|
// The security context provider can make changes to the HostConfig, affecting
|
|
|
|
// security options, whether the container is privileged, volume binds, etc.
|
|
|
|
// An error is returned if it's not possible to secure the container as requested
|
2015-03-16 12:20:03 +00:00
|
|
|
// with a security context.
|
|
|
|
ModifyHostConfig(pod *api.Pod, container *api.Container, hostConfig *docker.HostConfig)
|
2015-01-22 14:32:30 +00:00
|
|
|
}
|
|
|
|
```
|
2015-02-09 19:17:51 +00:00
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
If the value of the SecurityContextProvider field on the Kubelet is nil, the
|
|
|
|
kubelet will create and run the container as it does today.
|
2015-01-22 14:32:30 +00:00
|
|
|
|
|
|
|
### Security Context
|
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
A security context resides on the container and represents the runtime
|
|
|
|
parameters that will be used to create and run the container via container APIs.
|
|
|
|
Following is an example of an initial implementation:
|
2015-01-22 14:32:30 +00:00
|
|
|
|
|
|
|
```go
|
2015-08-06 04:53:01 +00:00
|
|
|
type Container struct {
|
2015-05-08 20:38:28 +00:00
|
|
|
... other fields omitted ...
|
|
|
|
// Optional: SecurityContext defines the security options the pod should be run with
|
|
|
|
SecurityContext *SecurityContext
|
|
|
|
}
|
2015-02-09 19:17:51 +00:00
|
|
|
|
2015-05-08 20:38:28 +00:00
|
|
|
// SecurityContext holds security configuration that will be applied to a container. SecurityContext
|
|
|
|
// contains duplication of some existing fields from the Container resource. These duplicate fields
|
|
|
|
// will be populated based on the Container configuration if they are not set. Defining them on
|
|
|
|
// both the Container AND the SecurityContext will result in an error.
|
2015-01-22 14:32:30 +00:00
|
|
|
type SecurityContext struct {
|
2015-05-08 20:38:28 +00:00
|
|
|
// Capabilities are the capabilities to add/drop when running the container
|
|
|
|
Capabilities *Capabilities
|
2015-02-09 19:17:51 +00:00
|
|
|
|
2015-05-08 20:38:28 +00:00
|
|
|
// Run the container in privileged mode
|
|
|
|
Privileged *bool
|
2015-01-22 14:32:30 +00:00
|
|
|
|
2015-05-08 20:38:28 +00:00
|
|
|
// SELinuxOptions are the labels to be applied to the container
|
|
|
|
// and volumes
|
|
|
|
SELinuxOptions *SELinuxOptions
|
2015-02-09 19:17:51 +00:00
|
|
|
|
2015-05-08 20:38:28 +00:00
|
|
|
// RunAsUser is the UID to run the entrypoint of the container process.
|
|
|
|
RunAsUser *int64
|
|
|
|
}
|
2015-02-09 19:17:51 +00:00
|
|
|
|
2015-05-08 20:38:28 +00:00
|
|
|
// SELinuxOptions are the labels to be applied to the container.
|
|
|
|
type SELinuxOptions struct {
|
|
|
|
// SELinux user label
|
|
|
|
User string
|
2015-02-09 19:17:51 +00:00
|
|
|
|
2015-05-08 20:38:28 +00:00
|
|
|
// SELinux role label
|
|
|
|
Role string
|
2015-01-22 14:32:30 +00:00
|
|
|
|
2015-05-08 20:38:28 +00:00
|
|
|
// SELinux type label
|
|
|
|
Type string
|
2015-02-09 19:17:51 +00:00
|
|
|
|
2015-05-08 20:38:28 +00:00
|
|
|
// SELinux level label.
|
|
|
|
Level string
|
2015-01-22 14:32:30 +00:00
|
|
|
}
|
|
|
|
```
|
2015-07-17 02:01:02 +00:00
|
|
|
|
2015-05-08 20:38:28 +00:00
|
|
|
### Admission
|
2015-01-22 14:32:30 +00:00
|
|
|
|
2016-04-14 00:55:22 +00:00
|
|
|
It is up to an admission plugin to determine if the security context is
|
|
|
|
acceptable or not. At the time of writing, the admission control plugin for
|
|
|
|
security contexts will only allow a context that has defined capabilities or
|
|
|
|
privileged. Contexts that attempt to define a UID or SELinux options will be
|
|
|
|
denied by default. In the future the admission plugin will base this decision
|
|
|
|
upon configurable policies that reside within the [service account](http://pr.k8s.io/2297).
|
2015-02-09 19:17:51 +00:00
|
|
|
|
2015-05-14 22:12:45 +00:00
|
|
|
|
2015-07-14 00:13:09 +00:00
|
|
|
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
2015-05-14 22:12:45 +00:00
|
|
|
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/design/security_context.md?pixel)]()
|
2015-07-14 00:13:09 +00:00
|
|
|
<!-- END MUNGE: GENERATED_ANALYTICS -->
|