1、Pod 使用 ServiceAccount
参考资料:https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-service-account/
大致意思这样:1、创建一个 SA(ServiceAccount)2、修改已有 yaml 文件指定创建的 SA3、删除当前命名空间中未绑定 Pod 的 SA
创建一个sa
kubectl create serviceaccount backend-sa
修改yaml指定sa
kubectl get pod/nginx -o yaml > pod-nginx.ymlapiVersion: v1kind: Podmetadata:name: nginxspec:containers:- image: nginxname: nginxserviceAccountName: backend-sa # 修改这里# Pod 被创建时服务账户必须存在,否则会被拒绝。# 你不能更新已经创建好的 Pod 的服务账户。kubectl delete po/nginxkubectl create -f pod-nginx.yml
删除未被使用的serviceaccount
# 查询所有名命空间下所有的serviceaccountkubectl get serviceaccount# 查询所有被使用的serviceaccountkubectl get pod -o yaml | grep -i serviceaccountname# 删除未被使用的kubectl delete serviceaccount geray
2、kube-bench
解读:使用 kube-bench 工具检查集群组件配置文件存在的问题与修复,并重启对应组件确保新配置生效。
修复以下 apiserver 发现的问题:

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

修复以下 kubelet 发现的问题:

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

修复一下etcd发现的问题:

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

最后重启kubelet服务
# kubelet 获取配置文件systemctl cat kubelet | grep -i Environment# 修改 yaml 后,默认会重启容器,正常可以不用使用这个命令再重启,为确保重启生效可以再执行下systemctl restart kubelet
3、网络策略
参考资料 : https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/

解读:在 testing 命名空间创建一个名为 denypolicy 的网络策略。拒绝所有 Ingress 和Egress 流量。将网络策略应用到 testing 命名空间中的所有 pod。
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:name: testingspec:podSelector: {}policyTypes:- Ingress- Egress
- 拒绝所有pod进出流量
4、Pod安全策略(PSP)- 将被启用
参考资料:https://kubernetes.io/zh/docs/concepts/policy/pod-security-policy/

解读:Create a new PodSecurityPolicy named restrict-policy,which prevents the creation of privieged Pods.1. 创建一个名为 restrict-policy 的 PodSecurityPolicy,防止创建特权 Pod2. 创建一个名为 restrict-access-role 的 ClusterRole 能够使用 PSP restrict-policy3. 在 staging 命名空间创建一个名为 psp-denial-sa 的 ServiceAccount4. 最后,创建一个名为 dany-access-bind 的 ClusterRoleBinding,绑定 ClusterRolerestrict-access-role 到 ServiceAccount psp-denial-sa
4.1 启用PSP准入控制器
# 启用 PSP 准入控制器vi /etc/kubernetes/manifests/kube-apiserver.yaml- --enable-admission-plugins=NodeRestriction,PodSecurityPolicysystemctl restart kubelet
4.2 配置安全策略
vi psp.yamlapiVersion: policy/v1beta1kind: PodSecurityPolicymetadata:name: restrict-policyspec:privileged: false # Don't allow privileged pods!# The rest fills in some required fields.seLinux:rule: RunAsAnysupplementalGroups:rule: RunAsAnyrunAsUser:rule: RunAsAnyfsGroup:rule: RunAsAnyvolumes:- '*'kubectl apply -f psp.yaml
4.3 使用PSP
# 创建clusterrole(使用psp策略)kubectl create clusterrole restrict-access-role --verb=use --resource=psp --resource-name=restrict-policy# 创建serviceaccount在staging命名空间kubectl create sa psp-denial-sa -n staging# 创建ClusterRoleBinding绑定clusterrole和staging命名空间中的sakubectl 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/

解读:1. 在 db 命名空间存在一个名为 web-pod 的 Pod2. 编辑该 Pod 绑定的 ServiceAccount service-account-web Role,只允许对 Endpoints 资源类型执行 get 操作3. 在 db 命名空间创建一个名为 role-2 的 Role,该角色只允许对 namespaces 资源类型执行delete 操作4. 创建一个名为 role-2-binding 的 RoleBinding,绑定到 ServiceAccount
kubectl edit role -n dbapiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata:namespace: dbname: role-1rules:- apiGroups: [""]resources: ["endpoints"]verbs: ["get"]
# 在 db 命名空间创建一个名为 role-2 的 Role,该角色只允许对 namespaces 资源类型执行delete 操作kubectl create role role-2 -n db --verb=delete --resource=namespaces# 创建一个名为 role-2-binding 的 RoleBinding,绑定到 ServiceAccountkubectl create rolebinding role-2-binding --role=role-2 --serviceaccount=db:service-account-web -n db
6、日志审计
参考资料:https://kubernetes.io/zh/docs/tasks/debug-application-cluster/audit/

