任何访问k8s集群资源的操作(比如创建Pod、访问controller、service等),都需要首先经过3个步骤:认证、鉴权(授权)、准入控制。
一、认证
传输安全
集群对外不暴露8080端口,8080只能内部访问,对外使用的是6443端口。
客户端认证
https证书认证,基于CA证书
http token认证,通过token识别用户
http基本认证,用户名+密码认证
二、鉴权
基于RBAC模式:基于角色的访问控制,用户绑定角色,角色有的权限,用户就可以做相应的操作。除了k8s,在java中也是一种很常用的方式。
角色
Role:对特定的命令空间做访问控制。
ClusterRole: 对所有的命令空间做访问控制。
角色绑定
roleBinding: 角色绑定到主体
ClusterRoleBinding: 集群角色绑定到主体
主体
user: 用户
group: 用户组
serviceaccount: 服务账号
三、准入控制
准入控制器中有请求内容,则通过;否则就拒绝。
四、演示效果
- 新建一个命名空间:
[root@master-146 ~]# kubectl create ns roledemo
namespace/roledemo created
[root@master-146 ~]# kubectl get ns
NAME STATUS AGE
default Active 2d11h
kube-node-lease Active 2d11h
kube-public Active 2d11h
kube-system Active 2d11h
roledemo Active 3s
2. 在新的命令空间创建Pod:
[root@master-146 ~]# kubectl run nginx --image=nginx -n roledemo
pod/nginx created
[root@master-146 ~]# kubectl get pods -n roledemo
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 92s
3. 创建角色:
[root@master-146 ~]# cat rbac-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: roledemo
name: pod-reader
rules:
- apiGroups: [""] #"" indicates the core API group
resources: ["pods"] #该角色可访问的资源
verbs: ["get", "watch", "list"] #对这个资源拥有的权限
[root@master-146 ~]# kubectl apply -f rbac-role.yaml
role.rbac.authorization.k8s.io/pod-reader created
[root@master-146 ~]# kubectl get role -n roledemo
NAME CREATED AT
pod-reader 2021-07-25T03:55:24Z
4. 创建角色绑定
[root@master-146 ~]# cat rbac-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: roledemo
subjects:
- kind: User
name: lucy
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role #this must be Role or ClusterRole
name: pod-reader #match the Role's name or ClusterRole's name
apiGroup: rbac.authorization.k8s.io
[root@master-146 ~]# kubectl apply -f rbac-rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/read-pods created
[root@master-146 ~]# kubectl get rolebinding -n roledemo
NAME ROLE AGE
read-pods Role/pod-reader 30s
5. 使用证书识别身份
5.1准备工作
下载cfssl证书生成工具
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64赋予执行权限
chmod -x cfssl*重命名
for x in cfssl*; do mv $x ${x%*_linux-amd64}; done移动文件到目录 (/usr/bin)
mv cfssl* /usr/bin
5.2生成ca配置文件
vim ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
vim ca-csr.json
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing",
"O": "k8s",
"OU": "System"
}
]
}
5.3生成ca证书和私钥
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
[root@master-146 mary]# ls
ca-config.json ca.csr ca-csr.json ca-key.pem(ca私钥,妥善保管) ca.pem(ca公钥) mary-csr.json
[root@master-146 mary]# cat mary-csr.json
{
"CN": "mary",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing"
}
]
}
5.4为主体(用户mary)生成证书进行认证
[root@master-146 mary]# cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes mary-csr.json | cfssljson -bare mary
2021/07/25 12:40:10 [INFO] generate received request
2021/07/25 12:40:10 [INFO] received CSR
2021/07/25 12:40:10 [INFO] generating key: rsa-2048
2021/07/25 12:40:11 [INFO] encoded CSR
2021/07/25 12:40:11 [INFO] signed certificate with serial number 404368084889979684908438842196280861506265687406
2021/07/25 12:40:11 [WARNING] This certificate lacks a "hosts" field. This makes it unsuitable for
websites. For more information see the Baseline Requirements for the Issuance and Management
of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org);
specifically, section 10.2.3 ("Information Requirements").
[root@master-146 mary]# kubectl config set-cluster kubernetes \
> --certificate-authority=ca.pem \
> --embed-certs=true \
> --server=https://192.168.1.146:6443 \
> --kubeconfig=mary-kubeconfig
Cluster "kubernetes" set.
[root@master-146 mary]# kubectl config set-credentials mary \
> --client-key=mary-key.pem \
> --client-certificate=mary.pem \
> --embed-certs=true \
> --kubeconfig=mary-kubeconfig
User "mary" set.
[root@master-146 mary]# kubectl config set-context default \
> --cluster=kubernetes \
> --user=mary \
> --kubeconfig=mary-kubeconfig
Context "default" created.
[root@master-146 mary]# kubectl config use-context default --kubeconfig=mary-kubeconfig
Switched to context "default".
mary用户只对pod有访问权限
[root@master-146 mary]# kubectl get pod -n roledemo
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 58m
[root@master-146 mary]# kubectl get svc -n roledemo
No resources found in roledemo namespace.