K8S-CKS模拟

K8S-CKS题目解析

考试大纲

集群安装:15%

  • 使用网络安全策略来限制集群级别的访问
  • 使用CIS基准检查Kubernetes组件(etcd, kubelet, kubedns, kubeapi)的安全配置。
  • 正确设置入口与TLS
  • 保护节点元数据和端点
  • 在部署之前验证平台二进制文件

集群强化:15%

  • 限制访问Kubernetes API
  • 使用基于角色的访问控制来最小化暴露
  • 谨慎使用服务帐户,例如禁用默认设置,减少新创建帐户的权限
  • 经常更新Kubernetes

系统强化:10%

  • 最小化主机操作系统的大小(减少攻击面)
  • 使用最小权限标识和访问管理
  • 最小化对网络的外部访问
  • 适当使用内核强化工具,如AppArmor, seccomp

微服务漏洞最小化:20%

  • 使用适当的pod安全标准
  • 管理Kubernetes机密
  • 理解并实现隔离技术(多租户、沙盒容器等)
  • 使用Cilium实现Pod-to-Pod加密

供应链安全:20%

  • 最小化基本图像占用空间
  • 了解您的供应链(例如,SBOM、CI/CD、工件存储库)
  • 保护您的供应链(允许的注册中心、签名和验证工件等)。
  • 执行用户工作负载和容器映像的静态分析(例如Kubesec, KubeLinter)

监控、日志记录和运行时安全:20%

  • 执行行为分析以检测恶意活动
  • 检测物理基础设施、应用程序、网络、数据、用户和工作负载中的威胁
  • 调查并识别攻击阶段和环境中的不良参与者
  • 确保容器在运行时的不变性
  • 使用Kubernetes审计日志监控访问

注意:大部分题目都需要切换context,请读者注意,下面的解题不再赘述。

1、容器运行时类(Runtime Class)(新)

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

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

​ 更新 namespace client 中所有Pod以在 gVisor上运行

​ 你可以在 /home/candidate/KSMV00301/runtime-class.yaml中找到一个模板清单文件 .

注意:题目可能发生变化,如果Pod由Deployment或其他控制器控制,请修改对应控制器的配置,修改位置为spec.template.spec.runtimeClassName。修改条目为runtimeClassName: untrusted

答案:

vim /home/candidate/KSMV00301/runtime-class.yaml
# RuntimeClass 定义于 node.k8s.io API 组
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  # 用来引用 RuntimeClass 的名字
  # RuntimeClass 是一个集群层面的资源
  name: untrusted
# 对应的 CRI 配置的名称
handler: runsc
kubectl create -f /home/candidate/KSMV00301/runtime-class.yaml
kubectl edit deployment -n client $Controller_name
spec:
  template:
    spec:
      runtimeClassName: sandbox
https://kubernetes.io/zh-cn/docs/concepts/containers/runtime-class/

2、ServiceAccount

题目:清单文件 /home/candidate/KSCH00301/pod-manifest.yaml 中指定的Pod由于ServiceAccount指定错误而无法调度。请完成以下项目:

​ 1、在现有NameSpace prod 中创建一个名为backend-sa 的新ServiceAccount确保此ServiceAccount不自动挂载API凭据

​ 2、使用 /home/candidate/KSCH00301/pod-manifest.yaml 中的清单文件来创建一个Pod

​ 3、最后,清理NameSpace prod 中任何未使用的ServiceAccount

答案:

vim 2.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: backend-sa
  namespace: prod
automountServiceAccountToken: false
kubectl create -f 2.yaml
vim /home/candidate/KSCH00301/pod-manifest.yaml
apiVersion: v1
kind: Pod
metadata:
  name: backend
  namespace: prod
spec:
  serviceAccountName: backend-sa
  containers:
    - name: backend
      image: nginx
kubectl create -f /home/candidate/KSCH00301/pod-manifest.yaml
kubectl get sa -n prod
kubectl delete sa $sa_name -n prob
https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-service-account/

3、APIServer 禁止匿名访问(新)

