Kubernetes:创建和分配Kubernetes Pod安全策略

简介: Kubernetes:创建和分配Kubernetes Pod安全策略

目录

Pod Security Policies(PSP)

Pod的安全策略配置

1.PodSecurityPolicy的工作机制

2.PodSecurityPolicy配置详情

2.1.特权模式相关配置

2.2.宿主机资源相关配置

2.3.用户和组相关配置

      2.4.提升权限相关配置

     2.5.Linux能力相关配置

    2.6.SELinux相关配置

    2.7.其他Linux相关配置

示例的PodSecurityPolicy安全策略配置

例1:基本没有限制的安全策略,允许创建任意安全设置的Pod。

例2:要求Pod运行用户为非特权用户;禁止提升权限;不允许使用宿主机网络、端口号、IPC等资源;限制可以使用的Volume类型,等等。

分配Kubernetes Pod安全策略

Security Context

Container-level Security Context

Container级别可以设置的安全策略类型

Pod-level Security Context

Pod级别可以设置的安全策略类型



Pod Security Policies(PSP)

Pod Security Policies(PSP)是集群级的Pod安全策略,自动为集群内的Pod和Volume设置Security Context。

使用PSP需要API Server开启extensions/v1beta1/podsecuritypolicy,并且配置PodSecurityPolicyadmission控制器。


Pod的安全策略配置

Pod 安全策略 是集群级别的资源,它能够控制 Pod 运行的行为,以及它具有访问什么的能力。

为了更精细地控制Pod对资源的使用方式,Kubernetes从1.4版本开始引入了PodSecurityPolicy资源对象对Pod的安全策略进行管理,并在1.10版本中升级为Beta版,到1.14版本时趋于成熟。


1.PodSecurityPolicy的工作机制

若想启用PodSecurityPolicy机制,则需要在kube-apiserver服务的启动参数--enable-admission-plugins中进行设置:

如果是高可用,所有apiserver均需要修改

kubectl edit pod -n kube-system kube-apiserver-k8s-master
--enable-admission-plugins=PodSecurityPolicy

kube-apiserver-k8s-master,值得是你apiserver组件的pod名称

在开启PodSecurityPolicy准入控制器后,Kubernetes默认不允许创建任何Pod,需要创建PodSecurityPolicy策略和相应的RBAC授权策略(Authorizing Policies),Pod才能创建成功。


例如,尝试创建如下Pod:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx


使用Kubectl命令创建时,系统将提示“禁止创建”的报错信息

接下来创建一个PodSecurityPolicy,配置文件psp-non-privileged.yaml的内容如下:

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: psp-non-privileged
spec:
  privileged: false # 不允许特权模式的Pod
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  runAsUser:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  volumes:
  - '*'


之后再次创建Pod既可成功。

上面的PodSecurityPolicy“psp-non-privileged”设置了privileged: false,表示不允许创建特权模式的Pod。

在下面的YAML配置文件pod-privileged.yaml中为Pod设置了特权模式:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    securityContext:
      privileged: true

创建Pod时,系统将提示“禁止创建特权模式的Pod”的报错信息.


2.PodSecurityPolicy配置详情

在PodSecurityPolicy对象中可以设置下列字段来控制Pod运行时的各种安全策略。

Pod 安全策略 由设置和策略组成,它们能够控制 Pod 访问的安全特征。这些设置分为如下三类:

  • 基于布尔值控制 :这种类型的字段默认为最严格限制的值。
  • 基于被允许的值集合控制 :这种类型的字段会与这组值进行对比,以确认值被允许。
  • 基于策略控制 :设置项通过一种策略提供的机制来生成该值,这种机制能够确保指定的值落在被允许的这组值中。


2.1.特权模式相关配置

privileged:是否允许Pod以特权模式运行。


2.2.宿主机资源相关配置

(1)hostPID:是否允许Pod共享宿主机的进程空间。

(2)hostIPC:是否允许Pod共享宿主机的IPC命名空间。

(3)hostNetwork:是否允许Pod使用宿主机网络的命名空间。

(4)hostPorts:是否允许Pod使用宿主机的端口号,可以通过hostPortRange字段设置允许使用的端口号范围,以【min,max】设置最小端口号和最大端口号。

