• K8s: 运行Pod时的root用户和非root用户的安全相关配置


    关于 root 用户


    1 )概述

    • docker 容器运行起来,默认是 root 用户
    • 这样运行起来后,基本不会遇到权限相关问题
    • 带来的问题是: 权限过大,被攻击后会遇到严峻挑战
    • 基于这个问题,K8s提出了特权用户的概念
    • 在容器启动时,虽然启动的是 root 用户,但是不具备所有root功能
    • 只是一个映射的root用户,如果不开启 privilege 试图修改系统关键信息
    • 是会报错的,加上 --privilege 之后,就是一个特权用户,就可以进行修改

    2 )正常场景

    • $ docker run -it busybox sh
    • $ whoami 这里显示 root
    • $ id -u 0
    • $ hostname db3437d25c87
    • $ sysctl kernel.hostname=wwwwwwww sysctl: error setting key ‘kernel.hostname’: Read-only file system

    3 )启用 privileged

    • $ docker run -it --privileged busybox sh
    • $ sysctl kernel.hostname=wwwwwwww kernel.hostname = wwwwwwww
    • $ hostname wwwwwwww

    4 )在 yaml 中配置 securityContext 和 privileged

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        securityContext:
          privileged: true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    非 root 用户

    • 对容器越权访问控制,K8s 提供 securityContext 这一概念
    • 它提供一个非root用户运行容器的能力
    • 容器对root用户本身是有一定自我保护能力的
    • root权限太大,更安全方式是设定好用户和组来运行

    1 )先不进行权限处理

    • 默认是root权限,但是root权限本身收到一定的限制
    • 但是root总是不太安全的
    • security.yaml
      apiVersion: v1  
      kind: Pod  
      metadata:
        name: security-context  
        labels:  
          name: security-context  
      spec:  
        volumes:  
          - name: security  
            emptyDir: {} # 这是一个 Pod 内部的临时目录  
        containers:  
          - name: busybox  
            image: busybox  
            command: ["sh", "-c", "sleep 1h"]  
            resources:  
              limits:  
                memory: "64Mi"  
                cpu: "500m"  
            volumeMounts:  
              - name: security # 注意,这个名字需要与卷定义中的 name 匹配  
                mountPath: /data/demo  
            securityContext:  
              privileged: false # 是否以特权模式运行容器  
              allowPrivilegeEscalation: false # 是否允许权限提升
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
    • $ kubectl apply -f security.yaml 创建 pod
      pod/security-context created
      
      • 1
    • $ kubectl get pod -w | grep secu 查询 pod 状态
      security-context   1/1     Running            0                 21s
      
      • 1
    • $ kubectl exec -it security-context -- sh 进入容器(pod内一个容器不用-c指定)
    • $ id 查看 id 信息
      uid=0(root) gid=0(root) groups=0(root),10(wheel)
      
      • 1
    • $ ps 查看进程
      PID   USER     TIME  COMMAND
          1 root      0:00 sh -c sleep 1h
         12 root      0:00 sh
         19 root      0:00 ps
      
      • 1
      • 2
      • 3
      • 4
    • $ cd /data/demo && ls -la
      total 0
      drwxrwxrwx    2 root     root             6 Apr 19 04:25 .
      drwxr-xr-x    3 root     root            18 Apr 19 04:26 ..
      
      • 1
      • 2
      • 3
    • 好,从上面可以看到都是 root 权限,现在我们进行修改

    2 )添加 securityContext 配置

    • 要为 Pod 设置安全性设置,可在 Pod 规约中包含 securityContext 字段
    • 为 Pod 所设置的安全性配置会应用到 Pod 中所有 Container 上
    • 清理刚才的pod, 并对之前 yaml 文件进行编辑
    • 在 security.yaml 中添加 securityContext 更多的配置
    • 注意这个配置的位置,在 spec 下面第一个位置
      spec:
        securityContext:
          runAsUser: 1000
          runAsGroup: 3000
          fsGroup: 2000
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 在配置文件中, runAsUser 字段指定 Pod 中的所有容器内的进程都使用用户 ID 1000 来运行
      • runAsGroup 字段指定所有容器中的进程都以主组 ID 3000 来运行
      • 如果忽略此字段,则容器的主组 ID 将是 root(0)
      • 当 runAsGroup 被设置时,所有创建的文件也会划归用户 1000 和组3000
      • 由于 fsGroup被设置,容器中所有进程也会是附组 ID 2000 的一部分
      • 卷 /data/demo 及在该卷中创建的任何文件的属主都会是组 ID 2000
    • 重新运行起来后,进入容器
    • $ kc exec -it security-context -- sh
    • $ id
      uid=1000 gid=3000 groups=2000,3000
      
      • 1
      • 你会看到 gid 值为 3000,也就是 runAsGroup 字段的值
      • 如果 runAsGroup 被忽略,则 gid 会取值 0(root)
      • 而进程就能够与 root 用户组所拥有以及要求 root 用户组访问权限的文件交互
    • $ ps
      PID   USER     TIME  COMMAND
          1 1000      0:00 sh -c sleep 1h
          7 1000      0:00 sh
         15 1000      0:00 ps
      
      • 1
      • 2
      • 3
      • 4
    • $ cd /data/demo && ls -la
      total 0
      drwxrwsrwx    2 root     2000             6 Apr 19 04:42 .
      drwxr-xr-x    3 root     root            18 Apr 19 04:42 ..
      
      • 1
      • 2
      • 3
    • 从上面可以看到用户权限变更了,这样在受到攻击的时候,会尽可能减少损失
  • 相关阅读:
    C++模板详解--函数模板及类模板
    Vue 指令、计算属性、侦听器
    Rust中FFI编程知识点整理总结
    【软件测试】软件测试的基础概念
    第2关:还原键盘输入(list)
    自回归策略是什么
    2022年CCPC桂林站C题Array Concatenation
    VMWare ESXi接口
    elementplus el-table(行列互换)转置
    day08|字符串题目part01
  • 原文地址:https://blog.csdn.net/Tyro_java/article/details/137960632