题目:由 kubeadm 创建的 cluster 的 Kubernetes API 服务器,出于测试目的,临时配置允许未经身份验证和未授权的访问,授权匿名用户 cluster-admin 的访问权限 .

​ 重新配置 cluster 的 Kubernetes API 服务器以确保只允许经过身份验证和授权的REST请求 .

​ 使用授权模式 Node,RBAC 和准入控制器 NodeRestriction .

​ 删除用户 system:anonymous 的 ClusterRoleBinding来进行清理 .

​ 所有 kubectl 配置环境/文件也被配置为使用未经身份验证和未授权的访问。您不必更改它,但请注意,一旦完成 cluster 的安全加固, kubectl 的配置将无法工作。您可以使用位于集群的 master节点上,集群原本的 kubectl 配置文件 /etc/kubernetes/admim.conf,以确保经过身份验证和授权的请求仍被允许。

答案:

#更改授权模式和添加 NodeRestriction 准入控制器
vim /etc/kubernetes/manifests/kube-apiserver.yaml
    - --authorization-mode=Node,RBAC
    - --anonymous-auth=false
    - --enable-admission-plugins=NodeRestriction
kubectl delete clusterrolebinding system:anonymous
kubectl get nodes
kubectl get nodes --kubeconfig=/etc/kubernetes/admim.conf
https://kubernetes.io/zh-cn/docs/reference/command-line-tools-reference/kube-apiserver/

4、kube-bench CIS 基准测试(新)

题目:针对 kubeadm 创建的 cluster 运行CIS基准测试工具时,发现了多个必须立即解决的问题 .

​ 通过配置修复所有问题并重启受影响的组件以确保新设置生效 .

​ 修复针对 API 服务器发现的所有违规行为:(尽可能使用Webhook身份验证/授权)

注意:题目可能只要求修改kubelet和etcd的配置

序号 条目 状态
1.2.7 Ensure that the --authorization-mode argument is not set to AlwaysAllow FAIL
1.2.8 Ensure that the --authorization-mode argument includes Node FAIL
1.2.9 Ensure that the --autuorization-mode argument includes RBAC FAIL
4.2.1 Ensure that the anonymous-auth argument is set to false FAIL
4.2.2 Ensure that the --authorization-mode argument is not set to AlwaysAllow FAIL

​ 修复针对 etcd 发现的所有违规行为:

序号 条目 状态
2.2 Ensure that the --client-cert-auth argument is set to true FAIL

注意:Kubelet的配置在 master 节点修改完成后,需要退出,随后SSH到 Node 节点检查是否需要修改配置

答案:

#需要登录到master节点
vim /etc/kubernetes/manifests/kube-apiserver.yaml
   #原来此处为配置为AlwaysAllow
    - --authorization-mode=Node,RBAC
vim /etc/kubernetes/manifests/etcd.yaml
   #原来此处为配置为false
    - --client-cert-auth=true
vim /var/lib/kubelet/config.yaml
authentication: 
  anonymous: 
    enabled: false #原先配置为true
...省略部分输出...
authorization: 
  mode: Webhook #原先配置为AlwaysAllow
systemctl daemon-reload
systemctl restart kubelet

5、TLS 通信加密配置

题目:修改 API Server 和 etcd 之间通信的 TLS 配置 .

​ 对于 API Server ,删除对除TLS 1.3及更高版本之外的所有 TLS 版本支持 . 此外,删除TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 之外的所有 cipher suites的支持 .

​ 对于 etcd ,删除对除TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 之外的所有 cipher suites 的支持 .

注意:需要在master节点上修改

答案:

vim /etc/kubernetes/manifests/kube-apiserver.yaml
- --tls-min-version=VersionTLS13
- --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
vim /etc/kubernetes/manifests/etcd.yaml
--cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
systemctl restart kubelet
kubectl get node

6、RBAC授权

题目: 绑定到 Pod 的 ServiceAccount 的 Role 授予过度宽松的权限 . 完成以下项目以减少权限集 .

​ 一个名为 dev-pod 的现有 Pod 已在 namespace monitoring 中运行 .

​ 编辑绑定到 Pod 的 ServiceAccount service-account-web 的现有 Role . 仅允许对 pods类型的资源进行 get 操作 .

