Authentication and authorization

In order to use more advanced management, we can add permission rules to the Kubernetes system. Two permission types could be generated in our cluster: one is between the machines. Nodes having authentication can contact the controlling node. For example, the master who owns certification with the etcd server can store data in etcd. The other permission rule is inside the Kubernetes master. Users can be given authorization for checking and creating the resources. Applying authentication and authorization is a secure solution to prevent your data or status being accessed by others.

Getting ready

Before you start configuring your cluster with some permissions, please have your cluster installed. Nevertheless, stop every service in the system. They will be started later with the authentication enabled.

How to do it…

In this recipe, we will have a discussion on both authentication and authorization. For authentication, etcd and the Kubernetes server need to do identity verification before they respond to the requests. On the other hand, authorization restricts users by different resource access permissions. All of these contacts are based on the API connection. Later sections show you how to complete the configuration and follow the authentication.

Enabling authentication for an API call

There are several methods to block the unauthenticated communication in the Kubernetes system. We are going to introduce basic authentication mechanism. It is easier to set it on not only the Kubernetes masters, but etcd servers.

Basic authentication of etcd

First, let's try to send API requests on the etcd host. You will find that anyone can access the data by default:

// Create a key-value pair in etcd
# curl -X PUT -d value="Happy coding" http://localhost:4001/v2/keys/message
{"action":"set","node":{"key":"/message","value":"Happy coding","modifiedIndex":4,"createdIndex":4}}
// Check the value you just push
# curl http://localhost:4001/v2/keys/message
{"action":"get","node":{"key":"/message","value":"Happy coding","modifiedIndex":4,"createdIndex":4}}
// Remove the value
# curl -X DELETE http://localhost:4001/v2/keys/message
{"action":"delete","node":{"key":"/message","modifiedIndex":5,"createdIndex":4},"prevNode":{"key":"/message","value":"Happy coding","modifiedIndex":4,"createdIndex":4}}

Without authentication, neither reading nor writing functions can be protected. The way to enable basic authentication of etcd is through the RESTful API as well. The procedure is as follows:

  • Add a password for the admin account root
  • Enable basic authentication
  • Stop both read and write permissions of the guest account

Make sure the etcd service is running. We will transfer the preceding logics into the following commands:

// Send the API request for setup root account
# curl -X PUT -d "{"user":"root","password":"<YOUR_ETCD_PASSWD>","roles":["root"]}" http://localhost:4001/v2/auth/users/root
{"user":"root","roles":["root"]}
// Enable authentication 
# curl -X PUT http://localhost:4001/v2/auth/enable
// Encode "USERACCOUNT:PASSWORD" string in base64 format, and record in a value
# AUTHSTR=$(echo -n "root:<YOUR_ETCD_PASSWD>" | base64)
// Remove all permission of guest account. Since we already enable authentication, use the authenticated root.
# curl -H "Authorization: Basic $AUTHSTR" -X PUT -d "{"role":"guest","revoke":{"kv":{"read":["*"],"write":["*"]}}}" http://localhost:4001/v2/auth/roles/guest
{"role":"guest","permissions":{"kv":{"read":[],"write":[]}}}

Now, for validation, try to check anything in etcd through the API:

# curl http://localhost:4001/v2/keys
{"message":"Insufficient credentials"}

Because we didn't specify any identity for this API call, it is regarded as a request from a guest. No authorization for even viewing data.

For long-term usage, we would put user profiles of etcd in the Kubernetes master's configuration. Check your configuration file of the Kubernetes API server. In the RHEL server, it is the file /etc/kubernetes/apiserver; or for the other Linux server, just the one for service, /etc/init.d/kubernetes-master. You can find a flag for the etcd server called --etcd-servers. Based on the previous settings, the value we attached is a simple URL with a port. It could be http://ETCD_ELB_URL:80. Add an account root and its password in a plain text format to the value, which is the authorization header for the HTTP request. The new value for flag --etcd-servers would become http://root:YOUR_ETCD_PASSWD@ETCD_ELB_URL:80. Afterwards, your Kubernetes API server daemon will work well with an authentication-enabled etcd endpoint.

Basic authentication of the Kubernetes master

Before we set up authentication in the Kubernetes master, let's check the endpoint of the master first:

# curl https://K8S_MASTER_HOST_IP:SECURED_PORT --insecure

or

# curl http://K8S_MASTER_ELB_URL:80
{
  "paths": [
    "/api",
    "/api/v1",
    "/apis",
    "/apis/extensions",
    "/apis/extensions/v1beta1",
    "/healthz",
    "/healthz/ping",
    "/logs/",
    "/metrics",
    "/resetMetrics",
    "/swagger-ui/",
    "/swaggerapi/",
    "/ui/",
    "/version"
  ]
}

We don't want the previous message to be exposed to everyone, do we? Same as the etcd host, Kubernetes master can apply basic authentication as a security mechanism. In this section, we are going to limit the permission of the API server. However, different from etcd, the information of authentication is defined in a file:

// Create a file for basic authentication with content: PASSWORD,USERNAME,UID
# cat /root/k8s-bafile
<APISERVER_BA_PASSWORD>,<APISERVER_BA_USERACCOUNT>,1

Then, we have to specify this file in the configuration file. According to your daemon management tool, the configuration file could be located at /etc/init.d/kubernetes-master or /etc/kubernetes/apiserver. A new flag named --basic-auth-file should be added to the configuration file:

  • For the file kubernetes-master, append flag --basic-auth-file after the kube-apiserver command or the hyperkube apiserver command. The value for this tag should be the full path of the basic authentication file. For instance, --basic-auth-file=/root/k8s-bafile.
  • For the file apiserver, add the tag to the variable KUBE_API_ARGS. For example, KUBE_API_ARGS=--basic-auth-file=/root/k8s-bafile.

Most important of all, ensure the user who starts the services of Kubernetes, either root or kubelet, has the permission to access the file you attached to the tag. After you add the new tag, it is necessary to restart the service for making the authentication effective. Next, it is good for you to try the curl command at the beginning of this section. It will return Unauthorized without providing the username and password.

Our nodes communicate with API server through the insecure port 8080. Although we didn't have to specify any role for authorizing permission, be aware of configuring the firewall of master, which only allows nodes to go through port 8080. On AWS, a security group can help for this part.

There are still some methods for the Kubernetes master's authentication. Please check the official website for other ideas (http://kubernetes.io/docs/admin/authentication/).

Making use of user authorization

We can also add different user permissions for the Kubernetes master's API server daemon. There are three flags required to set user authorization. They are as follows:

  • --authorization-mode=ABAC: The value, ABAC, is the abbreviation of Attribute-Based Access Control. By enabling this mode, we can set up customized user permissions.
  • --token-auth-file=<FULL_PATH_OF_YOUR_TOKEN_FILE>: This is the file we used to announce the qualified users for API access. It is possible to provide more accounts and token pairs.
  • --authorization-policy-file=<FULL_PATH_OF_YOUR_POLICY_FILE>: We would need this policy file to generate separated rules for different users.

These special tags are going to be appended after the command kube-apiserver or hyperkube apiserver. You can refer to the following example:

// The daemon configuration file of Kubernetes master for init.d service 
# cat /etc/init.d/kubernetes-master
(above lines are ignored)
:
# Start daemon.
    echo $"Starting apiserver: "
    daemon $apiserver_prog 
    --service-cluster-ip-range=${CLUSTER_IP_RANGE} 
    --insecure-port=8080 
    --secure-port=6443 
    --authorization-mode=ABAC 
    --token-auth-file=/root/k8s-tokenfile 
    --authorization-policy-file=/root/k8s-policyfile 
    --address=0.0.0.0 
    --etcd-servers=${ETCD_SERVERS} 
    --cluster-name=${CLUSTER_NAME} 
    > ${logfile}-apiserver.log 2>&1 &
:
(below lines are ignored)

or

// The kubernetes apiserver's configuration file for systemd service in RHEL
# cat /etc/kubernetes/apiserver
(above lines are ignored)
:
KUBE_API_ARGS="--authorization-mode=ABAC --token-auth-file=/root/k8s-tokenfile --authorization-policy-file=/root/k8s-policyfile"

You still need to configure the file for account and the file for policy. To demonstrate the usage of customizing user permission, the following content of files show you how to create an admin account with full access and a read-only account:

# cat /root/k8s-tokenfile
k8s2016,admin,1
happy123,amy,2

The format of user definition is similar to the basic authentication file we mentioned before. Each line has these items in sequence: token, username, and UID. Other than admin, we create another user account called amy, which will only have read-only permission:

# cat /root/k8s-policyfile
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "admin", "namespace": "*", "resource": "*", "apiGroup": "*"}}
{"apiVersion": "abac.authorization.kubernetes.io/v1beta1", "kind": "Policy", "spec": {"user": "amy", "namespace": "*", "resource": "*", "readonly": true}}

For the policy file, each line will be a policy in the JSON format. Every policy should indicate the user who obeys its rule. The first policy for admin allows control permission on every namespace, resource, and API group. The key apiGroup specifies different API categories. For instance, the resource job is defined in the extensions API group. In order to access job, the extensions type should be included in apiGroup. The second policy is defined with read-only permission, which means the role amy can only view resources, but not create, remove, and edit actions.

Later, restart all the daemons of the Kubernetes master after you make both configuration files and service files ready:

// For init.d service management
# service kubernetes-master restart
// Or, you can restart the individually with dependency
# systemctl stop kube-scheduler
# systemctl stop kube-controller-manager
# systemctl stop kube-apiserver
# systemctl start kube-apiserver
# systemctl start kube-controller-manager
# systemctl start kube-scheduler

See also

It is recommended to read some of the previous recipes on installing the Kubernetes cluster:

  • The Building datastore, Configuring master and Configuring nodes recipe in Chapter 1, Building Your Own Kubernetes
  • The Auto-deploying Kubernetes through Chef recipes recipe in Chapter 6, Building Kubernetes on AWS
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset