简述
最近在给k8s的一些java应用,包括lua项目,做火焰图的安装,后经仔细研究发现,火焰图安装需要打开docker的安全限制,由于我的环境基本都是在k8s中不熟的,所以找了一些文档,总结了下pod的安全策略。
PSP
Pod Security Policy, 是用于检查 Pod 安全的对象。他可以限制 Pod 是否可以使用特权模式,挂载主机目录等等。
限制范围
是否特权模式 | Running of privileged containers | privileged |
是否root namespace | Usage of the root namespaces | hostPID, hostIPC |
是否主机网络模式 | Usage of host networking and ports | hostNetwork, hostPorts |
可以选择存储类型 | Usage of volume types | volumes |
可以挂载主机哪些目录 | Usage of the host filesystem | allowedHostPaths |
lvm? | White list of FlexVolume drivers | allowedFlexVolumes |
Allocating an FSGroup that owns the pod’s volumes | fsGroup | |
read only root file | Requiring the use of a read only root file system | readOnlyRootFilesystem |
user in ctr | The user and group IDs of the container | runAsUser, supplementalGroups |
Restricting escalation to root privileges | allowPrivilegeEscalation, defaultAllowPrivilegeEscalation | |
Linux capabilities | defaultAddCapabilities, requiredDropCapabilities, allowedCapabilities | |
SELinux | The SELinux context of the container | seLinux |
The AppArmor profile used by containers | annotations | |
The seccomp profile used by containers | annotations | |
The sysctl profile used by containers | annotations |
策略实例
最宽松策略
1 | apiVersion: policy/v1beta1 |
最严格的限制
1 | apiVersion: policy/v1beta1 |
开启 PSP 功能
管理员需要关心这一章节。普通用户可以跳过。
Pod 安全检查的功能已经编译在 kube-apiserver
中。当 api server 接收到创建 Pod 的请求,他会检查 Pod 的各个参数,匹配创建者所能使用的策略。如果没有策略可以匹配,则 Pod 不会被创建。 只需要在 kube-apiserver
启动参数 --admission-control=
的值列表中加入 PodSecurityPolicy
就会开启检查。
从 1.10 开始,当 kube-apiserver
使用 Static Pod 的方式启动时会有一些问题。kube-apiserver
启动参数加入 PodSecurityPolicy
之后,他本身的 Pod 会因为没有匹配的策略而无法启动。 启动 kube-apiserver
的创建者是 group
system:node
。所以需要提前给他绑定绑定一个拥有 PSP 策略的角色。
创建规则
创建上一章节中的
最宽松策略
。或者其他你觉得合适的规则。
- 创建角色。
1 | apiVersion: rbac.authorization.k8s.io/v1beta1 |
- 绑定账户和角色
1 | apiVersion: rbac.authorization.k8s.io/v1beta1 |
- 修改
kube-apiserver
参数
cp /etc/kubernetes/manifests/kube-apiserver.yaml ./
vim kube-apiserver.yaml
- 在
--admission-control=
末尾加,PodSecurityPolicy
cp kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml
- 确保
kube-apiserver
启动
kubectl -n kube-system get pods | grep api
能看到 pod 。- 如果看不到,请从头看一遍文章。
- 如果还不行请参考 k8s 最新文档。
使用
- 用户创建 Pod
- Service Account 创建 Pod
用户创建 Pod
通常我们并不直接创建 Pod。这里只是为了理解各对象之间的关系。 可以快速浏览至下一小节[Service Account 创建 Pod]
确定使用哪个用户
1 | kubectl config view |
可以看到当前命令行的配置。参考 current-context
, context
可以知道默认用的那个用户。 这里如下用户作为例子。
1 | apiVersion: v1 |
这里看到 kubectl 使用的就是 user kubernetes-admin@kubernetes。我们假设 kubernetes-admin@kubernetes
是个普通用户,目前不能创建 Pod 。
- 创建规则
这里说的规则就是 PodSecutityPolicy
对象本身,也可以说是 psp 资源。psp 资源是 cluster scoped,不分 namespace。
这里使用前文中的 最宽松策略
。也可以使用其他你觉得合适的规则。如果已经创建,则不需要重复创建。
kubectl get psp
查看已有 psp 资源。
最宽松策略
1 | apiVersion: policy/v1beta1 |
- 创建角色
在 default namespace 下创建一个角色。
1 | kind: Role |
- 绑定角色和用户
1 | kind: RoleBinding |
- 创建 Pod
1 | apiVersion: v1 |
Service Account 创建 Pod
当用命令行直接创建 Pod 时(kubectl apply -f pod.yaml
)。通常都是用某个 User
作为创建者。 当通过 Deployment,StatefulSet 这类对象创建 Pod 时。Pod 的创建者是 Service Account 类型的。 当没有明确指定 Service Account 时,将会使用所在 namespace 下名为 default 的 Service Account。所以只要给 default Service Account 绑定 privileged-user 就可以了。 当在 Pod 的 spec 中明确定义了所使用的 serviceAccountName
,那么将会使用指定的。 所以只要给对应的 Service Account 绑定 privileged-user 就可以了。可以参考如下绑定。
绑定 default Service Account
1 | apiVersion: rbac.authorization.k8s.io/v1beta1 |
以上是 psp 的基本使用。下边是扩展技巧。
绑定角色使用 ClusterRole
Role
资源是 namespace scoped。仅限所在的 namespace 使用。当在不同 namespace 中使用同一个 psp 策略时,需要创建不同的 Role
。这个时候可以使用 ClusterRole
。
ClusterRole
是 cluster scoped 资源。当用 ClusterRoleBinding
绑定 ClusterRole
和账户时。此账户就在集群范围内拥有了 ClusterRole
定义的权限。
当在 RoleBinding
中绑定 ClusterRole
和账户时。此账户就只在 RoleBinding
所在 namespace 中拥有 ClusterRole
定义的权限。 这样就可以给不同账户绑定同一个角色。
1 | apiVersion: rbac.authorization.k8s.io/v1beta1 |
绑定账户使用 Group
当使用 RoleBinding
时可以在 namespace 范围内给所有 Service Account 或者所有认证用户绑定角色。
1 | apiVersion: rbac.authorization.k8s.io/v1beta1 |
对于 kube-system ns 和集群管理方的 ns 可以直接授权所有 service account 高权限角色。
1 | apiVersion: rbac.authorization.k8s.io/v1beta1 |
火焰图
1 | 一个简单的基于cpu的火焰图 |
1 | psp出自: |