​ 在 namespace monitoring 中创建一个名为 role-2 ,并仅允许只对 statefulsets 类型的资源执行 update 操作的新 Role .

​ 创建一个名为 role-2-binding的新 RoleBinding . 将新创建的 Role 绑定到 Pod 的 ServiceAccount .

答案:

#查找绑定的 Role
kubectl get rolebinding -n monitoring -oyaml | grep service-account-web -B 5
#或者直接edit对应的Pod
#修改 web-role 的 Role 权限
kubectl edit role web-role -n monitoring
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: web-role
  namespace: monitoring
  creationTimestamp: "2024-12-19T06:20:17Z"
  resourceVersion: "52423639"
  uid: c67ytga2-ee47-4d8d-b9sd-a0802cc340987e
rules:
  - apiGroups: [""]
    resources:
      - pods
    verbs:
      - get
vim 6.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: monitoring
  name: role-2
rules:
  - apiGroups: ["apps"]
    resources: ["statefulsets"]
    verbs: ["update"]
kubectl create -f 6.yaml
kubectl create rolebinding role-2-binding --role=role-2 --serviceaccount=monitoring:service-account-web -n monitoring
https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/rbac/

7、RBAC授权-2

题目: 绑定到 Pod 的 ServiceAccount 的 Role 授予过度宽松的权限 . 完成以下项目以减少权限集 .

​ 一个名为 dev-pod 的现有 Pod 已在 namespace monitoring 中运行 .

​ 编辑绑定到 Pod 的 ServiceAccount test-sa-3 的现有 Role . 仅允许对 endpoints 类型的 resources 执行 get 操作.

​ 在 namespace monitoring 中创建一个名为 role-2 ,并仅允许只对 namespaces 类型的 resources 执行 delete 操作的新 Role.

​ 创建一个名为 role-2-binding的新 RoleBinding . 将新创建的 Role 绑定到 Pod 的 ServiceAccount .

注意:namespace为集群级别的资源,需要使用ClusterRole进行创建

答案:

#查找绑定的 Role
kubectl get rolebinding -n monitoring -oyaml | grep service-account-web -B 5
#或者直接edit对应的Pod
#修改 web-role 的 Role 权限
kubectl edit role web-role -n monitoring
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: web-role
  namespace: monitoring
  creationTimestamp: "2024-12-19T06:20:17Z"
  resourceVersion: "52423639"
  uid: c67ytga2-ee47-4d8d-b9sd-a0802cc340987e
rules:
  - apiGroups: [""]
    resources:
      - endpoints
    verbs:
      - get
vim 6.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  namespace: monitoring
  name: role-2
rules:
  - apiGroups: [""]
    resources: ["namespaces"]
    verbs: ["delete"]
kubectl create -f 6.yaml
kubectl create rolebinding role-2-binding --Clusterrole=role-2 --serviceaccount=monitoring:service-account-web -n monitoring
https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/rbac/

8、Audit Log(新)

题目:在集群中启用审计日志。为此,请启用日志后端并确保:

​ 日志存储在 /var/log/kubernetes/kubernetes-logs.txt

​ 日志文件能保留 30 天

​ 最多保留 10 个旧审计日志文件

​ /etc/kubernetes/logpolicy/sample-policy.yaml 提供了基本策略。它仅指定不记录的内容。(基本策略位于集群的 master 节点上)

​ 编辑和扩展基本策略以记录:

​ RequestResponse 级别的 ConfigMap 更改

​ namespace front-apps 中 persistentvolumes 更改的请求体

​ Metedata 级别的所有 namespace 中的 ConfigMap 和 Secret 的更改

​ 此外,添加一个全方位的规则以在 Metadata 级别记录所有其他请求(不要忘记应用修改后的策略)

注意:资源类型为复数

答案:

vim /etc/kubernetes/logpolicy/sample-policy.yaml 
apiVersion: audit.k8s.io/v1
kind: Policy
omitStages:
- "RequestReceived"
rules:
- level: RequestResponse
  resources:
  - group: ""
    resources: ["configmaps"]
