pod 权限配置

pod使用宿主节点的Linux命名空间

pod中的容器通常在分开的Linux命名空间中运行。 这些命名空间将容器中的进程与其他容器中,或者宿主机默认命名空间中的进程隔离开来。

一、在pod中使用宿主节点的网络命名空间

部分pod(特别是系统pod)需要在宿主节点的默认命名空间中运行,以允许它们看到和操作节点级别的资源和设备。例如,某个pod可能需要使用宿主节点上的网络适配器,而不是自己的虚拟网络设备。
 
在这种情况下,这个pod可以使用宿主节点的网络接口,而不是拥有自己独立的网络。这意味着这个pod没有自己的IP地址;如果这个pod中的某一进程绑定了某个端口,那么该进程将被绑定到宿主节点的端口上。
 
配置清单     
apiVersion: vl
  kind: Pod
  metadata:
    name: pod-with-host-network
spec:
  hostNetwork: true                #使用宿主节点的网络命名空间
  containers
  - name. dfse
  image: asdf
  command : ["/bin/sleep”,1000000”] 
View Code

通过将pod  spec中的hostNetwork设置为true实现。

 

二、绑定宿主节点上的端口而不使用宿主节点的网络命名空间

通过配置 pod spec containers ports 字段中某个容器某一端口的 hostPort 属性来实现。
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - image: docker.io/nginx
    name: asdf
    ports:
    - containersPorts: 8080          #可以通过pod  的Ip:8080 访问该pod 
      hostPort: 9000              #也可以通过Pod 所在节点的9000访问该pod
     protocol: TCP
View Code

 

三、hostPort pod 和通过 Node Port 服务暴露的 pod 区别

对于使用 hostPort ,到达宿主节点的端口的连接会被直接转发到 pod 的对应端口上:然而在 Node Port 服务中,到达宿主节点的端口的连接将被转发到随机选取的 pod 上(这个 pod 可能在其他节点上)。另外一个区别是,对于使用 hostPort 的pod ,仅有运行了这类 pod 的节点会绑定对应的端口;而 Node Port 类型的服务会在所有的节点上绑定端口,即使这个节点上没有运行对应的 pod。
还有一个区别就是 hostPort 的 pod 绑定了宿主节点上的 个特定端口,每个宿主节点只能调度一个这样的 pod 实例,因为两个进程不能绑定宿主机上的同一个端口。
 
Tips:
host Port 功能最初是用于暴露通过 DeamonSet 部署在每个节点上的系统服务。最初,这个功能也用于保证 pod 两个副本不被调度到同一节点上,但是现在有更好的方法来实现这一需求。
 

四、使用宿主节点的 PID IPC 命名空间

pod spec 中的 hostPID host IPC 选项与 hostNetwork 相似。当它们被设置为 true 时, pod 中的容器会使用宿主节点的 PID IPC 名空间 ,分别允许它们看到宿主机上的全部进程,或通过 IPC 机制与它们通信
apiVersion: v1
kind: Pod
metadata:
  name: pod-with-host-pid-and-ipc
spec:
  hostPID: true
  hostIPC: true
  containers:
  ... ...
View Code

配置节点的安全上下文

除了让 pod 使用宿主节点的 Linux 命名空间,还可以在 pod 或其所属容器的描述中通过 security Context 选项配置其他与安全性相关的特性。这个选项可以运用于整个 pod ,或者每个 pod 中单独的容器

安全上下文中可以配置的内容

指定容器中运行进程的用户(用户ID)
  阻止容器使用 root 户运行(容器的默认运行用户通常在其镜像中指定,所以可能需要阻止容器 root 用户运行)
  
  使用特权模式运行容器,使其对宿主节点的内核具有完全的访问权限
  
  与以上相反,通过添加或禁用内核功能,配置细粒度的内核访问权限
  
  设置 SELinux (Security Enhaced Linux 安全增强型 Linux )选项,加强对容器的限制。
  
  阻止进程写入容器的根文件系统
View Code

 

使用指定用户运行容器
默认情况运行容器的用户是root ,用户id 为0
apiVersion: v1
kind: Pod
metadata:
  name· pod-as-user-guest
spec·
  containers:
  - name: asdf
    image: wq55/lks
    command: ["..."]
    securityContext:
    runAsUser: 405          #通过指定用户id 来指定用户运行
View Code
 
阻止容器以 root 用户运行
使用 Dockerfile 配置镜像以root 用户启动,如果避免此情况,可以配置pod  如下:
apiVersion: v1
kind: Pod
metadata:
spec:
  containers:
  - name: asdf
    image: lkjl/sdf
    command: ["..."]
   securityContext:
   runAsNonRoot: true
View Code

 

使用特权模式运行 pod

有时 pod 需要做它们的宿主节点上能够做的任何事,例如操作被保护的系统设备,或使用其他在通常容器中不能使用的内核功能。

apiVersion: v1
kind: Pod
metadata:
spec:
  containers:
  - name: asdf
    image: lkjl/sdf
    command: ["..."]
   securityContext:
   privileged : true
View Code

 

为容器单独添加内核功能
相比于让容器运行在特权模式下以给予其无限的权限,一个更加安全的做法是只给予它使用真正需要的内核功能的权限。K8s允许为特定的容器添加内核功能,或禁用部分内核功能,以允许对容器进行更加精细的权限控制,限制攻击者潜在侵入的影响。
 
例如添加一个能够修改内核时间的功能
apiVersion: v1
kind: Pod
metadata:
spec:
  containers:
  - name: asdf
    image: lkjl/sdf
    command: ["..."]
   securityContext:
   capabilities:
         add
         -  SYS_TIME
View Code
注意 Linux内核功能的名称通常以CAP_开头。但在podspec中指定内核功能时,必须省略CAP_前缀。提示:: 可以在Linux手册中查阅Linux内核功能列表。
 
 
在容器中禁用内核功能
默认情况下容器拥有CAP_CHOWN权限,允许进程修改文件系统中文件的所有者。为了阻止容 器的此种行为,需要如以下代码清单所示,在容器的securityContext.capabilities.drop列表中加入此项,以禁用这个修改文件所有者的内核功能。
apiVersion: v1
kind: Pod
metadata:
spec:
  containers:
  - name: asdf
    image: lkjl/sdf
    command: ["..."]
   securityContext:
   capabilities:
         drop:
         - CHOWN
View Code

 

阻止对容器根文件系统的写入
因为安全原因你可能需要阻止容器中的进程对容器的根文件系统进行写入,仅允许它们写入挂载的存储卷。
apiVersion: v1
kind: Pod
metadata:
spec:
  containers:
  - name: asdf
    image: lkjl/sdf
    command: ["..."]
   securityContext:
   readOnlyRootFilesystem: true            #不允许容器写入根文件系统
   volumeMounts:
   - name: my-volume
     mountPath: /volume
     readOnly: false                        #允许写入挂载卷目录
  volumes: 
  - name: my-volume 
    emptyDir:
View Code

 

设置pod级别的安全上下文
以上的例子都是对单独的容器设置安全上下文。 这些选项中的一部分也可以从pod级别设定(通过pod.spec.securityContext属性)。 它们会作为pod中每一个容器的默认安全上下文, 但是会被容器级别的安全上下文覆盖。
下面将会介绍 pod级别安全上下文独有的内容 
Kubemetes 允许为pod 中所有容器指定 supplemental 组,以允许它们无论以哪个用户ID运行都可以共享文件 。这可以通过以下两个属性设置:
• fsGroup
• supplementalGroups
apiVersion: v1
kind: Pod
metadata:
spec:

  securityContext:

    fsGroup: 555

  supplementalGroups: [666,777]
  containers:

  - name: first
  image: lkjl/sdf
  command: ["..."]
  volumeMounts:
  - name: my-volume
    mountPath: /volume
    readOnly: false 

  - name: second
  image: lkjl/sdf
  command: ["..."]
  volumeMounts:
  - name: my-volume
    mountPath: /volume
    readOnly: false 
  volumes: 
  - name: my-volume 
    emptyDir:
View Code

安全上下文中的fsGroup属性当进程在存储卷中创建文件时起作用, 而 supplementalGroups属性定义了某个用户所关联的额外的用户组。

限制pod使用安全相关的特性

以上章节中的例子已经介绍了如何在部署 pod时在任一宿主节点上做任何想做的事。 比如, 部署一个特权模式的 pod 。 很明显, 需要有一种机制阻止用户使用其中的部分功能。 集群管理入员可以通过创建 PodSecurityPolicy 资源来限制对以上提到的安全相关的特性的使用。
 
PodSecurityPolicy资源介绍
PodSecurityPolicy 是一种集群级别(无命名空间)的资源, 它定义了用户能否在 pod 中使用各种安全相关的特性。 维护 PodSecurityPolicy 资源中配置策略的工作由集成在 API 服务器中的 PodSecurityPolicy 准入控制插件完成
当有人向 API 服务器发送 pod 资源时, PodSecurityPolicy 准入控制插件会将这个 pod 与已经配置的 PodSecurityPolicy 进行校验。 如果这个 pod 符合集群中已有安策略, 它会被接收并存入 etcd; 否则它会立即被拒绝。 这个插件也会根据安全策略中配置的默认值对 pod 进行修改。
 
对不同的用户与组分配不同的 PodSecurityPolicy
PodSecurityPolic 是集群级别的资源,这意味着它不能存储和应用在某一特定的命名空间上 这是否意味着它总是会应用在所有的命名空间上呢?不是的,因为这样会使得它们相 当难以应用。毕竟,系统 pod 经常需要允许做一些常规 pod 不应当做的事情

实现机制

对不同用户分配不同 PodSecurityPolicy 是通过RBAC 机制实现。这个方法是,创建你需要的 PodSecurityPolicy 资源,然后创建 ClusterRole 资源并通过名称将它指向不同的策略,以此使PodSecurityPoIicy 资源中的策略对不同
的用户或组生效 通过 ClusterRoleBinding 资源将特定的用户或组绑定到 ClusterRole上,当 PodSecurityPolicy 访问 控制ity插件需要决定是否接纳 pod 时,它只会考虑 pod 的用户可以访问到 PodS ecurityPolicy 中的策略。
 
实现过程
创建一个 PodSecurityPolicy
    apiVersion: extensions/vlbetal 
    kind: PodSecurityPolicy 
    spec: 
      volumes : 
      - emptyDir 
      - configMap 
      - secret 
      - downwardAPI 
      - persistentVolumeClaim
      
    kubectl get psp                    #查看已经创建得podSecrityPolicy

使用 RBAC 将不同的 PodSecurityPolicy 分配给不同用户
    创建Clusterrole
        kubectl create clusterrole psp-defaul t --verb=use  --resource=podsecuritypolicies  --resource-name=default
        注意: 你使用的动词是 use ,而非 get list watch 或类似动词
    创建 ClusterRoleBinding 资源而非 (有命名空间的)RoleBinding,绑定Clusterrole 到用户上
        kubectl create clusterrolebinding psp-bob --clusterrole=psp-privileged --user=bob
        
为kubectl 创建用户
    $ kubectl config set-credentials bob --username=bob  --password=password
    因为你使用了用户名和密码作为凭据 kubectl将对这两个用户使用基础 HTTP 认证进行认证(其他的认证方法包括 oken 客户端证书等)
    
使用不同用户创建 pod
    kubectl --user bob create -f pod-privileged.yaml
View Code

 

PodSecurityPolicy 可以做的事

• 是否允许 pod 使用宿主节点的 PID、 IPC、 网络命名空间
• pod 允许绑定的宿主节点端口
• 容器运行时允许使用的用户 ID
• 是否允许拥有特权模式容器的 pod
• 允许添加哪些内核功能, 默认添加哪些内核功能, 总是禁用哪些内核功能
• 允许容器使用哪些 SELinux 选项 • 容器是否允许使用可写的根文件系统
• 允许容器在哪些文件系统组下运行
• 允许 pod 使用哪些类型的存储卷
View Code
 
一个 PodSecurityPolicy 样例
apiVersion: extensions/vlbetal
kind: PodSecurityPolicy
metadata:
  name: default
spec:
  hostIPC: false
  hostPID: false
  hostPorts:
  - min: 10000
    max: 11000
  - min: 13000
    max: 14000
  privileged: false
  readOnlyRootFilesystem: true
  runAsUser:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  seLinux:
    rule: RunAsAny
  volumes:
  - '*'
  
  
View Code
了解 runAsUser、 fsGroup 和 supplementalGroup 策略
如果需要限制容器可以使用的用户和用户组ID, 可以将规则改为MustRunAs, 并指定允许使用的ID范围。
runAsUser: 
  rule: MustRunAs
  ranges: 
  - min: 2 
    max: 2 
fsGroup: 
  rule: MustRunAs
  ranges: 
  - min: 2 
    max: 10
  - min: 20
    max: 30
supplementalGroups: 
  rule: MustRunAs 
  ranges: 
  - min: 2 
    max: 10
  - min: 20
    max: 30  
View Code
如果pod spec试图将其中的任一字段设置为该范围之外的值,这个pod将不会被API服务器接收。
 
Notice:
修改策略对已经存在的pod无效,因为PodSecurityPolicy资原仅在创建和升级pod 时生效

部署镜像中用户 ID 在指定范围之外的 pod

与之前不同, API 服务器接收了这 pod, kube et 也运行了这个容器。PodSecurityPolicy 可以将硬编码覆盖到镜像中的用户 ID
 
runAsUser 字段中使用 mustRunAsNonRoot 规则
runAsUs er 宇段 中还可以 使用另-科 规则: mustRunAsNonRoot 。正名,它将阻止用户部署以 root 用户运行的容器。在此种情况下, spec 容器中必须指定 runAsUser 宇段,并且不能为 root 用户的 ID ),或者容器的镜像本身指
定了用一个非 的用户 ID 运行。这种做法的好处己经在之前介绍过。
 
