CKS (Certified Kubernetes Security Specialist)CKS (Certified Kubernetes Security Specialist)
CKS认证考试包括这些一般领域及其在考试中的权重:
集群安装:10%
集群强化:15%
系统强化:15%
微服务漏洞最小化:20%
供应链安全:20%
监控、日志记录和运行时安全:20%
1 kube-bench 修复不安全项
做题前需切换集群kubectl config use-context k8s(模拟环境不需要执行,建议执行形成肌肉记忆)
题目
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
修复针对 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.sh
操作
参考资料:https://kubernetes.io/zh/docs/reference/config-api/kubelet-config.v1beta1/
#考试时务必执行,切换集群。模拟环境中不需要执行。
root@master01:~# kubectl config use-context k8s
#切换到 Master 的 root 下
root@master01:~# ssh master01
root@master01:~# sudo -i
root@master01:~# sh kube-bench.sh #注:模拟故障
#修改 api-server
可用kube-bench查一下,考试不用查按题目要求做即可
root@master01:~# vim /etc/kubernetes/manifests/kube-apiserver.yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 11.0.1.111:6443
creationTimestamp: null
labels:
component: kube-apiserver
tier: control-plane
name: kube-apiserver
namespace: kube-system
spec:
containers:
- command:
- kube-apiserver
- --advertise-address=11.0.1.111
- --allow-privileged=true
- --authorization-mode=Node,RBAC #将AlwaysAllow改为Node,RBAC
......
:wq #保存退出
#修改 kubelet
root@master01:~# vim /var/lib/kubelet/config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
anonymous:
enabled: false #true改为false
webhook:
cacheTTL: 0s
enabled: true #false改为true,注意考试时可能只有一处错误,确保anonymous为false,webhook为true
x509:
clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
mode: Webhook #修改为Webhook
webhook:
cacheAuthorizedTTL: 0s
cacheUnauthorizedTTL: 0s
cgroupDriver: systemd
......
#修改 etcd
root@master01:~# vim /etc/kubernetes/manifests/etcd.yaml
apiVersion: v1
kind: Pod
metadata:
annotations:
kubeadm.kubernetes.io/etcd.advertise-client-urls: https://11.0.1.111:2379
creationTimestamp: null
labels:
......
apiVersion: v1
kind: Pod
metadata:
annotations:
kubeadm.kubernetes.io/etcd.advertise-client-urls: https://11.0.1.111:2379
creationTimestamp: null
labels:
component: etcd
tier: control-plane
name: etcd
namespace: kube-system
spec:
containers:
- command:
- etcd
- --advertise-client-urls=https://11.0.1.111:2379
- --cert-file=/etc/kubernetes/pki/etcd/server.crt
- --client-cert-auth=true #false改为true
- --data-dir=/var/lib/etcd
......
#编辑完后重新加载配置文件,并重启 kubelet
root@master01:~# systemctl daemon-reload
root@master01:~# systemctl restart kubelet.service #修改完成后,等待 5 分钟,再检查一下所有 pod,确保模拟环境里的所有 pod 都正常。
#*****************************************
注:\# 退出 root,退回到 candidate@master01
root@master01:~# exit
logout
Connection to master01 closed.
root@node01:~# exit
exit
candidate@node01:~$
#*****************************************
#考试时,要确保这个kube-apiserver-master01 是正常running状态的
candidate@node01:~$ kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
calico-apiserver calico-apiserver-556f6d894-7z9xn 1/1 Running 5 (50m ago) 157d
calico-apiserver calico-apiserver-556f6d894-ncc4w 1/1 Running 5 (50m ago) 157d
calico-system calico-kube-controllers-687c447f4b-75xfq 1/1 Running 5 (50m ago) 157d
calico-system calico-node-8xgq7 1/1 Running 5 (50m ago) 157d
calico-system calico-node-d8wrr 1/1 Running 5 (50m ago) 157d
calico-system calico-node-mzz24 1/1 Running 5 (50m ago) 157d
calico-system calico-typha-6d6f5f8cbf-rt545 1/1 Running 5 (50m ago) 157d
calico-system calico-typha-6d6f5f8cbf-zcjwz 1/1 Running 5 (50m ago) 157d
calico-system csi-node-driver-29ckz 2/2 Running 11 (45m ago) 157d
calico-system csi-node-driver-jwghc 2/2 Running 10 (50m ago) 157d
calico-system csi-node-driver-r7xxz 2/2 Running 10 (50m ago) 157d
db web-pod 1/1 Running 3 (50m ago) 155d
default redis123-56c7cd579-wzk9f 1/1 Running 3 (50m ago) 155d
dev-team products-service 1/1 Running 3 (50m ago) 155d
kamino tri111 1/1 Running 3 (50m ago) 155d
kamino tri222 2/2 Running 6 (50m ago) 155d
kamino tri333 2/2 Running 6 (50m ago) 155d
kamino tri444 1/1 Running 3 (50m ago) 155d
kube-system coredns-857d9ff4c9-7zmvq 1/1 Running 5 (50m ago) 157d
kube-system coredns-857d9ff4c9-pk8vm 1/1 Running 5 (50m ago) 157d
kube-system etcd-master01 1/1 Running 0 2m57s
kube-system kube-apiserver-master01 1/1 Running 0 39m
kube-system kube-controller-manager-master01 1/1 Running 8 (5m45s ago) 157d
kube-system kube-proxy-v9vzq 1/1 Running 5 (50m ago) 157d
kube-system kube-proxy-vgkdl 1/1 Running 5 (50m ago) 157d
kube-system kube-proxy-x5qrq 1/1 Running 5 (50m ago) 157d
kube-system kube-scheduler-master01 1/1 Running 8 (5m41s ago) 157d
qa qatt 1/1 Running 3 (50m ago) 155d
qaqa qaqa-pod 1/1 Running 3 (50m ago) 155d
sec-ns secdep-7988476f56-t9tf2 2/2 Running 6 (50m ago) 155d
server busybox-run-7b598f4679-ggvr7 1/1 Running 3 (50m ago) 155d
server nginx-host-69c64cb4fb-xsd9b 1/1 Running 3 (50m ago) 155d
server run-test-5898f87bbf-z6dmj 1/1 Running 3 (50m ago) 155d
tigera-operator tigera-operator-55585899bf-7f4x5 1/1 Running 12 (3m30s ago) 157d
2 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。
操作
#考试时务必执行,切换集群。模拟环境中不需要执行。
candidate@node01:~$ kubectl config use-context k8s
error: no context exists with the name: "k8s"
#创建 ServiceAccount
#方法一官网复制内容
candidate@node01:~$ vim qa-ns.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: backend-sa #修改name
namespace: qa #添加namespace
automountServiceAccountToken: false #false表示不自动挂载
#方法二命令行创建
candidate@node01:~$ kubectl create serviceaccount backend-sa --namespace=qa --dry-run=client -oyaml > qa-sa.yaml
candidate@node01:~$ vim qa-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: backend-sa
namespace: qa
automountServiceAccountToken: false #添加此行
candidate@node01:~$ kubectl apply -f qa-ns.yaml
serviceaccount/backend-sa created
candidate@node01:~$ kubectl get sa -n qa
NAME SECRETS AGE
backend-sa 0 12s
default 0 155d
test01 0 155d
#创建 Pod 使用该 ServiceAccount
candidate@node01:~$ vim /cks/sa/pod1.yaml
apiVersion: v1
kind: Pod
metadata:
name: backend
namespace: qa #注意命名空间是否对
spec:
serviceAccountName: backend-sa # 没有则添加一行,有则修改这一行为刚才创建的 ServiceAccount(考试时,默认已有这一行,需要修改。)
containers:
- image: nginx:1.9
imagePullPolicy: IfNotPresent
name: backend
candidate@node01:~$ kubectl apply -f /cks/sa/pod1.yaml #应用配置
pod/backend created
candidate@node01:~$ kubectl get pod -n qa
NAME READY STATUS RESTARTS AGE
backend 1/1 Running 0 7s
qatt 1/1 Running 3 (68m ago) 155d
#删除没有使用的 ServiceAccount
candidate@node01:~$ kubectl get sa -n qa #查看所有qa下的pod
NAME SECRETS AGE
backend-sa 0 6m20s
default 0 155d
test01 0 155d
candidate@node01:~$ kubectl get pod -n qa -o yaml|grep -i serviceAccountName #查看default和backend-sa都已使用
{
"apiVersion":"v1","kind":"Pod","metadata":{
"annotations":{
},"name":"backend","namespace":"qa"},"spec":{
"containers":[{
"image":"nginx:1.9","imagePullPolicy":"IfNotPresent","name":"backend"}],"serviceAccountName":"backend-sa"}}
serviceAccountName: backend-sa
serviceAccountName: default
#删除不用的 sa
candidate@node01:~$ kubectl delete sa test01 -n qa #删除不用的 sa
serviceaccount "test01" deleted
3 默认网络策略
题目
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 找到一个模板清单文件。
实操
#考试时务必执行,切换集群。模拟环境中不需要执行。
candidate@node01:~$ kubectl config use-context k8s
error: no context exists with the name: "k8s"
#修改yaml文件
candidate@node01:~$ vim /cks/net/p1.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: denypolicy #修改 name
namespace: testing #注意添加 namespace
spec:
podSelector: {
} #所有pod
policyTypes:
- Ingress #注意看题,是 Ingress + Egress(入口+出口),还是只是 Ingress 或只是 Egress。
- Egress #在 1.28 的考试中,只要求拒绝所有 Egress 流量,那就只写这这个- Egress 即可,这种情况就不要写- Ingress 了。
candidate@node01:~$ kubectl apply -f /cks/net/p1.yaml #创建
networkpolicy.networking.k8s.io/denypolicy created
#检查
candidate@node01:~$ kubectl describe networkpolicies denypolicy -n testing
Name: denypolicy
Namespace: testing
Created on: 2024-07-22 13:14:31 +0800 CST
Labels: <none>
Annotations: <none>
Spec:
PodSelector: <none