简述
最近在给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出自: |