(5)Volumes:允许Pod使用的存储卷Volume类型,设置为“*”表示允许使用任意Volume类型,建议至少允许Pod使用下列Volume类型。

  • configMap
  • downwardAPI
  • emptyDir
  • persistentVolumeClaim
  • secret
  • projected

(6)AllowedHostPaths:允许Pod使用宿主机的hostPath路径名称,可以通过pathPrefix字段设置路径的前缀,并可以设置是否为只读属性,例子如下。

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: allow-hostpath-volumes
spec:
  volumes:
  - hostPath
  allowedHostPaths:
  - pathPrefix: "/foo"
    readOnly: true

结果为允许Pod访问宿主机上以“/foo”为前缀的路径,包括“/foo”“/foo/”“/foo/bar”等,但不能访问“/fool”“/etc/foo”等路径,也不允许通过“/foo/../”表达式访问/foo的上层目录。


(7)FSGroup:设置允许访问某些Volume的Group ID范围,可以将规则(rule字段)设置为MustRunAs、MayRunAs或RunAsAny。

  • MustRunAs:需要设置Group ID的范围,例如1~65535,要求Pod的securityContext.fsGroup设置的值必须属于该Group ID的范围。
  • MayRunAs:需要设置Group ID的范围,例如1~65535,不强制要求Pod设置securityContext.fsGroup。
  • RunAsAny:不限制Group ID的范围,任何Group都可以访问Volume。


(8)ReadOnlyRootFilesystem:要求容器运行的根文件系统(root filesystem)必须是只读的。


(9)allowedFlexVolumes:对于类型为flexVolume的存储卷,设置允许使用的驱动类型,例子如下。

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: allow-flex-volumes
spec:
  volumes:
  - flexVolume
  allowedFlexVolumes:
  - driver: example/lvm
  - driver: example/cifs


2.3.用户和组相关配置

(1)RunAsUser:设置运行容器的用户ID(User ID)范围,规则字段(rule)的值可以被设置为MustRunAs、MustRunAsNonRoot或RunAsAny。

  • MustRunAs:需要设置User ID的范围,要求Pod的securityContext.runAsUser设置的值必须属于该User ID的范围。
  • MustRunAsNonRoot:必须以非root用户运行容器,要求Pod的securityContext.runAsUser设置一个非0的用户ID,或者镜像中在USER字段设置了用户ID,建议同时设置allowPrivilegeEscalation=false以避免不必要的提升权限操作。
  • RunAsAny:不限制User ID的范围,任何User都可以运行。

(2)RunAsGroup:设置运行容器的Group ID范围,规则字段的值可以被设置为MustRunAs、MustRunAsNonRoot或RunAsAny。

  • MustRunAs:需要设置Group ID的范围,要求Pod的securityContext.runAsGroup设置的值必须属于该Group ID的范围。
  • MustRunAsNonRoot:必须以非root组运行容器,要求Pod的securityContext.runAsUser设置一个非0的用户ID,或者镜像中在USER字段设置了用户ID,建议同时设置allowPrivilegeEscalation=false以避免不必要的提升权限操作。
  • RunAsAny:不限制Group ID的范围,任何Group的用户都可以运行

(3)SupplementalGroups:设置容器可以额外添加的Group ID范围,可以将规则(rule字段)设置为MustRunAs、MayRunAs或RunAsAny。

  • MustRunAs:需要设置Group ID的范围,要求Pod的securityContext.supplementalGroups设置的值必须属于该Group ID范围。
  • MayRunAs:需要设置Group ID的范围,不强制要求Pod设置securityContext.supplementalGroups。
  • RunAsAny:不限制Group ID的范围,任何supplementalGroups的用户都可以运行。


2.4.提升权限相关配置

(1)AllowPrivilegeEscalation:设置容器内的子进程是否可以提升权限,通常在设置非root用户(MustRunAsNonRoot)时进行设置。

(2)DefaultAllowPrivilegeEscalation:设置AllowPrivilegeEscalation的默认值,设置为disallow时,管理员还可以显式设置AllowPrivilegeEscalation来指定是否允许提升权限。


2.5.Linux能力相关配置

(1)AllowedCapabilities:设置容器可以使用的Linux能力列表,设置为“*”表示允许使用Linux的所有能力(如NET_ADMIN、SYS_TIME等)。

