k8s

PSP

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用户运行。
file

如果是privileged: true,那么容器就会以root用户运行。一般是禁用的。但是一些特殊情况也会开启,比如calico-node,它会把CNI文件推送到主机上,还会修改主机的网络配置。
file

Pod-level Security Context

应用到Pod内所有容器,并且还会影响 Volume(包括 fsGroup 和 selinuxOptions)

securityContext:
    fsGroup: 1234
    supplementalGroups: [5678]
    seLinuxOptions:
    level: "s0:c123,c456"

file

Pod Security Policies (PSP)

集群级的 Pod 安全策略,自动为集群内的 Pod 和 Volume 设置
Security Context。
file

实例

  1. 定义默认psp策略。否则开启psp集群无法工作。
    privileged.yaml

    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'

    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 .

    file

  2. 开启psp,编辑kube-apiserver.yaml
    file
    pod会自动重建
  3. 测试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

    file

  4. 创建别名
    # 以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'

    file

  5. 创建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

    file

  6. 用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

    file

  7. 测试kube-user的权限。
    kubectl-user auth can-i use podsecuritypolicy/example

    file

  8. 创建role,可以使用example psp
    kubectl-admin create role psp:unprivileged \
    --verb=use \
    --resource=podsecuritypolicy \
    --resource-name=example

    file

  9. 绑定role给fake-user
    kubectl-admin create rolebinding fake-user:psp:unprivileged \
    --role=psp:unprivileged \
    --serviceaccount=psp-example:fake-user

    file

  10. 再次测试权限。
    file
  11. 创建pod成功
    file

总结

PSP的主要作用是定义一个全局维度的通用策略,policy中定义pod以什么样的角色运行,如果有用户需要这样的角色,那么就需要定义clusterrole,clusterrolebinding,把role和用户进行绑定,用户才能正确的使用psp,admission controller校验才能通过。

分类: k8s
0 0 投票数
文章评分
订阅评论
提醒
guest

0 评论
最旧
最新 最多投票
内联反馈
查看所有评论

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部
0
希望看到您的想法,请您发表评论x