一、K8S账户管理

  • 账户管理分为: userAccountserviceAccount
  • userAccount: 通常是给人设计使用的,并且不在k8s集群内管理,所以无法使用kubectl进行创建。
  • serviceAccount: 通常是为集群内pod,外部service访问而设计的,更轻量级,更专注与实现某个任务。属于K8S集群管理,所以可以使用kubectl命令创建。
  • k8s账户管理: 主要提供身份验证的功能,必须是k8s授权的账户才能被允许进入集群。但是进入集群不代表有访问资源的权限,访问资源的权限是通过RBAC授权来实现。
  • K8S账户认证: 主要有证书+私钥、token和账户密码等方式进行认证。

二、userAccount

1、userAccount的创建

以创建名为 myuser 的 userAccount 为例。
首先,创建该账户的私钥:

# openssl genrsa -out myuser.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
.............................+++++
..........................................+++++
e is 65537 (0x010001)
# ls -lrt myuser.key 
-rw------- 1 root root 1679 Nov 28 09:07 myuser.key

然后,基于私钥签署证书,必须由k8s的ca来签署(该ca是创建k8s集群的时候生成的)。

  • 使用kubeadm安装的k8s集群的ca一般保存在/etc/kubernetes/pki
  • 使用kubeaz安装的二进制k8s集群的ca一般保存在/etc/kubernetes/ssl
# openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser"
# ls -lrt myuser.*
-rw------- 1 root root 1679 Nov 28 09:07 myuser.key
-rw-r--r-- 1 root root  887 Nov 28 09:15 myuser.cs
# openssl x509 -req -in myuser.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out myuser.crt
Signature ok
subject=CN = myuser
Getting CA Private Key
# ls -lrt myuser*
-rw------- 1 root root 1679 Nov 28 09:07 myuser.key
-rw-r--r-- 1 root root  887 Nov 28 09:15 myuser.csr
-rw-r--r-- 1 root root  989 Nov 28 09:18 myuser.crt

签署完成后,k8s怎样识别你的账户名呢:

# openssl x509 -in myuser.crt -text
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            7c:b2:d0:63:73:6b:08:a7:63:71:27:f7:60:ee:2f:71:24:60:22:d6
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = kubernetes
        Validity
            Not Before: Nov 28 01:18:18 2023 GMT
            Not After : Dec 28 01:18:18 2023 GMT
        Subject: CN = myuser
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                ...

k8s主要是通过 Subject: CN = myuser 来识别账户名。
至此,myuser 这个 userAccount 就已经创建完成了。

2、userAccount 在kube-config中的配置

上面只是创建好了账户,接下来还需要再kube-config中配置好才能方便使用该账户连接集群进行相关操作。
a、设置该账户需要连接的集群(如果是连接已有集群,则此步骤省略)

# kubectl config get-clusters  ##获取当前已配置的集群列表
NAME
kubernetes
# kubectl config set-cluster myuser-k8s --server https://10.1.163.190:6443
Cluster "myuser-k8s" set.
# kubectl config get-clusters 
NAME
kubernetes
myuser-k8s

b、为新集群项嵌入证书颁发机构数据(如果是连接已有集群,则此步骤省略)

# kubectl config set-cluster myuser-k8s --certificate-authority=/etc/kubernetes/pki/ca.crt
Cluster "myuser-k8s" set.

c、配置上下文(可指定默认的namespace)

# kubectl config get-contexts  ##获取当前的上下文列表
# kubectl config set-context context@myuser-k8s --cluster=myuser-k8s --user=myuser --namespace=test
Context "context@myuser-k8s" created.
# kubectl config get-contexts 
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
          context@myuser-k8s            myuser-k8s   myuser             test
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   
## 上面这个是上下文就是使用了myuser这个账户连接 myuser-k8s这个集群,并且默认使用的namespace是test。\

d、设置myuser的认证密钥信息

# kubectl config set-credentials myuser --client-certificate=myuser.crt --client-key=myuser.key
User "myuser" set.

e、验证是否能连接集群(需要先切换到新创建的上下文)

# kubectl config use-context context@myuser-k8s
Switched to context "context@myuser-k8s".
# kubectl get pod
Error from server (Forbidden): pods is forbidden: User "myuser" cannot list resource "pods" in API group "" in the namespace "test"
root@t-kubeadm-001:~# 

提示没有权限查看pod,说明已经能连接集群,但是没权限查看资源。还需要配置RBAC来实现资源的授权,请看后面介绍。

三、serviceAccount

1、serviceAccount 的创建

serviceAccount简称为sa,后面提到的sa都是指serviceAccount。这里以创建名为 mysauser 的sa 为例子。

  • 当一个pod被创建的时候,pod也需要去k8s-api注册自己的信息,这时候使用的身份验证就是sa。
  • 相对于userAccount创建证书与私钥的方式,sa突出轻的特点,使用token认证。
  • sa是与namespace关联的,属于namespace下面的一种资源类型。k8s默认创建了很多sa账户:
# kubectl get sa -A|grep kube
kube-node-lease        default                              1         7d19h
kube-public            default                              1         7d19h
kube-system            attachdetach-controller              1         7d19h
kube-system            bootstrap-signer                     1         7d19h
kube-system            certificate-controller               1         7d19h
kube-system            clusterrole-aggregation-controller   1         7d19h
kube-system            coredns                              1         7d19h
......

