赞
踩
前言:
cka和cks认证真的比较恶心,他们的那个PSI Bridge Secure Browser真的非常卡。
吐槽完毕,不废话,直接上真题解析。
CKS总共是16道题,题目顺序是打乱的,由于认证系统非常卡,因此,不建议使用官方文档,本文采用尽量避开官方文档的方式解析。
注:考试使用的是kubernetes1.25,整个系统有N个kubernetes集群。
一,
- 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.25 中这项题目没给出,但最好也检查一下,模拟环境里需要
- 改)
- 1.2.19 Ensure that the --insecure-port argument is set to 0 FAIL (1.25 中这项题目没给出,不需要再修改了)
- 修复针对 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
解析:
kube-bench是干什么的工具我在这就不班门弄斧了,很明显,题目是指定了一个集群,而kube-bench工具主要是检测的集群配置,因此,我们需要准确的登陆到集群的master节点上,然后,根据题目要求修改配置文件。
题目要求的修复对象包括kube-apiserver,kubelet,etcd这三个组件的配置文件,kube-apiserver和etcd都是静态pod的形式部署的。因此,我们修改文件后等待一段时间,这两个组件就会自动重启,而kubelet服务是yum安装的,因此,需要systemctl daemon-reload&&systemctl restart kubelet让改动生效即可。
可以用kube-bench确认一下题目里的要求是否正确:
- kube-bench run --targets=master
- kube-bench run --targets=node
- kube-bench run --targets=etcd
例如,第一个命令输出如下:
输出中有如何修改的方法,这个不需要去官方文档查看,自己就可以搞定。
- [FAIL] 1.2.6 Ensure that the --authorization-mode argument is not set to AlwaysAllow (Automated)
- [FAIL] 1.2.7 Ensure that the --authorization-mode argument includes Node (Automated)
- [FAIL] 1.2.8 Ensure that the --authorization-mode argument includes RBAC (Automated)
- [FAIL] 1.2.18 Ensure that the --insecure-bind-address argument is not set (Automated)
- [FAIL] 1.2.19 Ensure that the --insecure-port argument is set to 0 (Automated)
- 。。。
- 1.2.7 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml
- on the master node and set the --authorization-mode parameter to values other than AlwaysAllow.
- One such example could be as below.
- --authorization-mode=RBAC
- 1.2.8 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml
- on the master node and set the --authorization-mode parameter to a value that includes Node.
- --authorization-mode=Node,RBAC
- 1.2.9 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml
- on the master node and set the --authorization-mode parameter to a value that includes RBAC,
- for example:
- --authorization-mode=Node,RBAC
- 1.2.18 Edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml
- on the master node and remove the --insecure-bind-address parameter
kubectl config use-context KSCS00201
切换集群后,查看该集群有几个节点,并ssh到该集群的主节点:
假设主节点名称是master01
- kubectl get no -owide
- ssh master01
1,kube-apiserver配置文件的修改
- 修改之前,备份一下配置文件。
- mkdir bak1
- cp /etc/kubernetes/manifests/kube-apiserver.yaml bak1/
- vim /etc/kubernetes/manifests/kube-apiserver.yaml
- #修改、添加、删除相关内容
- #修改 authorization-mode,注意 Node 和 RBAC 之间的符号是英文状态的逗号,而不是点。
- - --authorization-mode=Node,RBAC
- #删除 insecure-bind-address,考试中,有可能本来就没写这行。
- - --insecure-bind-address=0.0.0.0
2,kubelet配置文件的修改
- 修改之前,备份一下配置文件。
- mkdir bak1
- cp /var/lib/kubelet/config.yaml bak1/
- vim /var/lib/kubelet/config.yaml
- 修改
- apiVersion: kubelet.config.k8s.io/v1beta1
- authentication:
- anonymous: #修改 anonymous 下的,将 true 改为 false
- enabled: false #改为 false
- webhook:
- cacheTTL: 0s
- enabled: true #这个 webhook 下的 true 不要改
- x509:
- clientCAFile: /etc/kubernetes/pki/ca.crt
- authorization: #修改 authorization 下的
- mode: Webhook #改为 Webhook
- webhook:
- ……
- #编辑完后重新加载配置文件,并重启 kubelet
- systemctl daemon-reload
- systemctl restart kubelet.service
- 修改之前,备份一下配置文件。
- mkdir bak1
- cp /etc/kubernetes/manifests/etcd.yaml bak1/
- vim /etc/kubernetes/manifests/etcd.yaml
- 修改
- - --client-cert-auth=true #修改为 true
- Context
- 您组织的安全策略包括:
- ⚫ ServiceAccount 不得自动挂载 API 凭据
- ⚫ ServiceAccount 名称必须以“-sa”结尾
- 清单文件 /cks/sa/pod1.yaml 中指定的 Pod 由于 ServiceAccount 指定错误而无法调度。
- 请完成一下项目:
- Task
- 1. 在现有 namespace qa 中创建一个名为 backend-sa 的新 ServiceAccount,
- 确保此 ServiceAccount 不自动挂载 API 凭据。
- 2. 使用 /cks/sa/pod1.yaml 中的清单文件来创建一个 Pod。
- 3. 最后,清理 namespace qa 中任何未使用的 ServiceAccount
解析:
三个任务,第一个任务是创建一个名称为backend-sa的sa,第二个任务是部署pod,当然是使用新的sa,第三个任务是清理多余的sa
第一个任务:新创建的sa backend-sa 要求不自动挂载api凭据,serviceAccount创建使用命令生成模板文件,然后修改模板文件,在metadata下添加auotmountServiceAccountToken: false即可(auotmountServiceAccountToken不支持命令行方式,所以先生成模板文件,然后在修改,最后应用创建)
第二个任务:修改/cks/sa/pod1.yaml文件,该文件内挂载的serviceAccount指定上一步新创建的sa backend-sa即可。主要是serviceAccountName:backend-sa ,这一段是在pod文件的spec下面。
第三个任务:kubectl get sa -n qa 先查询有哪些sa在这个namespace下,然后kubectl get po -n qa -oyaml|grep serviceAccountName查询在使用的serviceAccount有哪些,删除没有使用的serviceAccount即可
答题:
按题目要求,先做第一个任务:
生成模板文件
kubectl create sa backend-sa -n qa --dry-run=client -oyaml >2-sa.yaml
编辑模板文件2-sa.yaml .在metadata下添加auotmountServiceAccountToken: false
- apiVersion: v1
- kind: ServiceAccount
- metadata:
- name: backend-sa #修改 name
- namespace: qa #注意添加 namespace
- automountServiceAccountToken: false #修改为 false,表示不自动挂载 secret
然后应用此文件,如果模板文件修改有问题,将不会应用成功,继续修改文件即可
kubectl apply -f 2-sa.yaml
第二个任务:
- 创建 Pod 使用该 ServiceAccount
- vi /cks/sa/pod1.yaml
- 修改如下内容
- ……
- metadata:
- name: backend
- namespace: qa #注意命名空间是否对
- spec:
- serviceAccountName: backend-sa # 没有则添加一行,有则修改这一行为刚才创建的 ServiceAccount(考试时,默认已有这一行,需要修改。)
- containers:
- ……
第三个任务:
- 查看所有 sa
- kubectl get sa -n qa
- 查看已经在用的 sa
- kubectl get pod -n qa -o yaml | grep -i serviceAccountName
- 删除不用的 sa
- kubectl delete sa test01 -n qa
- 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
解析:
此题是有一定的迷惑性的, 名称为service-account-web的sa是通过rolebinding绑定role和serviceAccount的,而题目只告诉了sa的名称是service-account-web,因此,我们需要先查询出namespace db 下的rolebinding的名称(rolebinding是有namespace限定的),然后通过此rolebinding查询出role,然后修改此role。
第二步是创建一个名称为role-2的role,并对这个新的role赋予指定权限,然后创建名为role-2-binding的新绑定,绑定新角色role2和service-account-web
这里有一个点,一个serviceaccount可以通过rolebinding绑定多个role(比较拗口,但请仔细阅读理解)
- root@k8s-master:~# kubectl get rolebindings.rbac.authorization.k8s.io -n db -owide
- NAME ROLE AGE USERS GROUPS SERVICEACCOUNTS
- role1-db Role/role1 31m db/service-account-web
第二个命令:
kubectl edit role -n db role1
输出如下:
- # Please edit the object below. Lines beginning with a '#' will be ignored,
- # and an empty file will abort the edit. If an error occurs while saving this file will be
- # reopened with the relevant failures.
- #
- apiVersion: rbac.authorization.k8s.io/v1
- kind: Role
- metadata:
- creationTimestamp: "2023-01-15T09:04:27Z"
- name: role1
- namespace: db
- resourceVersion: "692739"
- uid: 12c9ff1a-4e30-4f09-99ab-01fb42956186
- rules:
- - apiGroups:
- - ""
- resources:
- - services
- verbs:
- - get
- - list #删除这一行
- - watch#删除这一行
- - create#删除这一行
第三个命令:
按题目要求创建新的role-2
这一步不需要看官方文档,命令补全就可以十分轻松的创建好了
- root@k8s-master:~# kubectl create role role-2 -n db --verb=delete --resource=namespace
- role.rbac.authorization.k8s.io/role-2 created
第四个命令:
- root@k8s-master:~# kubectl create rolebinding role-2-binding -n db --role=role-2 --serviceaccount=db:service-account-web
- rolebinding.rbac.authorization.k8s.io/role-2-binding created
四,默认网络策略
题目:
- 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 找到一个模板清单文件。
解析:
这道题目还是需要官方文档的,不过有模板文件,只是参考一下而已,基本算是送分题
上面是官网的示例,按题目要求修改微调一下就可以了
解答:
vim /cks/net/p1.yaml
- apiVersion: networking.k8s.io/v1
- kind: NetworkPolicy
- metadata:
- name: denypolicy
- namespace: testing
- spec:
- podSelector: {}
- policyTypes:
- - Ingress
- - Egress
应用以上文件:
kubectl apply -f /cks/net/p1.yaml
五,
- Task
- 创建一个名为 pod-restriction 的 NetworkPolicy 来限制对在 namespace dev-team 中运行的 Pod products-service 的访问。
- 只允许以下 Pod 连接到 Pod products-service
- ⚫ namespace qaqa 中的 Pod
- ⚫ 位于任何 namespace,带有标签 environment: testing 的 Pod
- 注意:确保应用 NetworkPolicy。
解析:
很明显,这个networkPolicy创建的时候需要指定namespace是dev-team,名称是pod-restriction
由于是允许其它pod连接到Pod products-service,因此,策略应该是ingress,也就是入站策略
入站策略指定了两个范围一个是namespace为qaqa(由于网络策略是基于标签的,因此,本题需要查看namespace qaqa的标签),一个是带有指定标签envirnment:testing的pod,因此,该策略需要两个from
解答:
查询namespace qaqa的标签:
kubectl get ns qaqa --show-labels
查询Pod products-service的标签:
kubectl get po products-service -n dev-team --show-labels
- vi /cks/net/po.yaml
- 根据官网,修改为如下内容:
- ……
- metadata:
- name: pod-restriction #修改
- namespace: dev-team #修改
- spec:
- podSelector:
- matchLabels:
- environment: testing #根据题目要求的标签修改,这个写的是 Pod products-service 的标签,也就是使用 kubectl get pod -n dev-team --show-labels
- 查出来的 pod 的标签,这个标签不要和题目里要求的“位于任何 namespace,带有标签 environment: testing 的 Pod”这句话里的标签混淆了,两个没有关系,所以
- 可不一样。比如你考试时查出来的 POD products-service 的标签是 name: products,那这里的 environment: testing 就要换成 name: products。
- policyTypes:
- - Ingress #注意,这里只写 - Ingress,不要将 - Egress 也复制进来!
- ingress:
- - from: #第一个 from
- - namespaceSelector:
- matchLabels:
- name: qaqa #命名空间有 name: qaqa 标签的
- - from: #第二个 from
- - namespaceSelector: {} #修改为这样,所有命名空间
- podSelector: #注意,这个 podSelector 前面的“-” 要删除,换成空格,空格对齐要对。
- matchLabels:
- environment: testing #有 environment: testing 标签的 Pod,这个地方是根据题目要求“Pods with label environment: testing , in any namespace”,这
- 句话里的 pod 标签写的。不要和上面 spec 里的混淆
六,创建 Secret
题目:
- 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
解析:
此题有三个任务,
第一个任务是:要求查看已存在的名为db1-test的位于namespace istio-system的secrets,然后将编码存储的username和password解密为明文后存放到 /cks/sec/user.txt和/cks/sec/pass.txt 这个任务基本是送分的
第二个任务是按照题目要求,创建新的secrets
第三个任务是创建规定名称的pod,并引用第二个任务创建的secrets
这三个任务都可以不使用官方文档就可以完成,只需要使用命令即可。
那么,第一个任务先做一个简单的演示(随意创建一个secrets,简单的加密形式,username是zsk,password是123456):
注意,secrets后面紧跟 generic,test是secrets的名称
kubectl create secret generic -n kube-system test --from-literal=username=zsk --from-literal=password=123456
查看这个secrets:
- kubectl get secrets test -n kube-system -o jsonpath={.data}
- {"password":"MTIzNDU2","username":"enNr"}
解密后对比解密结果是否符合我们前面创建的值:
- root@k8s-master:~# echo "MTIzNDU2" |base64 -d
- 123456root
- root@k8s-master:~# echo "enNr" |base64 -d
- zsk
可以看到解密后的明文是符合我们创建的时候的值的,因此,第一个和第二个任务还是用命令就可以比较简单的完成。
第三个任务可以复制kube-apiserver.yaml里的关于volume挂载,这个也是不需要官方文档就可以搞定的。
解答:
1,
- kubectl get secrets db1-test -n istio-system -o jsonpath={.data}
- 会反馈结果为:{"password":"aGVsbG8=","username":"ZGIx"}
- 解密,并将结果写入指定文件
- echo 'ZGIx'|base64 -d > /cks/sec/user.txt
- echo 'aGVsbG8='|base64 -d > /cks/sec/pass.txt
2,
- 创建名为 db2-test 的 secret 使用题目要求的用户名和密码作为键值。注意要加命名空间。
- 注意,如果密码中有特殊字符(例如:$,\,*,= 和 !),需要加单引号来转义--from-literal=password='G!Y\*d$zDsb'这样。
- kubectl create secret generic db2-test -n istio-system --from-literal=username=production-instance --from-literal=password=KvLftKgs4aVH
3,
- 根据题目要求,创建 Pod 使用该 secret
- vim k8s-secret.yaml
- 添加如下内容
- apiVersion: v1
- kind: Pod
- metadata:
- name: secret-pod #pod 名字
- namespace: istio-system #命名空间
- spec:
- containers:
- - name: dev-container #容器名字
- image: nginx #镜像名字
- volumeMounts: #挂载路径
- - name: secret-volume #卷名
- mountPath: /etc/secret
- volumes:
- - name: secret-volume #卷名
- secret:
- secretName: db2-test #名为 db2-test 的 secret
- 创建
- kubectl apply -f k8s-secret.yaml
七,Dockerfile 检测
题目:
- Task
- 分析和编辑给定的 Dockerfile /cks/docker/Dockerfile(基于 ubuntu:16.04 镜像),
- 并修复在文件中拥有的突出的安全/最佳实践问题的两个指令。
- 分析和编辑给定的清单文件 /cks/docker/deployment.yaml ,
- 并修复在文件中拥有突出的安全/最佳实践问题的两个字段。
- 注意:请勿添加或删除配置设置;只需修改现有的配置设置让以上两个配置设置都不再有安全/最佳实践问题。
- 注意:如果您需要非特权用户来执行任何项目,请使用用户 ID 65535 的用户 nobody 。
- 只修改即可,不需要创建
解析:
这一题是两个任务,第一个任务是dockerfile的安全排查,dockerfile里是镜像版本不正确,需要修改为ubuntu:16.04 还一个是USER 指定的是root,修改为nobody就可以了,十分简单的两个地方。
第二个任务是/cks/docker/deployment.yaml 文件的安全排查,一个是pod的安全上下文权限问题,一个是标签问题
解答:
编辑/cks/docker/Dockerfile
- <1> 修改 Dockerfile
- vi /cks/docker/Dockerfile
- 1、仅将 CMD 上面的 USER root 修改为 USER nobody,不要改其他的
- USER nobody
- 2、修改基础镜像为题目要求的 ubuntu:16.04
- FROM ubuntu:16.04
编辑 /cks/docker/deployment.yaml
三个标签一致即可;
下图是正确的
此题也是送分题,没什么好说的。
八,沙箱运行容器 gVisor
题目:
- 该 cluster 使用 containerd 作为 CRI 运行时。containerd 的默认运行时处理程序是 runc。
- containerd 已准备好支持额外的运行时处理程序 runsc (gVisor)。
- Task
- 使用名为 runsc 的现有运行时处理程序,创建一个名为 untrusted 的 RuntimeClass。
- 更新 namespace server 中的所有 Pod 以在 gVisor 上运行。
- 您可以在 /cks/gVisor/rc.yaml 中找到一个模版清单。
解析:
这道题是两个任务,第一个任务创建一个容器运行时类,第二个任务是应用第一个任务创建的容器运行时类到名为server的namespace下的所有pod,也就是重新编辑pod
runrc是已经创建好的,直接使用即可,这里就不啰嗦如何创建runrc了
解答:
官方文档:容器运行时类(Runtime Class) | Kubernetes
根据官方文档修改即可:
- 1 创建 RuntimeClass
- vi /cks/gVisor/rc.yaml
- 修改或添加如下内容
- apiVersion: node.k8s.io/v1 ##将 apiVersion: node.k8s.io/v1beta1 修改为 apiVersion: node.k8s.io/v1。这个在 1.25 正式考试的时候,是对的,不需要修改的。
- kind: RuntimeClass
- metadata:
- name: untrusted # 用来引用 RuntimeClass 的名字,RuntimeClass 是一个集群层面的资源
- handler: runsc # 对应的 CRI 配置的名称
- 创建
- kubectl create -f /cks/gVisor/rc.yaml
- 2 将命名空间为 server 下的 Pod 引用 RuntimeClass。
- 考试时,3 个 Deployment 下有 3 个 Pod,修改 3 个 deployment 即可。
- kubectl -n server get deployment
-
- 编辑 deployment
- kubectl -n server edit deployments busybox-run
- kubectl -n server edit deployments nginx-host
- kubectl -n server edit deployments run-test
- 修改如下内容
- spec: #找到这个 spec,注意在 deployment 里是有两个单独行的 spec 的,要找第二个,也就是下面有 containers 这个字段的 spec。
- runtimeClassName: untrusted #添加这一行,注意空格对齐,保存会报错,忽略即可。
- containers:
- - image: nginx:1.9
- imagePullPolicy: IfNotPresent
- name: run-test
九,
AppArmor
题目:
- Task
- 在 cluster 的工作节点 node02 上,实施位于 /etc/apparmor.d/nginx_apparmor 的现有 APPArmor 配置文件。
- 编辑位于 /cks/KSSH00401/nginx-deploy.yaml 的现有清单文件以应用 AppArmor 配置文件。
- 最后,应用清单文件并创建其中指定的 Pod 。
- 请注意,考试时,考题里已表明 APPArmor 在工作节点上,所以你需要 ssh 到开头写的工作节点上。
解析:
这道题需要注意一点,确定/cks/KSSH00401/nginx-deploy.yaml是部署在工作节点的。
apparmor等于centos系统的selinux,因此,我们首先应该是查看位于工作节点的/etc/apparmor.d/nginx_apparmor 这个文件,确定次文件是正常的后,将apparmor规则加载到内核,然后修改/cks/KSSH00401/nginx-deploy.yaml这个文件,增加一个注解container.apparmor.security.beta.kubernetes.io/podx: localhost/nginx-profile-3指定到apparmor的名称,最后应用此部署文件即可。
由于注解是比较长的,因此这里还是需要使用官方文档的,地址为:使用 AppArmor 限制容器对资源的访问 | Kubernetes
解答:
- 1 切换到 node02 的 root 下
- ssh node02
- sudo -i
- 2 切换到 apparmor 的目录,并检查配置文件
- cd /etc/apparmor.d/
- vi /etc/apparmor.d/nginx_apparmor
- 注意,nginx-profile-3 这一行要注释掉,但要确保 profile nginx-profile-3 这一行没有注释。
- #include <tunables/global>
- profile nginx-profile-3 flags=(attach_disconnected) { #这句是正确的配置,不要修改。profile 后面的 nginx-profile-3 为 apparmor 策略模块的名字。
- #include <abstractions/base>
- file,
- ……
- 3 执行 apparmor 策略模块
- 没有 grep 到,说明没有启动。
- apparmor_status | grep nginx-profile-3
- 加载启用这个配置文件
- apparmor_parser -q /etc/apparmor.d/nginx_apparmor
- # 再次检查有结果了
- apparmor_status | grep nginx
- 显示如下内容
- nginx-profile-3
- 4 修改 pod 文件
- vi /cks/KSSH00401/nginx-deploy.yaml
- 修改如下内容
- ……
- metadata:
- name: podx
- #添加 annotations,kubernetes.io/podx 名字和 containers 下的名字一样即可,nginx-profile-3 为前面在 worker node02 上执行的 apparmor 策略模块的名
- 字。
- annotations:
- container.apparmor.security.beta.kubernetes.io/podx: localhost/nginx-profile-3
- spec:
- containers:
- - image: busybox
- imagePullPolicy: IfNotPresent
- name: podx #这个就是 containers 下的名字,为 podx
- command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]
- ……
- 创建
- kubectl apply -f /cks/KSSH00401/nginx-deploy.yaml
十,
ImagePolicyWebhook 容器镜像扫描
题目:
- Context
- cluster 上设置了容器镜像扫描器,但尚未完全集成到 cluster 的配置中。
- 完成后,容器镜像扫描器应扫描并拒绝易受攻击的镜像的使用。
- Task
- 注意:你必须在 cluster 的 master 节点上完成整个考题,所有服务和文件都已被准备好并放置在该节点上。
- 给定一个目录 /etc/kubernetes/epconfig 中不完整的配置,
- 以及具有 HTTPS 端点 https://image-bouncer-webhook.default.svc:1323/image_policy 的功能性容器镜像扫描器:
- 1. 启用必要的插件来创建镜像策略
- 2. 校验控制配置并将其更改为隐式拒绝(implicit deny)
- 3. 编辑配置以正确指向提供的 HTTPS 端点
- 最后,通过尝试部署易受攻击的资源 /cks/img/web1.yaml 来测试配置是否有效。
解析:
image_policywebhook的部署是通过一个服务来完成的,https://image-bouncer-webhook.default.svc:1323/image_policy,考试的时候,这个服务是已经部署好的,因此,我们不需要关心这个服务是否部署,是以何种形式部署的,只需要知道该服务是可用的即可。
imagePolicyWebhook是需要apiserver引用的,因此,我们需要更改apiserver以插件的形式使用这个功能。
最后需要执行/cks/img/web1.yaml,如果此pod部署失败,表示imagePolicyWebhook插件启用成功。
解答:
- 第 1 步 切换到 Master 的 root 下
- ssh master01
- sudo -i
- 第 2 步,编辑 admission_configuration.json(题目会给这个目录),修改 defaultAllow 为 false:
- vi /etc/kubernetes/epconfig/admission_configuration.json
- ……
- "denyTTL": 50,
- "retryBackoff": 500,
- "defaultAllow": false #将 true 改为 false
- ……
- 第 3 步,编辑/etc/kubernetes/epconfig/kubeconfig.yml,添加 webhook server 地址:
- 操作前,先备份配置文件
- mkdir bak16
- cp /etc/kubernetes/epconfig/kubeconfig.yml bak16/
- vi /etc/kubernetes/epconfig/kubeconfig.yml
- 修改如下内容
- ……
- certificate-authority: /etc/kubernetes/epconfig/server.crt
- server: https://image-bouncer-webhook.default.svc:1323/image_policy #添加 webhook server 地址
- name: bouncer_webhook
- ……
- 第 4 步,编辑 kube-apiserver.yaml,从官网中引用 ImagePolicyWebhook 的配置信息:
- 操作前,先备份配置文件
- mkdir bak16
- cp /etc/kubernetes/manifests/kube-apiserver.yaml bak16/
- vi /etc/kubernetes/manifests/kube-apiserver.yaml
- 在- command:下添加如下内容,注意空格要对齐(不建议放到最后,建议放置的位置详见下方截图)
- - --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook
- - --admission-control-config-file=/etc/kubernetes/epconfig/admission_configuration.json #在 1.25 的考试中,默认这行已经添加了
-
- # 在 kube-apiserver.yaml 的 volumeMounts 增加
- volumeMounts: #在 volumeMounts 下面增加 #注意,在 1.25 考试中,蓝色的内容可能已经有了
- - mountPath: /etc/kubernetes/epconfig #建议紧挨着 volumeMounts 的下方增加
- name: epconfig
- readOnly: true
- # 在 kube-apiserver.yaml 的 volumes 增加
- volumes: #在 volumes 下面增加 #注意,在 1.25 考试中,蓝色的内容可能已经有了,你只需要检查确认一下是否准确
- - name: epconfig #建议紧挨着 volumes 的下方增加
- hostPath:
- path: /etc/kubernetes/epconfig
- type: DirectoryOrCreate
- #如果你写的是目录,则是 DirectoryOrCreate,如果你写的是文件,则是 File
- 第 5 步,重启 kubelet。
- systemctl restart kubelet
- 等待 3 分钟,等集群应用策略后,确保 kube-apiserver 是 running 的
- kubectl -n kube-system get pod
- 通过尝试部署易受攻击的资源 /cks/img/web1.yaml 来测试配置是否有效
- 无法创建 pod,如下报错,表示成功。
- kubectl apply -f /cks/img/web1.yaml
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。