kubernetes PodSecurityPolicy Pod安全策略PSP
PodSecurityPolicy可以对Pod的创建更新进行细粒度的授权。
注意:controller-manager 必须以非超级用户运行,和在安全的api端口运行,要不然请求会绕过身份验证和授权模块,创建特权容器和psp策略都将被允许。
官方文档:
https://kubernetes.io/docs/concepts/policy/pod-security-policy/
最少的限制:相当于不使用Pod安全策略
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'
禁止以root用户运行:阻止用户升级到root用户。
apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: restricted annotations: seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default,runtime/default' apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' seccomp.security.alpha.kubernetes.io/defaultProfileName: 'runtime/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
使用PSP安全策略
psp策略定义好之后还需要再创建role,把psp策略绑定到role上,再将role绑定到serviceaccount,再在Pod中使用serviceaccount。
还有几个必要条件:
1、在apiserver启动参数 --enable-admission-plugins 中要加上 PodSecurityPolicy 选项,默认是没有启用的。
2、在 controller-manager 的启动参数中开启 --use-service-account-credentials=true 选项,这个选项默认是开启的,会自动为k8s中每一个控制器创建一个serviceaccount,例如运行 deployment 的时候默认就会使用名称为 deployment-controller 的 serviceaccount 来创建Pod。
参考:
https://www.qikqiak.com/post/setup-psp-in-k8s/
如果想给某个 deployment 或某个Pod单独设置一个策略可以单独创建serviceaccount、psp、role、rouebinding这些资源,然后在Pod中使用这个serviceaccount 即可。
示例:
创建一个deployment 和一个 serviceaccount,并在deployment中使用这个serviceaccount,然后再创建psp策略,再为psp创建权限role,然后用 rolebinding 将 role 和 serviceaccount绑定。这样修改psp策略就可以控制Pod的权限了。
psp-test.yaml:
apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: privileged annotations: seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' spec: privileged: true allowPrivilegeEscalation: true allowedCapabilities: - '*' volumes: - '*' hostNetwork: false # 修改true 或 false来控制Pod是否可用 hostNetwork hostPorts: - min: 0 max: 65535 hostIPC: true hostPID: true runAsUser: rule: 'RunAsAny' seLinux: rule: 'RunAsAny' supplementalGroups: rule: 'RunAsAny' fsGroup: rule: 'RunAsAny' --- apiVersion: v1 kind: ServiceAccount metadata: name: psp-sa --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: psp-role rules: - apiGroups: ['policy'] resources: ['podsecuritypolicies'] verbs: ['use'] resourceNames: - privileged --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: psp-rolebinding roleRef: kind: ClusterRole name: psp-role apiGroup: rbac.authorization.k8s.io subjects: - kind: ServiceAccount name: psp-sa namespace: default --- apiVersion: apps/v1 kind: Deployment metadata: name: psp-nginx namespace: default labels: app: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx hostNetwork: true serviceAccount: psp-sa
创建上面的资源并应用:
kubectl apply -f psp-test.yaml
如下可以看到deployment虽然创建了,但是READY数为0,并没有Pod被创建,因为这个Pod需要使用到hostNetwork,但是策略中是禁止使用的,所以创建不成功。
~]# kubectl get deployments.apps NAME READY UP-TO-DATE AVAILABLE AGE psp-nginx 0/1 0 0 21m
修改psp策略:hostNetwork的false改为true。
kubectl delete deployments.apps psp-nginx
删除之前的deployment再重新创建这个deployment。
kubectl apply -f psp-test.yaml
再次创建资源后查看:可以看到Pod已近被创建了。
~]# kubectl get pods NAME READY STATUS RESTARTS AGE psp-nginx-7cd85768f8-dn98v 0/1 ContainerCreating 0 22s