跳转至

04微服务漏洞最小化

考试大纲

微服务漏洞最小化:20%

  • 设置适当的 OS 级安全域,例如使用 PSP, OPA,安全上下文
  • 管理 Kubernetes 机密
  • 在多租户环境中使用容器运行时(例如 gvisor, kata 容器)
  • 使用 mTLS 实现 Pod 对 Pod 加密

SecurityContext 安全容器配置

题目描述:

  • 按照如下要求修改 sec-ns 命名空间里的 Deployment secdep

一、用 ID 为 30000 的用户启动容器(设置用户 ID 为: 30000)

二、不允许进程获得超出其父进程的特权(禁止 allowPrivilegeEscalation

三、以只读方式加载容器的根文件系统(对根文件的只读权限)

官方文档:

参考解答:

编辑 secdep Deployment

kubectl edit deployments.apps -n sec-ns secdep

spec.containers 中加入(注意 2 个容器)

securityContext:
  allowPrivilegeEscalation: false
  readOnlyRootFilesystem: true
  runAsUser: 30000

创建 Sercrets

题目描述:

  • 在 namespace istio-system 中获取名为 db1-test 的现有 secret 的内容;将 username 字段存储在名为 /cks/sec/user.txt 的文件中,并将 password 字段存储在名为 /cks/sec/pass.txt 的文件中。

注意:你必须创建以上两个文件,他们还不存在。

注意:不要在以下步骤中使用/修改先前创建的文件,如果需要,可以创建新的临时文件。

  • istio-system namespace 中创建一个名为 db2-test 的新 secret,内容如下:

username : production-instance

password : KvLftKgs4aVH

  • 最后,创建一个新的 Pod,它可以通过卷访问 secret db2-test

Pod 名称 secret-pod

Namespace istio-system

容器名 dev-container

镜像 nginx

卷名 secret-volume

挂载路径 /etc/secret

官方文档:

参考解答:

查看 namespace istio-system中的 db1-test 的内容

# kubectl get secrets -n istio-system db1-test -oyaml

apiVersion: v1
data:
  password: aGVsbG8=
  username: ZGIx
kind: Secret
metadata:
  creationTimestamp: "2023-05-21T14:58:44Z"
  name: db1-test
  namespace: istio-system
  resourceVersion: "16898"
  uid: bed8df2e-5c4d-4543-80a1-ba2392545510
type: Opaque

解密用户名和密码,并放到对应的文件中

# 解密用户名
echo -n 'ZGIx' | base64 -d > /cks/sec/user.txt

# 解密密码
echo -n 'aGVsbG8=' | base64 -d > /cks/sec/pass.txt

创建新 Secret

kubectl create secret generic db-test \
--from-literal=username=production-instance \
--from-literal=password=KvLftKgs4aVH \
-n istio-system

创建 Pod,使用挂载

# secret-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: secret-pod
  namespace: istio-system
spec:
  containers:
  - image: nginx
    name: dev-container
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/secret
  volumes:
  - name: secret-volume
    secret:
      secretName: db2-test

# 创建该pod
kubectl create -f secret-pod.yaml

沙箱运行容器 gVisor(RuntimeClass)

题目描述:

  • 该集群使用 containerd 作为 CRI 运行时。containerd 的默认运行时处理程序是 runc。containerd 已准备好支持额外的运行时处理程序 runsc(gVisor)

  • 使用名为 runsc 的现有运行时处理程序,创建一个名为 untrusted 的 RuntimeClass

  • 更新 namespace server 中的所有 Pod 以在 gVisor 上运行。您可以在 /cks/gVisor/rc.yaml 中找到一个模版清单

# /cks/gVisor/rc.yaml
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:

官方文档:

RuntimeClass:是一个让 Pod 选择容器运行时的一个特性,用于多运行时环境

可以在不同的 Pod 设置不同的 RuntimeClass,以提供性能与安全性之间的平衡。 例如,如果你的部分工作负载需要高级别的信息安全保证,你可以决定在调度这些 Pod 时尽量使它们在使用硬件虚拟化的容器运行时中运行。 这样,你将从这些不同运行时所提供的额外隔离中获益,代价是一些额外的开销

用户发布创建 Pod 请求 ——>Master 集群将请求分配到 Node 节点 ——>Node 节点通过 kubelet,来分析采用哪个 Runtime 进行 Pod 创建

runtime运行时.webp

参考解答:

配置 RuntimeClass

创建 gvisorRuntimeClass.yaml文件

# RuntimeClass 定义于 node.k8s.io API 组
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  # 用来引用 RuntimeClass 的名字
  # RuntimeClass 是一个集群层面的资源
  name: untrusted
# 对应的 CRI 配置的名称
handler: runsc

创建 RuntimeClass.yaml

kubectl create -f gvisorRuntimeClass.yaml

修改 Pod 的 RuntimeClass

apiVersion: v1
kind: Pod
metadata:
  namespace: client
spec:
  runtimeClassName: untrusted
  containers:
    - name: foo
      image: janedoe/awesomeapp:v1

这一设置会告诉 kubelet 使用所指的 RuntimeClass 来运行该 Pod。 如果所指的 RuntimeClass 不存在或者 CRI 无法运行相应的 handler, 那么 Pod 将会进入 Failed 终止阶段