Security Context介绍
- Pod 定义包含了一个安全上下文,可以定义运行pod时我的权限是什么,比如是否能访问主机文件,是否能访问主机网络,是否允许以root用户运行等。
- Pod 安全策略可以限制哪些用户或服务帐户的安全上下文设置。例如:Pod 的安全策略可以限制卷挂载,尤其是 hostpath,这些都是 Pod 应该控制的一些方面。
- 一般来说,大多数应用程序需要限制对主机资源的访问,他们可以在不能访问主机信息的情况下成功以根进程(UID O)运行。但是,考虑到与 root 用户相关的特权,在编写应用程序容器时,你应该使用非 root 用户运行。
Kubernetes 提供了三种配置 Security Context 的方法:
- Container-level Security Context:仅应用到指定的容器。
- Pod-level Security Context:应用到 Pod 内所有容器以及 Volume。
- Pod Security Policies (PSP):应用到集群内部所有 Pod 以及 Volume。
Container-level Security Context
仅应用到指定的容器上,并且不会影响 Volume。
下图就是容器级别的安全上下文,定义了容器的用户是1001,以非root用户运行。
如果是privileged: true,那么容器就会以root用户运行。一般是禁用的。但是一些特殊情况也会开启,比如calico-node,它会把CNI文件推送到主机上,还会修改主机的网络配置。
Pod-level Security Context
应用到Pod内所有容器,并且还会影响 Volume(包括 fsGroup 和 selinuxOptions)
securityContext:
fsGroup: 1234
supplementalGroups: [5678]
seLinuxOptions:
level: "s0:c123,c456"
Pod Security Policies (PSP)
集群级的 Pod 安全策略,自动为集群内的 Pod 和 Volume 设置
Security Context。
实例
- 定义默认psp策略。否则开启psp集群无法工作。
privileged.yamlapiVersion: 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'
restricted.yaml
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' apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' spec: privileged: false # Required to prevent escalations to root. allowPrivilegeEscalation: false requiredDropCapabilities: - ALL # Allow core volume types. volumes: - 'configMap' - 'emptyDir' - 'projected' - 'secret' - 'downwardAPI' # Assume that ephemeral CSI drivers & persistentVolumes set up by the cluster admin are safe to use. - 'csi' - 'persistentVolumeClaim' - 'ephemeral' 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
privileged-binding.yaml
定义了可以使用privileged这个psp的ClusterRole,并授权给kube-system,让kubelet有权限来操作pod。apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: privileged-psp rules: - apiGroups: - policy resourceNames: - privileged resources: - podsecuritypolicies verbs: - use --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: kube-system-psp namespace: kube-system roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: privileged-psp subjects: - apiGroup: rbac.authorization.k8s.io kind: Group name: system:nodes namespace: kube-system - apiGroup: rbac.authorization.k8s.io kind: Group name: system:serviceaccounts:kube-system
k apply -f .
- 开启psp,编辑kube-apiserver.yaml
pod会自动重建 - 测试psp是否能限制创建pod
kubectl create namespace psp-example # 创建serviceaccount kubectl create serviceaccount -n psp-example fake-user # 绑定edit的clusterrole给fake-user kubectl create rolebinding -n psp-example fake-editor --clusterrole=edit --serviceaccount=psp-example:fake-user
- 创建别名
# 以admin用户操作psp-example namespace alias kubectl-admin='kubectl -n psp-example' # 以fake-user用户操作psp-example namespace alias kubectl-user='kubectl --as=system:serviceaccount:psp-example:fake-user -n psp-example'
- 创建privileged: false的psp
cat example-psp.yaml apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: example spec: privileged: false # Don't allow privileged pods! seLinux: rule: RunAsAny supplementalGroups: rule: RunAsAny runAsUser: rule: RunAsAny fsGroup: rule: RunAsAny volumes: - '*' k apply -f example-psp.yaml
- 用kube-user测试创建pod。
kubectl-user create -f- <<EOF apiVersion: v1 kind: Pod metadata: name: pause spec: containers: - name: pause image: k8s.gcr.io/pause EOF
- 测试kube-user的权限。
kubectl-user auth can-i use podsecuritypolicy/example
- 创建role,可以使用example psp
kubectl-admin create role psp:unprivileged \ --verb=use \ --resource=podsecuritypolicy \ --resource-name=example
- 绑定role给fake-user
kubectl-admin create rolebinding fake-user:psp:unprivileged \ --role=psp:unprivileged \ --serviceaccount=psp-example:fake-user
- 再次测试权限。
- 创建pod成功
总结
PSP的主要作用是定义一个全局维度的通用策略,policy中定义pod以什么样的角色运行,如果有用户需要这样的角色,那么就需要定义clusterrole,clusterrolebinding,把role和用户进行绑定,用户才能正确的使用psp,admission controller校验才能通过。