Kubernetes has many components and functionalities that need to be carefully configured in order to maintain the security of the cluster.
The API server is the pivotal point where the cluster’s security configuration is applied. All of the other components are able to interact directly with the cluster’s state store via its REST API.
For this reason, client access to the Kubernetes API should be authenticated, authorized, and encrypted.
Kubernetes uses client certificates, bearer tokens, an authenticating proxy, or HTTP basic auth to authenticate API requests through authentication plugins. The plugins attempt to associate the following attributes with each request:
- Username: a string which identifies the end user.
- UID: a unique string which identifies the end user.
- Groups: associate users with a set of commonly grouped users.
- Extra fields: a map of strings for additional information.
At a minimum, the service account tokens for service accounts and user authentication methods should be enabled.
system:authenticated group is included in the list of groups for all authenticated users.
Starting from version 1.6, anonymous access is enabled by default if an authorization mode other than
AlwaysAllow is used, and anonymous requests are not rejected but are given a username of
system:anonymous and a group of
Role-based access control (RBAC) is an access control mechanism to regulate access to resources based on the roles within your organization. In Kubernetes, permissions are grouped into roles and combine verbs (get, create, delete) with resources (pods, services, nodes); permissions can be scoped to a namespace or to the entire cluster.
To enable RBAC, start the API server with the
--authorization-mode flag set to a comma-separated list that includes
RBAC; for example
The RBAC API declares four kinds of objects:
ClusterRole can be used to grant permissions.
ClusterRole is cluster-scoped.
Here’s an example
Role in the
default namespace that can be used to grant read access to
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: secret-reader rules: - apiGroups: [""] # "" indicates the core API group resources: ["secrets"] verbs: ["get", "watch", "list"]
ClusterRoleBinding grant the permissions defined in a role to a user or set of subjects (users, groups, or service accounts).
ClusterRoleBinding is cluster-scoped.
Here is an example of a
RoleBinding that grants the
Role to the user
jane within the
default namespace. This allows
jane to read secrets in the
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: read-secrets namespace: default subjects: - kind: User name: jane roleRef: kind: Role name: secret-reader
If you want to grant permissions to a Pod instead of a user, you can create a custom
ServiceAccount to be referenced in the
--- apiVersion: v1 kind: ServiceAccount metadata: name: secret-reader-account --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: read-secrets namespace: default subjects: - kind: ServiceAccount name: secret-reader-account roleRef: kind: Role name: secret-reader
spec.serviceAccountName for any pod you want to entitle with such permissions.
Kubelet is an agent running on every node that should be configured correctly to prevent unauthorized access from the pods.
In prior versions of Kubernetes (prior to 1.7), Kubelet had read-write access to the Node and Pod APIs, allowing numerous resources to be taken control of in the event of a compromise. More recent versions introduced the Node Authorizer, which limits the kubelet to access only resources that are related specifically to the node on which the kubelet runs.
REST APIs are exposed on ports 10250 (read/write) and 10255 (read-only) ports.
Unrestricted access to the read-write port could result in a take over of the cluster, as it’s possible to run commands inside the pod’s containers or start new resources. This can’t be fully disabled because it is needed for metric collection and other important functions, so the access should be carefully controlled.
Kubelet should be configured to enforce authentication of all clients. The methods that can be enabled are X.509 client certificates, or requests with Authorization headers containing authentication tokens.
In the case of X.509 client certificates, the contents of a CA bundle need to be made available to the kubelet (
By default, when receiving anonymous requests, Kubelet passes them on for authorization, rather than rejecting them.
The authorization setting (
--authorization-mode) can operate in one of two modes;
AlwaysAllow (default) or
Webhook. The first option disables the authentication, while the
Webhook value performs further checks to determine whether the subject is allowed to make the request.
To disable anonymous access and send 401 Unauthorized responses to unauthenticated requests, the anonymous settings (
--anonymous-auth) must be set to
The read-only access could also be abused to disclose sensitive information regarding the cluster.
For this reason, the read-only port should be disabled by removing the option or by setting the option (
--read-only-port ) to
Kubernetes uses etcd key-value store for storing cluster state and configurations. For this reason, getting write access to the etcd backend for the APIs is equivalent to granting cluster-admin access, and read access can be used to escalate fairly quickly. It listens on TCP port 2379 for client and TCP port 2380 for server-to-server communications.
In versions prior to etcd 2.1, authentication did not exist; however, etcd currently supports strong credentials such as mutual authentication via client certificates. This should always be used by creating a new key pair for every entity in the cluster that needs to access etcd API.