配置允许、默认添加、禁止使用的内核功能
以下 个字段会影响容器可以使用的内核功能:
• allowedCapabilities
• defaultAddCapabilities
•requiredDropCapabilities
View Code

示例

apiVersion: extensions/vlbetal 
kind: PodSecurityPolicy 
spec:
  allowedCapabilities:
  - SYS_TIME                             #允许容器添 SYS_TIME功能
  defaultAddCapabilities
  - CHOWN                                 #为每个容器自动添CHOWN功能
  requiredDropCapabilites
  - SYS_ADMIN                             #要求容器禁用SYS_ADMIN和SYS_MODULE功能
  - SYS_MODULE                 
  
注:SYS_ADMIN 功能允许使用一系列的管理操作; SYS_MODULE 功能允许加载或卸载 inux 核模块
View Code
 
限制 pod 可以使用的存储卷类型
kind: PodSecurityPolicy 
spec: 
  volumes : 
  - emptyDir 
  - configMap 
  - secret 
  - downwardAPI 
  - persistentVolumeClaim
View Code
如果有多个 PodSecurityPolicy 资源, pod 可以使用 PodSecurityPolicy 中允许使用的任何一个存储卷类型(实际生效的是所有 volume 列表的并集〉。
 
posted @ 2020-01-17 11:28  fanggege  阅读(2925)  评论(0编辑  收藏  举报