标签:控制器 不同 客户 rest table visio this man 失败
大概分为三个部分,其一Kubernetes
安全框架,其二传输安全,认证。授权准入控制,其三使用RBAC
授权,这算是一系列流程,了解一下每个环节都做了哪些操作。
当你使用kubectl||API||UI
实际上就是操作apiserver
上的资源,之前创建过Deployment
,使用api
版本为apps/v1
,也就是这个,
apiVersion: apps/v1
kind: Deployment
在你创建的时候apiserver
会识别你请求的资源,也就是上面的那两个,如果无法识别直接报错,识别成功后会经历三个阶段,第一认证,第二授权,第三准入控制,当你发起一个请求需要过了这三步验证K8S
才会为你创建资源,如果这三步有任意一步出现问题,那你看到的就是一个失败的结果。
通常用户如果要安全访问集群Apiserver
往往需要证书、token
、或用户名加密码,token
之前配置过,手动生成的一个token
,而且指定了一个token
文件,也就是这里。
[root@k8s01 ~]# cat /opt/kubernetes/cfg/kube-apiserver.conf | grep token.csv
--token-auth-file=/opt/kubernetes/cfg/token.csv [root@k8s01 ~]#
这个token
文件有一个值是随机生成的,这里就是使用token
来认证的,指定了用户,把token
对应的用户绑定相对应的权限,那么拿着个token
值就有相对应的权限来访问apiserver
了。
[root@k8s01 ~]# kubectl get serviceaccounts
NAME SECRETS AGE
default 1 7h2m
nfs-client-provisioner 1 6h46m
[root@k8s01 ~]#
可以通过serveraccount
在pod
中去访问apiserver
,说白了就是不同类型的来访问apiserver
都会有不同的方式,apiserver
在各组件之间起到了协调的作用,和集群访问入口的功能,你想访问集群资源就必须得经过Apiserver
。
K8S
安全控制框架主要是由以下三个阶段进行控制,
Authentication
Authorrization
AdmissionControl
如图所示
每一个阶段都支持插件方式,需要通过API Server
配置来启用插件,之前都已经配置过了,现在看一下,例如准入控制
[root@k8s01 ~]# cat /opt/kubernetes/cfg/kube-apiserver.conf | grep -i Admission
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction
授权启用了RBAC
[root@k8s01 ~]# cat /opt/kubernetes/cfg/kube-apiserver.conf | grep -i Author
--authorization-mode=RBAC,Node
Authentication
也就是认证,在认证之前还有个传输,现在已经告别了8080
,使用了6443
,现在8080
已经不对外提供服务了,对外提供服务的是6443
,8080
主要是本地master
组件来连接使用。
认证方面提供了三种客户端认证方式。
K8S
时我们生成了N
多证书,通过证书内的CN
字段就可以识别出您是谁。apiserver
中配置的那个token
文件,那个是做kubelet-bootstrap
认证时候用到的,这个用的比较广泛这是传输和认证层面,第一阶段验证你的身份,你可以理解为这是门禁,你通过工卡进行身份验证,验证通过之后你就能进入到某片区域了。
Authorrization
第二阶段,授权,第一阶段你身份验证通过了,然后进入到了某片区域,但是这片区域有很多房间,具体你能进入到哪个房间就得看你工卡的授权了,你有权限就可以刷开某个门,没权限你就是刷不开,所以这就涉及到授权了,一般用的就是RBAC
,基于角色的访问控制,角色就是具体的访问权限的集合,他是负责完成授权工作的。
他去判断你是否有权限去访问某些资源,他会检查以下属性,如图。
在你请求的时候我绝对会携带我要访问哪个资源,下面他就开始检查你有没有权限去访问那个资源,如果没授权的话在这个阶段直接给你拒绝了,你看到的是没有权限访问,所以这就是授权这个阶段。
AdmissionControl
准入控制,前两步认证都过了就该这个了,他实际上是一个准入控制器插件列表,发送到API Server
的请求都需要经过这个列表中的每个准入控制器检查,检查不通过,则拒绝请求,啥意思呢,大概是这样,我现在想通过apiserver
限制pod
资源,但是想限制pod
资源需要用到apiserver
的LimitRanger
插件,如果这个插件没启用直接拒绝请求,提示我不支持这个撒,现在这个插件启着呢,所以不会有这个问题,他的工作逻辑就是这样,下面主要看一下RBAC
授权。
也就是上文第二阶段的授权,它允许我们通过API Server
来动态修改配置,实时生效,在开始之前先来了解一下RBAC
的组成。
(Role,ClusterRole)
K8S
逻辑隔离是使用namespaces
实现的,它的授权是在命名空间层面的,你能不能访问某个命名空间Role
,创建Role
使用这个去绑定,绑定后才会有相对应的权限ClusterRole
,创建ClusterRole
使用这个去绑定,绑定后才会有相对应的权限现在授权一个用户对某个命名空间有读取的权限,说白了就是只读,让你看看就行了,现在随便创建一个命名空间,然后在这个命名空间里启动几个pod
[root@k8s01 ~]# kubectl create namespace opesn
namespace/opesn created
[root@k8s01 ~]# kubectl get namespaces opesn
NAME STATUS AGE
opesn Active 8s
[root@k8s01 ~]# kubectl run nginx --image=nginx --replicas=3 --namespace=opesn
[root@k8s01 ~]# kubectl get pods -n opesn
NAME READY STATUS RESTARTS AGE
nginx-6db489d4b7-9xg6b 1/1 Running 0 26s
nginx-6db489d4b7-bfgwf 1/1 Running 0 26s
nginx-6db489d4b7-s6hrn 1/1 Running 0 26s
[root@k8s01 ~]#
现在新建一个用户opesn
,他的权限为只读opesn
命名空间,其他的全部拒绝,首先要创建一个Role
角色,需要定义规则了,基于官方文档
[root@k8s01 ~]# cat rbac-role.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: opesn
name: opesn
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
权限为get,watch,list
,只读的,创建看一下
[root@k8s01 ~]# kubectl apply -f rbac-role.yaml
role.rbac.authorization.k8s.io/opesn created
[root@k8s01 ~]# kubectl get role -n opesn
NAME AGE
opesn 12s
[root@k8s01 ~]#
现在有一个角色了,现在把他绑定到这个角色里。
[root@k8s01 ~]# cat rbac-rolebinding.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: opesn
subjects:
- kind: User
name: opesn # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role #this must be Role or ClusterRole
name: opesn # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
[root@k8s01 ~]#
主要两块,命名空间,subjects
的kind
指定为User
,不是程序,用户名是opesn
,在下面就是角色绑定了,指定了类型和名称,也就是上面创建的那个,这就可以了,创建吧。
[root@k8s01 ~]# kubectl create -f rbac-rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/read-pods created
[root@k8s01 ~]# kubectl get role,rolebinding -n opesn
NAME AGE
role.rbac.authorization.k8s.io/opesn 4m40s
NAME AGE
rolebinding.rbac.authorization.k8s.io/read-pods 10s
[root@k8s01 ~]#
现在是创建完了,现在还差识别身份,现在使用基于证书的来识别身份,直接上脚本吧。
[root@k8s01 kubernetes]# cat rabc-user.sh
cat > opesn-csr.json <<EOF
{
"CN": "opesn",
"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 opesn-csr.json | cfssljson -bare opesn
kubectl config set-cluster kubernetes --certificate-authority=ca.pem --embed-certs=true --server=https://192.168.10.4:6443 --kubeconfig=opesn-kubeconfig
kubectl config set-credentials opesn --client-key=opesn-key.pem --client-certificate=opesn.pem --embed-certs=true --kubeconfig=opesn-kubeconfig
kubectl config set-context default --cluster=kubernetes --user=opesn --kubeconfig=opesn-kubeconfig
kubectl config use-context default --kubeconfig=opesn-kubeconfig
opesn
就是我之前定义的用户名,apiserver
我写的是负载均衡地址,会用到apiserver
的根证书,所以要复制过来,下面执行一下吧。
[root@k8s01 kubernetes]# bash rabc-user.sh
2020/06/07 23:14:29 [INFO] generate received request
2020/06/07 23:14:29 [INFO] received CSR
2020/06/07 23:14:29 [INFO] generating key: rsa-2048
2020/06/07 23:14:29 [INFO] encoded CSR
2020/06/07 23:14:29 [INFO] signed certificate with serial number 147728077879656546154832435011075986225633644035
2020/06/07 23:14:29 [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 "opesn" set.
Context "default" created.
Switched to context "default".
[root@k8s01 kubernetes]#
[root@k8s01 kubernetes]# kubectl --kubeconfig=opesn-kubeconfig get pod -n default
Error from server (Forbidden): pods is forbidden: User "opesn" cannot list resource "pods" in API group "" in the namespace "default"
[root@k8s01 kubernetes]# kubectl --kubeconfig=opesn-kubeconfig get pod -n opesn
NAME READY STATUS RESTARTS AGE
nginx-6db489d4b7-9xg6b 1/1 Running 0 16m
nginx-6db489d4b7-bfgwf 1/1 Running 0 16m
nginx-6db489d4b7-s6hrn 1/1 Running 0 16m
[root@k8s01 kubernetes]# kubectl --kubeconfig=opesn-kubeconfig get service
Error from server (Forbidden): services is forbidden: User "opesn" cannot list resource "services" in API group "" in the namespace "default"
[root@k8s01 kubernetes]#
只能看到opesn
命名空间下的pod
,什么service
之类的都不行,因为没有授权,
ServiceAccount
访问命名空间WEBUI
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta8/aio/deploy/recommended.yaml
vi recommended.yaml
…
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
type: NodePort
ports:
- port: 443
targetPort: 8443
nodePort: 30001
selector:
k8s-app: kubernetes-dashboard
…
# kubectl apply -f recommended.yaml
#创建service account并绑定默认cluster-admin管理员集群角色:
cat dashboard-adminuser.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
#启动
apply -f dashboard-adminuser.yaml
#获取token
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk ‘{print $1}‘)
访问地址:http://NodeIP:30001
使用输出的token登录Dashboard。
现在创建一个ServiceAccount
,只允许访问opesn
命名空间,权限和上面的一样,首先要创建一个ServiceAccount
,然后把这个ServiceAccount
绑定到上面创建的角色里。
[root@k8s01 ~]# cat sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: pod-reader
namespace: opesn
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: sa-read-pods
namespace: opesn
subjects:
- kind: ServiceAccount
name: pod-reader
roleRef:
kind: Role
name: opesn
apiGroup: rbac.authorization.k8s.io
[root@k8s01 ~]#
就是这样,然后创建
[root@k8s01 ~]# kubectl create -f sa.yaml
serviceaccount/pod-reader created
rolebinding.rbac.authorization.k8s.io/sa-read-pods created
[root@k8s01 ~]# kubectl get secrets -n opesn pod-reader-token-fv9qg
NAME TYPE DATA AGE
pod-reader-token-fv9qg kubernetes.io/service-account-token 3 38s
[root@k8s01 ~]# kubectl describe secrets -n opesn pod-reader-token-fv9qg
Name: pod-reader-token-fv9qg
Namespace: opesn
Labels: <none>
Annotations: kubernetes.io/service-account.name: pod-reader
kubernetes.io/service-account.uid: 009f347c-be63-40cf-97c2-b4631f5e5b4c
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1359 bytes
namespace: 5 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IlNqcHV5S0V5dnZEWDJtck9TSGdZYkppb0V5SFdyOXpVUnd5b3NHX1Zmd00ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJvcGVzbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJwb2QtcmVhZGVyLXRva2VuLWZ2OXFnIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6InBvZC1yZWFkZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiIwMDlmMzQ3Yy1iZTYzLTQwY2YtOTdjMi1iNDYzMWY1ZTViNGMiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6b3Blc246cG9kLXJlYWRlciJ9.j8ZryrAGx4c2VAiW2ZR_McJCDSUDYKXpDf5hwkLxOzYAt5_gIzvJCWE3htCd3IGiALanK88iDCid3nwRzyNPXSEcMtTGeLtAdIJ9ZwtFfxZVTNuHhW0p4C1Gw-9PWTNvbZiLQv4IUKzJRlSvfn121lo7OSG5WdovmCkmGug_c8es4FJvOHPVtQBXvOTWihlvwZMO6NRLQ9mTtBaqbpXseBUUjfENk7tuRs-LsS31bqlmCH2DkcPGlLArpMBp0bnjtAH0OAfYJbfErTfeXyNjHDVSx1tOJV7yly4nvKwe5_PFYlKBKZ-FDMT6T0qTmitDvYjB6cml9AdzgukJjHJ9AQ
下面去用这个token
登陆一下UI
命名空间需要你手动输入了,然后会发现各种权限不足,就是这种效果,只读opesn
命名空间,其他的全部权限不足,这就是RBAC
授权
标签:控制器 不同 客户 rest table visio this man 失败
原文地址:https://www.cnblogs.com/opesn/p/13211976.html