系列目录

什么是pod安全策略

pod安全策略是集群级别的用于控制pod安全相关选项的一种资源.PodSecurityPolicy定义了一系列pod相要进行在系统中必须满足的约束条件,以衣一些默认的约束值.它允许管理员控制以下方面内容

Control Aspect Field Names
以特权运行容器 privileged
使用宿主名称空间 hostPID, hostIPC
使用宿主网络和端口 hostNetwork, hostPorts
使用存储卷类型 volumes
使用宿主机文件系统 allowedHostPaths
flex存储卷白名单 allowedFlexVolumes
分配拥有 Pod 数据卷的 FSGroup fsGroup
只读root文件系统 readOnlyRootFilesystem
容器的用户id和组id runAsUser, runAsGroup, supplementalGroups
禁止提升到root权限 allowPrivilegeEscalation, defaultAllowPrivilegeEscalation
Linux能力 defaultAddCapabilities, requiredDropCapabilities, allowedCapabilities
SELinux上下文 seLinux
允许容器加载的proc类型 allowedProcMountTypes
The AppArmor profile used by containers annotations
The seccomp profile used by containers annotations
The sysctl profile used by containers annotations

启用pod安全策略

pod安全策略作为可选的(但强烈建议的)admission controller的实现.pod安全策略通过启用admission controller来实现,但是仅仅启用而没有对策略授权则会导致整个集群无法创建pod!

由于pod安全策略api(policy/v1beta1/podsecuritypolicy)独立于admission controller之外启用,对于已经存在的集群建议在启用admission controller之前添加并授权策略.

授权策略

当一个pod安全策略资源被创建(前面说过,psp(PodSecurityPolicy )pod安全策略是一种kubernetes资源),它什么都不会做.为了使用它,请求操作的用户或者目标pod的serviceaccount必须通过策略的use动词来授权.

绝大部分kubernetes pod并不是直接由用户直接创建的.相反,典型使用场景是它们通过Deployment或者ReplicaSet间接被创建,或者通过控制器管理器的其它模板控制器来创建.对控制器进行策略授权也将对它所创建的所有pod进行策略授权.因此首选的授权方法是对pod的serviceaccount进行策略授权(后面有示例).

通过RBAC授权

RBAC是kubernetes标准的授权模式,并且很容易用于授权安全策略使用.

首先,一个角色(role)或者集群角色(clusterRole)需要被授权使用(use动词)它想要的策略.对角色的授权类似下面

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: <role name>
rules:
- apiGroups: ['policy']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames:
- 一系列要进行授权的资源名称

然后把集群角色(或角色)与授权的用户绑定

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: 绑定名称
roleRef:
kind: ClusterRole
name: 角色名称
apiGroup: rbac.authorization.k8s.io
subjects:
# Authorize specific service accounts:
- kind: ServiceAccount
name: 授权的serviceaccount名称
namespace: <authorized pod namespace>
# Authorize specific users (not recommended):
- kind: User
apiGroup: rbac.authorization.k8s.io
name: 授权的用户名

如果一个角色绑定(不是集群角色绑定)被使用,它仅对和它处于同一名称空间下的pod才能进行有效策略授权,这样同样适用于用户和用户组

# Authorize all service accounts in a namespace:
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:serviceaccounts
# Or equivalently, all authenticated users in a namespace:
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: system:authenticated

故障排除

控制器管理器必须运行在安全的api端口上,并且不能有超级权限.不然请求就会绕过认证和授权模块,将导致所有的策略均被允许,并且用户可以创建特权pod

策略顺序

除了限制pod的创建和更新,pod安全策略还用于提供它所控制的诸多字段的默认值.当有多个策略时,pod安全策略根据以下因素来选择策略

  • 任何成功通过验证没有警告的策略将被使用

  • 如果是请求创建pod,则按通过验证的策略按字母表顺序被选用

  • 否则,如果是一个更新请求,将会返回错误.因为在更新操作过程中不允许pod变化

示例

以下示例假定你运行的集群开启了pod安全策略admission controller并且你有集群管理员权限

初始设置

我们为示例创建一个名称空间和一个serviceaccount.我们使用这个serviceaccount来模拟一个非管理员用户

kubectl create namespace psp-example
kubectl create serviceaccount -n psp-example fake-user
kubectl create rolebinding -n psp-example fake-editor --clusterrole=edit --serviceaccount=psp-example:fake-user

为了方便辨认我们使用的账户,我们创建两个别名

alias kubectl-admin='kubectl -n psp-example'
alias kubectl-user='kubectl --as=system:serviceaccount:psp-example:fake-user -n psp-example'

创建一个策略和一个pod