- level: Request
  resources:
  - group: ""
    resources: ["persistentvolumes"]
  namespaces: ["front-apps"]
- level: Metadata
  resources:
  - group: ""
    resources: ["secrets", "configmaps"]
- level: Metadata
#应用审计日志规则
vim /etc/kubernetes/manifests/kube-apiserver.yaml
    - --audit-policy-file=/etc/kubernetes/logpolicy/sample-policy.yaml
    - --audit-log-path=/var/log/kubernetes/kubernetes-logs.txt
    - --audit-log-maxage=30
    - --audit-log-maxbackup=10
#挂载策略和日志至 APIServer 的 Pod(考试环境有可能已经挂载)
volumeMounts:
  - mountPath: /etc/kubernetes/audit-policy.yaml
    name: audit
    readOnly: true
  - mountPath: /var/log/kubernetes/
    name: audit-log
    readOnly: false
volumes:
- name: audit
  hostPath:
    path: /etc/kubernetes/audit-policy.yaml
    type: File

- name: audit-log
  hostPath:
    path: /var/log/kubernetes/
    type: DirectoryOrCreate
systemctl daemon-reload
systemctl restart kubelet
tail -f /var/log/kubernetes/kubernetes-logs.txt
https://kubernetes.io/zh-cn/docs/tasks/debug/debug-cluster/audit/

9、Secret 基本使用(新)

题目: 在 namespace monitoring 中获取名为 db1-test 的现有 secret 的内容。

​ 将 username字段存储在名为 /home/candidate/user.txt 的文件中,并将 password 字段存储在名为 /home/candidate/old-password.txt 的文件中

​ 在 monitoring namespace 中创建一个名为 dev-mark 的新 secret ,内容如下:

​ username:production-instance

​ password: sdKS8sdf3J4f

​ 最后,创建一个新的 Pod ,它可以通过卷访问 secret dev-mark :

参数
Pod 名 secret-pod
Namespace monitoring
容器名 test-secret-container
镜像 redis
卷名 secret-volume
挂载路径 /etc/test-secret

答案:

kubectl get secret db1-test -n monitoring -oyaml | grep data -A 2 -m 1
echo -n "$username" | base64 -d > /home/candidate/user.txt
echo -n "$password" | base64 -d > /home/candidate/old-passwort.txt
kubectl create secret generic dev-mark --from-literal=username=production-instance --from-literal=password=sdKS8sdf3J4f -n monitoring
kubectl run secret-pod -n monitoring --image=redis --dry-run=client -oyaml > 9.yaml
vim 9.yaml
apiVersion: v1
kind: Pod
metadata:
  name: secret-pod
  namespace: monitoring
spec:
  containers:
    - image: redis
      name: redis
      volumeMounts:
        - name: secret-volume
          mountPath: "/etc/test-secret"
  volumes:
    - name: secret-volume
      secret:
        secretName: dev-mark
kubectl create -f 9.yaml
https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/

10、Dockerfile 和 Deployment 优化(新)

题目:分析和编辑给定的 Dockerfile /home/candidate/KSSC00301/Dockerfile(基于ubuntu:16.04 镜像)并修复在文件中拥有突出的安全/最佳实践问题的两个指令。

​ 分析和编辑给定的清单文件 /home/candidate/KSSC00301/deployment.yaml 并修复在文件中拥有突出的安全/最佳实践问题的两个字段。

答案:

#优化 Dockerfile
vim /home/candidate/Dockerfile
FROM ubuntu:16.04 #如果是latest,请修改为题目的指定版本
USER root
RUN apt get install -y nginx=4.2
ENV ENV=testing

USER nobody #原值为root
CMD ["nginx -d"]
#优化 Deployment
vim /home/candidate/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: test
  name: test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: test
    spec:
      containers:
        - image: redis
          name: redis
          resources: {}
          securityContext:
            {'capabilities':{'add':['NET_ADMIN'],'drop':['all']},'privileged': False, 'readOnlyRootFilesystem': True, 'runAsUser': 65535} #原本是打开了特权模式和关闭了readonlyRootFilesystem