(2)RequiredDropCapabilities:设置不允许容器使用的Linux能力列表。

(3)DefaultAddCapabilities:设置默认为容器添加的Linux能力列表,例如SYS_TIME等,Docker建议默认设置的Linux能力请查看https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities


2.6.SELinux相关配置

seLinux:设置SELinux参数,可以将规则字段(rule)的值设置为MustRunAs或RunAsAny。

  • MustRunAs:要求设置seLinuxOptions,系统将对Pod的securityContext.seLinuxOptions设置的值进行校验。
  • RunAsAny:不限制seLinuxOptions的设置。


2.7.其他Linux相关配置

(1)AllowedProcMountTypes:设置允许的ProcMountTypes类型列表,可以设置allowedProcMountTypes或DefaultProcMount。

(2)AppArmor:设置对容器可执行程序的访问控制权限,详情请参考https://kubernetes.io/docs/tutorials/clusters/apparmor/#podsecuritypolicy-annotations

(3)Seccomp:设置允许容器使用的系统调用(System Calls)的profile。

(4)Sysctl:设置允许调整的内核参数,详情请参考https://kubernetes.io/docs/concepts/cluster-administration/sysctl-cluster/#podsecuritypolicy


示例的PodSecurityPolicy安全策略配置

例1:基本没有限制的安全策略,允许创建任意安全设置的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'


例2:要求Pod运行用户为非特权用户;禁止提升权限;不允许使用宿主机网络、端口号、IPC等资源;限制可以使用的Volume类型,等等。

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
  annotations:
    seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default'
    apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default'
    seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default'
    apparmor.security.beta.kubernetes.io/dafaultProfileName: 'runtime/default'
spec:
  privileged: false
  allowPrivilegeEscalation: false
  requiredDropCapabilities:
  - ALL
  volumes:
  - 'configMap'
  - 'emptyDir'
  - 'projected'
  - 'secret'
  - 'downwardAPI'
  - 'persistentVolumeClaim'
  hostNetwork: false
  hostIPC: false
  hostPID: false
  runAsUser:
    rule: 'MustRunAsNonRoot'
  seLinux:
    rule: 'MustRunAs'
    ranges:
    - min: 1
      max: 65535
  fsGroup:
    rule: 'MustRunAs'
    ranges:
    - min: 1
      max: 65535
  readOnlyRootFilesystem: false


分配Kubernetes Pod安全策略

Kubernetes建议使用RBAC授权机制来设置针对Pod安全策略的授权,通常应该对Pod的ServiceAccount进行授权。

角色的访问控制(RBAC)是kubernetes标准的授权模式,并且很容应用于Pod安全策略。借助RBAC,你可以将Pod安全策略分配给应用。

为此,我们将创建一个新的YAML文件,该文件不仅会创建集群范围的角色(使用ClusterRole定义),还将创建集群绑定(使用ClusterRoleBinding定义),以向每个经过身份验证的用户授予访问权限。

例如,可以创建如下ClusterRole(也可以创建Role)并将其设置为允许使用PodSecurityPolicy:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: <role name>
rules:
- apiGroup: ['policy']
  resources: ['podsecuritypolicies']
  verbs: ['use']
  resourceNames:
  - <list of policies to authorize>  # 允许使用的PodSecurityPolicy列表


然后创建一个ClusterRoleBinding与用户和ServiceAccount进行绑定:

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: <binding name>
roleRef:
  kind: ClusterRole
  name: <roke name>  # 之前创建的ClusterRole名称
  apiGroup: rbac.authorization.k8s.io
subjects:
# 对特定Namespace中的ServiceAccount进行授权
- kind: ServiceAccount
  name: <authorized servie account name> # ServiceAccount 的名称
  namespace: <authorized pod namespace> # Namespace的名称
# 对特定用户进行授权(不推荐)
- kind: User
  apiGroup: rbac.authorization.k8s.io
  name: <authorized user name>  # 用户名


也可以创建RoleBinding对与该RoleBinding相同的Namespace中的Pod进行授权,通常可以与某个系统级别的Group关联配置,例如:

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: <binding name>
  namespace: <binding namespace>  # 该RoleBinding 所属的Namespace
