《K8s CKS考试流程与真题解析》.pdf

1、Pod 使用 ServiceAccount

参考资料:https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-service-account/

  1. 大致意思这样:
  2. 1、创建一个 SAServiceAccount
  3. 2、修改已有 yaml 文件指定创建的 SA
  4. 3、删除当前命名空间中未绑定 Pod SA

创建一个sa

  1. kubectl create serviceaccount backend-sa

修改yaml指定sa

  1. kubectl get pod/nginx -o yaml > pod-nginx.yml
  2. apiVersion: v1
  3. kind: Pod
  4. metadata:
  5. name: nginx
  6. spec:
  7. containers:
  8. - image: nginx
  9. name: nginx
  10. serviceAccountName: backend-sa # 修改这里
  11. # Pod 被创建时服务账户必须存在,否则会被拒绝。
  12. # 你不能更新已经创建好的 Pod 的服务账户。
  13. kubectl delete po/nginx
  14. kubectl create -f pod-nginx.yml

删除未被使用的serviceaccount

  1. # 查询所有名命空间下所有的serviceaccount
  2. kubectl get serviceaccount
  3. # 查询所有被使用的serviceaccount
  4. kubectl get pod -o yaml | grep -i serviceaccountname
  5. # 删除未被使用的
  6. kubectl delete serviceaccount geray

2、kube-bench

  1. 解读:使用 kube-bench 工具检查集群组件配置文件存在的问题与修复,并重启对应组件确保
  2. 新配置生效。

修复以下 apiserver 发现的问题:

CKS-真题 - 图1

  • —authorization-mode 参数不能设置为AlwaysAllow,需要包含Node、RBAC( kube-apiserver.yaml )

CKS-真题 - 图2

修复以下 kubelet 发现的问题:

CKS-真题 - 图3

  • 将kubelet中authentication.anonymous.enabled设置问false(/var/lib/kubelet/config.yaml)
  • authorization.mode 不能包含AlwaysAllow

CKS-真题 - 图4

修复一下etcd发现的问题:

CKS-真题 - 图5

  • —client-cert-auth=true 参数设置为true(/etc/kubernetes/manifests/etcd.yaml)

CKS-真题 - 图6

最后重启kubelet服务

  1. # kubelet 获取配置文件
  2. systemctl cat kubelet | grep -i Environment
  3. # 修改 yaml 后,默认会重启容器,正常可以不用使用这个命令再重启,为确保重启生效可以再执行下
  4. systemctl restart kubelet

3、网络策略

参考资料 : https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/

CKS-真题 - 图7

  1. 解读:在 testing 命名空间创建一个名为 denypolicy 的网络策略。拒绝所有 Ingress Egress 流量。将网络策略应用到 testing 命名空间中的所有 pod
  1. apiVersion: networking.k8s.io/v1
  2. kind: NetworkPolicy
  3. metadata:
  4. name: testing
  5. spec:
  6. podSelector: {}
  7. policyTypes:
  8. - Ingress
  9. - Egress
  • 拒绝所有pod进出流量

4、Pod安全策略(PSP)- 将被启用

参考资料:https://kubernetes.io/zh/docs/concepts/policy/pod-security-policy/

CKS-真题 - 图8

  1. 解读:
  2. Create a new PodSecurityPolicy named restrict-policy,which prevents the creation of privieged Pods.
  3. 1. 创建一个名为 restrict-policy PodSecurityPolicy,防止创建特权 Pod
  4. 2. 创建一个名为 restrict-access-role ClusterRole 能够使用 PSP restrict-policy
  5. 3. staging 命名空间创建一个名为 psp-denial-sa ServiceAccount
  6. 4. 最后,创建一个名为 dany-access-bind ClusterRoleBinding,绑定 ClusterRolerestrict-access-role ServiceAccount psp-denial-sa

