Kubernetes安全篇2:安全框架、RBAC、SA、资源配额 、资源限制

K8s安全框架

Kubernetes安全篇2:安全框架、RBAC、SA、资源配额 、资源限制

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:开头的为系统内部使用。

Kubernetes安全篇2:安全框架、RBAC、SA、资源配额 、资源限制

实验案例可以参考: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访问权限

实施大致步骤:

  1. 创建Role
  2. 创建ServiceAccount
  3. 将ServiceAccount与Role绑定
  4. 为Pod指定自定义的SA
  5. 进入容器里执行Python程序测试操作K8s API权限
Kubernetes安全篇2:安全框架、RBAC、SA、资源配额 、资源限制

命令行使用:授权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

Kubernetes安全篇2:安全框架、RBAC、SA、资源配额 、资源限制

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

Kubernetes安全篇2:安全框架、RBAC、SA、资源配额 、资源限制

资源配额 ResourceQuota

当多个团队、多个用户共享使用K8s集群时,会出现不均匀资源使用,默认情况下先到先得,这时可以通过ResourceQuota来对命名空间资源使用总量做限制,从而解决这个问题。

使用流程:k8s管理员为每个命名空间创建一个或多个ResourceQuota对象,定义资源使用总量,K8s会跟踪命名空间资源使用情况,当超过定义的资源配额会返回拒绝。

ResourceQuota功能是一个准入控制插件,默认已经启用。

Kubernetes安全篇2:安全框架、RBAC、SA、资源配额 、资源限制

计算资源配额:

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
Kubernetes安全篇2:安全框架、RBAC、SA、资源配额 、资源限制

查看配额:

Kubernetes安全篇2:安全框架、RBAC、SA、资源配额 、资源限制

命名空间若限制了空间,则要求内部新创建的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"
Kubernetes安全篇2:安全框架、RBAC、SA、资源配额 、资源限制

vi pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: task-pv-claim
  namespace: test
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 11Gi
Kubernetes安全篇2:安全框架、RBAC、SA、资源配额 、资源限制

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"
Kubernetes安全篇2:安全框架、RBAC、SA、资源配额 、资源限制

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

Kubernetes安全篇2:安全框架、RBAC、SA、资源配额 、资源限制

这里创建一个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
Kubernetes安全篇2:安全框架、RBAC、SA、资源配额 、资源限制

发布者:LJH,转发请注明出处:https://www.ljh.cool/33984.html

(0)
上一篇 2023年4月1日 下午9:27
下一篇 2023年4月2日 下午2:19

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注