以下定义文件定义了一个简单pod安全策略(PodSecurityPolicy),这个策略仅仅阻止创建特权pod

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: example
spec:
privileged: false # Don't allow privileged pods!
# The rest fills in some required fields.
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
runAsUser:
rule: RunAsAny
fsGroup:
rule: RunAsAny
volumes:
- '*'

我们使用kubectl命令来应用以上文件.

现在,做为一个非特权用户,我们创建一个简单pod

kubectl-user create -f- <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pause
spec:
containers:
- name: pause
image: k8s.gcr.io/pause
EOF
Error from server (Forbidden): error when creating "STDIN": pods "pause" is forbidden: unable to validate against any pod security policy: []

发生了什么?尽管pod安全策略已创建,不管是pod的serviceaccount还是fack-user都没有权限使用这个策略.

kubectl-user auth can-i use podsecuritypolicy/example
no

创建一个rolebing来授权fake-user来使用example策略(example是前面创建的策略的名称)

但是请注意这里并不是首选方式!后面的示例将介绍首选的方式

kubectl-admin create role psp:unprivileged \
--verb=use \
--resource=podsecuritypolicy \
--resource-name=example
role "psp:unprivileged" created kubectl-admin create rolebinding fake-user:psp:unprivileged \
--role=psp:unprivileged \
--serviceaccount=psp-example:fake-user
rolebinding "fake-user:psp:unprivileged" created kubectl-user auth can-i use podsecuritypolicy/example
yes

此时,再重新尝试创建pod

kubectl-user create -f- <<EOF
apiVersion: v1
kind: Pod
metadata:
name: pause
spec:
containers:
- name: pause
image: k8s.gcr.io/pause
EOF
pod "pause" created

这次正如我们期待的一样,可以正常工作.但是试图创建特权pod仍然会被阻止(因此策略本身阻止创建特权pod)

kubectl-user create -f- <<EOF
apiVersion: v1
kind: Pod
metadata:
name: privileged
spec:
containers:
- name: pause
image: k8s.gcr.io/pause
securityContext:
privileged: true
EOF
Error from server (Forbidden): error when creating "STDIN": pods "privileged" is forbidden: unable to validate against any pod security policy: [spec.containers[0].securityContext.privileged: Invalid value: true: Privileged containers are not allowed]

再运行一个其它pod

我们再尝试创建一个pod,这次有一点不同

ubectl-user run pause --image=k8s.gcr.io/pause
deployment "pause" created kubectl-user get pods
No resources found. kubectl-user get events | head -n 2
LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON SOURCE MESSAGE
1m 2m 15 pause-7774d79b5 ReplicaSet Warning FailedCreate replicaset-controller Error creating: pods "pause-7774d79b5-" is forbidden: no providers available to validate pod request

从以上可以看到deployment已经成功创建(kubectl run 实际上会创建一个deployment).但是使用kubectl get pod命令却没有发现pod被创建.这是为什么?问题的答案隐藏在replicaset控制器里.Fake-user成功创建的deployment(deployment又成功创建replicaset),但是当replicaset尝试创建pod的时候,它并没有被授权使用example定义的策略.

为了解决这个问题,需要把psp:unprivileged角色(前面创建的)绑定到pod的serviceaccount上(前面我们是绑定在了fake-user上).这里serviceaccount是default(因为我们没有指定其它用户)

看到这里如果你仍然觉得难以理解,可以回头再看看,还是无法理解的话则需要补充关于角色,用户和RBAC相关的知识.

kubectl-admin create rolebinding default:psp:unprivileged \
--role=psp:unprivileged \
--serviceaccount=psp-example:default
rolebinding "default:psp:unprivileged" created

这时候等待若干分钟,replicaset的控制器最终会成功创建pod

kubectl-user get pods --watch
NAME READY STATUS RESTARTS AGE
pause-7774d79b5-qrgcb 0/1 Pending 0 1s
pause-7774d79b5-qrgcb 0/1 Pending 0 1s
pause-7774d79b5-qrgcb 0/1 ContainerCreating 0 1s
pause-7774d79b5-qrgcb 1/1 Running 0 2s

清理工作

删除名称空间以删除绝大部分示例中用到的资源

kubectl-admin delete ns psp-example
namespace "psp-example" deleted

注意现在刚刚创建的pod安全策略已经没有了名称空间,并且需要单独被清除

kubectl-admin delete psp example
podsecuritypolicy "example" deleted

策略示例

以下是一个最小限制的策略,和不使用pod安生策略admission controller效果一样

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: privileged
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*'
spec:
privileged: true
allowPrivilegeEscalation: true
allowedCapabilities:
- '*'
volumes:
- '*'
hostNetwork: true
hostPorts:
- min: 0
max: 65535
hostIPC: true
hostPID: true
runAsUser:
rule: 'RunAsAny'
seLinux:
rule: 'RunAsAny'
supplementalGroups:
rule: 'RunAsAny'
fsGroup:
rule: 'RunAsAny'