4.1 启用PSP准入控制器

  1. # 启用 PSP 准入控制器
  2. vi /etc/kubernetes/manifests/kube-apiserver.yaml
  3. - --enable-admission-plugins=NodeRestriction,PodSecurityPolicy
  4. systemctl restart kubelet

4.2 配置安全策略

  1. vi psp.yaml
  2. apiVersion: policy/v1beta1
  3. kind: PodSecurityPolicy
  4. metadata:
  5. name: restrict-policy
  6. spec:
  7. privileged: false # Don't allow privileged pods!
  8. # The rest fills in some required fields.
  9. seLinux:
  10. rule: RunAsAny
  11. supplementalGroups:
  12. rule: RunAsAny
  13. runAsUser:
  14. rule: RunAsAny
  15. fsGroup:
  16. rule: RunAsAny
  17. volumes:
  18. - '*'
  19. kubectl apply -f psp.yaml

4.3 使用PSP

  1. # 创建clusterrole(使用psp策略)
  2. kubectl create clusterrole restrict-access-role --verb=use --resource=psp --resource-name=restrict-policy
  3. # 创建serviceaccount在staging命名空间
  4. kubectl create sa psp-denial-sa -n staging
  5. # 创建ClusterRoleBinding绑定clusterrole和staging命名空间中的sa
  6. kubectl create clusterrolebinding dany-access-bind --clusterrole=restrict-access-role --serviceaccount=staging:psp-denial-sa

5、RBAC

参考资料:https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/

CKS-真题 - 图9

  1. 解读:
  2. 1. db 命名空间存在一个名为 web-pod Pod
  3. 2. 编辑该 Pod 绑定的 ServiceAccount service-account-web Role,只允许对 Endpoints 资源类型执行 get 操作
  4. 3. db 命名空间创建一个名为 role-2 Role,该角色只允许对 namespaces 资源类型执行delete 操作
  5. 4. 创建一个名为 role-2-binding RoleBinding,绑定到 ServiceAccount
  1. kubectl edit role -n db
  2. apiVersion: rbac.authorization.k8s.io/v1
  3. kind: Role
  4. metadata:
  5. namespace: db
  6. name: role-1
  7. rules:
  8. - apiGroups: [""]
  9. resources: ["endpoints"]
  10. verbs: ["get"]
  1. # 在 db 命名空间创建一个名为 role-2 的 Role,该角色只允许对 namespaces 资源类型执行delete 操作
  2. kubectl create role role-2 -n db --verb=delete --resource=namespaces
  3. # 创建一个名为 role-2-binding 的 RoleBinding,绑定到 ServiceAccount
  4. kubectl create rolebinding role-2-binding --role=role-2 --serviceaccount=db:
  5. service-account-web -n db

6、日志审计

参考资料:https://kubernetes.io/zh/docs/tasks/debug-application-cluster/audit/

CKS-真题 - 图10

  1. 解读:在集群启用审计,并确保:
  2. 日志路径为 /var/log/kubernetes/audit-logs.txt
  3. 日志文件保留 10
  4. 最多保留 2 个日志文件
  5. 基本策略在/etc/kubernetes/logpolicy/sample-policy.yaml 文件(该文件在 master 节点上)中提供,它指定了不记录的内容编辑和扩展基本策略:
  6. 命名空间在 RequestResponse 级别更改
  7. PV request请求内容级别在 front-apps 命名空间发生了更改
  8. Configmap secret 在所有命名空间 Metadata 级别更改

