一、K8S账户管理
- 账户管理分为:
userAccount与serviceAccount 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推荐的,所以这里不作介绍了。
...