Namespaces are an extremely important concept in Kubernetes, and since they can affect API access as well as authorization, we'll cover them now.
Namespaces
A namespace in Kubernetes is a construct that allows you to group Kubernetes resources in your cluster. They are a method of separation with many possible uses. For instance, you could have a namespace in your cluster for each environment – dev, staging, and production.
By default, Kubernetes will create the default namespace, the kube-system namespace, and the kube-public namespace. Resources created without a specified namespace will be created in the default namespace. kube-system contains the cluster services such as etcd, the scheduler, and any resource created by Kubernetes itself and not users. kube-public is readable by all users by default and can be used for public resources.
Users
There are two types of users in Kubernetes – regular users and service accounts.
Regular users are generally managed by a service outside the cluster, whether they be private keys, usernames and passwords, or some form of user store. Service accounts however are managed by Kubernetes and restricted to specific namespaces. To create a service account, the Kubernetes API may automatically make one, or they can be made manually through calls to the Kubernetes API.
There are three possible types of requests to the Kubernetes API – those associated with a regular user, those associated with a service account, and anonymous requests.
Authentication methods
In order to authenticate requests, Kubernetes provides several different options: HTTP basic authentication, client certificates, bearer tokens, and proxy-based authentication.
To use HTTP authentication, the requestor sends requests with an Authorization header that will have the value bearer "token value".
In order to specify which tokens are valid, a CSV file can be provided to the API server application when it starts using the --token-auth-file=filename parameter. A new beta feature (as of the writing of this book), called Bootstrap Tokens, allows for the dynamic swapping and changing of tokens while the API server is running, without restarting it.
Basic username/password authentication is also possible via the Authorization token, by using the header value Basic base64encoded(username:password).
Kubernetes' certificate infrastructure for TLS and security
In order to use client certificates (X.509 certificates), the API server must be started using the --client-ca-file=filename parameter. This file needs to contain one or more Certificate Authorities (CAs) that will be used when validating certificates passed with API requests.
In addition to the CA, a Certificate Signing Request (CSR) must be created for each user. At this point, user groups can be included, which we will discuss in the Authorization options section.
For instance, you can use the following:
openssl req -new -key myuser.pem -out myusercsr.pem -subj "/CN=myuser/0=dev/0=staging"
This will create a CSR for the user myuser who is part of groups named dev and staging.
Once the CA and CSR are created, the actual client and server certificates can be created using openssl, easyrsa, cfssl, or any certificate generation tool. TLS certificates for the Kubernetes API can also be created at this point.
Since our aim is to get you started running workloads on Kubernetes as soon as possible, we will leave all the various possible certificate configurations out of this book – but both the Kubernetes documentation and the article Kubernetes The Hard Way have some great tutorials on setting up a cluster from scratch. In the majority of production settings, you will not be doing these steps manually.
Authorization options
Kubernetes provides several authorization methods: nodes, webhooks, RBAC, and ABAC. In this book, we will focus on RBAC and ABAC as they are the ones used most often for user authorization. If you extend your cluster with other services and/or custom features, the other authorization modes may become more important.
RBAC
RBAC stands for Role-Based Access Control and is a common pattern for authorization. In Kubernetes specifically, the roles and users of RBAC are implemented using four Kubernetes resources: Role, ClusterRole, RoleBinding, and ClusterRoleBinding. To enable RBAC mode, the API server can be started with the --authorization-mode=RBAC parameter.
Role and ClusterRole resources specify a set of permissions, but do not assign those permissions to any specific users. Permissions are specified using resources and verbs. Here is a sample YAML file specifying a Role. Don't worry too much about the first few lines of the YAML file – we'll get to those soon. Focus on the resources and verbs lines to see how the actions can be applied to resources:
Read-only-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: read-only-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
The only difference between a Role and ClusterRole is that a Role is restricted to a particular namespace (in this case, the default namespace), while a ClusterRole can affect access to all resources of that type in the cluster, as well as cluster-scoped resources such as nodes.
RoleBinding and ClusterRoleBinding are resources that associate a Role or ClusterRole with a user or a list of users. The following file represents a RoleBinding resource to connect our read-only-role with a user, readonlyuser:
Read-only-rb.yaml
apiVersion: rbac.authorization.k8s.io/v1namespace.
kind: RoleBinding
metadata:
name: read-only
namespace: default
subjects:
- kind: User
name: readonlyuser
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: read-only-role
apiGroup: rbac.authorization.k8s.io
The subjects key contains a list of all entities to associate a role with; in this case, the user alex. roleRef contains the name of the role to associate, and the type (either Role or ClusterRole).
ABAC
ABAC stands for Attribute-Based Access Control. ABAC works using policies instead of roles. The API server is started in ABAC mode with a file called an authorization policy file, which contains a list of JSON objects called policy objects. To enable ABAC mode, the API server can be started with the --authorization-mode=ABAC and --authorization-policy-file=filename parameters.
In the policy file, each policy object contains information about a single policy: firstly, which subjects it corresponds to, which can be either users or groups, and secondly, which resources can be accessed via the policy. Additionally, a Boolean readonly value can be included to limit the policy to list, get, and watch operations.
A secondary type of policy is associated not with a resource, but with types of non-resource requests, such as calls to the /version endpoint.
When a request to the API is made in ABAC mode, the API server will check the user and any group it is a part of against the list in the policy file, and see if any policies match the resource or endpoint that the user is trying to access. On a match, the API server will authorize the request.
You should have a good understanding now of how the Kubernetes API handles authentication and authorization. The good news is that while you can directly access the API, Kubernetes provides an excellent command-line tool to simply authenticate and make Kubernetes API requests.