做这道题之前最好先备份配置文件

  1. # 配置策略文件
  2. vi /etc/kubernetes/logpolicy/sample-policy.yaml
  3. apiVersion: audit.k8s.io/v1 # This is required.
  4. kind: Policy
  5. omitStages:
  6. - "RequestReceived"
  7. rules:
  8. - level: RequestResponse
  9. resources:
  10. - group: ""
  11. resources: ["namespaces"]
  12. - level: Request
  13. resources:
  14. - group: ""
  15. resources: ["persistentVolumes"]
  16. namespace: front-apps
  17. - level: Metadata
  18. resources:
  19. - group: ""
  20. resources: ["configmaps","secrets"]
  21. - level: Metadata
  22. omitStages:
  23. - "RequestReceived"
  1. # 开启日志审计并设置日志路径、保留天数、日志数量以及策略文件位置
  2. vi /etc/kubernetes/manifests/kube-apiserver.yaml
  3. ...
  4. # 设置日志审计参数
  5. - --audit-policy-file=/etc/kubernetes/logpolicy/sample-policy.yaml
  6. - --audit-log-path=/var/log/kubernetes/audit-logs.txt
  7. - --audit-log-maxage=10
  8. - --audit-log-maxbackup=2
  9. ...
  10. # volumeMounts挂载日志升级策略到容器
  11. - mountPath: /etc/kubernetes/logpolicy/sample-policy.yaml
  12. name: log-policy
  13. readOnly: true
  14. - mountPath: /var/log/kubernetes/audit-logs.txt
  15. name: log-audit
  16. readOnly: false
  17. ...
  18. # volumes中添加挂载
  19. - hostPath:
  20. path: /etc/kubernetes/logpolicy/sample-policy.yaml
  21. type: File
  22. name: log-policy
  23. - hostPath:
  24. path: /var/log/kubernetes/audit-logs.txt
  25. type: FileOrCreate
  26. name: log-audit
  27. # 最后重启kubelet
  28. kubectl restart kubelet

7、创建Secret

参考资料:https://kubernetes.io/zh/docs/concepts/configuration/secret/

CKS-真题 - 图11

  1. 解读:
  2. 1、在 istio-system 命名空间存在一个名为 db1-test secret,将 username 字段保存到文
  3. 件名为/home/candidate/user.txt password 字段保存到文件名为
  4. /home/candidate/pass.txt
  5. 注:文件需要自己创建
  6. 2、在 istio-system 命名空间创建一个名为 db2-test secret,内容如下:
  7. username: production-instance
  8. password: KvLftKgs4aVH
  9. 最后,创建一个新的 Pod,可以通过 volume 方式访问 secret 内容。
  1. kubectl get secret db1-test -n istio-system -o jsonpath={.data.username} | base64 -d > /home/candidate/user.txt
  2. kubectl get secret db1-test -n istio-system -o jsonpath={.data.password} | base64 -d > /home/candidate/pass.txt
  3. kubectl create secret generic db2-test -n istio-system --from-literal=username=production-instance --from-literal=password=KvLftKgs4aVH
  4. apiVersion: v1
  5. kind: Pod
  6. metadata:
  7. name: secret-pod
  8. namespace: istio-system
  9. spec:
  10. containers:
  11. - name: dev-container
  12. image: nginx
  13. volumeMounts:
  14. - name: secret-volume
  15. mountPath: "/etc/secret"
  16. volumes:
  17. - name: secret-volume
  18. secret:
  19. secretName: db2-test
  20. kubectl exec -it pod/secret-pod -n istio-system -- sh

8、Dockerfile和Deployment优化

CKS-真题 - 图12

  1. 解读:
  2. 分析和编辑给定的 Dockerfile(基于 Ubuntu:16.04 镜像)/home/candidate/KSSC00301/Dockerfile,修复文件中有突出安全性和最佳实践问题。
  3. 分析和编辑给定的 YAML 清单文件/home/candidate/KSSC00301/deployment.yaml,修复文件中字段存在安全性和最佳实践问题。
  1. # Dockerfile禁用root用户
  2. vi /home/candidate/KSSC00301/Dockerfile
  3. #USER root
  4. # 这里应该使用USER指定非root用户
  5. vi /home/candidate/KSSC00301/deployment.yaml
  6. securityContext:
  7. capabilities:
  8. add: ["NET_BIND_SERVICE"]
  9. #privileged: true # 关闭这个特权启用
  • user root 一共有两行
  • 对 deploy 也注释2行 true的

