考试心得 我是去年3月份考的CKA,5月份考了2次都没有过CKS,主要还是因为个人没有复习好,刷题太少,2次考试都没有过。后来又重新找了几篇2023年最新的真题,针对的进行练习。我几次考CKS经验来看,如果考试题目不熟练的话,时间大概率不够的。由于2022年7月份之后考试PSI系统进行了升级,所有操作都要在ubuntu20.04主机上进行,包括浏览器。
第一题 kube-bench 修复不安全项 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Context 针对kubeadm创建的cluster运行CIS基准测试工具时,发现了多个必须立即解决的问题。 Task 通过配置修复所有问题并重新启动受影响的组件以确保新的设置生效。 修复针对API服务器发现的所有以下违规行为: 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 --authorization-mode argument includes RBAC FAIL 1.2.18 Ensure that the --insecure-bind-address argument is not set FAIL (1.23中这项题目没给出,但最好也检查一下,模拟环境里需要改) 1.2.19 Ensure that theinsecure-port argument is set te 0 FAIL(1.23中这项题目没给出,不需要再修改了) 修复针对kubelet发现的所有以下违规行为: Fix all of the following violations that were found against the kubelet: 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 注意:尽可能使用Webhook身份验证/授权。 修复针对etcd发现的所有以下违规行为: Fix all of the following violations that were found against etcd: 2.2 Ensure that the --client-cert-auth argument is set to true FAIL
解答:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 1、先备份kube-apiserver.yaml,etcd.yaml,config.yaml三个文件; 2、修改kube-apiserver.yaml文件,执行vim /etc/kubernetes/manifests/kube-apiserver.yaml - --authorization-mode=Node,RBAC - --insecure-bind-address=0.0.0.0 3、修改config.yaml文件,执行vim /var/lib/kubelet/config.yaml authentication: anonymous: enabled: false ... authorization: mode: Webhook 4、修改etcd.yaml文件, vim /etc/kubernetes/manifests/etcd.yaml - --client-cert-auth=true 5、重启kubelet服务 [root@k8s-master manifests] [root@k8s-master manifests]
第二题 Pod 指定 ServiceAccount 1 2 3 4 5 6 7 8 9 10 11 12 13 Context 您组织的安全策略包括: - ServiceAccount不得自动挂载API凭据 - ServiceAccount名称必须以"-sa" 结尾 清单文件/cks/sa/pod1.yaml中指定的Pod由于ServiceAccount指定错误而无法调度。 请完成一下项目: Task 1.在现有namespace ga中创建一个名为backend-sa的新ServiceAccount, 确保此ServiceAccount不自动挂载API凭据。 2.使用/cks/sa/pod1.yaml中的清单文件来创建一个Pod。 3.最后,清理namespace ga中任何未使用的ServiceAccount。
解答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 1、创建sa apiVersion: v1 kind: ServiceAccount metadata: name: backend-sa namespace: qa automountServiceAccountToken: false 2、创建pod apiVersion: v1 kind: Pod metadata: name: backend namespace: qa spec: serviceAccountName: backend-sa containers: - image: nginx:alpine imagePullPolicy: IfNotPresent name: backend 3、删除没有使用的sa
第三题 默认网络策略 1 2 3 4 5 6 7 8 Context 一个默认拒绝(default-deny)的NetworkPolicy可避免在未定义任何其他NetworkPolicy的namespace中意外公开Pod。 Task 为所有类型为Ingress-+Egress的流量在namespace testing中创建一个名为denypolicy的新默认拒绝NetworkPolicy。 此新的NetworkPolicy必须拒绝namespace testing中的所有的Ingress+Egress流量。 将新创建的默认拒绝NetworkPolicy应用与在namespace testing中运行的所有Pod。 你可以在/cks/net/p1,yaml找到一个模板清单文件。
解答:网络策略
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 1、创建默认网络策略 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: denypolicy namespace: testing spec: podSelector: {} policyTypes: - Ingress - Egress 2、检查 Name: denypolicy Namespace: testing Created on: 2022-12-28 15:18:22 +0800 CST Labels: <none> Annotations: <none> Spec: PodSelector: <none> (Allowing the specific traffic to all pods in this namespace) Allowing ingress traffic: <none> (Selected pods are isolated for ingress connectivity) Allowing egress traffic: <none> (Selected pods are isolated for egress connectivity) Policy Types: Ingress, Egress
第四题 RBAC - RoleBingding 1 2 3 4 5 6 7 8 Context 绑定到Pod的ServiceAccount的Role授予过度宽松的权限。完成以下项目以减少权限集。 Task 一个名为web-pod的现有Pod已在namespace db中运行。 编辑绑定到Pod的ServiceAccount service-account-web的现有Role,仅允许只对services类型的资源执行get操作。 在namespace db中创建一个名为role-2,并仅允许只对namespaces类型的资源执行delete操作的新Role。 创建一个名为role-2-binding的新RoleBinding,将新创建的Role绑定到Pod的ServiceAccount。 注意:请勿删除现有的RoleBinding。
解答:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 1、本地测试环境 apiVersion: v1 kind: Pod metadata: name: web-pod namespace: db spec: serviceAccountName: service-account-web containers: - image: nginx:alpine imagePullPolicy: IfNotPresent name: web-pod 2、答题 apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: creationTimestamp: "2022-12-28T07:48:59Z" name: role-1 namespace: db resourceVersion: "224470" uid: 3406bbfb-25aa-4930-ab29-9abad1e1de77 rules: - apiGroups: - "" resources: - services verbs: - get 检查 Name: role-1 Labels: <none> Annotations: <none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- services [] [] [get] 创建role-2 role.rbac.authorization.k8s.io/role-2 created Name: role-2 Labels: <none> Annotations: <none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- namespaces [] [] [delete] 创建新rolebinding Name: role-2-binding Labels: <none> Annotations: <none> Role: Kind: Role Name: role-2 Subjects: Kind Name Namespace ---- ---- --------- ServiceAccount service-account-web db
第五题 日志审计 log audit (建议最后做,比较耗时,易错题) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 在cluster中启用审计日志。为此,请启用日志后端,并确保: - 日志存储在 /var/log /kubernetes/.audit-logs.txt - 日志文件能保留10天 - 最多保留2个旧审计日志文件 /etc/kubernetes/logpolicy/sample-policy.yaml提供了基本策略。它仅指定不记录的内容。 注意:基本策略位于cluster的master节点上。 编辑和扩展基本策略以记录: - RequestResponse 级别的 persistentvolumes更改 - namespace front-apps 中 configmaps 更改的请求体 - Metadata 级别的所有 namespace 中的 ConfigMap 和 Secret 的更改 此外,添加一个全方位的规则以在Metadata级别记录所有其他请求。 注意:不要忘记应用修改后的策略。
解答:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 apiVersion: audit.k8s.io/v1 kind: Policy omitStages: - "RequestReceived" rules: - level: RequestResponse resources: - group: "" resources: ["persistentvolumes" ] - level: Request resources: - group: "" resources: ["configmaps" ] namespaces: ["front-apps" ] - level: Metadata resources: - group: "" resources: ["secrets" , "configmaps" ] - level: Metadata omitStages: - "RequestReceived" - --audit-log-path=/var/log /kubernetes/audit-log.txt - --audit-log-maxage=10 - --audit-log-maxbackup=2 - --audit-policy-file=/etc/kube ... volumeMounts: - mountPath: /var/log /kubernetes name: audit-log readOnly: false - mountPath: /etc/kubernetes/logpolicy name: audit readOnly: true volumes: - hostPath: path: /var/log /kubernetes type : DirectoryOrCreate name: audit-log - hostPath: path: /etc/kubernetes/logpolicy type : DirectoryOrCreate name: audit
第六题 创建Secret 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Task 在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
解答:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 apiVersion: v1 data: password: aGVsbG8= username: ZGIx kind: Secret metadata: creationTimestamp: "2022-12-29T08:24:22Z" name: db1-test namespace: istio-system resourceVersion: "252538" uid: 1821cc24-a8a1-4a81-ab80-a1a4ad787ccf type : OpaqueapiVersion: v1 kind: Pod metadata: name: secret-pod namespace: istio-system spec: containers: - name: dev-container image: nginx volumeMounts: - name: secret-volume mountPath: "/etc/secret" readOnly: true volumes: - name: secret-volume secret: secretName: db2-test
第7题 dockerfile检测 1 2 3 4 5 6 7 8 9 10 11 12 13 Task 分析和编辑给定的Dockerfile/cs/docken/Dockerfile(基于ubuntu:16.04镜像). 并修复在文件中拥有的突出的安全/最佳实践问题的两个指令。 分析和编辑给定的清单文件Icks/docker/.deploymentyaml, 并修复在文件中拥有突出的安全/最佳实践问题的两个字段。 注意:请勿添加或别除配置设置:只需修改现有的配置设置让以上两个配置设置都不再有安全/最佳实践问题。 注意:如果您需要非特权用户来执行任何项目。 2使用用户1D65535的用户nobody· 只修改即可。不需要创建。
解答:
1 2 3 4 5 6 7 8 9 USER root --》 USER nobody FROM ubuntu:last -->FROM ubuntn:16.04 在安全内容里删除'SYS_ADMIN' ; 在template字段里把lables标签的run: couchdb 改成 app: couchdb,并增加一行:version: stable
第8题 沙箱运行容器gVisor 1 2 3 4 5 6 7 Context 该cluster使用containerd作为CRl运行时。containerd的默认运行时处理程序是runc。 containerd已准备好支持额外的运行时处理程序unsc(gVisor)。 Task 使用名为runsc的现有运行时处理程序,创建一个名为untrusted的RuntimeClass。 更新namespace server中的所有Pod以在gVisor上运行。 您可以在/cks/gVisor/rc.yaml中找到一个模版清单。
解答:容器运行时类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 apiVersion: node.k8s.io/v1 kind: RuntimeClass metadata: name: untrusted handler: runsc runtimeClassName: untrusted
第9题 容器安全,删除特权 Pod (旧) 1 2 3 4 5 6 7 8 Context 最佳实践是将容器设计为无状态和不可变的。 Task 检查在namespace production中运行的Pod,并制除任何非无状态或非不可变的Pod。 使用以下对无状态和不可变的严格解释: - 能够在容器内存储数据的Pod的容器必须被视为非无状态的。 注意:你不必担心数据是否实际上已经存储在容器中。 - 被配置为任何形式的特权Pod必须被视为可能是非无状态和非不可变的。
解答:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 apiVersion: v1 kind: Pod metadata: name: test-pd namespace: production spec: containers: - image: nginx:alpine name: test-container volumeMounts: - mountPath: /test-pd name: test-volume volumes: - name: test-volume hostPath: path: /data [root@k8s-master 09] NAME READY STATUS RESTARTS AGE pri001 1/1 Running 0 28m pri002 1/1 Running 0 6m55s test-pd 1/1 Running 0 2m23s [root@k8s-master 09] privileged: true [root@k8s-master 09] pod "pri001" deleted [root@k8s-master 09] privileged: true [root@k8s-master 09] pod "pri002" deleted [root@k8s-master 09] [root@k8s-master 09] {"apiVersion" :"v1" ,"kind" :"Pod" ,"metadata" :{"annotations" :{},"name" :"test-pd" ,"namespace" :"production" },"spec" :{"containers" :[{"image" :"nginx:alpine" ,"name" :"test-container" ,"volumeMounts" :[{"mountPath" :"/test-pd" ,"name" :"test-volume" }]}],"volumes" :[{"hostPath" :{"path" :"/data" },"name" :"test-volume" }]}} - hostPath: [root@k8s-master 09] pod "test-pd" deleted
第9题 container 安全上下文(新) 1 2 3 4 5 6 7 Context Container Security Context应在特定namespace中修改Deployment。 Task 按照如下要求修改sec-ns命名空间里的Deployment secdep 1、用ID为30000的用户启动容器(设置用户1D为:30000) 2、不允许进程获得超出其父进程的特权(禁止allowPrivilegeEscalation) 3、以只读方式加载容器的根文件系统(对根文件的只读权限)
解答:容器安全上下文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ... spec: securityContext: runAsUser: 30000 ... containers: securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true ... containers: securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true
第10题 网络策略 NetworkPolicy 1 2 3 4 5 6 7 8 9 Task 创建一个名为pod-restriction的NetworkPolicy来限制对在namespace dev-team中运行的Pod products-service的访问。 只允许以下Pod连接到Pod products-service - namespace gaga中的Pod - 位于任何namespace,带有标签environment:testing的Pod 注意:确保应用NetworkPolicy,. 你可以在/cks/net/po.yaml找到一个模板清单文件,
解答:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: pod-restriction namespace: dev-team spec: podSelector: matchLabels: environment: testing policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: name: qaqa - from: - namespaceSelector: {} podSelector: matchLabels: environment: testing Name: pod-restriction Namespace: dev-team Created on: 2022-12-29 19:56:59 +0800 CST Labels: <none> Annotations: <none> Spec: PodSelector: environment=testing Allowing ingress traffic: To Port: <any> (traffic allowed to all ports) From: NamespaceSelector: name=qa ---------- To Port: <any> (traffic allowed to all ports) From: NamespaceSelector: <none> PodSelector: environment=testing Not affecting egress traffic Policy Types: Ingress
第11题 Trivy 扫描镜像安全漏洞 1 2 3 4 5 6 7 8 Task 使用Triy开源容器扫描器检测namespace kamino中Pod使用的具有严重漏洞的镜像。 查找具有High或Critical严重性漏闲的镜像,并测除使用这些镜像的Pod。 注意:Triy仅安装在cluster的master节点上, 在工作节点上不可使用。 你必须切换到cluster的master节点才能使用Ty。
解答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 安装trivy漏洞扫描工具 - image: nginx:1.13 image: docker.io/library/nginx:1.13
第12题 AppArmor (易错) 1 2 3 4 5 6 Context APPArmor 已在 cluster 的工作节点上被启用。一个 APPArmor 配置文件已存在,但尚未被实施 Task 在 cluster 的工作节点上,实施位于 /etc/apparmor.d/nginx_apparmor 的现有 APPArmor配置文件。 编辑位于 /home/candidate/KSSH00401/nginx-deploy.yaml 的现有清单文件以应用AppArmor 配置文件。 最后,应用清单文件并创建其中指定的 Pod 。
解答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 apparmor_status cat /etc/apparmor.d/nginx_apparmor profile nginx-profile flags=(attach_disconnected) { file, deny /** w, } ssh node1 apparmor_parser -q /etc/apparmor.d/nginx_apparmor apparmor_status | grep nginx metadata: name: hello-apparmor annotations: container.apparmor.security.beta.kubernetes.io/podx: localhost/nginx-profile
第13题 Sysdig & falco 1 2 3 4 5 6 7 8 9 Task: 使用运行时检测工具来检测 Pod tomcat123 单个容器中频发生成和执行的异常进程。 有两种工具可供使用: - sysdig - falco 注: 这些工具只预装在 cluster 的工作节点node02,不在 master 节点。 使用工具至少分析 30 秒,使用过滤器检查生成和执行的进程,将事件写到 /opt/KSR00101/incidents/summary 文 件中,其中包含检测的事件, 格式如下: [timestamp],[uid],[processName] 保持工具的原始时间戳格式不变。 注:确保事件文件存储在集群的工作节点上。
解答:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 crictl info | grep sock "containerdEndpoint" : "/run/containerd/containerd.sock" ,crictl ps | grep tomcat123 sysdig -l | grep time sysdig -l | grep uid sysdig -l | grep proc sysdig -M 30 -p "%evt.time,%user.name,%proc.name" --cri /run/containerd/containerd.sock container.name=tomcat123 >> /opt/KSR00101/incidents/summary sysdig-probe-loader
第14题 TLS通信加强(新题) 1 2 3 4 5 6 7 Task 通过TLS加强kube-apiserver安全配置,要求 1、kube-apiserver除了VersionTLS13及以上的版本可以使用,其他版本都不允许使用。 2、密码套件(Cipher suite)为TLS_AES_128_GCM_SHA256 通过TLS加强ETCD安全配置,要求 1、密码套件(Cipher suite)为TLS_AES_128_GCM_SHA256
解答:
1 2 3 4 5 6 7 8 9 vim /etc/kubernetes/manifests/kube-apiserver.yaml - --tls-min-version=VersionTLS13 - --tls-cipher-suites=TLS_AES_128_GCM_SHA256 - --cipher-suites=TLS_AES_128_GCM_SHA256
第15题 启用 API server 认证 1 2 3 4 5 6 7 8 9 Context 由 kubeadm 创建的 cluster 的 Kubernetes API 服务器,出于测试目的,临时配置允许未经身份验证和未经授权的访问,授予匿名用户 cluster-admin 的访问权限. Task 重新配置 cluster 的Kubernetes APl 服务器,以确保只允许经过身份验证和授权的 REST 请求。 使用授权模式 Node,RBAC 和准入控制器NodeRestriction。 删除用户 system:anonymous 的 ClusterRoleBinding 来进行清理。 注意:所有 kubectl 配置环境/文件也被配置使用未经身份验证和未经授权的访问。 你不必更改它,但请注意,一旦完成 cluster的安全加固, kubectl 的配置将无法工作。 您可以使用位于 cluster 的 master 节点上,cluster 原本的kubectl 配置文件 /etc/kubernetes/admin.conf ,以确保经过身份验证的授权的请求仍然被允许。
解答:
1 2 3 4 5 6 7 8 9 10 11 12 vim /etc/kubernetes/manifests/kube-apiserver.yaml - --authorization-mode=Node,RBAC - --enable-admission-plugins=NodeRestriction systemctl daemon-reload systemctl restart kubelet
第16题 ImagePolicyWebhook容器镜像扫描 1 2 3 4 5 6 7 8 9 10 11 12 Context cluster 上设置了容器镜像扫描器,但尚未完全集成到 cluster 的配置中。 完成后,容器镜像扫描器应扫描并拒绝易受攻击的镜像的使用。 Task 注意:你必须在 cluster 的 master节点上完成整个考题,所有服务和文件都已被准备好并放置在该节点上。 给定一个目录 /etc/kubernetes/epconfig中不完整的配置以及具有 HTTPS 端点 <https://acme.local:8082/image_policy> 的功能性容器镜像扫描器: 1. 启用必要的插件来创建镜像策略 2. 校验控制配置并将其更改为隐式拒绝(implicit deny) 3. 编辑配置以正确指向提供的 HTTPS 端点 最后,通过尝试部署易受攻击的资源 /cks/img/web1.yaml 来测试配置是否有效。 你可以在/var/log /imagepolicy/roadrunner.log 找到容器镜像扫描仪的日志文件。
解答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 "defaultAllow" : false ... cluster: certificate-authority: /path/to/ca.pem server: <https://acme.local:8082/image_policy> ... cp /etc/kubernetes/manifests/kube-apiserver.yaml{,.bak} - --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook - --admission-control-config-file=/etc/kubernetes/epconfig/admission_configuration.json - mountPath: /etc/kubernetes/epconfig name: epconfig readOnly: true - hostPath: path: /etc/kubernetes/epconfig type : DirectoryOrCreate name: epconfig
验证
# kubectl apply -f /cks/img/web1.yaml
参考 新版PSI系统下CKS考试注意事项
2022年12月CKS真题