[root@master01 ~]# ps aux | grep apiserver
...
--token-auth-file=/opt/kubernetes/cfg/token.csv
...
[root@master01 ~]# kubectl get sa
NAME SECRETS AGE
default 1 3d
[root@master01 ~]# netstat -ntap | grep 8080 | grep LISTEN
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 1815/kube-apiserver
[root@master01 ~]# netstat -ntap | grep 6443 | grep LISTEN
tcp 0 0 192.168.170.128:6443 0.0.0.0:* LISTEN 1815/kube-apiserver
服务帐户是由Kubernetes API管理的用户。它们被绑定到特定的名称空间,并由API服务器自动创建或通过API调用手动创建。服务帐户被关联到一组用作凭证的secret中,这些secret凭证被挂载到pod中,允许集群内进程与Kubernetes API通信
API请求要么绑定到普通用户,要么绑定到服务帐户,要么作为匿名请求处理。这意味着集群内外的每个进程,不论是PC客户端上使用kubectl的人工用户或者节点上的kubelets,再到控制平面的成员,向API服务器发出请求时都必须进行身份验证,或者被视为匿名用户
[root@master01 ~]# cat /root/k8s/k8s-sert/k8s-cert.sh
。。。
cat > server-csr.json <
[root@master01 ~]# cat /opt/kubernetes/cfg/token.csv
73af5869be7dea86e14a328bb99da139,kubelet-bootstrap,10001,"system:kubelet-bootstrap"
用户名(username):标识最终用户的字符串。常见的值可能是kube-admin或[email protected]。
UID:标识最终用户并试图比username更一致和惟一的字符串。
组(group):一组字符串,它将用户与一组通常分组的用户相关联。
额外字段(extra fileds):字符串映射到包含附加信息授权方可能会发现有用的字符串列表
所有值对身份验证系统都是不透明的,只有在由授权方( authorizer)使用时才具有意义
可以同时启用多个身份验证方法。通常应该使用至少两种方法:
当启用多个验证器模块时,第一个模块将成功地验证 “请求短路评估” (request short-circuits evaluation)。,如果验证失败,则进行断路操作,API服务器不保证运行验证器的执行顺序
所有通过验证的用户都会被添加进system:authenticated组
可以使用authenticating proxy 或authentication webhook与其他身份验证协议(LDAP、SAML、Kerberos、备用x509方案等)集成
ABAC 授权——基于属性的访问控制(ABAC)定义了一种访问控制范式,通过将属性组合在一起的策略将访问权限授予用户。策略可以使用任何类型的属性(用户属性、资源属性、对象、环境属性等)。有关使用ABAC模式的更多信息,请参见ABAC模式
RBAC 授权——基于角色的访问控制(RBAC)是一种基于企业中单个用户的角色来调节对计算机或网络资源的访问的方法。在此上下文中,访问是单个用户执行特定任务的能力,例如查看、创建或修改文件。要了解关于使用RBAC模式的更多信息,请参见RBAC模
当指定RBAC(基于角色的访问控制)时,使用RBAC.authority .k8s.io API组驱动授权决策,允许管理员通过Kubernetes API动态配置权限策略。
NODE 授权——一个特殊用途的授权器,根据调度到kubelet所在节点的pod向kubelet授予权限。有关使用节点授权模式的更多信息,请参见节点授权
WEBHOOK 授权——WebHook是当某个事件发生时触发一个HTTP POST的回调;实现webhook的web应用程序将向URL发送一条消息。有关使用Webhook模式的更多信息,请参见Webhook模式
允许所有访问
拒绝所有访问
--authorization-mode=ABAC
--authorization-mode=RBAC
--authorization-mode=Webhook
--authorization-mode=Node
--authorization-mode=AlwaysDeny
--authorization-mode=AlwaysAllow
user — 身份验证期间提供的用户字符串。
group — 已验证用户所属的组名称列表。
extra — 由身份验证层提供的任意字符串键到字符串值的映射。
API — 指示请求是否为API资源。
request path — 到其他非资源端点(如/api或/healthz)的路径。
API request verb(动词) — API verb(动词) , get、list、create、update、patch、watch、proxy、redirect、delete和deletecollection用于资源请求。要确定资源API端点的请求谓词,请参见 Determine the request verb.。
HTTP请求动词 — HTTP动词get、post、put和delete用于非资源请求。
resource — 正在访问的资源的ID或名称(仅用于资源请求)——对于使用get、update、patch和delete谓词的资源请求,您必须提供资源名称。
子资源 —— 正在访问的子资源(仅用于资源请求)。
Namespace —— 正在访问的对象的名称空间(仅用于名称空间大小的资源请求)。
API group —— 正在访问的API组(仅用于资源请求)。空字符串指定核心API组
补充一下关于K8S api的一些知识, K8S api 遵守openapi规范. 在K8S的API 设计中,最重要的几个概念就是 api version, api group, resource type , meta, 以及 spec
apiVersion — 您使用Kubernetes API的哪个版本来创建这个对象
kind — 创建什么样的对象
meta —— 帮助惟一标识对象的数据,包括名称字符串、UID和可选名称空间
准入控制(Admission Control)在授权后对请求做进一步的验证或添加默认参数,在对kubernetes api服务器的请求过程中,先经过认证、授权后,执行准入操作,在对目标对象进行操作。这个准入插件代码在apiserver中,而且必须被编译到二进制文件中才能被执行
在对集群进行请求时,每个准入控制插件都按顺序运行,只有全部插件都通过的请求才会进入系统,如果序列中的任何插件拒绝请求,则整个请求将被拒绝,并返回错误信息
在某些情况下,为了适用于应用系统的配置,准入逻辑可能会改变目标对象。此外,准入逻辑也会改变请求操作的一部分相关资源
Adminssion Control实际上是一个准入控制器插件列表,发送到API Server的请求都需要经过这个列表中的每个准入控制器 插件的检查,检查不通过,则拒绝请求
[root@master01 ~]# ps aux | grep apiserver
...
--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction
...
//AlwaysAdmit
结束所有的请求
//AlwaysPullImages
该插件修改每个新的Pod,强制pull最新镜像,这在多租户群集中非常有用,以便私有镜像只能由拥有授权凭据的用户使用
//AlwaysDeny
拒绝所有请求,一般用于测试
//DenyExecOnPrivileged(已弃用)
该插件将拦截所有请求。如果pod有一个privileged container,将只执行这个pod中的命令
如果自己的集群支持privileged container,自己又希望限制用户在这些privileged container上执行命令,那么强烈推荐使用它
此功能已合并到DenyEscalatingExec中
//DenyEscalatingExec
禁止privileged container的exec和attach操作。
//ImagePolicyWebhook
通过webhook决定image策略,需要同时配置--admission-control=ImagePolicyWebhook
//ServiceAccount
该插件将serviceAccounts 实现了自动化。如果打算使用Kubernetes ServiceAccount对象,那么强烈建议使用此插件
//SecurityContextDeny
该插件会将使用了 SecurityContext的pod中定义的选项全部失效
//ResourceQuota
该插件将会观察传入的所有请求,并确保它不会违反ResourceQuota对象中枚举的任何限制Namespace。如果在Kubernetes Deployment中使用了ResourceQuota对象,则必须使用此插件来约束Container
推荐在Admission Control参数列表中,这个插件排最后一个。
//LimitRanger
该插件将会观察传入的所有请求,并确保它不会违反LimitRanger对象中枚举的任何限制Namespace,如果在Kubernetes Deployment中使用了LimitRanger对象,则必须使用此插件。LimitRanger还可使用Apply将default资源请求不指定任何的Pods; 目前LimitRanger对Default Namespace中的所有pod应用要求0.1 CPU
//InitialResources(试验)
根据镜像的历史使用记录,为容器设置默认资源请求和limits。
//NamespaceLifecycle
该插件确保处于Termination状态的Namespace不再接收新的对象创建请求,并拒绝请求不存在的Namespace。该插件还可以防止删除系统保留的Namespace:default,kube-system,kube-public
//DefaultStorageClass
该插件将观察PersistentVolumeClaim,并自动设置默认的Storage Class
当没有配置默认Storage Class时,此插件不会执行任何操作。当有多个Storage Class被标记为默认值时,它也将拒绝任何创建,管理员必须重新访问StorageClass对象,并且只标记一个作为默认值。此插件不用于PersistentVolumeClaim的更新,仅用于创建
//DefaultTolerationSeconds
该插件设置Pod的默认forgiveness toleration为5分钟。
//PodSecurityPolicy
该插件用于创建和修改pod,使用Pod Security Policies时需要开启。
当 Kubernetes <1.6.0版本时,API服务器需要启用扩展名/ v1beta1 / podsecuritypolicy API扩展组(--runtime-config=extensions/v1beta1/podsecuritypolicy=true)
//NodeRestriction
此插件限制kubelet修改Node和Pod对象,这样的kubelets只允许修改绑定到Node的Pod API对象,以后版本可能会增加额外的限制。
限制kubelet仅可访问node、endpoint、pod、service以及secret、configmap、PV和PVC等相关的资源(仅适用于v1.7+)
--enable-admission-plugins= \ NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds, ResourceQuota
--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds
--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota
--admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota
--admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,PersistentVolumeLabel,ResourceQuota
//角色:
Role—— 一组权限的集合,只有许可形式的权限,没有拒绝形式的权限, 用户被授予角色即表示拥有角色对应的资源的访问权限。角色存在与namespace 内,跨 namespace的角色需要时用cluster role
Cluster Role—— 集群角色,和角色拥有同样的作用,但是其范围为整个集群。同时拥有集群范围的资源类型(如 NODE, /healthz 等)访问权限。
aggregated cluster role—— 聚合集群角色,可以让一个集群角色,拥有其他几个集群角色的权限 k8s version 1.9+
//角色绑定:
RoleBinding——将角色绑定到主体上,主体可以是user,group,service account
ClusterBinding—— 将集群角色绑定到主体上,主体可以是user,group,service account
//主体(subject):
User:用户
Group:用户组
ServiceAccount:服务账号(程序型用户,认为不可控)
官方网站:https://kubernetes.io/docs/reference/access-authn-authz/rbac/
[root@master01 demo]# kubectl create ns csdn
namespace/csdn created
[root@master01 demo]# kubectl get ns
NAME STATUS AGE
csdn Active 9s
//创建nginx的pod
[root@master01 demo]# kubectl run nginx --image=nginx -n csdn
kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead.
deployment.apps/nginx created
//扩容成三个副本
[root@master01 demo]# kubectl scale deploy/nginx --replicas=3 -n csdn
deployment.extensions/nginx scaled
[root@master01 demo]# kubectl get pods -n csdn
nginx-dbddb74b8-9wbnp 1/1 Running 0 30s
nginx-dbddb74b8-tnvnl 1/1 Running 0 72s
nginx-dbddb74b8-x4285 1/1 Running 0 30s
[root@master01 demo]# vim rbac-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: csdn
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"] //赋予pod资源查看的权限
verbs: ["get", "watch", "list"]
[root@master01 demo]# kubectl apply -f rbac-role.yaml
role.rbac.authorization.k8s.io/pod-reader created
[root@master01 demo]# kubectl get role -n csdn
NAME AGE
pod-reader 20s
[root@master01 demo]# vim rbac-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding //类型为RoleBinding
metadata:
name: read-pods //绑定的资源
namespace: csdn //指定命名空间
subjects:
- kind: User
name: zhangsan //指定绑定的用户
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader //指定绑定角色
apiGroup: rbac.authorization.k8s.io
[root@master01 demo]# kubectl apply -f rbac-rolebinding.yaml
rolebinding.rbac.authorization.k8s.io/read-pods created
[root@master01 demo]# kubectl get role,rolebinding -n csdn
NAME AGE
role.rbac.authorization.k8s.io/pod-reader 8m4s
NAME AGE
rolebinding.rbac.authorization.k8s.io/read-pods 22s
[root@master01 demo]# mkdir zhangsan
[root@master01 demo]# cd zhangsan/
[root@master01 zhangsan]# rz -E
rz waiting to receive.
[root@master01 zhangsan]# ls
rbac-user.sh rbac.yaml
[root@master01 zhangsan]# cat rbac.yaml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
apiVersion: v1
kind: ServiceAccount
metadata:
name: pod-reader
namespace: default
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: sa-read-pods
namespace: default
subjects:
- kind: ServiceAccount
name: pod-reader
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
[root@master01 zhangsan]# cat rbac-user.sh
cat > zhangsan-csr.json <
[root@master01 zhangsan]# cp /root/k8s/k8s-sert/ca* ./
[root@master01 zhangsan]# vim rbac-user.sh
kubectl config set-cluster kubernetes \
--certificate-authority=ca.pem \
--embed-certs=true \
--server=https://192.168.170.100:6443 \ //地址改为VIP
--kubeconfig=zhangsan-kubeconfig
//安装格式化工具
[root@master01 zhangsan]# yum install dos2unix -y
//格式化
[root@master01 zhangsan]# dos2unix rbac-user.sh
dos2unix: converting file rbac-user.sh to Unix format ...
[root@master01 zhangsan]# bash rbac-user.sh
2020/05/30 21:13:41 [INFO] generate received request
2020/05/30 21:13:41 [INFO] received CSR
2020/05/30 21:13:41 [INFO] generating key: rsa-2048
2020/05/30 21:13:41 [INFO] encoded CSR
2020/05/30 21:13:41 [INFO] signed certificate with serial number 501963456644305280486350133378326123692229677297
2020/05/30 21:13:41 [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 "zhangsan" set.
Context "default" created.
Switched to context "default".
//查看证书
[root@master01 zhangsan]# cat zhangsan-kubeconfig
[root@master01 zhangsan]# kubectl --kubeconfig=zhangsan-kubeconfig get pods -n csdn
NAME READY STATUS RESTARTS AGE
nginx-dbddb74b8-9wbnp 1/1 Running 0 17m
nginx-dbddb74b8-tnvnl 1/1 Running 0 17m
nginx-dbddb74b8-x4285 1/1 Running 0 17m
//使用zhangsan-kubeconfig访问 svc资源就会被拒绝
[root@master01 zhangsan]# kubectl --kubeconfig=zhangsan-kubeconfig get svc -n csdn
Error from server (Forbidden): services is forbidden: User "zhangsan" cannot list resource "services" in API group "" in the namespace "csdn"
//也无法访问默认的命令空间
[root@master01 zhangsan]# kubectl --kubeconfig=zhangsan-kubeconfig get pods
Error from server (Forbidden): pods is forbidden: User "zhangsan" cannot list resource "pods" in API group "" in the namespace "default"
[root@master01 zhangsan]# kubectl --kubeconfig=zhangsan-kubeconfig get svc
Error from server (Forbidden): services is forbidden: User "zhangsan" cannot list resource "services" in API group "" in the namespace "default"
[root@master01 zhangsan]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes-dashboard NodePort 10.0.0.228 443:30001/TCP 16d
//查看令牌
[root@master01 zhangsan]# kubectl get secret -n kube-system
NAME TYPE DATA AGE
dashboard-admin-token-452j2 kubernetes.io/service-account-token 3 7d5h
[root@master01 zhangsan]# kubectl describe secret dashboard-admin-token-452j2 -n kube-system
。。。
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tNDUyajIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiNGFiN2ZlZTEtOWNjYS0xMWVhLTlmYjQtMDAwYzI5MzBkNWNiIiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.JWmIUjO6o4mrnCpwYZUfWWZwGuC3kuW5GjRuvcgHAIOTAfevcd9IixaOeM963kRgF1wwzvvoFxFrLu-gfVxP7368UXlY2RxX5Ytpta2sYFonJ2XDjDv5RT8ux-NBtsNfteHdhkeCzLigm1SuSE-9FpZ7wO4kVOyLCC71OK3PBM6Y4icNAC_yu9zFtibOf9dSTxy9Ob1ktX1Fxi_db348t5OhR7ghs43lTAvFj93SABIcbMnXx40NP-ZEWsA2EkZPN6Otki-GKn4ed-d597JfpSGCkZGtQhAEuo8TxK7bWu9tH4SZJNQz2Fdsi3Y0ACcWDJCrqDPwS-8fohXHx50ifA
[root@master01 zhangsan]# vim sa.yaml //创建资源
apiVersion: v1
kind: ServiceAccount
metadata:
name: pod-reader
namespace: csdn
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: sa-read-pods
namespace: csdn
subjects:
- kind: ServiceAccount
name: pod-reader
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
[root@master01 zhangsan]# kubectl apply -f sa.yaml
serviceaccount/pod-reader created
rolebinding.rbac.authorization.k8s.io/sa-read-pods created
[root@master01 zhangsan]# kubectl get sa -n csdn
NAME SECRETS AGE
default 1 27m
pod-reader 1 10s
[root@master01 zhangsan]# kubectl describe secret pod-reader -n csdn
Name: pod-reader-token-ghxlq
Namespace: csdn
Labels:
Annotations: kubernetes.io/service-account.name: pod-reader
kubernetes.io/service-account.uid: 88f97066-a278-11ea-9fb4-000c2930d5cb
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1359 bytes
namespace: 4 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJjc2RuIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InBvZC1yZWFkZXItdG9rZW4tZ2h4bHEiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoicG9kLXJlYWRlciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6Ijg4Zjk3MDY2LWEyNzgtMTFlYS05ZmI0LTAwMGMyOTMwZDVjYiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpjc2RuOnBvZC1yZWFkZXIifQ.fZsqTtdSRi8LayrZXE1hzSUjEecOzys3qhPRzkxTPZU7ApR0L4OuGtuEdzMMnSKo33eTMPPBe268CRLsLwu7Y9skx8XnYtMajhHb7sUNlGsHCVDn20fGleyC0Zp8RJvSKwMDafApwlfHSYHBmzMF2moJYvq7RI-LbFqr5ocnpdL637FT0nPElJONfNswoBbPiwOivtPSczCIsMVCIEY7F7h7IPxryUtH2znRvqzZYtVbOHf2Ujta-TLl9O2MY91E29p-G4-zNQkzcSC0VJIxeyoOFE4rmYpuln13rd7HJfGw8q3G7JRxhFBQc2X7sCId3hjNeYCMDAnZpo9BcOo1Cw