test
1.创建 Secret
环境准备:
kubectl create namespace istio-system
kubectl create secret generic test-app --namespace istio-system --from-literal=username=test --from-literal=password=123456
参考资料:
三个网址都要看
- https://kubernetes.io/zh/docs/tasks/configmap-secret/managing-secret-using-kubectl/#decoding-secret
- https://kubernetes.io/zh/docs/tasks/configmap-secret/managing-secret-using-kubectl/#create-a-secret
- https://kubernetes.io/zh/docs/concepts/configuration/secret/#using-secret
您必须在以下 cluster /节点上完成此考题
Cluster Master 节点 工作节点
KSMV00201
ksmv00201-master
ksmv00201-worker1
您可以使用以下命令来切换 cluster / 配置环境:
[candidate@cli] $kubectl config use-context KSMV00201
Task
在namespace istio-system 中获取名为 test-app 的现有 secret 的内容。
将 username 字段存储在名为 /home/candidate/user.txt 的文件中,
并将password 字段存储在名为 /home/candidate/password.txt 的文件中。
您必须创建以上两个文件; 它们还不存在
==不要在以下步骤中使用/修改先前创建的文件,如果需要创建新的临时文件。==
在 istio-system namespace
中创建一个名为 test-workflow
的新 secret,
内容如下:
username: dev-database
password: aV7HR7nU3JLx
最后,创建一个新的 Pod,它可以通过卷访问 secret test-workflow :
Pod名 test-secret-pod
Namespace istio-system
容器名 dev-container
镜像 nginx
卷名 secret-volume
挂载路径 /etc/secret
答题步骤:
1 将 test-app 的 username 和 password,通过 base64 解码保存到题目指定文件:
#方法 1:
root@cka-master01:~# kubectl get secrets test-app -n istio-system -o jsonpath={.data}
{"password":"MTIzNDU2","username":"dGVzdA=="}r
mkdir /home/candidate/ -pv
echo 'dGVzdA=='|base64 -d > /home/candidate/user.txt
echo 'MTIzNDU2'|base64 -d > /home/candidate/password.txt
#方法 2:
mkdir /home/candidate/ -pv
kubectl get secrets -n istio-system test-app -o jsonpath={.data.username} | base64 -d > /home/candidate/user.txt
kubectl get secrets -n istio-system test-app -o jsonpath={.data.password} | base64 -d > /home/candidate/password.txt
#检查
cat /cks/sec/user.txt
cat /cks/sec/pass.txt
2 创建名为 db2-test 的 secret 使用题目要求的用户名和密码作为键值。注意要加命名空间。
#注意,如果密码中有特殊字符(例如:$,\,*,= 和 !),需要加单引号来转义--from-literal=password='G!Y\*d$zDsb'这样。
kubectl create secret generic test-workflow -n istio-system --from-literal=username=dev-database --from-literal=password=aV7HR7nU3JLx
#检查
root@cka-master01:~# kubectl get secret -n istio-system test-workflow
NAME TYPE DATA AGE
test-workflow Opaque 2 25s
3 根据题目要求,参考官网,创建 Pod 使用该 secret
vim k8s-secret.yaml
#添加如下内容
apiVersion: v1
kind: Pod
metadata:
name: test-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: test-workflow #名为 test-workflow 的 secret
#创建
kubectl apply -f k8s-secret.yaml
#检查
root@cka-master01:~# kubectl get pod -n istio-system
NAME READY STATUS RESTARTS AGE
test-secret-pod 1/1 Running 0 4s
2.ImagePolicyWebhook (准入控制器)容器镜像扫描
环境准备:
mkdir /etc/kubernetes/controlconf -pv
cd /etc/kubernetes/controlconf
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssl_1.6.0_linux_amd64
wget https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssljson_1.6.0_linux_amd64
chmod +x cfssl*
mv cfssl_1.6.0_linux_amd64 /usr/local/bin/cfssl
mv cfssljson_1.6.0_linux_amd64 /usr/local/bin/cfssljson
cat << EOF | cfssl genkey - | cfssljson -bare server
{
"hosts": [
"acme.local",
"acme.local.svc.cluster.local",
"acme.local.pod.cluster.local",
"172.22.136.223",
"10.244.1.0/24"
],
"CN": "system:node:acme.local.pod.cluster.local",
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"O": "system:nodes"
}
]
}
EOF
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: acme.local
spec:
request: $(cat server.csr | base64 | tr -d '\n')
signerName: kubernetes.io/kubelet-serving
usages:
- digital signature
- key encipherment
- server auth
EOF
kubectl get csr|grep 'Pending'| awk 'NR>0{print $1}' |xargs kubectl certificate approve
kubectl get csr acme.local -o jsonpath='{.status.certificate}' | base64 --decode > server.crt
kubectl create namespace local
kubectl create secret tls tls-acme --key /etc/kubernetes/controlconf/server-key.pem --cert /etc/kubernetes/controlconf/server.crt --namespace local
cat << EOF > /etc/kubernetes/controlconf/image-bouncer-webhook.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: acme
name: acme
namespace: local
spec:
ports:
- name: https
port: 8082
targetPort: 1323
protocol: "TCP"
selector:
app: acme
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: acme
namespace: local
spec:
selector:
matchLabels:
app: acme
template:
metadata:
labels:
app: acme
spec:
containers:
- name: image-bouncer-webhook
imagePullPolicy: Always
image: "kainlite/kube-image-bouncer:latest"
args:
- "--cert=/etc/admission-controller/tls/tls.crt"
- "--key=/etc/admission-controller/tls/tls.key"
- "--debug"
volumeMounts:
- name: tls
mountPath: /etc/admission-controller/tls
volumes:
- name: tls
secret:
secretName: tls-acme # Webhook 证书的 tls 密钥 和密钥
EOF
kubectl apply -f /etc/kubernetes/controlconf/image-bouncer-webhook.yaml
echo $(kubectl get service -n local acme -o jsonpath='{.spec.clusterIP}') acme.local >> /etc/hosts
cat << EOF >> /etc/kubernetes/controlconf/kubeconfig.yml
apiVersion: v1
kind: Config
clusters:
- cluster:
certificate-authority: /etc/kubernetes/controlconf/server.crt
server: server
name: bouncer_webhook
contexts:
- context:
cluster: bouncer_webhook
user: api-server
name: bouncer_validator
current-context: bouncer_validator
preferences: {}
users:
- name: api-server
user:
client-certificate: /etc/kubernetes/pki/apiserver.crt
client-key: /etc/kubernetes/pki/apiserver.key
EOF
cat << EOF >> /etc/kubernetes/controlconf/admission_configuration.json
{
"imagePolicy": {
"kubeConfigFile": "/etc/kubernetes/controlconf/kubeconfig.yml",
"allowTTL": 50,
"denyTTL": 50,
"retryBackoff": 500,
"defaultAllow": true
}
}
EOF
mkdir /root/KSSC00202
cat << EOF >> /root/KSSC00202/configuration-test.yml
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx-latest
spec:
replicas: 1
selector:
app: nginx-latest
template:
metadata:
name: nginx-latest
labels:
app: nginx-latest
spec:
containers:
- name: nginx-latest
image: nginx # 不写标签默认是nginx:latest
ports:
- containerPort: 80
EOF
参考资料: 三个网址都要看
- https://kubernetes.io/zh/docs/reference/access-authn-authz/admission-controllers/#%E5%A6%82%E4%BD%95%E5%90%AF%E7%94%A8%E4%B8%80%E4%B8%AA%E5%87%86%E5%85%A5%E6%8E%A7%E5%88%B6%E5%99%A8
- https://kubernetes.io/zh/docs/reference/access-authn-authz/admission-controllers/#imagepolicywebhook
- https://kubernetes.io/zh/docs/tasks/debug/debug-cluster/audit/#log-%E5%90%8E%E7%AB%AF
您必须在以下 cluster群 彪啊傍佬嫡尺节点上完成此考题:
Cluster Master 节点 工作节点
KSSC00202
kssc00202-master
kssc00202-worker1
您可以使用以下命今来切换 cluster /配置环境
[candidate@cli] $kubectl config use-context KSSCO0202
Context
cluster 上设置了容器镜像扫描器,但尚未完全集成到 cluster 的配置中。完成后,容器镜像扫描器应扫描并拒绝易受攻击的镜像的使用。
Task
您必须在 cluster的 master 节点上完成整个考题,所有服务和文件都已被准备好并放置在该节点上。
给定一个目录 /etc/kubernetes/controlconf 中不完整的配置以及具有HTTPS 端点 https://acme.local:8082/image_policy
的功能性容器镜像扫描器:
- 启用必要的插件来创建镜像策略
- 校验控制配置并将其更改为隐式拒绝(implicit deny)
- 编辑配置以正确指向提供的 HTTPS 端点
最后,通过尝试部署易受攻击的资源
/root/KSSC00202/configuration-test.yml
来测试配置是否有效
==您可以在 /var/log/imagepolicy/wakanda.log
找到容器镜像扫描仪的日志文件。==
答题步骤:
本题分数比较多,占 10%
第 1 步 切换到 Master 的 root 下
ssh master01
sudo -i
第 2 步,编辑 admission_configuration.json(题目会给这个目录),修改 defaultAllow 为 false:
vi /etc/kubernetes/controlconf/admission_configuration.json
……
"denyTTL": 50,
"retryBackoff": 500,
"defaultAllow": false #将 true 改为 false
……
第 3 步,编辑/etc/kubernetes/controlconf/kubeconfig.yml,添加 webhook server 地址:
#操作前,先备份配置文件
mkdir backup
cp /etc/kubernetes/controlconf/kubeconfig.yaml backup/
vi /etc/kubernetes/controlconf/kubeconfig.yaml
#修改如下内容
……
certificate-authority: /etc/kubernetes/controlconf/ca.crt
server: https://acme.local:8082/image_policy #添加 webhook server 地址
name: image-checker
……
第 4 步,编辑 kube-apiserver.yaml,从官网中引用 ImagePolicyWebhook 的配置信息:
#操作前,先备份配置文件
mkdir backup
cp /etc/kubernetes/manifests/kube-apiserver.yaml backup/
vi /etc/kubernetes/manifests/kube-apiserver.yaml
#在- command:下添加如下内容,注意空格要对齐
- --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook
- --admission-control-config-file=/etc/kubernetes/controlconf/admission_configuration.json #在 1.23 的考试中,默认这行已经添加了,但为了以防万一,模拟环境,没有添加,需要你手动添加。考试时,你先检查,有的话,就不要再重复添加了。重复添加反而会报错!
# 在 kube-apiserver.yaml 的 volumeMounts 增加
volumeMounts: #在 volumeMounts 下面增加 #注意,在 1.23 考试中,蓝色的内容可能已经有了,你只需要添加绿色字体的内容。可以通过红色字,在文件中定位。但模拟环境没有加,需要你全部手动添加。这样是为了练习,万一考试中没有,你也会加。但是如果考试中已添加,你再添加一遍,则会报错,导致 api-server 启不起来。
- mountPath: /etc/kubernetes/controlconf
name: kubeconfig
readOnly: true
# 在 kube-apiserver.yaml 的 volumes 增加
volumes: #在 volumes 下面增加 #注意,在 1.23 考试中,蓝色的内容可能已经有了,你只需要检查确认一下是否准确。可以通过红色字,在文件中定位。
#但模拟环境没有加,需要你全部手动添加。这样是为了练习,万一考试中没有,你也会加。但是如果考试中已添加,你再添加一遍,则会报错,导致 api-server启不起来。
- name: kubeconfig
hostPath:
path: /etc/kubernetes/controlconf
type: DirectoryOrCreate
#如果你写的是目录,则是 DirectoryOrCreate,如果你写的是文件,则是 File
第 5 步,重启 kubelet。
systemctl restart kubelet
#通过尝试部署易受攻击的资源 /root/KSSC00202/configuration-test.yml 来测试配置是否有效
#无法创建 pod,如下报错,表示成功。
#因为模拟环境里的 image_policy 策略是镜像 tag 是 latest 的不允许创建。
kubectl apply -f /root/KSSC00202/configuration-test.yml
第 6 步 退回到原 ssh 终端
# 退出 root,退回到 candidate@master01
exit
# 退出 master01,退回到 candidate@node01
exit
3.网络策略 NetworkPolicy
环境准备:
mkdir /home/candidate/KSSHO0301 -pv
cat << EOF >> /home/candidate/KSSHO0301/network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: multi-port-egress
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 32000
endPort: 32768
EOF
kubectl create namespace development
参考资料:
Quick Reference |
---|
文档 NetworkPolicy ,Pod ,Namespace
|
您必须在以下 cluster /节点上完成此考题
Cluster Master 节点 工作节点
KSSH00301
kssh00301-master
kssh00301-worker1
您可以使用以下命今来切换 cluster /配置环境
[candidate@cli] $kubectl config use-context KSSHO0301
Task
创建一个名为 pod-restriction
的 NetworkPolicy 来限制对在 namespace development
中运行的 Pod users-service
的访问
只允许以下 Pod 连接到 Pod users-service
:
- namespace
qa
中的 Pod - 位于任何 namespace ,带有标签
environment: staging
的 Pod
==确保应用 NetworkPolicy 。==
==你可以在 /home/candidate/KSSHO0301/network-policy.yaml
找到个模板清单文件。==
答题步骤:
1 检查 namespace 标签
#模拟环境已提前打好标签了,所以你只需要检查标签即可。但为了防止考试时,没有给你打标签,所以还是需要你将下面打标签的命令记住。
# 查看 qaqa 命名空间标签(name: qaqa)
kubectl get ns --show-labels
# 查看 pod 标签(environment: testing)
kubectl get pod -n development --show-labels
如果 Pod 或者 Namespace 没有标签,则需要打上标签。
#注意:我这里将 pod users-service 的标签打成了 environment: staging,下面会有解释,不要和题目里要求的“位于任何 namespace,带有标签 environment: staging 的 Pod”这句话里的标签混淆了。
# kubectl label ns qa name=qa
# kubectl label pod users-service environment=staging -n development
2 创建 NetworkPolicy
vi /home/candidate/KSSHO0301/network-policy.yaml
#根据官网,修改为如下内容:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: pod-restriction #修改
namespace: development #修改
spec:
podSelector:
matchLabels:
environment: staging #根据题目要求的标签修改,这个写的是 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: qa #命名空间有 name: qaqa 标签的
- from: #第二个 from
- namespaceSelector: {} #修改为这样,所有命名空间
podSelector: #注意,这个 podSelector 前面的“-” 要删除,换成空格,空格对齐要对。
matchLabels:
environment: staging #有 environment: testing 标签的 Pod,这个地方是根据题目要求“Pods with label environment: testing , in any namespace”,这句话里的 pod 标签写的。不要和上面 spec 里的混淆。
#创建
kubectl apply -f /home/candidate/KSSHO0301/network-policy.yaml
#检查
kubectl get networkpolicy -n dev-team
4.沙箱运行容器 gVisor
环境准备:
mkdir /home/candidate/KSMV00301 -pv
cat << EOF > /home/candidate/KSMV00301/runtime-class.yaml
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: myclass
handler: mycofiguration
EOF
kubectl create namespace client
kubectl create deployment busybox-run --image nginx --namespace client
kubectl create deployment nginx-host --image nginx --namespace client
kubectl create deployment run-test --image nginx --namespace client
参考资料:
Quick Reference |
---|
文档 RuntimeClass ,Pod ,Namespace
|
您必须在以下 cluster /节点上完成此考题
Cluster Master 节点 工作节点
KSMV00301
ksmv00301-master
ksmv00301-worker1
您可以使用以下命令来切换 cluster / 配置环境:
[candidate@cli] $kubectl config use-context KSMV00301
Context
该 cluster 使用 containerd
作为 CRI运行时。containerd
的默认运行时处理程序是 runc
。containerd
已准备好支持额外的运行时处理程序 runsc
( gVisor ) 。
Task
使用名为 runsc
的现有运行时处理程序,创建一个名为 untrusted
的RuntimeClass .
更新 namespace client 中的所有 Pod 以在gVisor 上运行
==你可以在 /home/candidate/KSMV00301/runtime-class.yaml
找到一个模板清单文件。==
答题步骤:
1 创建 RuntimeClass
vi /home/candidate/KSMV00301/runtime-class.yaml
#修改如下内容
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: untrusted # 用来引用 RuntimeClass 的名字,RuntimeClass 是一个集群层面的资源
handler: runsc # 对应的 CRI 配置的名称
#创建
kubectl apply -f /home/candidate/KSMV00301/runtime-class.yaml
#检查
root@cka-master01:~# kubectl get runtimeclasses.node.k8s.io
NAME HANDLER AGE
untrusted runsc 8s
2 将命名空间为 client 下的 Pod 引用 RuntimeClass。
#考试时,3 个 Deployment 下有 3 个 Pod,修改 3 个 deployment 即可。
kubectl -n client get deployment
#编辑 deployment
kubectl -n client edit deployments busybox-run
kubectl -n client edit deployments nginx-host
kubectl -n client edit deployments run-test
#修改如下内容
spec: #找到这个 spec,注意在 deployment 里是有两个单独行的 spec 的,要找第二个,也就是下面有 containers 这个字段的 spec。
runtimeClassName: untrusted #添加这一行,注意空格对齐,保存会报错,忽略即可。
containers:
- image: nginx:1.9
imagePullPolicy: IfNotPresent
name: run-test
#因为模拟环境没有安装 runsc 运行环境,所以改完后,新 Pod 是ContainerCreating 状态。考试时,改完后 Pod 会重建并 Running 的
5.Pod指定ServiceAccount
准备环境:
mkdir /home/candidate/KSCHO0301/ -pv
kubectl create namespace dev
kubectl create serviceaccount test01 --namespace dev
cat << EOF >> /home/candidate/KSCH00301/pod-manifest.yaml
apiVersion: v1
kind: Pod
metadata:
name: backend
spec:
containers:
- name: nginx
image: nginx
ports:
- name: nginx
targetPort: 80
EOF
Quick Reference |
---|
文档 ServiceAccount ,Pod ,Namespace
|
您必须在以下 cluster /节点上完成此考题:
Cluster Master 节点 工作节点
KSCH00301
ksch00301-master
ksch00301-worker1
您可以使用以下命今来切换 cluster / 配置环境:
[candidate@cli] $kubectl config use-context KSCHO0301
Context
您组织的安全策略包括:
- ServiceAccount 不得自动挂载API 凭据
- ServiceAccount 名称必须以“-sa”结尾
清单文件 /home/candidate/KSCHO0301/pod-manifest.yaml
中指定的 Pod由于 ServiceAccount 指定错误而无法调度。
请完成以下项目:
Task
在现有 namespace dev
中创建一个名为 database-sa
的新ServiceAccount 确保此 ServiceAccount 不自动挂载 API 凭据
使用 /home/candidate/KSCH00301/pod-manifest.yaml
中的清单文件来创建一个Pod。
最后,清理 namespace dev
中任何未使用的 ServiceAccount。
题目操作:
1 创建 ServiceAccount
vi dev-ns.yaml
根据官网修改如下内容
apiVersion: v1
kind: ServiceAccount
metadata:
name: database-sa #修改 name
namespace: dev #注意添加 namespace
automountServiceAccountToken: false #修改为 false,表示不自动挂载 secret
kubectl apply -f dev-ns.yaml
kubectl get sa -n dev
2 创建 Pod 使用该 ServiceAccount
vi /home/candidate/KSCH00301/pod-manifest.yaml修改如下内容
……
metadata:
name: backend
namespace: dev #注意命名空间是否对
spec:
serviceAccountName: backend-sa # 没有则添加一行,有则修改这一行为刚才创建的 ServiceAccount(考试时,默认已有这一行,需要修改。)
containers:
……
kubectl apply -f /home/candidate/KSCH00301/pod-manifest.yaml
kubectl get pod -n dev
3. 删除没有使用的 ServiceAccount
查看所有 sa
kubectl get sa -n dev
查看已经在用的 sa
kubectl get pod -n dev -o yaml | grep -i serviceAccountName
删除不用的 sa
kubectl delete sa test01 -n dev
6.日志审计 log audit
环境准备:
mkdir /etc/kubernetes/logpolicy -p
cat << EOF >> /etc/kubernetes/logpolicy/audit-policy.yaml
apiVersion: audit.k8s.io/v1 # 这是必填项。
kind: Policy
# 不要在 RequestReceived 阶段为任何请求生成审计事件。
omitStages:
- "RequestReceived"
rules:
# 在日志中用 RequestResponse 级别记录 Pod 变化。
- level: RequestResponse
resources:
- group: ""
# 资源 "pods" 不匹配对任何 Pod 子资源的请求,
# 这与 RBAC 策略一致。
resources: ["pods"]
# 在日志中按 Metadata 级别记录 "pods/log"、"pods/status" 请求
- level: Metadata
resources:
- group: ""
resources: ["pods/log", "pods/status"]
# 不要在日志中记录对名为 "controller-leader" 的 configmap 的请求。
- level: None
resources:
- group: ""
resources: ["configmaps"]
resourceNames: ["controller-leader"]
# 不要在日志中记录由 "system:kube-proxy" 发出的对端点或服务的监测请求。
- level: None
users: ["system:kube-proxy"]
verbs: ["watch"]
resources:
- group: "" # core API 组
resources: ["endpoints", "services"]
# 不要在日志中记录对某些非资源 URL 路径的已认证请求。
- level: None
userGroups: ["system:authenticated"]
nonResourceURLs:
- "/api*" # 通配符匹配。
- "/version"
# 在日志中记录 kube-system 中 configmap 变更的请求消息体。
- level: Request
resources:
- group: "" # core API 组
resources: ["configmaps"]
# 这个规则仅适用于 "kube-system" 名字空间中的资源。
# 空字符串 "" 可用于选择非名字空间作用域的资源。
namespaces: ["kube-system"]
# 在日志中用 Metadata 级别记录所有其他名字空间中的 configmap 和 secret 变更。
- level: Metadata
resources:
- group: "" # core API 组
resources: ["secrets", "configmaps"]
# 在日志中以 Request 级别记录所有其他 core 和 extensions 组中的资源操作。
- level: Request
resources:
- group: "" # core API 组
- group: "extensions" # 不应包括在内的组版本。
# 一个抓取所有的规则,将在日志中以 Metadata 级别记录所有其他请求。
- level: Metadata
# 符合此规则的 watch 等长时间运行的请求将不会
# 在 RequestReceived 阶段生成审计事件。
omitStages:
- "RequestReceived"
EOF
参考文档:
您必须在以下 cluster /节点上完成此考题
Cluster Master 节点 工作节点
KSRS00602
ksrs00602-master
ksrs00602-worker1
您可以使用以下命今来切换 cluster /配置环境:
[candidate@cli] $kubectl config use-context KSRS00602
Task
在 cluster 中启用审计日志。为此,请启用日志后端,并确保:
- 日志存储在
/var/log/kubernetes/logs.txt
- 日志文件能保留
10
天 - 最多保留
1
个日审计日志文件
/etc/kubernetes/logpolicy/audit-policy.yaml
提供了基本策略。
它仅指定不记录的内容。
==基本策略位于 cluster的 master 节点上==
编辑和扩展基本策略以记录:
- RequestResponse 级别的
cronjobs
更改 - namespace
frontweb
中deployments
更改的请求体 -
Metadata
级别的所有 namespace 中的 ConfigMap 和 Secret 的更改
此外,添加一个全方位的规则以在 Metadata
级别记录所有其他请求
==不要忘记应用修改后的策略==
答题步骤:
#本题分数比较多,占 12%。
#日志审计这一题需要自己调整的内容还是挺多的,因此要非常仔细,建议修改前备份一下原始的环境,要不然修改错了就会导致集群崩溃。
#1 切换到 Master 的 root 下
ssh master01
sudo -i
#2.配置审计策略
#先备份配置文件
mkdir backup
cp /etc/kubernetes/logpolicy/audit-policy.yaml backup/
vim /etc/kubernetes/logpolicy/audit-policy.yaml
#参考官方网址内容
……rules:
# namespaces changes at RequestResponse level
- level: RequestResponse
resources:
- group: ""
resources: ["cronjobs"] #根据题目要求修改,比如题目要求的是 namespaces或者persistentvolumes。
#the request body of persistentvolumes/pods changes in the namespace front-apps
- level: Request
resources:
- group: ""
resources: ["deployments"] #根据题目要求修改,比如题目要求的是 configmaps 或者 persistentvolumes 或者 pods。
namespaces: ["frontweb"]
# Log configmap and secret changes in all other namespaces at the Metadata level.
- level: Metadata
resources:
- group: ""
resources: ["secrets", "configmaps"]
# Also, add a catch-all rule to log all other requests at the Metadata level.
- level: Metadata
omitStages:
- "RequestReceived"
#3 配置 master 节点的 kube-apiserver.yaml
#先备份配置文件
mkdir backup
cp /etc/kubernetes/manifests/kube-apiserver.yaml backup/
vi /etc/kubernetes/manifest
# 添加以下参数,注意空格要对齐,注意检查,如果考试中已经存在了则不要重复添加。
- command:
- --audit-policy-file=/etc/kubernetes/logpolicy/audit-policy.yaml #定义审计策略yaml文件位置,通过 hostpath 挂载
- --audit-log-path=/var/log/kubernetes/logs.txt #定义审计日志位置,通过 hostpath 挂载
- --audit-log-maxage=10 #定义保留旧审计日志文件的最大天数为 10 天
- --audit-log-maxbackup=1 #定义要保留的审计日志文件的最大数量为 1 个
volumeMounts: #找到这个字段,添加下面内容
- mountPath: /etc/kubernetes/logpolicy/audit-policy.yaml #这里也可以写到目录/etc/kubernetes/logpolicy/
name: audit
readOnly: true #这个为 true
- mountPath: /var/log/kubernetes/
name: audit-logs
readOnly: false #这个为 false
volumes: #找到这个字段,添加下面内容
- hostPath:
path: /etc/kubernetes/logpolicy/audit-policy.yaml
type: File #file如果写到目录/etc/kubernetes/logpolicy/,则type:应为 type: DirectoryOrCreate
name: audit
- hostPath:
path: /var/log/kubernetes/
type: DirectoryOrCreate
name: audit-logs
#4 重启 kubelet 服务
systemctl restart kubelet
等待 2 分钟后,再检查
kubectl get pod -A
tail /var/log/kubernetes/logs.txt
# 退出 root,退回到 candidate@master01
exit
# 退出 master01,退回到 candidate@node01
exit
7.AppArmor(限制容器对资源的访问)
环境准备:
cat << EOF >>/etc/apparmor.d/nginx_apparmor
#include <tunables/global>
nginx-profile-3
profile nginx-profile-3 flags=(attach_disconnected) {
#include <abstractions/base>
file,
# 拒绝所有文件写入
deny /** w,
}
EOF
mkdir /home/candidate/KSSH00401 -pv
cat << EOF >> /home/candidate/KSSH00401/nginx-ds.yaml
apiVersion: v1
kind: Pod
metadata:
name: podx
spec:
containers:
- image: busybox
imagePullPolicy: IfNotPresent
name: podx
command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]
resources: {}
nodeName: node01
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
EOF
参考资料:
Quick Reference |
---|
文档 AppArmor ,Pod ,Node
|
您必须在以下 cluster /节点上完成此考题:
Cluster Master 节点 工作节点
KSSH00401
kssh00401-master
kssh00401-worker1
您可以使用以下命令来切换 cluster /配置环境:
[candidate@cli] $kubectl config use-context KSSHO0401
Context
AppArmor 已在 cluster 的工作节点上被启用。一个AppArmor 配置文件已存在,但尚未被实施。
==您可以使用浏览器打开一个额外的标签页来访问 AppArmor 的文档
==
Task
在cluster 的工作节点上,实施位于 /etc/apparmor.d/nginx_apparmor
的现有AppArmor 配置文件
编辑位于 /home/candidate/KSSH00401/nginx-ds.yaml
的现有清单文件以应用AppArmor 配置文件。
最后,应用清单文件并创建其中指定的 Pod。
答题步骤:
1 切换到 node02 的 root 下
ssh node02
sudo -i
2 切换到 apparmor 的目录,并检查配置文件
cd /etc/apparmor.d/
#在考试时,可以先 cat /etc/apparmor.d/nginx_apparmor,有错误则改,没错误,则不要再改了
cat /etc/apparmor.d/nginx_apparmor
#include <tunables/global>
# nginx-profile-3 #注释掉 模拟环境里多写了一行的,会导致 apparmor_parser -q 的时候会报错。
profile nginx-profile-3 flags=(attach_disconnected) {
#这句是正确的配置,不要修改。profile 后面的 nginx-profile-3 为 apparmor 策略模块的名字。
file,
# 拒绝所有文件写入
deny /** w,
}
3 执行 apparmor 策略模块
#没有 grep 到,说明没有启动。
apparmor_status | grep nginx-profile-3
#加载启用这个配置文件
apparmor_parser -q /etc/apparmor.d/nginx_apparmor
# 再次检查有结果了
root@cka-master1:~# apparmor_status | grep nginx
nginx-profile-3
4 修改 pod 文件
vi /home/candidate/KSSH00401/nginx-ds.yaml
#修改如下内容
……
metadata:
name: podx
annotations:
container.apparmor.security.beta.kubernetes.io/podx: localhost/nginx-profile-3
#添加 annotations,kubernetes.io/podx 名字和 containers 下的名字一样即可,nginx-profile-3 为前面在 worker node01 上执行的 apparmor 策略模块的名字。
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
# 退出 root,退回到 candidate@node02
exit
# 退出 node02,退回到 candidate@node01
exit
8.Trivy 扫描镜像安全漏洞
环境准备:
https://github.com/aquasecurity/trivy
wget https://github.com/aquasecurity/trivy/releases/download/v0.48.2/trivy_0.48.2_Linux-64bit.tar.gz
tar -zxf trivy_0.48.2_Linux-64bit.tar.gz
mv trivy /usr/local/bin/
kubectl create namespace naboo
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: tri222
namespace: naboo
spec:
containers:
- name: amazonlinux
image: amazonlinux:1
- name: nginx
image: nginx:1.19
EOF
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: tri333
namespace: naboo
spec:
containers:
- name: amazonlinux
image: amazonlinux:2
- name: vicuu-nginx
image: vicuu/nginx:host
EOF
参考资料:
Quick Reference |
---|
文档 Trivy
|
您必须在以下 cluster /节点上完成此考题
Cluster Master 节点 工作节点
KSSC00401
kssc00401-master
kssc00401-worker1
您可以使用以下命今来切换 cluster /配置环境
[candidate@cli] $kubectl config use-context KSSCO0401
==您可以使用浏览器打开一个额外的标签页来访问 Trivy 的文档
==
Task
使用 Trivy 开源容器扫描器检测 namespace naboo
中 Pod 使用的具有严重漏洞的镜像
查找具有 High 或 Critical 严重性漏洞的镜像,并删除使用这些镜像的 Pod
==Trivy 仅预装在 cluster 的 master 节点上; 它在原本的系统或工作节点上不可用。您必须连接到 cluster 的 master 节点才能使用 Trivy。==
答题步骤:
注意:这个题非常耗费时间,考试时关注一下剩余时间。如果时间剩余不多,可以放到最后做这道题。
方法 1:(推荐,能快一些)
1 切换到 Master 的 candidate 下
ssh master01
2 获取命名空间 naboo 下的所有 pod 的 image
kubectl get pods --namespace naboo --output=custom-columns="NAME:.metadata.name,IMAGE:.spec.containers[*].image"
3 检查镜像是否有高危和严重的漏洞
trivy image -s HIGH,CRITICAL nginx:1.19 # HIGH,CRITICAL,这里的 nginx:1.19 换成你上一步查出来的镜像名字
# 或者也可以使用这条命令查询 trivy image nginx:1.19 | grep -iE 'High|Critical'
# 注意 tri222 和 tri333 的 2 个 pod 里各有 2 个 image,都需要扫描。
trivy image -s HIGH,CRITICAL amazonlinux:1
trivy image -s HIGH,CRITICAL amazonlinux:2
trivy image -s HIGH,CRITICAL nginx:1.19
trivy image -s HIGH,CRITICAL vicuu/nginx:host
4 删除有问题的 pod
kubectl delete pod XXXX -n kamino
5 退出 master01,退回到 candidate@node01
exit
#请注意,考试时有 5 个 pod,每个 pod 里有多个 image 镜像,都需要扫描。扫描出有漏洞的镜像,则删除有这个镜像的 pod。
#另外,网友 WilliamLee 还提供了一种方法,对 shell 命令比较熟习的,可以参考。
#让它后台扫,然后退出来继续做其他的,做完其他的回来看报告,删 pod。
#注意别忘了每道题要切换集群。
方法 2:(太消耗时间,因为考试时,有 5 个 pod,而且每一个 pod 里面还有两三个 image)
# 切换到 Master 的 root 下
ssh master01
#检查所有 pod
kubectl get pod -n naboo
#获取每一个 pod 的 image
kubect get pod XXXX -n naboo -o yaml | grep image
#检查镜像是否有高危和严重的漏洞
trivy image -s HIGH,CRITICAL nginx:1.19 # HIGH,CRITICAL,这里的 nginx:1.19 换成你上一步查出来的镜像名字
#或者也可以使用下面命令查询: trivy image nginx:1.19 | grep -iE 'High|Critical'
# 删除有问题的 pod
kubectl delete pod XXXX -n naboo
# 退出 master01,退回到 candidate@node01
exit
#请注意,考试时有 5 个 pod,每个 pod 里有多个 image 镜像。检查出有漏洞的镜像,则删除有这个镜像的 pod。
方法 3:(写 while 脚本有点麻烦)
(对于 pod 数量多的情况,可以使用下面方法)
# 切换到 Master 的 root 下
ssh master01
检查所有 pod
kubectl get po -n naboo
kubectl get po -n naboo | grep -v "NAME" | awk '{print $1}' > podlist.txt
cat podlist.txt
#循环检查 pod 里的 image
while read line;do
echo $line
kubectl get pod -n naboo $line -o yaml | grep "image:"
done < podlist.txt
#对查出来的 image 逐一扫描
trivy image -s HIGH,CRITICAL nginx:1.19 #注意 HIGH,CRITICAL 为大写
#删除扫描的镜像带有高危或严重漏洞的 Pod
kubectl delete pod XXXX -n kamino
# 退出 master01,退回到 candidate@node01
exit
9.容器安全,更改特权 Pod
准备环境:
mkdir /home/candidate/finer-sunbeam/ -pv
kubectl create namespace lamp
cat << EOF > /home/candidate/finer-sunbeam/lamp-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: lamp-deployment
namespace: lamp
spec:
replicas: 1
selector:
matchLabels:
app: lamp
template:
metadata:
labels:
app: lamp
spec:
containers:
- name: lamp-container
image: nginx
securityContext:
readOnlyRootFilesystem: false
allowPrivilegeEscalation: true
EOF
kubectl apply -f /home/candidate/finer-sunbeam/lamp-deployment.yaml
Quick Reference |
---|
文档 Deployment ,Pod ,Namespace
|
您必须在以下 cluster /节点上完成此考题:
Cluster 控制平面节点 工作节点
KSRS00502
ksrs00502-master
ksrs00502-worker1
您可以使用以下命令来切换 cluster /配置环境:
[candidate@cli] $kubectl config use-context KSRS00502
Context
必须更新一个现有的Pod 以确保其容器 的不变性
Task
修改运行在namespace lamp
,名为 lamp-deployment
的现有 Deployment使其容器 :
- 使用用户ID
10000
运行 - 使用一个只读的根文件系统
- 禁止特权提升
👉您可以在 /home/candidate/finer-sunbeam/lamp-deployment.yaml 找到lamp-deployment 的清单文件
答题步骤:
apiVersion: apps/v1
kind: Deployment
metadata:
name: lamp-deployment
namespace: lamp
spec:
replicas: 1
selector:
matchLabels:
app: lamp
template:
metadata:
labels:
app: lamp
spec:
securityContext:
runAsUser: 10000
containers:
- name: lamp-container
image: nginx
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
10.默认网络策略
Quick Reference |
---|
文档 NetworkPolicy ,Pod ,Namespace
|
您必须在以下 cluster /节点上完成此考题:
Cluster Master 节点 工作节点
KSCS00101
kscs00101-master
kscs00101-worker1
您可以使用以下命今来切换 cluster /配置环境
[candidate@cli] $kubectl config use-context KSCS00101
Context
一个默认拒绝 (default-deny) 的 NetworkPolicy 可避免在未定义任何其他NetworkPolicy的namespace 中意外公开 Pod。
Task
为所有类型为 Ingress + Egress
的流量在 namespace development
中创建一个名为 denypolicy
的新默认拒绝 NetworkPolicy。
此新的 NetworkPolicy 必须拒绝 namespace development 中的所有Ingress + Egress 流量
将新创建的默认拒绝 NetworkPolicy 应用于在 namespace development 中运行的所有 Pod 。
==你可以在 /home/candidate/KSCS00101/network-policy.yaml
找到一个模板清单文件。==
准备环境:
mkdir -pv /home/candidate/KSCS00101
vim /home/candidate/KSCS00101/network-policy.yaml
kubectl create namespace development
考题操作:
#创建名为 denypolicy 的 NetworkPolicy,拒绝 testing 命名空间内所有 Ingress + Egress 流量
#(这里可能是 ingress 或 egress 或 ingress+egress,根据题目要求写。)
vi /home/candidate/KSCS00101/network-policy.yaml
#修改为
……
metadata:
name: denypolicy #修改 name
namespace: development #注意添加 namespace
spec:
podSelector: {}
policyTypes:
- Ingress #注意看题,是 Ingress + Egress(入口+出口),还是只是 Ingress 或只是 Egress。
- Egress #在 1.23 的考试中,只要求拒绝所有 Egress 流量,那就只写这这个- Egress 即可,这种情况就不要写- Ingress 了。
#创建
kubectl apply -f /home/candidate/KSCS00101/network-policy.yaml
#检查
kubectl describe networkpolicy denypolicy -n testing
11.启用 API server 认证
环境准备:
参考资料:
Quick Reference |
---|
文档 kubeadm ,ClusterRoleBinding ,kubect
|
您必须在以下 cluster /节点上完成此考题
Cluster Master 节点 工作节点
KSCH00101
ksch00101-master
ksch00101-worker1
您可以使用以下命今来切换 cluster /配置环境
[candidate@cli] $kubectl config use-context KSCH00101
Context
由 kubeadm
创建的集群的 Kubernetes API 服务器,出于测试目的,临时配置为允许未经身份验证和未经授权的访问,授予匿名用户 cluster-admin 的访问权限。
Task
重新配置 cluster的 Kubernetes API 服务器以确保只允许经过身份验证和授又的 REST 请求
使用授权模式 Node,RBAC
和准入控制器 NodeRestriction
.
删除用户 system:anonymous
的 ClusterRoleBinding 来进行清理
==所有kubectl
配置环境/文件也被配置为使用未经身份验证和未经授权的访问。==
==您不必更改它,但请注意,一旦完成 cluster 的安全加固,kubectl
的配置将无法工作。==
==您可以使用位于 cluster 的 master 节点上, cluster 原本的kubectl
配置文件 /etc/kubernetes/admin.conf
,以确保经过身份验证和授权的请求仍然被允许==
答题步骤:
1 切换到 Master 的 root 下
ssh master01
sudo -i
请先执行如下命令,模拟这道题的初始环境。
脚本在 master01 的/root 目录下。
sh b.sh
2 确保只有认证并且授权过的 REST 请求才被允许
#编辑/etc/kubernetes/manifests/kube-apiserver.yaml,修改下面内容
- --authorization-mode=AlwaysAllow
- --enable-admission-plugins=AlwaysAdmit
vi /etc/kubernetes/manifests/kube-apiserver.yaml
#修改为
- --authorization-mode=Node,RBAC #注意,只保留 Node,RBAC 这两个,中间是英文状态下的逗号。在 1.23 考试中,这一条可能默认已经有
了,但还是要检查确认一下。
- --enable-admission-plugins=NodeRestriction #在 1.23 考试中,这一个原先为 AlwaysAdmit,需要修改为 NodeRestriction。
- --client-ca-file=/etc/kubernetes/pki/ca.crt #这一条也要检查一下,是否存在配置文件中,如果没有,也需要添加。在 1.23 考试中,这一条默认已经有了。
- --enable-bootstrap-token-auth=true #这一条也要检查一下,是否存在配置文件中,如果没有,也需要添加。在 1.23 考试中,这一条默认已经有了。
#网友反馈和纠正
#重启 kubelet
systemctl daemon-reload
systemctl restart kubelet
#修改完成后,等待 3 分钟,集群才会恢复正常。
kubectl get pod -A
3 删除题目要求的角色绑定
#查
kubectl get clusterrolebinding system:anonymous
#删
kubectl delete clusterrolebinding system:anonymous
#再检查
kubectl get clusterrolebinding system:anonymous
# 退出 root,退回到 candidate@master01
exit
# 退出 master01,退回到 candidate@node01
exit
12.RBAC - RoleBinding
环境准备:
kubectl create ns db
kubectl -n db create serviceAccount test-sa-3
kubectl -n db create role role-1
kubectl -n db create role role-1 --verb=get,list,watch --resource='*'
kubectl -n db create rolebinding role-1-binding --role='role-1' --serviceaccount='db:test-sa-3'
cat << EOF > /opt/pod1.yaml
apiVersion: v1
kind: Pod
metadata:
name: web-pod
namespace: db
spec:
serviceAccountName: test-sa-3
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: web-pod
EOF
kubectl apply -f /opt/pod1.yaml
Quick Reference |
---|
文档 Role ,RoleBinding ,ServiceAccount ,Pod
|
您必须在以下 cluster /节点上完成此考题:
Cluster Master 节点 工作节点
KSCH00201
ksch00201-master
ksch00201-worker1
您可以使用以下命令来切换 cluster /配置环境
candidate@cli] $kubectl config use-context KSCHO0201
Context
绑定到 Pod 的 ServiceAccount的 Role 授予过度宽松的权限。完成以下项目以减少权限集
Task
一个名为 web-pod
的现有 Pod 已在namespace db
中运行
编辑绑定到 Pod 的 ServiceAccount test-sa-3
的现有 Role,仅允许只对 endpoints
类型的资源执行 watch
操作。
在namespace db
中创建一个名为 role-2
,并仅允许只对 namespaces
类型的资源 执行 update
操作的新 Role。
创建一个名为 role-2-binding
的新 RoleBinding,将新创建的 Role 绑定到 Pod 的 ServiceAccount 。
==请勿删除现有的 RoleBinding==
答题步骤:
#查看 ServiceAccount test-sa-3 对应的 rolebindings role-1-binding
#查看 rolebindings role-1-binding 对应的 role 为 role-1
root@cka-master01:~# kubectl describe rolebindings -n db
Name: role-1-binding
Labels: <none>
Annotations: <none>
Role:
Kind: Role
`Name: role-1`
Subjects:
Kind Name Namespace
---- ---- ---------
`ServiceAccount test-sa-3 db`
#编辑 role-1 权限:
kubectl edit role role-1 -n db
#修改如下内容
……
resourceVersion: "30867"
uid: 22e3c185-f7f5-4542-b86a-6ce153aa1c5a
rules: #模拟环境里要删除掉 null,然后添加以下内容。考试时,要根据实际情况修改。
- apiGroups: [""]
resources: ["endpoints"] #只允许对 endpoints 资源类型执行 watch 操作。还有可能会考只允许对 services 资源 list 的操作
verbs: ["watch"] # 三种权限watch,get,list
#检查
root@cka-master01:~# kubectl describe role -n db role-1
Name: role-1
Labels: <none>
Annotations: <none>
PolicyRule:
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
`endpoints [] [] [watch]`
#在 db 命名空间, 创建名为 role-2 的 role,并且通过 rolebinding 绑定 test-sa-3,只允许对 namespaces 做 delete 操作。
#记住 --verb 是权限,可能考 delete 或者 update 等 --resource 是对象,可能考 namespaces 或者 persistentvolumeclaims 等。
kubectl create role role-2 --verb=update --resource=namespaces -n db
kubectl create rolebinding role-2-binding --role=role-2 --serviceaccount=db:test-sa-3 -n db
#检查
root@cka-master01:~# kubectl describe rolebindings -n db role-2-binding
Name: role-2-binding
Labels: <none>
Annotations: <none>
Role:
Kind: Role
`Name: role-2`
Subjects:
Kind Name Namespace
---- ---- ---------
`ServiceAccount test-sa-3 db`
13.第14题 TLS通信加强【新题】
Quick Reference |
---|
文档 cipher suites
|
您必须在以下 cluster /节点上完成此考题!
Cluster Master 节点 工作节点
KSMV00401
ksmv00401-master
ksmv00401-worker1
您可以使用以下命今来切换 cluster / 配置环境
[candidate@cli] $kubectl config use-context KSMV00401
Context
个现有的 Kubernetes 集群应通过更新其中一部分组件的 TLS 配置来进行加固。
Task
修改API 服务器和 etcd 之间通信的 TLS 配置
对于API服务器,删除对除 TLS 1.2
及更高版本之外的所有 TLS 版本的支持。此外,删除对除 TLS_ECDHE_ECDSA_WITH AES_128_GCM_SHA256
之外的所有密码套件 的支持
==确保应用配置的更改==
对于etcd
,删除对除 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
之外的所有密码套件的支持。
==确保应用配置的更改。==
答题步骤:
# 修改kube-apiserver.yaml, vim /etc/kubernetes/manifests/kube-apiserver.yaml,删除如下两行,
- --tls-min-version=VersionTLS13
- --tls-cipher-suites=TLS_AES_128_GCM_SHA256
# 修改etcd.yaml, vim /etc/kubernetes/manifests/etcd.yaml,参考etcd命令帮助,删除如下一行,
- --cipher-suites=TLS_AES_128_GCM_SHA256
14.Sysdig & falco
环境准备:
node:
curl -s https://s3.amazonaws.com/download.draios.com/stable/install-sysdig | sudo bash
mkdir /opt/KSR00101/incidents/ -pv
master:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: tomcat
spec:
containers:
- name: tomcat
image: tomcat:7.0.59
EOF
Quick Reference |
---|
文档 Falco ,Deployment ,Pod ,kubectl
|
您必须在以下 cluster /节点上完成此考题:
Cluster Master 节点 工作节点
KSRS00101
ksrs00101-master
ksrs00101-worker1
您可以使用以下命令来切换 cluster /配置环境
[candidate@cli] $kubectl config use-context KSRS00101
==您可以使用浏览器打开一个额外的标签页来访问 Falco 的文档。==
Task
使用运行时检测工具检测在属于 Pod tomcat
的单个容器中频繁产生和执行的异常进程。
cluster 的工作节点上已预装了两个工具:
sysdig
falco
使用您选择的工具(包括任何非预安装的工具),分析容器的行为至少 120秒,使用过滤器检测新生成和执行的进程。
==没有预安装的工具是被刻意配置成可以检测上述定义的异常进程的。==
在 /opt/KSRS00101/incidents/summary中存储一个事件文件,其中包含检测到的事件,每行一个,格式如下:
timestamp,uid or username,processName
以下示例显示了格式正确的事件文件
01:40:19.601363716,root,init
01:40:20.606013716,nobody,bash
01:40:21.137163716,1000,tar
==保持工具原本的时间戳格式==
==确保将事件文件存储在 cluster 的工作节点上。==
答题步骤:
#网友的反馈,之前的考试环境的 K8S 集群使用的容器全是 docker,新考试环境,部分使用 docker,部分使用 containerd。
#这也证明了 CKS 确实有多套考试环境的。
#所以此题给出了两个方法,方法 1 是 containerd 的,方法 2 是 docker 的。
#考试时,你可以先 docker ps 看一下,如果没有这个 pod,则应该是使用的 containerd。
考试形式 1 :K8S 集群使用 containerd
1 切换到 node02 的 root 下
ssh node02
sudo -i
2、先找到 containerd 的 socket
crictl info | grep sock
3、crontainerd 要使用 crictl 命令找到容器,题目要求的是 tomcat123,则 grep tomcat。
crictl ps | grep tomcat
4、通过 sysdig 扫描容器 30s 并输出到指定文件:sysdig -h 和-l 查看帮助
#注:可以使用 sysdig -l |grep time 过滤,确认输出格式字段
sysdig -l | grep time
sysdig -l | grep uid
sysdig -l | grep proc
#开始扫描 (我目前想不到别的方法,只能将命令分成 2 条了,谁有更好的方法,可以分享一下。)
sysdig -M 120 -p "%evt.time,%user.uid,%proc.name" --cri /run/containerd/containerd.sock container.name=tomcat >> /opt/KSR00101/incidents/summary
sysdig -M 120 -p "%evt.time,%user.name,%proc.name" --cri /run/containerd/containerd.sock container.name=tomcat >> /opt/KSR00101/incidents/summary
#提示:如果考试时执行 sysdig 报错“Unable to load the driver”,则执行下面一条命令:(模拟环境里不需要执行)
#启用模块
sysdig-probe-loader
#然后再次执行 sysdig -M 30 ……
#如果还是报错,就重装一下 sysdig,命令为 apt install sysdig
#查看保存的文件
root@cka-node1:~# cat /opt/KSR00101/incidents/summary |head
11:25:21.238100288,root,java
11:25:21.238102819,root,java
11:25:21.238103334,root,java
11:25:21.238111198,root,java
11:25:21.238114193,root,java
11:25:21.288211283,root,java
11:25:21.288218106,root,java
11:25:21.288219427,root,java
11:25:21.288233586,root,java
11:25:21.288241225,root,java
# 退出 root,退回到 candidate@node02
exit
# 退出 node02,退回到 candidate@node01
exit
考试形式 2 :K8S 集群使用 docker(1.24 基本不考这种了)
#以下命令记住即可,模拟环境使用的是 containerd。
1 切换到 node02 的 root 下
ssh node02
sudo -i
#首先找到容器的 container id:,我这里的容器 id 为 40c3c3e8b813
docker ps | grep tomcat
#通过 sysdig 扫描容器 30s 并输出到指定文件:
sysdig -h 和-l 查看帮助
#注:可以使用 sysdig -l |grep time 过滤,确认输出格式字段
sysdig -l | grep time
sysdig -l | grep uid
sysdig -l | grep proc
#开始扫描
sysdig -M 30 -p "%evt.time,%user.uid,%proc.name" container.id=40c3c3e8b813 > /opt/KSR00101/incidents/summary
#查看保存的文件
cat /opt/KSR00101/incidents/summary |head
# 退出 root,退回到 candidate@node02
exit
# 退出 node02,退回到 candidate@node01
exit
15. kube-bench 修复不安全项
您必须在以下 cluster /节点上完成此考题:
Cluster Master 节点 工作节点
KSCS00201
kscs00201-master
kscs00201-worker1
您可以使用以下命今来切换 cluster /配置环境
[candidate@cli] $kubectl config use-context KSCS00201
Context
针对 kubeadm
创建的 cluster 运行 CIS 基准测试工具时,发现了多个必须立即解决的问题
Task
通过配置修复所有问题并重新启动受影响的组件以确保新设置生效。
修复针对 Kubelet 发现的所有以下违规行为:
2.1.2 Ensure that the --anonymous-auth argument is set to false FAIL
2.1.3 Ensure that the --authorization-mode argument is not set to AlwaysAllow FAIL
翻译:
2.1.2确保anonymous-auth参数设置为false 失败
2.1.3确保——authorization-mode参数没有设置为alwaysallow 失败
==尽可能使用 Webhook
身份验证/授权==
修复针对 etcd 发现的所有以下违规行为:
2.2 Ensure that the --client-cert-auth argument is set to true FAIL
翻译:
2.2确保——client-cert-auth参数设置为true 失败
环境配置:
wget https://github.com/aquasecurity/kube-bench/releases/download/v0.6.17/kube-bench_0.6.17_linux_amd64.deb
dpkg -i kube-bench_0.6.17_linux_amd64.deb
root@cka-master1:~# sed -i 's/- --authorization-mode=Node,RBAC/#- --authorization-mode=Node,RBAC/g' /etc/kubernetes/manifests/kube-apiserver.yaml
root@cka-master1:~# cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep -e "- --authorization-mode=Node,RBAC"
#- --authorization-mode=Node,RBAC
做题操作:
# 1 切换到 Master 的 root 下
ssh master01
sudo -i
sh a.sh
# 2 修改 api-server
kube-bench master
# 查出来的,可能很多不安全项,但只修改考题要求的哪几项就行的。
#修改之前,备份一下配置文件。
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
# 3 修改 kubelet
kube-bench node
#修复方法 1:(推荐)
#如果考试时,你用方法 1 改完后, kubelet 启动不了, 肯定是你哪里改错了,如果又排查不出来, 则恢复此文件, 再使用方法 2 修改。
systemctl status kubelet
cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
#中你也会看到 Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"。
#所以去修改这个文件
#修改之前,备份一下配置文件。
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
修复方法 2:(不推荐, 建议用方法 1)
考试中,任选一种方法即可,模拟环境里推荐第一种方法。
systemctl status kubelet
修改之前,备份一下配置文件
mkdir bak1
cp /etc/systemd/system/kubelet.service.d/10-kubeadm.conf bak1/
vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
#在[Service]下面添加
Environment="KUBELET_SYSTEM_PODS_ARGS=--anonymous-auth=false"
Environment="KUBELET_AUTHZ_ARGS=--authorization-mode=Webhook"
#在 ExecStart 后追加
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS
$KUBELET_SYSTEM_PODS_ARGS $KUBELET_AUTHZ_ARGS
#编辑完后重新加载配置文件,并重启 kubelet
systemctl daemon-reload
systemctl restart kubelet.service
# 4 修改 etcd
kube-bench
#修改之前,备份一下配置文件。
mkdir bak1
cp /etc/kubernetes/manifests/etcd.yaml bak1/
vim /etc/kubernetes/manifests/etcd.yaml
#修改
- --client-cert-auth=true #修改为 true
修改完成后,等待 2 分钟,再检查一下所有 pod,确保模拟环境里的所有 pod 都正常。
kubectl get pod -A
# 退出 root,退回到 candidate@master01
exit
# 退出 master01,退回到 candidate@node01
exit
做下一题之前,确保所有的 pod 都是 Running,特别是 kube-apiserver-master01 也正常。(考试时,也要确保这个 apiserver 是正常的)
模拟环境里, calico-apiserver 和 calico-system 的几个 pod 可能需要比较长的时间才能恢复到 Running 状态,此时只要确保其他 pod 已恢复 Running 就可以继续
做题了。
16.Dockerfile 检测
环境准备:
mkdir -pv /home/candidate/KSSC00301/
cat << EOF > /home/candidate/KSSC00301/Dockerfile
FROM ubuntu:last
RUN apt-get install -y wget curl gcc gcc-c++ make openssl-devel pcre-devel gd-devel iproute net-tools telnet && \
yum clean all && \
rm -rf /var/cache/apt/*
USER root
COPY sunnydale.sh .
ADD nginx-1.15.5.tar.gz /
RUN cd nginx-1.15.5 && \
./configure --prefix=/usr/local/nginx
--with-http_ssl_module
--with-http_stub_status_module && \
make -j 4 && make install && \
mkdir /usr/local/nginx/conf/vhost && \
cd / && rm -rf nginx* && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
USER root
CMD["./sunnydale . sh"]
ENV PATH $PATH:/usr/local/nginx/sbin
COPY nginx.conf /usr/local/nginx/conf/nginx:conf
WORKDIR /usr/local/nginx
EXPOSE 80
CMD ["nginx","-g","daemon off;"]
EOF
cat << EOF > /home/candidate/KSSC00301/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: couchdb
namespace: default
labels:
app: couchdb
version: stable
spec:
replicas: 1
revisionHistoryLimit: 3
selector:
matchLabels:
app: couchdb
version: stable
template:
metadata:
labels:
run: couchdb
spec:
containers:
- name: couchdb
image: demo:v1
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /healthCheck
port: 8080
ports
- name: http
containerPort: 8080
protocol: TCP
volumeMounts:
- name: database-storage
mountPath: /var/lib/database
securityContext:
{"Capabilities": {'add': ['NET_BIND_SERVICE','SYS_ADMIN'], 'drop': ['all']}, 'privileged': False, 'readonlyRootFilesystem': False, 'runAsUser': 65535}
resources:
limits:
cpu: 300m
memory: 500Mi
requests:
cpu: 100m
memory: 100Mi
EOF
参考资料:
您必须在以下 cluster /节点上完成此考题:
Cluster Master 节点 工作节点
KSSC00301
kssc00301-master
kssc00301-worker1
您可以使用以下命令来切换 cluster /配置环境:
[candidate@cli] $kubectl config use-context KSSCO0301
Task
分析和编辑给定的 Dockerfile /home/candidate/KSSC00301/Dockerfile
(基于 ubuntu:22.04
镜像)
并修复在文件中拥有突出的安全/最佳实践问题的两个指令
分析和编辑给定的清单文件 /home/candidate/KSSCO0301/deployment.yaml
并修复在文件中拥有突出的安全/最佳实践问题的两个字段
==请勿添加或删除配置设置; 只需修改现有的配置设置让以上两个配置设置都不再有安全/最佳实践问题。==
==如果您需要非特权用户来执行任何项目,请使用用户 ID 65535
的用户 nobody
.==
答题步骤:
注意,本次的 Dockerfile 和 deployment.yaml 仅修改即可,无需部署。
<1> 修改 Dockerfile
vi /home/candidate/KSSC00301/Dockerfile
1、仅将 CMD 上面的 USER root 修改为 USER nobody,不要改其他的 USER root。
USER nobody
2、修改基础镜像为题目要求的 ubuntu:22.04
FROM ubuntu:22.04
#修改后
FROM ubuntu:22.04
RUN apt-get install -y wget curl gcc gcc-c++ make openssl-devel pcre-devel gd-devel iproute net-tools telnet && \
yum clean all && \
rm -rf /var/cache/apt/*
USER root
COPY sunnydale.sh .
ADD nginx-1.15.5.tar.gz /
RUN cd nginx-1.15.5 && \
./configure --prefix=/usr/local/nginx
--with-http_ssl_module
--with-http_stub_status_module && \
make -j 4 && make install && \
mkdir /usr/local/nginx/conf/vhost && \
cd / && rm -rf nginx* && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
USER nobody
CMD["./sunnydale . sh"]
ENV PATH $PATH:/usr/local/nginx/sbin
COPY nginx.conf /usr/local/nginx/conf/nginx:conf
WORKDIR /usr/local/nginx
EXPOSE 80
CMD ["nginx","-g","daemon off;"]
<2> 修改 deployment.yaml
vi /home/candidate/KSSCO0301/deployment.yaml
1、template 里标签跟上面的内容不一致,所以需要将原先的 run: couchdb 修改为 app: couchdb
app: couchdb
#(注意,这里具体要改成 app: couchdb 还是其他的标签,要以考试给你的 yaml 文件的上下文其他标签为准,要与另外两个标签一致,具体见下方截图。)
感谢网友 Tse 和 adams 的反馈和纠正。
2、删除 'SYS_ADMIN' 字段,确保 'privileged': 为 False 。(CKS 考试是有多套类似考试环境的,所以有时是删 SYS_ADMIN,有时是改'privileged': False)
#注意 注意,如果考试时,本来就没有'SYS_ADMIN' 字段,且'privileged':也默认就为 False,则直接将下面绿色的这两行注释掉,就是前面加#。
securityContext:
{'Capabilities': {'add': ['NET_BIND_SERVICE'], 'drop': ['all']}, 'privileged': False, 'readonlyRootFilesystem': False, 'runAsUser': 65535}
#修改后
apiVersion: apps/v1
kind: Deployment
metadata:
name: couchdb
namespace: default
labels:
app: couchdb
version: stable
spec:
replicas: 1
revisionHistoryLimit: 3
selector:
matchLabels:
app: couchdb
version: stable
template:
metadata:
labels:
app: couchdb
spec:
containers:
- name: couchdb
image: demo:v1
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /healthCheck
port: 8080
ports
- name: http
containerPort: 8080
protocol: TCP
volumeMounts:
- name: database-storage
mountPath: /var/lib/database
securityContext:
{"Capabilities": {'add': ['NET_BIND_SERVICE'], 'drop': ['all']}, 'privileged': False, 'readonlyRootFilesystem': False, 'runAsUser': 65535}
resources:
limits:
cpu: 300m
memory: 500Mi
requests:
cpu: 100m
memory: 100Mi