7.5. 管理 seccomp 配置集

创建和管理 seccomp 配置集,并将它们绑定到工作负载。

重要

Security Profiles Operator 仅支持 Red Hat Enterprise Linux CoreOS (RHCOS) worker 节点。不支持 Red Hat Enterprise Linux (RHEL) 节点。

7.5.1. 创建 seccomp 配置集

使用 SeccompProfile 对象来创建配置集。

seccompProfile 对象可以限制容器内的系统调用,限制应用程序的访问。

流程

  1. 运行以下命令来创建项目:

    $ oc new-project my-namespace
  2. 创建 SeccompProfile 对象:

    apiVersion: security-profiles-operator.x-k8s.io/v1beta1
    kind: SeccompProfile
    metadata:
      namespace: my-namespace
      name: profile1
    spec:
      defaultAction: SCMP_ACT_LOG

seccomp 配置集将保存在 /var/lib/kubelet/seccomp/operator/<namespace>/<name>.json 中。

init 容器创建 Security Profiles Operator 的根目录,以便在没有 root 组或用户 ID 权限的情况下运行 Operator。会创建一个符合链接,从无根配置存储 /var/lib/openshift-security-profiles 到 kubelet root /var/lib/kubelet/seccomp/operator 中的默认 seccomp root 路径。

7.5.2. 将 seccomp 配置集应用到 pod

创建 pod 以应用其中一个创建的配置集。

流程

  1. 创建定义 securityContext 的 pod 对象:

    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pod
    spec:
      securityContext:
        seccompProfile:
          type: Localhost
          localhostProfile: operator/my-namespace/profile1.json
      containers:
        - name: test-container
          image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
  2. 运行以下命令,查看 seccompProfile.localhostProfile 属性的配置集路径:

    $ oc -n my-namespace get seccompprofile profile1 --output wide

    输出示例

    NAME       STATUS     AGE   SECCOMPPROFILE.LOCALHOSTPROFILE
    profile1   Installed  14s   operator/my-namespace/profile1.json

  3. 运行以下命令,查看 localhost 配置集的路径:

    $ oc get sp profile1 --output=jsonpath='{.status.localhostProfile}'

    输出示例

    operator/my-namespace/profile1.json

  4. localhostProfile 输出应用到补丁文件:

    spec:
      template:
        spec:
          securityContext:
            seccompProfile:
              type: Localhost
              localhostProfile: operator/my-namespace/profile1.json
  5. 运行以下命令,将配置集应用到任何其他工作负载,如 Deployment 对象:

    $ oc -n my-namespace patch deployment myapp --patch-file patch.yaml --type=merge

    输出示例

    deployment.apps/myapp patched

验证

  • 运行以下命令确认配置集是否已正确应用:

    $ oc -n my-namespace get deployment myapp --output=jsonpath='{.spec.template.spec.securityContext}' | jq .

    输出示例

    {
      "seccompProfile": {
        "localhostProfile": "operator/my-namespace/profile1.json",
        "type": "localhost"
      }
    }

7.5.2.1. 使用 ProfileBindings 将工作负载绑定到配置集

您可以使用 ProfileBinding 资源将安全配置集绑定到容器的 SecurityContext

流程

  1. 要将使用 quay.io/security-profiles-operator/test-nginx-unprivileged:1.21 镜像的 pod 绑定到示例 SeccompProfile 配置集,请在与 pod 和 SeccompProfile 对象相同的命名空间中创建一个 ProfileBinding 对象:

    apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
    kind: ProfileBinding
    metadata:
      namespace: my-namespace
      name: nginx-binding
    spec:
      profileRef:
        kind: SeccompProfile 1
        name: profile 2
      image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
    1
    kind: 变量引用配置集的名称。
    2
    name: 变量引用配置集的名称。
  2. 运行以下命令,使用 enable-binding=true 标记命名空间:

    $ oc label ns my-namespace spo.x-k8s.io/enable-binding=true
  3. 定义名为 test-pod.yaml 的 pod:

    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pod
    spec:
      containers:
      - name: test-container
        image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
  4. 创建 pod:

    $ oc create -f test-pod.yaml
    注意

    如果 pod 已存在,您必须重新创建 pod 才能使绑定正常工作。

验证

  • 运行以下命令确认 pod 会继承 ProfileBinding

    $ oc get pod test-pod -o jsonpath='{.spec.containers[*].securityContext.seccompProfile}'

    输出示例

    {"localhostProfile":"operator/my-namespace/profile.json","type":"Localhost"}

7.5.3. 从工作负载记录配置集

Security Profiles Operator 可以使用 ProfileRecording 对象记录系统调用,从而更轻松地为应用程序创建基准配置集。