解读:在集群启用审计,并确保: 日志路径为 /var/log/kubernetes/audit-logs.txt 日志文件保留 10 天 最多保留 2 个日志文件基本策略在/etc/kubernetes/logpolicy/sample-policy.yaml 文件(该文件在 master 节点上)中提供,它指定了不记录的内容编辑和扩展基本策略: 命名空间在 RequestResponse 级别更改 PV 的request请求内容级别在 front-apps 命名空间发生了更改 Configmap 和 secret 在所有命名空间 Metadata 级别更改
做这道题之前最好先备份配置文件
# 配置策略文件vi /etc/kubernetes/logpolicy/sample-policy.yamlapiVersion: audit.k8s.io/v1 # This is required.kind: PolicyomitStages:- "RequestReceived"rules:- level: RequestResponseresources:- group: ""resources: ["namespaces"]- level: Requestresources:- group: ""resources: ["persistentVolumes"]namespace: front-apps- level: Metadataresources:- group: ""resources: ["configmaps","secrets"]- level: MetadataomitStages:- "RequestReceived"
# 开启日志审计并设置日志路径、保留天数、日志数量以及策略文件位置vi /etc/kubernetes/manifests/kube-apiserver.yaml...# 设置日志审计参数- --audit-policy-file=/etc/kubernetes/logpolicy/sample-policy.yaml- --audit-log-path=/var/log/kubernetes/audit-logs.txt- --audit-log-maxage=10- --audit-log-maxbackup=2...# volumeMounts挂载日志升级策略到容器- mountPath: /etc/kubernetes/logpolicy/sample-policy.yamlname: log-policyreadOnly: true- mountPath: /var/log/kubernetes/audit-logs.txtname: log-auditreadOnly: false...# volumes中添加挂载- hostPath:path: /etc/kubernetes/logpolicy/sample-policy.yamltype: Filename: log-policy- hostPath:path: /var/log/kubernetes/audit-logs.txttype: FileOrCreatename: log-audit# 最后重启kubeletkubectl restart kubelet
7、创建Secret
参考资料:https://kubernetes.io/zh/docs/concepts/configuration/secret/

解读:1、在 istio-system 命名空间存在一个名为 db1-test 的 secret,将 username 字段保存到文件名为/home/candidate/user.txt 和 password 字段保存到文件名为/home/candidate/pass.txt注:文件需要自己创建2、在 istio-system 命名空间创建一个名为 db2-test 的 secret,内容如下:username: production-instancepassword: KvLftKgs4aVH最后,创建一个新的 Pod,可以通过 volume 方式访问 secret 内容。
kubectl get secret db1-test -n istio-system -o jsonpath={.data.username} | base64 -d > /home/candidate/user.txtkubectl get secret db1-test -n istio-system -o jsonpath={.data.password} | base64 -d > /home/candidate/pass.txtkubectl create secret generic db2-test -n istio-system --from-literal=username=production-instance --from-literal=password=KvLftKgs4aVHapiVersion: v1kind: Podmetadata:name: secret-podnamespace: istio-systemspec:containers:- name: dev-containerimage: nginxvolumeMounts:- name: secret-volumemountPath: "/etc/secret"volumes:- name: secret-volumesecret:secretName: db2-testkubectl exec -it pod/secret-pod -n istio-system -- sh
8、Dockerfile和Deployment优化

解读:分析和编辑给定的 Dockerfile(基于 Ubuntu:16.04 镜像)/home/candidate/KSSC00301/Dockerfile,修复文件中有突出安全性和最佳实践问题。分析和编辑给定的 YAML 清单文件/home/candidate/KSSC00301/deployment.yaml,修复文件中字段存在安全性和最佳实践问题。
# Dockerfile禁用root用户vi /home/candidate/KSSC00301/Dockerfile#USER root# 这里应该使用USER指定非root用户vi /home/candidate/KSSC00301/deployment.yaml…securityContext:capabilities:add: ["NET_BIND_SERVICE"]#privileged: true # 关闭这个特权启用
- user root 一共有两行
- 对 deploy 也注释2行 true的
9、沙箱运行容器gVisor
参考资料:https://kubernetes.io/zh/docs/concepts/containers/runtime-class/

描述:这个集群使用 containerd 作为 CRI 运行时。Containerd 的默认运行时处理程序是runc,containerd 也支持额外的运行时处理程序 runsc(gVisor)解读:创建一个名为 untrusted 的 RuntimeClass,使用准备好的运行时处理程序 runsc。更新 server 命名空间中的所有 Pod 使其在 gVisor 上运行。
- 注:这个题目前有点变化,可能会让你修改 3 个 deployment
vi /home/candidate/KSMV00301/runtime-class.yamlapiVersion: node.k8s.io/v1 # RuntimeClass 定义于 node.k8s.io API 组kind: RuntimeClassmetadata:name: untrusted # 用来引用 RuntimeClass 的名字# RuntimeClass 是一个集群层面的资源handler: runsc # 对应的 CRI 配置的名称kubectl edit deployment web -n serverspec:runtimeClassName: untrustedcontainers:- image: nginximagePullPolicy: Alwaysname: nginx
10、删除启用的特权pod
参考资料:https://kubernetes.io/zh/docs/concepts/security/pod-security-standards/