11、SecurityContext 安全容器配置

题目:修改运行在 namespace app ,名为 lamp-deployment 的现有 Deployment,使其 containers:

​ 使用用户 ID 30000 运行

​ 使用一个只读的根文件系统

​ 禁止使用 privilege escalation

答案:

kubectl edit deploy lamp-deployment -n app
    containers:
    - image: redis
      name: redis
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        runAsUser: 30000
https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/security-context/

12、无状态和不可变应用

题目:最佳实践是将容器设置为无状态和不可变的。

​ 检查在 namespace development 中运行的 Pod,并删除任何非无状态或不可变的 Pod。

​ 使用以下对无状态和不可变的严格解释:

​ 能够在容器内存储数据的 Pod 必须被视为非无状态的。(您不必担心数据是否实际上已经存储在容器中)

​ 被配置为任何形式的特权的 Pod 必须被视为可能是非无状态和无不可变的。

​ 本题需要删除具有以下配置的 Pod:

​ allowPrivilegeEscalation 设置为 true 的

​ runAsUser 设置为 0 的

​ readOnlyRootFilesystem 设置为 true 的

​ privileged 设置为 true 的

​ 有挂载任何存储的,比如 PVC、hostPath 等

注意:容器数量如果多的话,查找需要仔细,最好可以用awk 'NR==2'和awk -F " " printf'{ $2 }',对Pod名进行截取

答案:

#检查具有特权容器的 Pod
kubectl get pod $Pod_name -n development -oyaml | grep -Ei "privilege|RootFileSystem|runAsUser"
kubectl delete pod $Pod_name -n development
#检查存储数据的容器
kubectl edit pod $Pod_name -n development

13、NetworkPolicy 访问控制(新)

题目:创建一个名为 pod-restriction 的 NetworkPolicy 来限制对在 namespace development 中运行的 Pod products-service 的访问

​ 只允许以下 Pod 连接到 Pod products-service:

​ namespace qa 中的 Pod

​ 位于任何namespace ,带有标签 environment:testing 的 Pod(确保应用 NetworkPolicy。您可以在 /home/candidate/KSSH00301/network-policy.yaml 找到一个模板清单文件。)

答案:

#查看 qa 命名空间的标签
kubectl get ns qa --show-labels
#查看被限制的 Pod 的标签
kubectl get po products-service -n development --show-labels
vim 13.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: pod-restriction
  namespace: development
spec:
  podSelector:
    matchLabels:
      run: products-service
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          environment: testing
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: qa
kubectl create -f 13.yaml
https://kubernetes.io/zh-cn/docs/concepts/services-networking/network-policies/

14、NetworkPolicy 拒绝所有入口/出口流量(新)

题目:一个默认拒绝 (default-deny)的 NetworkPolicy 可避免在未定义任何其他 NetworkPolicy 的namespace 中意外公开 Pod。

​ 为所有类型为 Ingress 的流量在 namespace production 中创建一个名为 defaultdeny 的 新默认拒绝 NetworkPolicy。

​ 此新的 NetworkPolicy 必须拒绝 namespace production 中的所有 Ingress 流量。

​ 将新创建的默认拒绝 NetworkPolicy 应用于在 namespace production 中运行的所有 Pod(您可以在 /home/candidate/KSCS00101/network-policy.yaml 找到一个模板清单文件)

vim 14.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: defaultdeny
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
https://kubernetes.io/zh-cn/docs/concepts/services-networking/network-policies/

15、Trivy 镜像扫描(新)

题目:使用 Trivy 开源容器扫描器检测 namespace kamino 中 Pod 使用的具有严重漏洞的镜像。

​ 查找具有 High 或 Critical 严重性漏洞的镜像,并删除使用这些镜像的 Pod。

​ Trivy 仅预装在集群的 master 节点上,它在原本的系统或工作节点上不可用。您必须连接到集群的 master 节点才能使用 Trivy。

注意:切换完context后,需要ssh到对应的master节点,还有先看命名空间下容器数量,如果太多,需要考虑其他快捷的办法