以下的一个示例有限制性策略,需要用户是一个非特权用户,阻止pod的权限提升

之所以要求是非特权用户,因为特权用户将会绕过限制

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: restricted
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default'
apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default'
seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default'
apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'
spec:
privileged: false
# Required to prevent escalations to root.
allowPrivilegeEscalation: false
# This is redundant with non-root + disallow privilege escalation,
# but we can provide it for defense in depth.
requiredDropCapabilities:
- ALL
# Allow core volume types.
volumes:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
# Assume that persistentVolumes set up by the cluster admin are safe to use.
- 'persistentVolumeClaim'
hostNetwork: false
hostIPC: false
hostPID: false
runAsUser:
# Require the container to run without root privileges.
rule: 'MustRunAsNonRoot'
seLinux:
# This policy assumes the nodes are using AppArmor rather than SELinux.
rule: 'RunAsAny'
supplementalGroups:
rule: 'MustRunAs'
ranges:
# Forbid adding the root group.
- min: 1
max: 65535
fsGroup:
rule: 'MustRunAs'
ranges:
# Forbid adding the root group.
- min: 1
max: 65535
readOnlyRootFilesystem: false

策略参考

特权的

它决定了pod中的所有容器是否被允许以特权方式运行.默认情况下容器不允许访问主机的设备,但是特权容器却被允许访问.这将允许容器有几乎和它所在的进程一样的访问主机的权利.这将非常有用当容器想要使用主机的功能,比如访问网络的设备.

Host名称空间

HostPID - 控制容器是否可以共享主机的进程id名称空间

HostIPC - 控制容器是否可以共享主机的IPC名称空间

HostNetwork - 控制容器是否可以使用所在节点的网络名称空间.这将允许pod访问回环设备,监听localhost,并且可以窥探同一节点上其它pod的网络活动状况

AllowedHostPaths - 控制允许访问的宿主机路径

存储卷和文件系统

Volumes - 提供了一系列的存储卷类型白名单.这些允许的值和创建存储卷时定义的资源类型相对应.想要获取所有存储卷类型,可以查看存储卷类型列表.此外,*可以被用来允许所有的存储卷类型

以下是推荐的最小化的允许存储卷类型的安全策略配置

  • configMap
  • downwardAPI
  • emptyDir
  • persistentVolumeClaim
  • secret
  • projected

AllowedHostPaths- 它定义了一个hostPath类型的存储卷可用的宿主机路径的白名单.空集群意味着对宿主机的path无使用限制.它被定义为一个包含了一系列对象的单个pathPrefix字段,允许hostpath类型的存储卷挂载以pathPrefix字段开头的宿主机路径.readonly字段意味着必须以readonly方式挂载(即不能写入,只能读)

allowedHostPaths:
# This allows "/foo", "/foo/", "/foo/bar" etc., but
# disallows "/fool", "/etc/foo" etc.
# "/foo/../" is never valid.
- pathPrefix: "/foo"
readOnly: true # only allow read-only mounts

警告,一个可以无限制访问宿主机文件系统的容器可以有很多方式提升权限,包括读取其它容器内的数据,滥用系统服务的密钥,比如kubecctl

可写的hostpath目录存储卷允许容器写入到宿主机文件系统,并且可以遍历pathPrefix以外的文件系统,readOnly: true在kubernetes 1.11+版本以后才能使用,并且在allowedHostPaths必须使用以有效限制访问特定的pathPrefix

ReadOnlyRootFilesystem - 限制容器必须以只读的root文件系统运行(没有可写层)

特权提升

这个选项控制着容器的allowPrivilegeEscalation选项.这个布尔值直接控制着no_new_privs是否设置到容器运行的进程.它将阻止setuid来改变user ID,并且阻止文件有其它的能力(比如禁止使用ping工具).这个行为需要启用MustRunAsNonRoot

AllowPrivilegeEscalation- 它决定着容器的安全上下文是否可以设置allowPrivilegeEscalation=true,为true是默认值.设置为false将使得容器所有的子进程没有比父进程更高的特权

DefaultAllowPrivilegeEscalation,为allowPrivilegeEscalation设置默认值,从上面可以看到,默认的值为true.如果这个行为不是我们期待的,这个字段可以用于把它设置为不允许,但是仍然pod显式请求allowPrivilegeEscalation