解读:检查在 production 命名空间运行的 Pod,并删除任何不是非无状态(有状态)或非不可变(可变)的 Pod以下是对无状态和不可变的解释: 在容器中存储数据的 Pod 视为非无状态(不用担心容器数据持久化) 启用特权的 Pod 都视为潜在的非无状态和非不可变
kubectl get pod -n productionkubectl get pod <pod-name> -n production -o yaml | grep "privileged: true"kubectl delete pod <pod-name> -n production
11、网络策略
参考资料 : https://kubernetes.io/zh/docs/concepts/services-networking/network-policies

解读:创建一个名为 pod-restriction 的网络策略,以限制命名空间 dev-team 中 products-service Pod。只允许以下 Pod 连接 products-service Pod: qa 命名空间中的 Pod Pod 标签为 environment:testing,在所有命名空间
# 查看products-service的pod的标签kubectl get pod products-service -n dev-team --show-labels# 查看qa命名空间的标签vi network-policy.yamlapiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:name: pod-restrictionnamespace: dev-teamspec:podSelector:matchLabels:environment: stagingpolicyTypes:- Ingressingress:- from:- namespaceSelector:matchLabels:name: qa- from:- namespaceSelector: {} # 这个namespace是必须的吗,表示所有命名空间podSelector:matchLabels:environment: testing
12、ImagePolicyWebhook (需要加强)
参考资料 : https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#imagepolicywebhook

提示:必须在集群 master 节点完成任务,其中包含的所有服务和文件已准备好。解读:在/etc/kubernetes/epconfig 目录下有一个不完整的配置和一个功能容器镜像扫描器HTTPS 端点:https://acme.local:8082/image_policy1. 启用准入控制插件2. 验证控制配置并将其更改为默认拒绝。3. 修改配置文件,指向正确的 HTTPS 端点最后,尝试部署易受供攻击的资源来测试配置是否有效。/root/KSSC00202/ulnerable-manifest.yml查看容器扫描日志:/var/log/imagepolicy/roadrunner.log
# 第一步vi /etc/kubernetes/manifests/kube-apiserver.yaml…- --enable-admission-plugins=NodeRestriction,ImagePolicyWebhook- --admission-control-config-file=/etc/kubernetes/epconfig/admission_configuration.json...# 在容器 volumeMounts 增加- mountPath: /etc/kubernetes/epconfigname: epconfig# 在 volumes 增加- name: epconfighostPath:path: /etc/kubernetes/epconfig# 第二步vi /etc/kubernetes/epconfig/admission_configuration.jsondefaultAllow: false# 第三步vi /etc/kubernetes/epconfig/kubeconfig.yamlserver: https://acme.local:8082/image_policysystemctl restart kubelet# 第四步 测试kubectl apply -f /root/KSSC00202/ulnerable-manifest.ymltail /var/log/imagepolicy/roadrunner.log
操作顺序:
- 1、修改admission_configuration.yaml配置文件(指定连接镜像服务器配置文件路径&修改defaultAllow为false)
- 2、修改kubeconfig.yaml(指定正确的server地址)
- 3、启动插件策略并指定配置文件以及挂载
- 4、查看日志
13、Trivy扫描镜像安全漏洞

解读:对 kamino 命名空间中 pod 使用 Trivy 工具扫描镜像安全漏洞。查找具有高危或严重漏洞的镜像,并删除使用这些镜像的 Pod。注:Trivy 已经预装集群的 master 节点,工作节点不可用。
14、AppArmor
参考资料:https://kubernetes.io/zh/docs/tutorials/clusters/apparmor

解读:在集群的工作节点上,执行下面准备好的配置文件/etc/apparmor.d/nginx_apparmor编辑准备好的清单文件/home/candidate/KSSH00401/nginx-deploy.yaml 应用于 AppArmor 文件。最后,在 Pod 中应用 apparmor 策略文件。
# 先进入工作节点操作ssh kssh00401-worker1# 确认策略名称vi /etc/apparmor.d/nginx_apparmor# nginx-profile-3或者apparmor_status | grep nginxapparmor_parser /etc/apparmor.d/nginx_apparmor # 加载策略# 在管理节点操作vi /home/candidate/KSSH00401/nginx-deploy.yaml…annotations:container.apparmor.security.beta.kubernetes.io/<容器名称>: localhost/nginx-profile-3kubectl apply -f /home/candidate/KSSH00401/nginx-deploy.yaml
15、启用kubernetes API认证
描述:kubeadm 创建的集群的 Kubernetes API 服务器,出于测试目的,临时配置为允许未经身份验证和未经授权的访问,授予匿名用户集群管理员访问权限。要求:重新配置集群的 Kubernetes API 服务器以确保只允许经过身份验证和授权的 API 请求。 使用授权模式 Node、RBAC 和准入控制器 NodeRestriction 删除名为 system:anonymous 的 ClusterRoleBinding
vi /etc/kubernetes/manifests/kube-apiserver.yaml- kube-apiserver- --authorization-mode=Node,RBAC # 只保留这两个- --enable-admission-plugins=NodeRestriction # 只保留这一个systemctl restart kubelet# 删除角色绑定kubectl delete clusterrolebinding system:anonymous