9、沙箱运行容器gVisor

参考资料:https://kubernetes.io/zh/docs/concepts/containers/runtime-class/

CKS-真题 - 图13

  1. 描述:这个集群使用 containerd 作为 CRI 运行时。Containerd 的默认运行时处理程序是
  2. runccontainerd 也支持额外的运行时处理程序 runscgVisor
  3. 解读:创建一个名为 untrusted RuntimeClass,使用准备好的运行时处理程序 runsc
  4. 更新 server 命名空间中的所有 Pod 使其在 gVisor 上运行。
  • 注:这个题目前有点变化,可能会让你修改 3 个 deployment
  1. vi /home/candidate/KSMV00301/runtime-class.yaml
  2. apiVersion: node.k8s.io/v1 # RuntimeClass 定义于 node.k8s.io API 组
  3. kind: RuntimeClass
  4. metadata:
  5. name: untrusted # 用来引用 RuntimeClass 的名字
  6. # RuntimeClass 是一个集群层面的资源
  7. handler: runsc # 对应的 CRI 配置的名称
  8. kubectl edit deployment web -n server
  9. spec:
  10. runtimeClassName: untrusted
  11. containers:
  12. - image: nginx
  13. imagePullPolicy: Always
  14. name: nginx

10、删除启用的特权pod

参考资料:https://kubernetes.io/zh/docs/concepts/security/pod-security-standards/

CKS-真题 - 图14

  1. 解读:检查在 production 命名空间运行的 Pod,并删除任何不是非无状态(有状态)或非不
  2. 可变(可变)的 Pod
  3. 以下是对无状态和不可变的解释:
  4. 在容器中存储数据的 Pod 视为非无状态(不用担心容器数据持久化)
  5. 启用特权的 Pod 都视为潜在的非无状态和非不可变
  1. kubectl get pod -n production
  2. kubectl get pod <pod-name> -n production -o yaml | grep "privileged: true"
  3. kubectl delete pod <pod-name> -n production

11、网络策略

参考资料 : https://kubernetes.io/zh/docs/concepts/services-networking/network-policies

CKS-真题 - 图15

  1. 解读:创建一个名为 pod-restriction 的网络策略,以限制命名空间 dev-team products-service Pod
  2. 只允许以下 Pod 连接 products-service Pod
  3. qa 命名空间中的 Pod
  4. Pod 标签为 environment:testing,在所有命名空间
  1. # 查看products-service的pod的标签
  2. kubectl get pod products-service -n dev-team --show-labels
  3. # 查看qa命名空间的标签
  4. vi network-policy.yaml
  5. apiVersion: networking.k8s.io/v1
  6. kind: NetworkPolicy
  7. metadata:
  8. name: pod-restriction
  9. namespace: dev-team
  10. spec:
  11. podSelector:
  12. matchLabels:
  13. environment: staging
  14. policyTypes:
  15. - Ingress
  16. ingress:
  17. - from:
  18. - namespaceSelector:
  19. matchLabels:
  20. name: qa
  21. - from:
  22. - namespaceSelector: {} # 这个namespace是必须的吗,表示所有命名空间
  23. podSelector:
  24. matchLabels:
  25. environment: testing

12、ImagePolicyWebhook (需要加强)

参考资料 : https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#imagepolicywebhook