当使用日志增强器来记录 seccomp 配置集时,请验证日志增强功能是否已启用。如需更多信息,请参阅附加资源

注意

具有 privileged: true 安全上下文保留的容器可防止基于日志的记录。特权容器不受到 seccomp 策略的影响,基于日志的记录利用特殊的 seccomp 配置集来记录事件。

流程

  1. 运行以下命令来创建项目:

    $ oc new-project my-namespace
  2. 运行以下命令,使用 enable-recording=true 标记命名空间:

    $ oc label ns my-namespace spo.x-k8s.io/enable-recording=true
  3. 创建包含 recorder: logs 变量的 ProfileRecording 对象:

    apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
    kind: ProfileRecording
    metadata:
      namespace: my-namespace
      name: test-recording
    spec:
      kind: SeccompProfile
      recorder: logs
      podSelector:
        matchLabels:
          app: my-app
  4. 创建一个工作负载来记录:

    apiVersion: v1
    kind: Pod
    metadata:
      namespace: my-namespace
      name: my-pod
      labels:
        app: my-app
    spec:
      containers:
        - name: nginx
          image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
          ports:
            - containerPort: 8080
        - name: redis
          image: quay.io/security-profiles-operator/redis:6.2.1
  5. 输入以下命令确认 pod 处于 Running 状态:

    $ oc -n my-namespace get pods

    输出示例

    NAME     READY   STATUS    RESTARTS   AGE
    my-pod   2/2     Running   0          18s

  6. 确认增强器表示它接收这些容器的审计日志:

    $ oc -n openshift-security-profiles logs --since=1m --selector name=spod -c log-enricher

    输出示例

    I0523 14:19:08.747313  430694 enricher.go:445] log-enricher "msg"="audit" "container"="redis" "executable"="/usr/local/bin/redis-server" "namespace"="my-namespace" "node"="xiyuan-23-5g2q9-worker-eastus2-6rpgf" "pid"=656802 "pod"="my-pod" "syscallID"=0 "syscallName"="read" "timestamp"="1684851548.745:207179" "type"="seccomp"

验证

  1. 删除 pod:

    $ oc -n my-namepace delete pod my-pod
  2. 确认 Security Profiles Operator 协调两个 seccomp 配置集:

    $ oc get seccompprofiles -lspo.x-k8s.io/recording-id=test-recording -n my-namespace

    seccompprofile 的输出示例

    NAME                   STATUS      AGE
    test-recording-nginx   Installed   2m48s
    test-recording-redis   Installed   2m48s

7.5.3.1. 每个容器配置集实例合并

默认情况下,每个容器实例记录都记录到单独的配置文件中。Security Profiles Operator 可将每个容器配置集合并到一个配置集中。当使用 ReplicaSetDeployment 对象部署应用程序时,合并配置集很有用。

流程

  1. 编辑 ProfileRecording 对象使其包含 mergeStrategy: containers 变量:

    apiVersion: security-profiles-operator.x-k8s.io/v1alpha1
    kind: ProfileRecording
    metadata:
      # The name of the Recording is the same as the resulting SeccompProfile CRD
      # after reconciliation.
      name: test-recording
      namespace: my-namespace
    spec:
      kind: SeccompProfile
      recorder: logs
      mergeStrategy: containers
      podSelector:
        matchLabels:
          app: sp-record
  2. 运行以下命令标记命名空间:

    $ oc label ns my-namespace security.openshift.io/scc.podSecurityLabelSync=false pod-security.kubernetes.io/enforce=privileged pod-security.kubernetes.io/audit=privileged pod-security.kubernetes.io/warn=privileged --overwrite=true
  3. 使用以下 YAML 创建工作负载:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deploy
      namespace: my-namespace
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: sp-record
      template:
        metadata:
          labels:
            app: sp-record
        spec:
          serviceAccountName: spo-record-sa
          containers:
          - name: nginx-record
            image: quay.io/security-profiles-operator/test-nginx-unprivileged:1.21
            ports:
            - containerPort: 8080
  4. 要记录单个配置集,请运行以下命令删除部署:

    $ oc delete deployment nginx-deploy -n my-namespace
  5. 要合并配置集,请运行以下命令删除配置集记录:

    $ oc delete profilerecording test-recording -n my-namespace
  6. 要启动合并操作并生成结果配置集,请运行以下命令:

    $ oc get seccompprofiles -lspo.x-k8s.io/recording-id=test-recording -n my-namespace

    seccompprofiles 的输出示例

    NAME                          STATUS       AGE
    test-recording-nginx-record   Installed    55s

  7. 要查看任何容器使用的权限,请运行以下命令:

    $ oc get seccompprofiles test-recording-nginx-record -o yaml

其他资源