API server authentication mechanism

In the section of coredns, although my attempt to install coredns failed, we can still see how DNS components are installed


There was an error during installation


Failed with no API token found for service account “coredns”


We chose to disable serviceaccount to avoid this error simply and rudely


To: Kube_ ADMISSION_ CONTROL=”–admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota”
Change to: Kube_ ADMISSION_ CONTROL=”–admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota”


So in this section, I’m going to study serviceaccount


When you access apiserver from outside the cluster, you use the kubectl command line. At this time, service account is not required. However, when we access it from inside a pod, there is often no kubectl available. Therefore, if you want to access API server from inside a pod, you need service account


If you look at all the services in the current cluster, you can see that there must be a service called kubernetes. The type is clusterip. In fact, this service is API server

To test the above, I’ll create a Ubuntu pod and use it to try to connect to the API server

apiVersion: apps/v1

kind: Deployment

metadata:

  name: ub2

  labels:

    app: ub2

spec:

  replicas: 1

  selector:

    matchLabels:

      app: ub2

  template:

    metadata:

      labels:

        app: ub2

    spec:

      containers:

      - name: ub2

        image: libaibai/ub2:latest

        command: ["/bin/bash","-c","sleep 3600"]

        ports:

        - containerPort: 80

Then we use this pod to try to access apiserver

The cert of API server is stored in secret

This file will be mapped to / var / run / secrets / kubernetes. For each pod io/serviceaccount/ca.crt


However, you cannot directly use this cert to pass the verification. The 401 below is the same as the 401 above. It is the result of the client ignoring or trusting the server


But the server does not authorize the client

if the client does not trust the server

You need to be authorized by API server to use
/var/run/secrets/kubernetes. io/serviceaccount/token

curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6Ikxsc0ZlMElUY3FLanNONGRoYzMtTGJDWXZjZWE2WXVkR2pOajdtNXNHTTAifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tZzZzdzYiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjQ1NzY1NzdkLTNkNGYtNDUyMS1iNDdkLWY5MmJhOGUxNjg3MyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.SAdvtBm1v4-YzD7qTC4KOdt6PDY4vAyptGzQkGNP17BqAqDNi9-dbrfJdYEFgof7nyMZH_TCMhi1FXMZJwQ5zOKXeS_YKruJuvJ1iXLwW2MoVy-conJmkoMU-SRcsy8tjv5KkLEZa9adIRG_8jHGc4zSRvs-5YkApsIYYOMFcUbhIVjyMt_rXIeb900hj1e5AhcaSQ19gy2paQkcCbaFnxq7dsgSbpsy011QDe-FzaWv7yY8xI3PJj-JIRgrDxV4WbtalJ5V5IrNcFhHyB7hxawZKvexIJ_ndPewacA42vIUoemAYCQYXm3Bio_ynd-gTQJQzo0YBGxSxfrHnIaHsQ"  https://10.43.0.1:443 

The return status code becomes 403 because our cluster uses RBAC
Kubernetes divides the clients connected to API server into two types

Real people
Application in pod (service account)
Both normal users and service accounts can belong to one or more groups


Common groups:
All plug-ins that request authentication for the client will not be authenticated:
System: the authenticated group will be automatically assigned to a user who has successfully passed the authentication
System: serviceaccounts contains all serviceaccounts in the system
System: serviceaccounts: < namespace > group contains all serviceaccounts in a specific namespace


Let’s do an experiment
The first is the failed experiment
We create a Ubuntu instance under Lizhe namespace,

Then try to access the API server without permission

Sure enough, I got 403
The following is the correct experiment
Given permission

kubectl create clusterrolebinding permissive-binding --clusterrole=cluster-admin --group=system:serviceaccounts:lizhe

how to remove:

kubectl delete clusterrolebindings permissive-binding

call curl again

Serviceaccount, like pod, secret and configmap, is a resource. A resource must exist in a namespace

We try to create a new namespace. We can see that the new namespace (lizhe2) automatically holds a service account

Each pod is associated with a serviceaccount, but multiple pods can use the same serviceaccount
Each pod will be assigned a single service account in this pod namespace
In the description file of the pod, you can assign a service account to a pod. If the service account is not specified explicitly, the pod will use the default service account of the namespace
Create a new namespace lizhe10

Create Ubuntu 10 under it

Experiment 1
When Ubuntu 10 uses the default service account (provided by lizhe10), it gets 403 and cannot access the API server

Experiment 2
Failed to assign service account – > under other namespace to pod
Pod Ubuntu 10 under namespace lizhe10
SA lizhesa under namespace Lizhe
Failed to assign lizhesa to Ubuntu 10

Experiment 3
Create an SA called lizhesa10 under the namespace lizhe10

Assign the newly created SA lizhesa10 to Ubuntu 10

At this point, if you try to use the SA lizhe10 to access the API server, you will get 403

然后我们为 lizhesa10 赋权限

语法是这样的,之前我们用的是 group 

 $ clusterrolebinding NAME --clusterrole=NAME [--user=username] [--group=groupname] [--serviceaccount=namespace:serviceaccountname] [--dry-run] 

This time we use service account

kubectl create clusterrolebinding permissive-binding-lizhesa10 --clusterrole=cluster-admin --serviceaccount=lizhe10:lizhesa10 

After it takes effect, you can get the correct response

Here are some digressions
If you use the describe command and look at the SA, you can see that it carries a token

kubectl describe sa lizhesa10 -n lizhe10 

This token is actually the one you get in the pod

RBAC authorization plug-in takes user role as the key factor to determine whether users can perform operations.

The principal (person, SA or group) is associated with one or more roles, each of which is allowed to perform specific actions on a specific resource

If a user has multiple roles, they can do any action allowed by the role.

RBAC does this by creating four specific kubernetes resources

Role and clusterrole

They specify what actions can be performed on the resource

Rolebinding and clusterrolebinding

They bind these roles to specific users, groups, or SAS

We used it before

kubectl create clusterrolebinding permissive-binding --clusterrole=cluster-admin --group=system:serviceaccounts:lizhe 

It means to create a binding to clusterrole with the type of permission binding, which is clusterrole binding. The bound object is a group whose scope is Lizhe namespace

RoleBinding and ClusterRoleBinding

RoleBinding

Rolebinding can bind a subject (user) in the same namespace to a role with specific permissions, then the subject has the permissions defined by the role.

ClusterRoleBinding

Clusterrolebinding binds specific subjects to clusterrole at the whole cluster level and all namespaces, and grants permissions.

Role and ClusterRole

Role

The role object can only be used to grant access to resources in a namespace.

ClusterRole

The clusterrole object can grant access rights to resources in the whole cluster, and can also grant access rights to the following resources:

Cluster wide resources (such as nodes)

Non resource type endpoint (for example “/ healthz”)

Resources across the range of all namespaces (for example, pod, you need to run the command kubectl get pods — all namespaces to query all pods in the cluster)

Send a Message