1、集群安全机制概述
1.1 访问k8s的三个步骤
-
1、认证
-
2、鉴权(授权)
-
3、准入控制
-
进行访问的时候,过程中都需要经过apiserver,apiserver做统一协调,比如门卫。且访问过程中需要证书、token、或者用户名+密码。如果需要访问pod,需要serviceAccount。
1.2 认证
- 传输安全:对外不会暴露8080端口,只能内部访问。对外使用端口6443
- 认证:客户端身份认证的常用方式有三种: 1>https证书认证,基于ca证书。2> http+token认证,通过token识别用户。3>http基本认证,用户名+密码(不常用,前两种更安全)
1.3 鉴权
- 基于RBAC进行鉴权操作
- 基于角色进行访问控制
1.4 准入控制
- 就是准入控制器的列表,如果该列表有请求内容,通过。没有则拒绝。
2、RBAC(基于角色的访问控制)
2.1 角色
- Role,特定命名空间具体操作。 ClusterRole,所有命名空间访问权限
[root@master ~]# kubectl get ns # 查看命名空间
[root@master ~]# kubectl create ns role
namespace/role created
[root@master ~]# kubectl get ns
NAME STATUS AGE
default Active 63d
kube-node-lease Active 63d
kube-public Active 63d
kube-system Active 63d
role Active 3s
[root@master ~]# kubectl delete ns role
namespace "role" deleted
2.2 角色绑定
- roleBinding: 将角色绑定到主体上
- ClusterroleBinding: 将集群角色绑定到主体
2.3 主体
- user : 用户
- group: 用户组
- serviceAcoount: 服务账号。用于pod访问
3、RBAC实现鉴权
3.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_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
# 生成自签证书
[root@master mary]# cat ca-config.json
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"kubernetes": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
[root@master mary]# cat ca-csr.json
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing",
"O": "k8s",
"OU": "System"
}
]
}
[root@master mary]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca - #生成自签证书
2022/05/13 13:47:19 [INFO] generating a new CA key and certificate from CSR
2022/05/13 13:47:19 [INFO] generate received request
2022/05/13 13:47:19 [INFO] received CSR
2022/05/13 13:47:19 [INFO] generating key: rsa-2048
2022/05/13 13:47:19 [INFO] encoded CSR
2022/05/13 13:47:19 [INFO] signed certificate with serial number 533587145625742162082018478504710590695605538243
[root@master mary]# ls
ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem mary-csr.json rabc-user.sh
3.2 创建命名空间和对应得pod
[root@master ~]# kubectl create ns roledemo
namespace/roledemo created
[root@master ~]# kubectl get ns
NAME STATUS AGE
roledemo Active 3s
[root@master ~]# kubectl run nginx --image=nginx -n roledemo
pod/nginx created
[root@master ~]# kubectl get pod -n roledemo
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 36s
3.3 创建角色
[root@master Roledemo]# vim rbac-role.yaml
[root@master Roledemo]# cat rbac-role.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: roledemo
name: pod-reader
rules:
- apiGroups: [""] #组
resources: ["pods"] #资源
verbs: ["get","watch","list"] #角色权限
[root@master Roledemo]# kubectl apply -f rbac-role.yaml
role.rbac.authorization.k8s.io/pod-reader created
[root@master Roledemo]# kubectl get role -n roledemo
NAME CREATED AT
pod-reader 2022-05-13T04:13:46Z
3.4 创建角色绑定
[root@master Roledemo]# vim rbac-rolebinding.yaml
[root@master Roledemo]# cat rbac-rolebinding.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: roledemo
subjects:
- kind: User
name: mary # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role #this must be Role or ClusterRole
name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
[root@master Roledemo]# kubectl apply -f rbac-rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/read-pods created
[root@master Roledemo]# kubectl get role,rolebinding -n roledemo #查看角色和角色绑定
NAME CREATED AT
role.rbac.authorization.k8s.io/pod-reader 2022-05-13T04:13:46Z
NAME ROLE AGE
rolebinding.rbac.authorization.k8s.io/read-pods Role/pod-reader 25s
3.5 使用证书识别身份
[root@master ~]# mkdir mary #充当用户文件夹
[root@master ~]# cd mary/ #目录下需要所有的ca文件
[root@master mary]# cat mary-csr.json
{
"CN": "mary",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing"
}
]
}
[root@master mary]# vim rabc-user.sh ##rbac鉴权文件
[root@master mary]# cat rabc-user.sh
cat > mary-csr.json <<EOF
{
"CN": "mary",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing"
}
]
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes mary-csr.json | cfssljson -bare mary
kubectl config set-cluster kubernetes \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=https://192.168.172.128:6443 \
--kubeconfig=mary-kubeconfig
kubectl config set-credentials mary \
--client-key=mary-key.pem \
--client-certificate=mary.pem \
--embed-certs=true \
--kubeconfig=mary-kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user=mary \
--kubeconfig=mary-kubeconfig
kubectl config use-context default --kubeconfig=mary-kubeconfig
## 执行
[root@master mary]# bash rabc-user.sh
2022/05/13 13:53:26 [INFO] generate received request
2022/05/13 13:53:26 [INFO] received CSR
2022/05/13 13:53:26 [INFO] generating key: rsa-2048
2022/05/13 13:53:26 [INFO] encoded CSR
2022/05/13 13:53:26 [INFO] signed certificate with serial number 697056282839922252602077574108282807182420364565
2022/05/13 13:53:26 [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").
Cluster "kubernetes" set.
User "mary" set.
Context "default" created.
Switched to context "default".
[root@master mary]# ls ##生成了mary-kubeconfig文件
ca-config.json ca-csr.json ca.pem mary-csr.json mary-kubeconfig rabc-user.sh
ca.csr ca-key.pem mary.csr mary-key.pem mary.pem
[root@master mary]# cat mary-kubeconfig ##里面是证书内容
3.6测试
#只有查看pod得权限,所以查看svc是没有任何东西的(不对) #应该是这里只是使用了文件夹模拟,所以出错。需要真实得用户
[root@master mary]# kubectl get pod -n roledemo
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 140m
[root@master mary]# kubectl create service clusterip test --clusterip="None" -n roledemo# 创建svc测试
[root@master mary]# kubectl get svc -n roledemo # 但是不对
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
test ClusterIP None <none> <none> 25m