CKS-真题 - 图16

  1. 提示:必须在集群 master 节点完成任务,其中包含的所有服务和文件已准备好。
  2. 解读:在/etc/kubernetes/epconfig 目录下有一个不完整的配置和一个功能容器镜像扫描器HTTPS 端点:https://acme.local:8082/image_policy
  3. 1. 启用准入控制插件
  4. 2. 验证控制配置并将其更改为默认拒绝。
  5. 3. 修改配置文件,指向正确的 HTTPS 端点最后,尝试部署易受供攻击的资源来测试配置是否有效。/root/KSSC00202/ulnerable-manifest.yml
  6. 查看容器扫描日志:/var/log/imagepolicy/roadrunner.log
  1. # 第一步
  2. vi /etc/kubernetes/manifests/kube-apiserver.yaml
  3. - --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook
  4. - --admission-control-config-file=/
  5. etc/kubernetes/epconfig/admission_configuration.json
  6. ...
  7. # 在容器 volumeMounts 增加
  8. - mountPath: /etc/kubernetes/epconfig
  9. name: epconfig
  10. # 在 volumes 增加
  11. - name: epconfig
  12. hostPath:
  13. path: /etc/kubernetes/epconfig
  14. # 第二步
  15. vi /etc/kubernetes/epconfig/admission_configuration.json
  16. defaultAllow: false
  17. # 第三步
  18. vi /etc/kubernetes/epconfig/kubeconfig.yaml
  19. server: https://acme.local:8082/image_policy
  20. systemctl restart kubelet
  21. # 第四步 测试
  22. kubectl apply -f /root/KSSC00202/ulnerable-manifest.yml
  23. tail /var/log/imagepolicy/roadrunner.log

操作顺序:

  • 1、修改admission_configuration.yaml配置文件(指定连接镜像服务器配置文件路径&修改defaultAllow为false)
  • 2、修改kubeconfig.yaml(指定正确的server地址)
  • 3、启动插件策略并指定配置文件以及挂载
  • 4、查看日志

13、Trivy扫描镜像安全漏洞

CKS-真题 - 图17

  1. 解读:对 kamino 命名空间中 pod 使用 Trivy 工具扫描镜像安全漏洞。查找具有高危或严重漏洞的镜像,并删除使用这些镜像的 Pod
  2. 注:Trivy 已经预装集群的 master 节点,工作节点不可用。

14、AppArmor

参考资料:https://kubernetes.io/zh/docs/tutorials/clusters/apparmor

CKS-真题 - 图18

  1. 解读:在集群的工作节点上,执行下面准备好的配置文件/etc/apparmor.d/nginx_apparmor编辑准备好的清单文件/home/candidate/KSSH00401/nginx-deploy.yaml 应用于 AppArmor 文件。
  2. 最后,在 Pod 中应用 apparmor 策略文件。
  1. # 先进入工作节点操作
  2. ssh kssh00401-worker1
  3. # 确认策略名称
  4. vi /etc/apparmor.d/nginx_apparmor
  5. # nginx-profile-3
  6. 或者
  7. apparmor_status | grep nginx
  8. apparmor_parser /etc/apparmor.d/nginx_apparmor # 加载策略
  9. # 在管理节点操作
  10. vi /home/candidate/KSSH00401/nginx-deploy.yaml
  11. annotations:
  12. container.apparmor.security.beta.kubernetes.io/<容器名称>: localhost/nginx-profile-3
  13. kubectl apply -f /home/candidate/KSSH00401/nginx-deploy.yaml

15、启用kubernetes API认证

  1. 描述:kubeadm 创建的集群的 Kubernetes API 服务器,出于测试目的,临时配置为允许未经身份验证和未经授权的访问,授予匿名用户集群管理员访问权限。
  2. 要求:重新配置集群的 Kubernetes API 服务器以确保只允许经过身份验证和授权的 API 请求。
  3. 使用授权模式 NodeRBAC 和准入控制器 NodeRestriction
  4. 删除名为 system:anonymous ClusterRoleBinding
  1. vi /etc/kubernetes/manifests/kube-apiserver.yaml
  2. - kube-apiserver
  3. - --authorization-mode=Node,RBAC # 只保留这两个
  4. - --enable-admission-plugins=NodeRestriction # 只保留这一个
  5. systemctl restart kubelet
  6. # 删除角色绑定
  7. kubectl delete clusterrolebinding system:anonymous