roleRef:
  kind: Role
  name: <role name>
  apiGroup: rbac.authorization.k8s.io
subjects:
# 授权该Namespace中的全部ServiceAccount
- kind: Group
  apiGroup: rbac.authorization.k8s.io
  name: system:serviceaccounts
# 授权该Namespace中的全部哦用户
- kind: Group
  apiGroup: rbac.authorization.k8s.io
  name: system:authenticated


Security Context

通过上文,我们了解了PodSecurityPolicy策略,知道了

  • 在系统管理员对Kubernetes集群中设置了PodSecurityPolicy策略之后,系统将对Pod和Container级别的安全设置进行校验,对于不满足PodSecurityPolicy安全策略的Pod,系统将拒绝创建。

但除此之外还有个,securityContext

  • Pod和容器的安全策略可以在Pod或Container的securityContext字段中进行设置,如果在Pod和Container级别都设置了相同的安全类型字段,容器将使用Container级别的设置。

Security Context的目的是限制不可信容器的行为,保护系统和其他容器不受其影响。

要为Pod指定安全设置,请securityContext在Pod规范中包括该字段。该securityContext字段是 PodSecurityContext对象。

Kubernetes提供了三种配置Security Context的方法:

  • Container-level Security Context:仅应用到指定的容器
  • Pod-level Security Context:应用到Pod内所有容器以及Volume
  • Pod Security Policies(PSP):应用到集群内部所有Pod以及Volume


Container-level Security Context

Container-level Security Context仅应用到指定的容器上,并且不会影响Volume。


Container级别可以设置的安全策略类型

  • runAsUser:容器内运行程序的用户ID。
  • runAsGroup:容器内运行程序的用户组ID。
  • runAsNonRoot:是否必须以非root用户运行程序。
  • privileged:是否以特权模式运行。
  • allowPrivilegeEscalation:是否允许提升权限。
  • readOnlyRootFilesystem:根文件系统是否为只读属性。
  • capabilities:Linux能力列表。
  • seLinuxOptions:SELinux相关设置。


比如

例1:Container级别的安全设置,作用于特定的容器。

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo-2
spec:
  securityContext:
    runAsUser: 1000
  containers:
  - name: sec-ctx-demo-2
    image: tomcat
    securityContext:
      runAsUser: 2000
      allowPrivilegeEscalation: false


创建该Pod之后进入容器环境,查看到运行进程的用户ID为2000:


例2:为Container设置可用的Linux能力,为容器设置允许使用的Linux能力包括NET_ADMIN和SYS_TIME。

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo-3
spec:
  containers:
  - name: sec-ctx-3
    image: tomcat
    securityContext:
      capabilities:
        add: ["NET_ADMIN","SYS_TIME"]

 

创建该Pod之后进入容器环境,查看1号进程的Linux能力设置:


Pod-level Security Context

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

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
  volumes:
  - name: sec-ctx-vol
    emptyDir: {}
  containers:
  - name: sec-ctx-demo
    image: tomcat
    volumeMounts:
    - name: sec-ctx-vol
      mountPath: /data/demo
    securityContext:
      allowPrivilegeEscalation: false

 

在spec.securityContext中设置了如下参数。

  • runAsUser=1000:所有容器都将以User ID 1000运行程序,所有新生成文件的User ID也被设置为1000。
  • runAsGroup=3000:所有容器都将以Group ID 3000运行程序,所有新生成文件的Group ID也被设置为3000。
  • fsGroup=2000:挂载的卷“/data/demo”及其中创建的文件都将属于Group ID 2000。
  • 创建该Pod之后进入容器环境,查看到运行进程的用户ID为1000:
  • 查看从Volume挂载到容器的/data/demo目录,其Group ID为2000
  • 在该目录下创建一个新文件,可见其用户ID为1000,组ID为2000:


Pod级别可以设置的安全策略类型

  • runAsUser:容器内运行程序的用户ID。
  • runAsGroup:容器内运行程序的用户组ID。
  • runAsNonRoot:是否必须以非root用户运行程序。
  • fsGroup:SELinux相关设置。
  • seLinuxOptions:SELinux相关设置。
  • supplementalGroups:允许容器使用的其他用户组ID。
  • sysctls:设置允许调整的内核参数。


