K8安全控制框架主要由下面3个阶段进行控制,每一个阶段都支持插件方式,通过API Server配置来启用插件
1.Authentication(鉴权)
2.Authorization(授权)
3..Admission Control(准入控制)
客户端要想要访问K8s集群API Server,一般需要证书、Token或者用户名+密码,如果Pod访问,需要ServiceAccount
门卫--鉴权 门禁卡--授权 准入控制--安全扫描设备
K8s Apiserver提供三种客户端身份认证
1.HTTPS证书认证:基于CA证书签名的数字证书认证(kubeconfig)
2.HTTP Token认证:通过一个Token来识别用户(serviceaccount)
3.HTTP Base认证:用户名+密码的方式认证(1.19版本弃用)
RBAC(Role-Based AccessControl,基于角色的访问控制):负责完成授权(Authorization)工作
RBAC
根据API请求属性,决定允许还是拒绝。
比较常见的授权维度:
user:用户名
group:用户分组
资源,例如pod、deployment
资源操作方法:get,list,create,update,patch,watch,delete
命名空间
API组
1)方便用户扩展apiserver工具(对所有请求处理的功能)
AdminssionControl实际上是一个准入控制器插件列表,发送到API Server的请求都需要经过这个列表中的每个准入控制器插件的检查,检查不通过,则拒绝请求。
启用一个准入控制器(改配置):
kube-apiserver--enable-admission-plugins=NamespaceLifecycle,LimitRanger ...
关闭一个准入控制器:
kube-apiserver --disable-admission-plugins=PodNodeSelector,AlwaysDeny...
查看默认启用(默认大部分启用,已经够用):
【】kubectl exec kube-apiserver-k8s-master1-n kube-system -- kube-apiserver -h | grep enable-admission-plugins
RBAC(Role-Based Access Cobtrol,基于角色的访问控制),是K8s默认授权策略,并且是动态配置策略(修改即时生效)
user:用户
group:用户组,是通过kubectl去访问
serviceaccount:服务账号,程序是直接访问apiserver
绑定多个角色,取交集
k8s预定好了四个集群角色供用户使用,使用kubectl get clusterrole查看
其中systemd:开头的为系统内部使用
内置集群角色 |
描述 |
cluster-admin |
超级管理员,对集群所有权限 |
admin |
主要用于授权命名空间所有读写权限 |
edit |
允许对命名空间大多数对象读写操作,不允许查看或者修改角色、角色绑定 |
view |
允许对命名空间大多数对象只读权限,不允许查看角色、角色绑定和Secret |
role:授权特点命名空间的访问权限
ClusterRole:授权所有命名空间的访问权限
RoleBinding:将角色绑定到主体(即subject)
ClusterRoleBinding:将集群角色绑定到主体
注:RoleBinding在指定命名空间中执行授权,ClusterRoleBinding在集群范围内执行授权
用户、用户组都是提取证书中的一个字段。不是在集群中创建的!!都是在客户端上的。
需求:为指定用户授权访问不同命名空间权限,例如新入职一个小弟,希望让他先熟悉K8s集群,为了安全性,先不能给他太大权限,因此先给他授权访问default命名空间pod读取权限。实施大致步骤
1.用K8s用K8s CA签发客户端证书
2.生成kubeconfig授权文件
3.创建RBAC权限策略
4.指定kubeconfig文件测试权限: kubectl get pods --kubeconfig=./zhang.kubeconfig
用K8sCA签发客户端证书
cat > ca-config.json < zhang-csr.json <
字段说明:
ca-config.json:可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个 profile;
signing:表示该证书可以签名其他证书;生成的ca.pem证书中 CA=TRUE;
server auth:表示client可以用该 CA 对server提供的证书进行验证;
client auth:表示server可以用该CA对client提供的证书进行验证;
“CN”:Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法;
“O”:Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的组 (Group)
2.生成kubeconfig授权文件
authority=/etc/kubernetes/pki/ca.crt \
--embed-certs=true \
--server=https://11.0.1.100:16443 \
--kubeconfig=zhang.kubeconfig
# 设置客户端认证
kubectl config set-credentials zhang \
--client-key=zhang-key.pem \
--client-certificate=zhang.pem \
--embed-certs=true \
--kubeconfig=zhang.kubeconfig
# 设置默认上下文
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=zhang \
--kubeconfig=zhang.kubeconfig
# 设置当前使用配置
kubectl config use-context kubernetes --kubeconfig=zhang.kubeconfig
#下面为生成的kubeconfig文件,看看就行,别执行
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUM1ekNDQWMrZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeU1USXhOREUwTVRZeU1Gb1hEVE15TVRJeE1URTBNVFl5TUZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTURxCkU1bW1OZVRXVFRRREZCQ3J4NTc5bis2dUVpcDR5TWxNd1BOa2RNM3VnOWVaaGFwNmJ5dmE2VzhtUUI1UkFCWk8KcFBoRUtzR2F3WDZiTlpmS0VWa2VxZ09RRmc2OE5Fc2xZc3hSazJqMlRhNkExUk4wNGpYdUUxeG1CK1JsVjB5dQpjRVRmVlYvaUJBZ1I5Mkg5OTFiQXQwVGVFVmFBWGI3c0NyaDFucVNBWDk4S3RENzQ1b0FybzdOQm1EOFMyTWlBCnlWY0didFdCRnNOUzBObSthSEViVGtaOFd2RmRwMW9aRlIvK2diZWtELzhHOGZBQnMwRnE3UUFMaUFnbFRwNDAKVTBCRnZnOVlnRmFTRm5hVCtZeWlFVEYxYWEzb25ZYVV5eGx4SkhRUkJYRlZjdFhUWkdrVzZvenVDYjhGc3JmNgpoSU8yZ1ZIRDdiNVVObEc0MXQ4Q0F3RUFBYU5DTUVBd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZOWlhqU2FGOTBEdUNRcWZXdjhwcXNTZGNWbW9NQTBHQ1NxR1NJYjMKRFFFQkN3VUFBNElCQVFBQ1lyejhBSU9OamlDUGpEZjcrVVd2aWUvVjZ3d3UvdjRzQjhxa1JpNlF0ckd4N25PVwpDMjZnK21yQ3p2eVdEM1FKZWhYaEwzQzhYRzN6L29sOGp1SDVxa1ppNDRCTHhYaGdaTTU1ZThDRDhBUHZJTFRwCjg2ZllLOVpneE81MGU0MkNyMmdlMTNsUDI2WCt2enRtWEJ1RDB1RGlOVVNXZVJSUFVoMERGbStkVEp1dEg3ZDUKWk1TdWFxeXN1dnFBaEdVeDhXeFRRNkpTeFhNZjNYWW9HRHQwaldUaGUrWTE1U0ZnUC9KQkRic1ZBcW1PYXpKRwpMR0FwVFZlR01KMjUxbWw0WUNYSi9rdktNT2RQdVBjSzluRkRSYktmYVhJaEM5T3hQditBSktRelFsbnVLYWlxCmJUQ2NXY2dCNGg3aHphcS9RWVhqWXJvaWduMWRzUDN2NFRQUwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
server: https://11.0.1.100:16443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: zhang
name: kubernetes
current-context: kubernetes
kind: Config
preferences: {}
users:
- name: zhang
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURnekNDQW11Z0F3SUJBZ0lVQlNxS1FhM3JGR2paZFk1bmxlOHVEVnMxaTR3d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZURVRNQkVHQTFVRUF4TUthM1ZpWlhKdVpYUmxjekFlRncweU1qRXlNVGt4TkRRME1EQmFGdzB6TWpFeQpNVFl4TkRRME1EQmFNR0V4Q3pBSkJnTlZCQVlUQWtOT01SQXdEZ1lEVlFRSUV3ZENaV2xLYVc1bk1SQXdEZ1lEClZRUUhFd2RDWldsS2FXNW5NUXd3Q2dZRFZRUUtFd05yT0hNeER6QU5CZ05WQkFzVEJsTjVjM1JsYlRFUE1BMEcKQTFVRUF4TUdZV3hwWVc1bk1JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBdmE5TgpOZWpCdDdSemRvWlBSSHpsQmh6TFV5eXNvd1YxdlRjaW83K3ArenJnNDduQUNLMXRmeUlFWFg2ZzhMaVF0Ym5ZCjMzZmcxODB6RFZ5NERSUFluYXgyYmo5U2YweDU1L0EwSjNBRmxuL1E4Y21SL3oybmtRU2w0RGI0bkQzQllodEQKN0lTNDJzY0JRSzRiWnYzYlBRREpkRjZCcHNPTlE2UTdIdStWU003b0NrS2ZJYjNoSFlZaUhwYUVreUszOEdDUgovT3orSFJ0ZmRPOGZ3Vzh4aVFUL21MRU1CQTZGRVNkZmFSY0cxWE9mcFBiNmhZTWpWU2pEL2Q4TDh0ejhqN2s3CldFd1ZxWnhzbWM4SXBCL2J2SjBncGNHdHJucSs1Z1NBOTF6aGRvNE9ncFBqQ3lBZnp4RmNuY1JmOXJjMmdDWUkKOUVYby95UTd0TWtxaFpORmZRSURBUUFCbzM4d2ZUQU9CZ05WSFE4QkFmOEVCQU1DQmFBd0hRWURWUjBsQkJZdwpGQVlJS3dZQkJRVUhBd0VHQ0NzR0FRVUZCd01DTUF3R0ExVWRFd0VCL3dRQ01BQXdIUVlEVlIwT0JCWUVGUHBHCmlxTmYySmQwc1ozZVBCOFQ2emJ4alpTcE1COEdBMVVkSXdRWU1CYUFGTlpYalNhRjkwRHVDUXFmV3Y4cHFzU2QKY1Ztb01BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQW9GVEJFcm9EOUN2TGhRR1paOE5xRnF3OTNadXJjRjVjSApOMEM1MEkzRWNsU0JJVEV3WExRRDVaUDdzNGxHZVhNNDZaQklTSWRXamIvRkd6RU5EbTdZeFRDM0dBYWQxSEFOClgwNENYTWNoT1JCOXRyU2NESHdDQlNWcU4rVXIvcW1oZWZDcE9RYU9EUkhZWFJjUloxUUVpNTZ1T2hjcVN5RmkKYW1sUy9sRTFoQkxGTXNHaXo1cmRNZllzTm44NHZHTmhFVStBakp5YXBuVTE5UE5za3dqejlUd1JzVUloMFdCNQpXK0libzhQZUNvYTFPdGdoanlYd3Zudy8rcDhoN2F2dC9jM253REJGKzVnblRoT2lnU21qUVpBN1VWVS9TeEFTCkpUY1ROcm8vMW1OcTVqa3ZMVHBqWVNVWk15VjNTd3ZrbkRiM0NIRUhlY0FjTlpzNE54dncKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBdmE5Tk5lakJ0N1J6ZG9aUFJIemxCaHpMVXl5c293VjF2VGNpbzcrcCt6cmc0N25BCkNLMXRmeUlFWFg2ZzhMaVF0Ym5ZMzNmZzE4MHpEVnk0RFJQWW5heDJiajlTZjB4NTUvQTBKM0FGbG4vUThjbVIKL3oybmtRU2w0RGI0bkQzQllodEQ3SVM0MnNjQlFLNGJadjNiUFFESmRGNkJwc09OUTZRN0h1K1ZTTTdvQ2tLZgpJYjNoSFlZaUhwYUVreUszOEdDUi9PeitIUnRmZE84ZndXOHhpUVQvbUxFTUJBNkZFU2RmYVJjRzFYT2ZwUGI2CmhZTWpWU2pEL2Q4TDh0ejhqN2s3V0V3VnFaeHNtYzhJcEIvYnZKMGdwY0d0cm5xKzVnU0E5MXpoZG80T2dwUGoKQ3lBZnp4RmNuY1JmOXJjMmdDWUk5RVhvL3lRN3RNa3FoWk5GZlFJREFRQUJBb0lCQUYxdkxsOHhxY3B0cnJwaApha1pZSnhBZHV1SGJqYVkzbUVsK0VTZ0x6eFViYVkrQy9kN0lYcmxTN2tlSGlvdEl2cTlsUGpqRmVoR1MyR1RxCm1SYUlBaG1ZekRWK0o0cmhCdU9DNUkzUWxsQU40Y1JYLy94MFNFZ2N2QUIzMDNwU3lTRWtRUThPU1dncXdxa3oKbWZmZmI5RGF4R0QzOUhGS3ZoamxtdUdnTGk3UU16UVMrN1dBZDBodXBZWVBYa0p5NHFHN3hiUCtEUTVDVXlOSApJSzJiOXpLMGk1c2JZdXN4VHRjbmxMYUc5alZ2eDR6Y1JVd2xzVzNLK2pWeDBYM2tVL1hSTVRWNUlnWlNYQ1JjCks3UDVNU2hONXRnK2Mwb0xaV2V3dmppVjdJSy9sZ3JyamlaL0hGeDBybVhsWGI2MlRVeWIybWJSR2hiZUQ5R04KTWtzT3NSa0NnWUVBMVcwaFAwZkNGUkgwc0tGWEovU0tTVE1mNWhob3ZiVFFDK0VpWlhTRlI5ems0Uml1TTJpLwp5NXVYYlVSbEJVbEJCSnVHWmMvZk5uT1dsWDJZY3RnMCt5ZTc0aE8vOVVzRG51VERpQXFtcExYWmI4QTg4bVVECmtJbzNHeGM3eU54MjZQNUxJd2tVdEZ4ZWgyQUJwa0FkVGR6azdUMENkd3Z6Z1A3MjM4ak9UN01DZ1lFQTQ0WEkKV2tmY3BDNXA0MlJPNHV6bmVLM0JCRlRHKzY2OEJLajBoWHJqTG9BZGlBMTUvT3dJeDlNdWtLcGVNZHJSSXZ4WApOQW5CVVZQN3gzQWRMZmgyaWVIaDJ0TWd6ZUtBM2VVUk5pYUM3YVVtODNvRi93V29XaWZzSHJNNlVpOWh5MXo0ClNGZVZyckxvaTNpQ1FhYVUvZkpYRlNEcGt1aGphY2RPcHp0ei9nOENnWUJJVjNNN2hkRXRYeWEzY0JpZ3ZHemIKSHU4akNRY0h0bkFHZHNzMzVHVUExTWpuMjN2QWhUTHRpdEdyQWRIVUZ0NW85Mlo0d0JzQzArOG93S2VaMWRzdgpmbXBhMlNMcHZBR0FMRDV5c0ZtSDN2UFN3ekJsWVFQeVRFY2RjYVNjRXM1amJ6NThvNmxXOFRCQlpyTm9iTGNDCkcydWxWbGF0ajJsOFFlL2dMcXB2clFLQmdRRGRxTENRaEFKSlVZNkhvbW5ZV3NVSHBQK3VvSWxiR2RqREVYZG4KczFreExFK1pCTWdieURpbHRQQmdzQm9rcC9Hb0MvOUpDMWZ6UzhhM2ZscHZOdWtGVzdNVjVTcklhaXJ5QXdESgpxS3RWcXRoUHpFbWJNbi9abFp0TUxZQmNJUjA5YXMzWWJMdSsvejNlNHdERHhPN1NtUTZOM3dxdnZRZGRQbmM2CkpZblRzUUtCZ0FqZW1rMkJ1Sm9uTXBhTlJnaU9PcXFCZGNNZTgxMHc2UHlENmU5Y1I1Q1FWa0xGNmVva1RydmwKeHExajdWbDEwazNPbEFZTUU1ZTdOWTJSVCtTcTJWWlZMYkNWTHQwZE9LeW9yQUNnUDNURTRyM0thN3U5d2VUdApEcGs4WTVJcVMyRVlMTDhha0Ewc25rdHJqcWFqRTlHRzVlajErR1AvQzUvVkdLM2M2a2lmCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg==
3.创建RBAC权限策略
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: default #在默认命名空间下
name: pod-reader
rules:
- apiGroups: ["","apps"] #api组,例如apps组,控制表示是核心API组(V1),向namesoace,pod,service,pv,pvc都在里面
resources: ["pods","deployments"] #资源名称(复数),例如pods、deploymenys、services
verbs: ["get", "watch", "list"] #资源操作方法
---
#将主体和角色绑定
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User #主体
name: zhang #主体名称,对应证书的CN字段
apiGroup: rbac.authorization.k8s.io
roleRef: #绑定的角色
kind: Role
name: pod-reader #角色名称
apiGroup: rbac.authorization.k8s.io
发现只能查看pod,因为只对核心组授权了,添加一下deplotment
查看想要的资源属于那个组
【】kubectl api-resources |grep deploy
修改对应组即可
4.指定kubeconfig文件测试权限:
【】kubectl get pods --kubeconfig=./zhang.kubeconfig
用户组的好处是无需单独为某个用户创建权限,统一为组名进行授权,所有的用户都以组的身份访问资源。
例如:为dev用户组统一授权
1、将certs.sh文件中的zhang-csr.json下的O字段改为dev,并重新生成证书和kubconfig文件
2、将dev用户组绑定role(pod-reader)
3、测试,只要O字段都是dev,这些用户持有的kubeconfig文件都拥有相同权限
参考用户修改即可
calico/coredns/dashboard >>都需要访问apiserver
简称SA,是一种用于让程序访问K8sAPI的服务账号
1.当创建namespace时,会自动创建一个名为default的SA,这个SA没有绑定任何权限
2.当default SA创建时,会自动创建一个default-token-xxx的secret,并自动关联到SA
3.当创建Pod时,如果没有指定SA,会自动为pod以volume方式挂载这个default SA ,在容器目录:/var/run/secrets/kubernets.io/serviceaccount
验证默认SA权限
【】kubectl--as=system:serviceaccount:default:default get pods
需求:授权容器中Python程序对K8sApi访问权限
1、创建role
2、创建serviceaccount
3、将service与role绑定
4、为pod指定自定义SA
5、进入容器里面执行python程序测试操作K8S Api权限
1-4
apiVersion: v1
kind: ServiceAccount
metadata:
name: py-k8s
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: py-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: py-role
namespace: default
subjects:
- kind: ServiceAccount
name: py-k8s
roleRef:
kind: Role
name: py-role
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: Pod
metadata:
name: py-k8s
spec:
serviceAccountName: py-k8s
containers:
- image: python:3
name: python
command:
- sleep
- 24h
测试sa权限
【】kubectl--as=system:serviceaccount:default:py-k8s get pods
【】kubectl cp k8s-api-test.py py-k8s:/
【】kubectl exec -it py-k8s bash
#python3 k8s-api-test.py
会报错,无模块,用pip装一下
#pip install kubernetes -I 指定国内源,不加比较慢
from kubernetes import client, config
with open('/var/run/secrets/kubernetes.io/serviceaccount/token') as f:
token = f.read()
configuration = client.Configuration()
configuration.host = "https://kubernetes" # APISERVER地址
configuration.ssl_ca_cert="/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" # CA证书
configuration.verify_ssl = True # 启用证书验证
configuration.api_key = {"authorization": "Bearer " + token} # 指定Token字符串
client.Configuration.set_default(configuration)
apps_api = client.AppsV1Api()
core_api = client.CoreV1Api()
try:
print("###### Deployment列表 ######")
#列出default命名空间所有deployment名称
for dp in apps_api.list_namespaced_deployment("default").items:
print(dp.metadata.name)
except:
print("没有权限访问Deployment资源!")
try:
#列出default命名空间所有pod名称
print("###### Pod列表 ######")
for po in core_api.list_namespaced_pod("default").items:
print(po.metadata.name)
except:
print("没有权限访问Pod资源!")
需求:
创建一个角色,具备查看控制器的权限。
创建一个SA,将SA绑定到角色。
命令行使用:授权SA只能查看test命名空间控制器的权限
# 创建角色
kubectl create role role-test--verb=get,list \
--resource=deployments,daemonsets,statefulsets-n test
# 创建服务账号
kubectl create serviceaccount app-demo -ntest
# 将服务账号绑定角色
kubectl create rolebinding role-test:app-demo\
--serviceaccount=test:app-demo--role=role-test -n test
# 测试
kubectl--as=system:serviceaccount:test:app-demo \
get pods -n test