K8s安全框架
K8S安全控制框架主要由下面3个阶段进行控制,每一个阶段都支持插件方式,通过API Server配置来启用插件。
认证:
K8s Apiserver提供三种客户端身份认证:
HTTPS 证书认证:基于CA证书签名的数字证书认证(kubeconfig)
HTTP Token认证:通过一个Token来识别用户(serviceaccount)
例:kubeconfig、dashboard token、kubeadm join、ServiceAccount
鉴权
RBAC(Role-Based Access Control,基于角色的访问控制):负责完成授权(Authorization)工作。
RBAC根据API请求属性,决定允许还是拒绝。
比较常见的授权维度
• user:用户名
• group:用户分组
• 资源,例如pod、deployment
• 资源操作方法:get,list,create,update,patch,watch,delete
• 命名空间
• API组
准入控制
Adminssion Control实际上是一个准入控制器插件列表,发送到API Server的请求都需要经过这个列表中的每个准入控制器插件的检查,检查不通过,则拒绝请求。类似于一个安全扫描设备
作用:
方便用户扩展apiserver工具(对所有强求处理的功能)
k8s提供很多功能,插件话设计
启用一个准入控制器:
kube-apiserver --enable-admission-plugins=NamespaceLifecycle,LimitRanger …
关闭一个准入控制器:
kube-apiserver --disable-admission-plugins=PodNodeSelector,AlwaysDeny …
查看默认启用:
kubectl exec kube-apiserver-k8s-master -n kube-system -- kube-apiserver -h | grep enable-admission-plugins
RBAC认证授权案例
RBAC(Role-Based Access Control,基于角色的访问控制),是K8s默认授权策略,并且是动态配置策略(修改即时生效)。
主体(subject)
User:用户
Group:用户组
ServiceAccount:服务账号
角色
Role:授权特定命名空间的访问权限
ClusterRole:授权所有命名空间的访问权限
角色绑定
RoleBinding:将角色绑定到主体(即subject)
ClusterRoleBinding:将集群角色绑定到主体
注:RoleBinding在指定命名空间中执行授权,ClusterRoleBinding在集群范围执行授权。
k8s预定好了四个集群角色供用户使用,使用kubectl get clusterrole查看,其中systemd:开头的为系统内部使用。
实验案例可以参考:https://www.ljh.cool/8084.html
搜索 “实践:创建一个用户只能管理 dev 空间”
对应用程序授权访问K8s(ServiceAccount)
先了解下ServiceAccount,简称SA,是一种用于让程序访问K8s API的服务账号
当创建namespace时,会自动创建一个名为default的SA,这个SA没有绑定任何权限
当default SA创建时,会自动创建一个default-token-xxx的secret,并自动关联到SA
当创建Pod时,如果没有指定SA,会自动为pod以volume方式挂载这个default SA,在容器目录:/var/run/secrets/kubernetes.io/serviceaccount
验证默认SA权限:kubectl --as=system:serviceaccount:default:default get pods
对应用程序授权访问K8s(ServiceAccount)
需求:
授权容器中Python程序对K8s API访问权限
实施大致步骤:
- 创建Role
- 创建ServiceAccount
- 将ServiceAccount与Role绑定
- 为Pod指定自定义的SA
- 进入容器里执行Python程序测试操作K8s API权限
命令行使用:授权SA只能查看test命名空间控制器的权限
创建test命名空间
kubectl create ns test
创建角色
kubectl create role role-test --verb=get,list --resource=pods,deployments,daemonsets,statefulsets -n test
创建服务账号
kubectl create serviceaccount app-demo -n test
将服务账号绑定角色
kubectl create rolebinding app-demo-rolebinding --serviceaccount=test:app-demo --role=role-test -n test
测试
kubectl --as=system:serviceaccount:test:app-demo get pods -n test
授权镜像中python程序调用k8s
授权镜像中python程序调用k8s
rabc.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: py-k8s
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: py-role
rules:
- apiGroups: [""] # "" 标明 core API 组
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: py-role
namespace: default
subjects:
# 你可以指定不止一个“subject(主体)”
- kind: ServiceAccount
name: py-k8s # "name" 是区分大小写的
roleRef:
# "roleRef" 指定与某 Role 或 ClusterRole 的绑定关系
kind: Role # 此字段必须是 Role 或 ClusterRole
name: py-role # 此字段必须与你要绑定的 Role 或 ClusterRole 的名称匹配
apiGroup: rbac.authorization.k8s.io
测试权限:
kubectl --as=system:serviceaccount:default:py-k8s get pods -n default
pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: py-k8s
spec:
serviceAccountName: py-k8s
containers:
- image: python:3
name: python
command:
- sleep
- 24h
kubectl apply -f pod.yaml
测试容器内部python程序是否能查看pod
kubectl exec -it py-k8s -- bash
pip install kubernetes -i https://pypi.tuna.tsinghua.edu.cn/simple/
k8s-api-test.py
cat <<EOF> /k8s-api-test.py
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://11.0.1.111:6443" # 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命名空间所有的dployment名称
for dp in apps_api.list_namespaced_deployment("default").items:
print(dp.metadata.name)
except:
print("没有权限访问Deployment资源!")
try:
print("##### Pod列表 #####")
#列出default命名空间所有的pod名称
for po in core_api.list_namespaced_pod("default").items:
print(po.metadata.name)
except:
print("没有权限访问pod资源!")
EOF
python3 /k8s-api-test.py
资源配额 ResourceQuota
当多个团队、多个用户共享使用K8s集群时,会出现不均匀资源使用,默认情况下先到先得,这时可以通过ResourceQuota来对命名空间资源使用总量做限制,从而解决这个问题。
使用流程:k8s管理员为每个命名空间创建一个或多个ResourceQuota对象,定义资源使用总量,K8s会跟踪命名空间资源使用情况,当超过定义的资源配额会返回拒绝。
ResourceQuota功能是一个准入控制插件,默认已经启用。
计算资源配额:
vi compute.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
namespace: test
spec:
hard:
requests.cpu: "4"
requests.memory: 10Gi
limits.cpu: "6"
limits.memory: 12Gi
查看配额:
命名空间若限制了空间,则要求内部新创建的pod资源强制指定requests和limits,而且创建的资源不可以高于命名空间的阈值
存储资源配额:
vi storage.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: storage-resources
namespace: test
spec:
hard:
requests.storage: "10G"
# storage.storageclass.storage.k8s.io/requests.storage: "5G"
vi pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pv-claim
namespace: test
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 11Gi
test命名空间总共容量要求10个G,目前已经使用0个G,要求是11个G
对象数量配额:
vi object-counts.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-counts
namespace: test
spec:
hard:
pods: "10"
count/deployments.apps: "3"
count/services: "3"
kubectl create deployment test-nginx --image=nginx:latest --replicas=3 -n test
资源限制 LimitRange
计算资源配额:
默认情况下,K8s集群上的容器对计算资源没有任何限制,可能会导致个别容器资源过大导致影响其他容器正常工作,这时可以使用LimitRange定义容器默认CPU和内存请求值或者最大上限。
LimitRange限制维度:
限制容器配置requests.cpu/memory,limits.cpu/memory的最小、最大值
限制容器配置requests.cpu/memory,limits.cpu/memory的默认值
限制PVC配置requests.storage的最小、最大值
计算资源最大、最小限制:
vi ContainerLimit.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-memory-min-max
namespace: test
spec:
limits:
- max: # 容器能设置limit的最大值
cpu: 1
memory: 1Gi
min: # 容器能设置request的最小值
cpu: 200m
memory: 200Mi
type: Container
计算资源默认值限制:
cpu-memory-min-max.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-memory-min-max
namespace: test
spec:
limits:
- default:
cpu: 500m
memory: 500Mi
defaultRequest:
cpu: 300m
memory: 300Mi
type: Container
存储资源最大、最小限制:
vi storage-min-max.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: storage-min-max
namespace: test
spec:
limits:
- type: PersistentVolumeClaim
max:
storage: 10Gi
min:
storage: 1Gi
kubectl describe limits -n test
这里创建一个pvc进行报错测试:
vi pv1.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pv-claim
namespace: test
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 0.5Gi
发布者:LJH,转发请注明出处:https://www.ljh.cool/33984.html