kubectl get pods -o custom-columns="name:.metadata.name,image:.spec.containers[*].image"
#通过trivy image --help可以查看扫描镜像的用法
trivy image --skip-update --severity HIGH,CRITICAL $Image_name
找出对应的Pod,随后删除

16、AppArmor

题目: AppArmor 已在集群的工作节点上启用。一个 AppArmor 配置文件已经存在,但尚未被实施。

​ 在集群的工作节点上,实施位于 /etc/apparmor.d/nginx_apparmor 的现有AppArmor 配置文件。

​ 编辑位于 /home/candidate/KSSH00401/nginx-deployment.yaml 的现有清单文件以应用 AppArmor配置文件。

​ 最后,应用清单文件并创建其中指定的 Pod。

注意:本题是在工作节点进行操作

答案:

#可以查看配置内容,主要查看profile后面跟着的名称
cat /etc/apparmor.d/nginx_apparmor
#加载apparmor配置文件
apparmor_parser /etc/apparmor.d/nginx_apparmor
#查看 apparmor 的策略名称
apparmor_status | grep nginx-profile
#需要先退出工作节点
vim /home/candidate/KSSH00401/nginx-deployment.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-deploy
spec:
  securityContext:
    appArmorProfile:
      type: Localhost
      localhostProfile: nginx-profile-1
  containers:
    - name: nginx-deploy
      image: registry.cn-beijing.aliyuncs.com/dotbalo/alpine:3.14
      command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]
kubectl create -f /home/candidate/KSSH00401/nginx-deployment.yaml
https://kubernetes.io/docs/tutorials/security/apparmor/

17、Falco 安全监控(新)

题目:使用运行时检测工具检测在属于 Pod tomcat 的单个容器中频繁产生和执行的异常进程。

​ 集群的工作节点上已预装了两个工具:

​ sysdig

​ falco

​ 使用您选择的工具(包括任何非预安装的工具),分析容器的行为至少 30 秒,使用过滤器检测新生成和执行的进程。

​ 在 /opt/KSRS00101/events/details 中存储一个事件如下,其中包含检测到的事件。每行一个,格式如下:

timestamp,uid/username,processName

以下示例显示了格式正确的事件文件:

01:40:19,601363716,root,init
01:40:20,606063716,nobody,bash
01:40:21,134314513,1000,tar

注意:本题是在工作节点进行操作

答案:

#查看 Pod 的容器名称,edit命令也可以
kubectl get po tomcat -oyaml | grep name:
#创建 falco 规则文件(如果题目中要求了存储在其他位置,请更换路径)
vim /etc/falco/tomcat_rule.yaml
- rule: "monitor tomcat"
  desc: "monitor tomcat"
  condition: container.name == "tomcat"
  output: "%evt.time,%container.id,%container.image,%user.uid,%proc.name"
  priority: NOTICE
falco -M 30 -r /etc/falco/tomcat_rule.yaml > /opt/KSRS00101/events/details

18、ImagePolicyWebhook(新)

题目:您必须在集群的 master 节点上完成整个考题,所有服务和文件都已被准备好并放置在该节点上。

​ 给定一个目录 /etc/kubernetes/epconfig 中不完整的配置以及具有 HTTPS 端点 https://wakanda.local:8082/image_prolicy 的功能性容器镜像扫描器:

​ 1、启用必要的插件来创建镜像策略

​ 2、校验控制配置并将其更改为隐式拒绝(implicit deny)

​ 3、编辑配置以正确指向提供的 HTTPS 端点

​ 最后,通过尝试部署易受攻击的资源 /root/KSSC00202/configuration-test.yml 来测试配置是否有效。(您可以在 /var/log/imgaepolicy/acme.log 找到容器镜像扫描仪的日志文件)

提示:本题是在master节点进行操作

答案:

vim /etc/kubernetes/epconfig/admission_configuration.json
'defaultAllow': false # 原值为true
#配置 Webhook 地址,配置在clusters.cluster下
vim /etc/kubernetes/epconfig/kubeconfig.yaml
server: https://wakanda.local:8082/image_policy
#若考试时没有挂载,则添加挂载
vim /etc/kubernetes/manifests/kube-apiserver.yaml
- mountPath: /etc/kubernetes/epconfig
name: epconfig
readOnly: true
volumes:
- hostPath:
path: /etc/kubernetes/epconfig
name: epconfig
#开启 ImagePolicyWebhook
vim /etc/kubernetes/manifests/kube-apiserver.yaml
- --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook
- --admission-control-config-file=/etc/kubernetes/epconfig/admission_configuration.json
systemctl daemon-reload
systemctl restart kubelet
kubectl create -f /root/KSSC00202/configuration-test.yml
tail -f  /var/log/imgaepolicy/acme.log 

19、Docker 安全问题(新)

题目:执行以下任务,以保障集群节点

​ 从 docker 组中删除用户 developer

​ 重新配置并重启 Docker守护进程,以确保位于/var/run/docker.sock的套接字文件由root组拥有。

​ 重新配置并重启 Docker 守护进程,以确保它不监听任何 TCP 端口。

答案:

gpasswd -d develop docker
id develop
#修改docker配置文件 添加SocketUser/SocketGroup字段,删除-H tcp://0.0.0.0:2375
vim /lib/systemd/system/docker.service
[Socket]
SocketUser=root
SocketGroup=root

[Service]
# ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd -H fd:// -containerd=/run/containerd/containerd.sock
systemctl daemon-reload
systemctl restart docker
ss -lntp | grep 2375
ls -l /var/run/docker.sock

20、Ingress SSL(新)

题目:您必须使用 HTTPS 路由来公开 web 应用程序。

​ 在 prod02 namespace 创建一个名为 web 的 Ingress 资源,并按照如下方式配置它:

​ 将主机 web.k8sng.local 和所有路径的流量路由到现有的 web Service。

​ 使用现有的 web-cert Secret来启用TLS终止。

​ 将HTTP请求重定向到HTTPS。

​ 您可以使用以下命令测试Ingress配置

curl -Lk https://web.k8sng.local

答案:

vim 20.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web
spec:
  tls:
  - hosts:
      - web.k8sng.local 
    secretName: web-cert
  rules:
  - host: web.k8sng.local
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80
kubectl create -f 20.yaml
https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/

21、falco扫描发现访问指定文件pod(新)

题目:Pod行为不当,对系统构成安全威胁。

​ 属于应用程序 ollama 的一个 Pod 出现异常。它正从敏感文件 /dev/mem 直接访问系统的内存读取数据。

​ 识别访问 /dev/men 行为不当的 Pod。

​ 将行为不当Pod 的 Deployment 缩放为零副本。

答案:

vim /etc/falco/devmem_rule.yaml
- rule: "monitor devmem"
  desc: "monitor devmem"
  condition: fd.name == '/dev/mem'
  output: "Container: container_id=%container.id reading /dev/mem"
  priority: NOTICE
#执行扫描
falco -M 60 -r /etc/falco/devmem_rule.yaml
#通过container.id找到对应的Pod
crictl ps | grep 4fc6f7734231
#找到Pod对应的控制器名称
kubectl get po -A | grep cpu-677fcb7db7-bj8lm
kubectl scale deploy cpu --replicas=0

22、ServiceAccount 凭据挂载(新)

题目:在现有 namespace monitoring 中有一个 serviceaccount 名为:statsmonitor-sa,修改该 ServiceAccount 关闭自动挂载 API 凭据。

​ 修改 monitoring 空间下一个名为 statsmonitor 的 Deployment,挂载该 ServiceAccount 的 Token 至/var/run/secrets/kubernetes.io/serviceaccount/token

​ 使用 projected 进行挂载,并且以只读的方式挂载,清单配置文件可以在以下位置找到: ~/statsmonitor/deployment.yaml

答案:

kubectl edit sa statsmonitor-sa -n monitoring
automountServiceAccountToken: false
vim ~/statsmonitor/deployment.yaml
spec:
  volumes:
    - name: token
      projected:
        sources:
          - serviceAccountToken:
              path: token
   serviceAccountName: statsmonitor-sa
  containers:
    - image: m.daocloud.io/docker.io/library/nginx:latest
      name: nginx
      volumeMounts:
        - mountPath: /var/run/secrets/kubernetes.io/serviceaccount/token
          name: token