所以在创建sa之前,我们应该先确认清楚我们需要在哪个namespace下面使用这个sa账户。
这里我们新建一个ns,并将sa创建到该ns下。

# kubectl create ns mysa-ns
namespace/mysa-ns created
# kubectl create serviceaccount mysauser -n mysa-ns 
serviceaccount/mysauser created

sa创建会自动创建一个对应的secret,里面保存着这个sa的token等信息:

# kubectl get sa mysauser -n mysa-ns  -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: "2023-11-28T02:01:17Z"
  name: mysauser
  namespace: mysa-ns
  resourceVersion: "943078"
  uid: e3871f7c-c745-4e85-bd40-2172f10a0034
secrets:
- name: mysauser-token-fslch

# kubectl -n mysa-ns get secrets mysauser-token-fslch -o yaml
apiVersion: v1
data:
  ca.crt: xxxxx
  namespace: bXlzYS1ucw==
  token: xxxxxx
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: mysauser
    kubernetes.io/service-account.uid: e3871f7c-c745-4e85-bd40-2172f10a0034
  creationTimestamp: "2023-11-28T02:01:17Z"
  name: mysauser-token-fslch
  namespace: mysa-ns
  resourceVersion: "943077"
  uid: 7f8e3e51-f6f4-40ea-8510-d6ae50892ccc
type: kubernetes.io/service-account-token

ca、namespace、token信息都是经过base64加密的。如果要使用,需要进行解密。

2、使用sa配置kube-config

a、创建集群(若使用已有集群可省略)

# kubectl config set-cluster mysa-k8s --embed-certs=true --server=https://10.1.163.190:6443 --certificate-authority=/etc/kubernetes/pki/ca.crt
Cluster "mysa-k8s" set.
# kubectl config get-clusters 
NAME
mysa-k8s
myuser-k8s
kubernetes

b、创建上下文

#kubectl config set-context context@mysa-k8s --cluster=mysa-k8s --user=mysauser --namespace=mysa-ns
Context "context@mysa-k8s" created.
# kubectl config get-contexts 
CURRENT   NAME                          CLUSTER      AUTHINFO           NAMESPACE
          context@mysa-k8s              mysa-k8s     mysauser           
          context@myuser-k8s            myuser-k8s   myuser             test
*         kubernetes-admin@kubernetes   kubernetes   kubernetes-admin   

c、配置账号认证信息(使用token)

#kubectl config set-credentials mysauser --token=eyJhbGciOixxxxxxxx
User "mysauser" set.

d、验证

# kubectl config use-context  context@mysa-k8s 
Switched to context "context@mysa-k8s".
root@t-kubeadm-001:~# kubectl get pod
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:mysa-ns:mysauser" cannot list resource "pods" in API group "" in the namespace "mysa-ns"

四、RDBC授权

上面创建的userAccount和serviceAccount都是能连接集群但是没有权限访问资源,这是因为它们都还没进行RDBC授权。
这里只简单介绍两种账号怎样进行RDBC授权,更多的关于RDBC授权的知识请参考其它文章。

1、确认要授权的权限

假设我们要给上面创建的两个测试用户对其默认的namespace下的所有pod、secret资源的创建、查看、编辑权限。需要创建两个角色,并给予对应权限。

2、创建角色

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 namespace: test
 name: test-myuser-role
rules:
- apiGroups: [""]
  resources: ["pods", "secrets"]    
  verbs: ["create","get", "list","update","watch","patch"]

另外一个基本一致,只是改下名字及对应的namespace:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 namespace: mysa-ns
 name: mysa-ns-mysauser-role
rules:
- apiGroups: [""]
  resources: ["pods", "secrets"]    
  verbs: ["create","get", "list","update","watch","patch"]

在k8s集群中创建:

# kubectl apply -f test-myuser-role.yaml 
role.rbac.authorization.k8s.io/test-myuser-role created
# kubectl apply -f mysa-ns-mysauser-role.yaml 
role.rbac.authorization.k8s.io/mysa-ns-mysauser-role created  

3、将角色和用户绑定

# kubectl create rolebinding test-myuser-role-binding --user=myuser --role=test-myuser-role -n test
rolebinding.rbac.authorization.k8s.io/test-myuser-role-binding created
# kubectl create rolebinding mysa-ns-mysauser-role-binding --serviceaccount=mysa-ns:mysauser --role=mysa-ns-mysauser-role -n mysa-ns
rolebinding.rbac.authorization.k8s.io/mysa-ns-mysauser-role-binding created

4、验证权限

# kubectl config use-context  context@myuser-k8s  
Switched to context "context@myuser-k8s".
# kubectl get pod
NAME                        READY   STATUS    RESTARTS   AGE
nginx-01-796b79c97-xc94c    1/1     Running   0          24h
nginx-02-76bc95f995-kggd7   1/1     Running   0          24h
# kubectl config use-context context@mysa-k8s
Switched to context "context@mysa-k8s".
# kubectl get secret
NAME                   TYPE                                  DATA   AGE
default-token-vbxsd    kubernetes.io/service-account-token   3      4h30m
mysauser-token-fslch   kubernetes.io/service-account-token   3      4h29m

五、总结

一定要弄清楚userAccount和serviceAccount的区别,这样才好理解针对两种用户类型有不同的创建方式,不同的管理方式。在RDBC授权时针对不同类型账户使用的参数名字也有不同。
userAccount也可以使用密码验证,但是不安全,也不是k8s推荐的,所以这里不作介绍了。