参考链接:

https://kubernetes.io/docs/tasks/configure-pod-container/security-context/

https://kubernetes.io/zh/docs/concepts/policy/pod-security-policy/

https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#securitycontext-v1-core


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
20天前
|
存储 Kubernetes Docker
【赵渝强老师】Kubernetes中Pod的基础容器
Pod 是 Kubernetes 中的基本单位,代表集群上运行的一个进程。它由一个或多个容器组成,包括业务容器、基础容器、初始化容器和临时容器。基础容器负责维护 Pod 的网络空间,对用户透明。文中附有图片和视频讲解,详细介绍了 Pod 的组成结构及其在网络配置中的作用。
【赵渝强老师】Kubernetes中Pod的基础容器
|
20天前
|
运维 Kubernetes Shell
【赵渝强老师】K8s中Pod的临时容器
Pod 是 Kubernetes 中的基本调度单位,由一个或多个容器组成,包括业务容器、基础容器、初始化容器和临时容器。临时容器用于故障排查和性能诊断,不适用于构建应用程序。当 Pod 中的容器异常退出或容器镜像不包含调试工具时,临时容器非常有用。文中通过示例展示了如何使用 `kubectl debug` 命令创建临时容器进行调试。
|
20天前
|
Kubernetes 调度 容器
【赵渝强老师】K8s中Pod中的业务容器
Pod 是 Kubernetes 中的基本调度单元,由一个或多个容器组成。除了业务容器,Pod 还包括基础容器、初始化容器和临时容器。本文通过示例介绍如何创建包含业务容器的 Pod,并提供了一个视频讲解。示例中创建了一个名为 &quot;busybox-container&quot; 的业务容器,并使用 `kubectl create -f firstpod.yaml` 命令部署 Pod。
|
20天前
|
Kubernetes 容器 Perl
【赵渝强老师】K8s中Pod中的初始化容器
Kubernetes的Pod包含业务容器、基础容器、初始化容器和临时容器。初始化容器在业务容器前运行,用于执行必要的初始化任务。本文介绍了初始化容器的作用、配置方法及优势,并提供了一个示例。
|
14天前
|
Kubernetes 监控 Cloud Native
Kubernetes集群的高可用性与伸缩性实践
Kubernetes集群的高可用性与伸缩性实践
47 1
|
2月前
|
JSON Kubernetes 容灾
ACK One应用分发上线:高效管理多集群应用
ACK One应用分发上线,主要介绍了新能力的使用场景
|
2月前
|
Kubernetes 持续交付 开发工具
ACK One GitOps:ApplicationSet UI简化多集群GitOps应用管理
ACK One GitOps新发布了多集群应用控制台,支持管理Argo CD ApplicationSet,提升大规模应用和集群的多集群GitOps应用分发管理体验。
|
2月前
|
Kubernetes Ubuntu Linux
Centos7 搭建 kubernetes集群
本文介绍了如何搭建一个三节点的Kubernetes集群,包括一个主节点和两个工作节点。各节点运行CentOS 7系统,最低配置为2核CPU、2GB内存和15GB硬盘。详细步骤包括环境配置、安装Docker、关闭防火墙和SELinux、禁用交换分区、安装kubeadm、kubelet、kubectl,以及初始化Kubernetes集群和安装网络插件Calico或Flannel。
171 4
|
2月前
|
Kubernetes Cloud Native 云计算
云原生之旅:Kubernetes 集群的搭建与实践
【8月更文挑战第67天】在云原生技术日益成为IT行业焦点的今天,掌握Kubernetes已成为每个软件工程师必备的技能。本文将通过浅显易懂的语言和实际代码示例,引导你从零开始搭建一个Kubernetes集群,并探索其核心概念。无论你是初学者还是希望巩固知识的开发者,这篇文章都将为你打开一扇通往云原生世界的大门。
128 17
|
2月前
|
Kubernetes 应用服务中间件 nginx
搭建Kubernetes v1.31.1服务器集群,采用Calico网络技术
在阿里云服务器上部署k8s集群,一、3台k8s服务器,1个Master节点,2个工作节点,采用Calico网络技术。二、部署nginx服务到k8s集群,并验证nginx服务运行状态。
650 1