kubernetes高级之pod安全策略的更多相关文章

  1. Kubernetes 中的 Pod 安全策略

    来源:伪架构师作者:崔秀龙很多人分不清 SecurityContext 和 PodSecurityPolicy 这两个关键字的差别,其实很简单:•SecurityContext 是 Pod 中的一个字 ...

  2. 实操教程丨使用Pod安全策略强化K8S安全

    本文来自Rancher Labs 什么是Pod安全策略? Kubernetes Pod安全策略(PSP)是Kubernetes安全版块中极为重要的组件.Pod安全策略是集群级别的资源,用于控制Pod安 ...

  3. Kubernetes 多租户:Pod 安全策略

    默认情况下,Kubernetes 允许创建一个有特权容器的 Pod,这些容器很可能会危机系统安全,而 Pod 安全策略(PSP)则通过确保请求者有权限按配置来创建 Pod,从而来保护集群免受特权 Po ...

  4. kubernetes高级之集群中使用sysctls

    系列目录 在linux系统里,sysctls 接口允许管理员在运行时修改内核参数.参数存在于/proc/sys/虚拟进程文件系统里.参数涉及到很多子模块,例如: 内核(kernel)(常见前缀kern ...

  5. 实例演示:如何简化生产中的Pod安全策略?

    Pod安全策略对于强化K8S集群安全至关重要.本文将延续之前的文章继续深入介绍Pod安全策略. 首先,简单介绍了如何将Pod与Pod安全策略相关联,并使用RBAC来展示具体步骤.然后介绍如何在Ranc ...

  6. 一文读懂k8s之Pod安全策略

    导读 Pod容器想要获取集群的资源信息,需要配置角色和ServiceAccount进行授权.为了更精细地控制Pod对资源的使用方式,Kubernetes从1.4版本开始引入了PodSecurityPo ...

  7. Kubernetes 实战 —— 03. pod: 运行于 Kubernetes 中的容器

    介绍 pod P53 pod 是 Kubernetes 中最为重要的核心概念,而其他对象仅仅用于 pod 管理. pod 暴露或被 pod 使用. pod 是一组并置的容器,代表了 Kubernete ...

  8. Kubernetes — 深入解析Pod对象:基本概念(二)

    作为 Kubernetes 项目里最核心的编排对象,Pod 携带的信息非常丰富.其中,资源定义(比如 CPU.内存等),以及调度相关的字段.在本篇,我们就先从一种特殊的 Volume 开始,来帮助你更 ...

  9. kubernetes集群pod使用tc进行网络资源限额

    kubernetes集群pod使用tc进行网络资源限额 Docker容器可以实现CPU,内存,磁盘的IO限额,但是没有实现网络IO的限额.主要原因是在实际使用中,构建的网络环境是往超级复杂的大型网络. ...

随机推荐

  1. 【Luogu】P2221高速公路(线段树乱搞)

    题目链接 这题……我从一开始就想歪了qwq. 为了缅怀逝去的一小时我就把我的30分暴力思路放上来. 首先我们观察枚举的区间.假设我们要枚举的范围是1~5之间的四条路,为了方便我们把它们叫做abcd. ...

  2. kb-07线段树-05-区间整体修改查询;(水)

    /* */ #include<iostream> #include<cstring> #include<cstdio> using namespace std; s ...

  3. [LOJ#531]「LibreOJ β Round #5」游戏

    [LOJ#531]「LibreOJ β Round #5」游戏 试题描述 LCR 三分钟就解决了问题,她自信地输入了结果-- > -- 正在检查程序 -- > -- 检查通过,正在评估智商 ...

  4. windows命令总结

    工作中还是经常使用windows系统,将windows中常用的命令进行总结. 1. 从命令行打开资源管理器,即文件夹 start . 2. 查看端口占用情况 比如查看3000端口的占用情况 netst ...

  5. iOS-Core Data基础

    Core Data基础 Core Data是一个API集合,被设计用来简化数据对象的持久存储. 在此先不普及概念,先通过一个简单的案例使用来感受一下Core Data的精妙之处. 在创建工程的时候勾选 ...

  6. bzoj 1137 [POI2009]Wsp 岛屿

    题目大意 Byteotia岛屿是一个凸多边形.城市全都在海岸上.按顺时针编号1到n.任意两个城市之间都有一条笔直的道路相连.道路相交处可以自由穿行.有一些道路被游击队控制了,不能走,但是可以经过这条道 ...

  7. 获取本机外网IP的工具类

    ExternalIpAddressFetcher.java package com.tyust.common; import java.io.IOException; import java.io.I ...

  8. ubuntu 为firefox 安装flash_player

    1.下载安装包install_flash_player_11_linux.i386.tar.gz: 2.解压文件:$ tar -xvf install_flash_player_11_linux.i3 ...

  9. 标准C程序设计七---116

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  10. 关于nginx所遇问题

    1. 如果出现 nginx: [error] invalid PID number “” in “/usr/local/var/run/nginx/nginx.pid” 错误重新加载配置文件 /usr ...