云原生|kubernetes|2022年底cks真题解析(1-10)

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

前言:

cka和cks认证真的比较恶心他们的那个PSI Bridge Secure Browser真的非常卡。

吐槽完毕不废话直接上真题解析。

CKS总共是16道题题目顺序是打乱的由于认证系统非常卡因此不建议使用官方文档本文采用尽量避开官方文档的方式解析。

注:考试使用的是kubernetes1.25整个系统有N个kubernetes集群。

kube-bench 修复不安全项
题目:
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-apiserverkubeletetcd这三个组件的配置文件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

1kube-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

2kubelet配置文件的修改

修改之前备份一下配置文件。
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

3etcd配置文件的修改
修改之前备份一下配置文件。
mkdir bak1
cp /etc/kubernetes/manifests/etcd.yaml bak1/
vim /etc/kubernetes/manifests/etcd.yaml
修改
 - --client-cert-auth=true #修改为 true
修改完成后等待 3分钟再检查一下所有 pod确保所有 pod 都正常。
Pod 指定 ServiceAccount
题目:
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
3、
RBAC - RoleBinding
题目:
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(比较拗口但请仔细阅读理解

解答:
第一个命令:
-owide参数可以看到sa的绑定情况确认是role1和service-account-web绑定
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 找到一个模板清单文件。

解析:

这道题目还是需要官方文档的不过有模板文件只是参考一下而已基本算是送分题

网络策略 | Kubernetes

 上面是官网的示例按题目要求修改微调一下就可以了

解答:

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

网络策略 NetworkPolicy
题目:
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是zskpassword是123456:

注意secrets后面紧跟 generictest是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

未完待续~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: k8s