kubectl create -f ~/statsmonitor/deployment.yaml
https://kubernetes.io/zh-cn/docs/concepts/storage/projected-volumes/

23、Secret 创建和使用(新)

题目:在 clever 空间内存在一个已经创建的 Deployment,名字为 clever,该 Deployment 绑定了一个 Secret,名字为 clever。请为该 Deployment 创建该 Secret 并使用以下文件:

​ 证书:~/cert/tls.crt

​ 密钥:~/cert/tls.key

答案:

kubectl create secret tls clever -n clever --cert=~/cert/tls.crt --key=~/cert/tls.key

24、SecurityContext 安全容器配置(新)

题目:为了符合要求,所有用户命名空间都强制执行受限的Pod安全标准。

​ 在 confidential namespace 中包含一个不符合限制性的 Pod 安全标准的Deployment。因此,其 Pod 无法被调度。

​ 修改这个 Deployment 以符合标准,并验证 Pod 可以正常运行。

​ 清单文件在 ~/confidential/nginx-unprivileged.yaml

答案:

#尝试创建,查看报错
kubectl create -f ~/confidential/nginx-unprivileged.yaml
Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "nginx" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "nginx" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
#根据提示直接修改模板
vim ~/confidential/nginx-unprivileged.yaml
containers:
- image: m.daocloud.io/docker.io/library/nginx:latest
  name: xxx
  resources: {}
  securityContext:
    allowPrivilegeEscalation: false
    runAsNonRoot: true
    capabilities:
      drop: ["ALL"]
    seccompProfile:
      type: RuntimeDefault
kubectl apply -f ~/confidential/nginx-unprivileged.yaml

25、Cilium NetworkPolicy(新)

题目:首先,在 nodebb namespace 里创建一个名为 nodebb 的L4 CiliumNetworkPolicy,并按照如下方式配置它:

​ 允许 ingress-nginx namespace 中运行的所有 Pod 访问 nodebb Deployment的Pod

​ 要求相互身份验证

​ 然后,将前一步创建的网络策略扩展如下:

​ 允许主机访问 nodebb Deployment 的 Pod

​ 不要求相互身份验证

vim 25.yaml
apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: nodebb
  namespace: nodebb
spec:
  endpointSelector:
    matchLabels:
      app: nodebb
  ingress:
  - fromEndpoints:
    - matchLabels:
        kubernetes.io/metadata.name: ingress-nginx
    authentication:  #自行记忆
      mode: "required"
    fromEntities:
      - "host"
kubectl create -f 25.yaml

26、Bom 合规性扫描(新)

题目:在alpine namespace中的alpine Deployment,有三个运行不同版本的alpine镜像的容器。

​ 首先,找出alpine镜像的哪个版本包含版本为3.1.4-r5的libcrypto3软件包。

​ 其次,使用预安装的 bom 工具,在 ~/alpine.spdx 为找出的镜像版本创建一个SPDX文档。

​ 最后,更新alpine Deployment并删除 使用找出的镜像版本的容器。Deployment的清单文件可以在~/alipine-deployment.yaml中找到。

答案:

#查看alipine-deployment.yaml文件,可以看到有三个容器和对应的镜像
#登录各个container内部去查看镜像所对应的libcrypto3软件包版本
 kubectl -n alpine exec -it alpine-5b9c8fd489-wcjqm -c alpine-a -- apk list | grep libcrypto3
 kubectl -n alpine exec -it alpine-5b9c8fd489-wcjqm -c alpine-b -- apk list | grep libcrypto3
 kubectl -n alpine exec -it alpine-5b9c8fd489-wcjqm -c alpine-c -- apk list | grep libcrypto3
#找到版本为3.1.4-r5的libcrypto3软件包对应的镜像,生成SPDX文档
bom generate -i $Image_name > ~/alpine.spdx
#删除yaml文件内对应的containerd
kubectl apply -f alipine-deployment.yaml

27、集群升级

#此题参考CKA文档,类似的题目不再赘述