一、K8s安全运维概述Kubernetes(K8s) 是一个广泛使用的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。随着 K8s 在生产环境中的普及,安全运维成为确保系统稳定性和数据安全的关键。
1.1 安全运维的重要性
— SecDevOps ![]() SecDevOps 与 DevOps相似,是一种哲学,鼓励运维人员、开发 人员、测试人员和安全人员进行更高水水平协作,将信息安全被放 在事前考虑,将安全性注入自动化流程中,以确保整个产品周期内 的信息安全。 1.2 K8s提供的安全机制为保证集群以及容器应用的安全,Kubernetes 提供了多 种安全机制,限制容器的行为,减少容器和集群的攻击面, 保证整个系统的安全性。
1.3 K8s安全运维实践思路![]() 二、部署一套完整的K8s高可用集群请移步:CKS认证 | 使用kubeadm部署K8s高可用集群(v1.26)-CSDN博客
三、CIS 安全基准介绍3.1 CIS 介绍CIS(Center for Internet Security)安全基准 是由 CIS 组织制定的一套安全标准,旨在帮助组织评估和改进其系统和应用程序的安全性。CIS 基准提供了一套详细的配置指南和最佳实践,通过遵循 CIS 基准,组织可以显著提高系统和应用程序的安全性,降低潜在的安全风险。使用 CIS-CAT 等自动化工具,可以简化评估和修复过程,确保系统和应用程序符合 CIS 基准的要求。主要用于保护常见的操作系统和软件平台免受已知的安全威胁。 互联网安全中心(CIS,Center for Internet Security),是一个非盈利组织,致力为互联网提供 免费的安全防御解决方案。
CIS 安全基准的核心概念: 1)目标
2)适用范围
CIS 安全基准的主要组成部分: (1) 控制项(CIS Controls)
(2) 配置基准(CIS Benchmarks)
(3) 自动化工具(CIS-CAT)
3.2 K8s基准测试工具kube-benchkube-bench 是由 Aqua Security 开发的一款开源工具,专门用于评估 Kubernetes 集群是否符合 CIS(Center for Internet Security)Kubernetes 基准。CIS 基准提供了一套针对 Kubernetes 的安全配置最佳实践,而 kube-bench 通过自动化扫描集群,帮助用户发现并修复不符合 CIS 基准的配置问题。以CIS K8s基准作为基础,用该工具来检查K8s是否安全部署。 主要查找不安全的配置参数、敏感的文件权限、不安全的帐户或公开端口等等。 Github项目地址:https://github.com/aquasecurity/kube-bench 3.2.1 kube-beach部署1)下载二进制包
2)解压tar包即可使用 [code]tar zxvf kube-bench_0.6.14_linux_amd64.tar.gz # 创建默认配置文件路径 mkdir /etc/kube-bench mv cfg/ /etc/kube-bench/ [root@k8s-master-1-71 ~]# ls /etc/kube-bench/cfg/ ack-1.0 cis-1.23 cis-1.6 eks-1.0.1 gke-1.0 rh-1.0 aks-1.0 cis-1.24 cis-1.6-k3s eks-1.1.0 gke-1.2.0 cis-1.20 cis-1.5 config.yaml eks-stig-kubernetes-v1r6 rh-0.7 [root@k8s-master-1-71 ~]# ls /etc/kube-bench/cfg/cis-1.24/ config.yaml etcd.yaml node.yaml controlplane.yaml master.yaml policies.yaml # 将解压的kube-bench执行程序,移动到二进制目录下 mv kube-bench /usr/bin/ [/code]
3.2.2 kube-beach使用Kube-bench 与 k8s 版本支持参考:https://github.com/aquasecurity/kube-bench/blob/main/docs/platforms.md#cis-kubernetes-benchmark-support
常用参数:
ls /etc/kube-bench/cfg/cis-1.24/ config.yaml etcd.yaml node.yaml controlplane.yaml master.yaml policies.yaml
示例1:检查master组件安全配置(通过修复方案建议进行配置修改)
执行后会逐个检查安全配置并输出修复方案及汇总信息输出: ![]() [PASS]:测试通过 [FAIL]:测试未通过,重点关注,在测试结果会给出修复建议 [WARN]:警告,可做了解 [INFO]:信息 示例2:测试项目配置文件:vi /etc/kube-bench/cfg/cis-1.24/目标文件.yaml(直接修改配置文件) ![]()
[code][root@k8s-master-1-71 ~]# kube-bench run --targets=master ## FAIL 审计问题 [FAIL] 1.1.12 Ensure that the etcd data directory ownership is set to etcd:etcd (Automated) [FAIL] 1.2.5 Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated) [FAIL] 1.2.17 Ensure that the --profiling argument is set to false (Automated) [FAIL] 1.2.18 Ensure that the --audit-log-path argument is set (Automated) [FAIL] 1.2.19 Ensure that the --audit-log-maxage argument is set to 30 or as appropriate (Automated) [FAIL] 1.2.20 Ensure that the --audit-log-maxbackup argument is set to 10 or as appropriate (Automated ) [FAIL] 1.2.21 Ensure that the --audit-log-maxsize argument is set to 100 or as appropriate (Automated) [FAIL] 1.3.2 Ensure that the --profiling argument is set to false (Automated) [FAIL] 1.4.1 Ensure that the --profiling argument is set to false (Automated) ... -------------------------------------------------------------------------------- ## 修复建议(注意:在不确定参数的情况下不建议修改) == Remediations master == 1.1.12 On the etcd server node, get the etcd data directory, passed as an argum from the command 'ps -ef | grep etcd'. Run the below command (based on the etcd data directory found above). For example, chown etcd:etcd /var/lib/etcd //etcd数据目录设置属组 1.2.5 Follow the Kubernetes documentation and setup the TLS connection between the apiserver and kubelets. Then, edit the API server pod specification file /etc/kubernetes/manifests/kube-apiserver.yaml on the control plane node and set --kubelet-certificate-authority parameter to the path to the cert file for the --kubelet-certificate-authority=<ca-string> 1.2.9 Follow the Kubernetes documentation and set the desired limits in a confi Then, edit the API server pod specification file /etc/kubernetes/manifests/kube and set the below parameters. --enable-admission-plugins=...,EventRateLimit,... --admission-control-config-file=<path/to/configuration/file> 1.2.17 Edit the API server pod specification file /etc/kubernetes/manifests/kub on the control plane node and set the below parameter. --profiling=false 1.2.18 Edit the API server pod specification file /etc/kubernetes/manifests/kub on the control plane node and set the --audit-log-path parameter to a suitable file where you would like audit logs to be written, for example, --audit-log-path=/var/log/apiserver/audit.log 1.2.19 Edit the API server pod specification file /etc/kubernetes/manifests/kub on the control plane node and set the --audit-log-maxage parameter to 30 or as an appropriate number of days, for example, --audit-log-maxage=30 1.2.20 Edit the API server pod specification file /etc/kubernetes/manifests/kub on the control plane node and set the --audit-log-maxbackup parameter to 10 or value. For example, --audit-log-maxbackup=10 1.2.21 Edit the API server pod specification file /etc/kubernetes/manifests/kub on the control plane node and set the --audit-log-maxsize parameter to an appro For example, to set it as 100 MB, --audit-log-maxsize=100 1.3.2 Edit the Controller Manager pod specification file /etc/kubernetes/manifeager.yaml on the control plane node and set the below parameter. --profiling=false 1.4.1 Edit the Scheduler pod specification file /etc/kubernetes/manifests/kube- on the control plane node and set the below parameter. --profiling=false == Summary master == 40 checks PASS 9 checks FAIL 12 checks WARN 0 checks INFO == Summary total == 40 checks PASS 9 checks FAIL 12 checks WARN 0 checks INFO [/code] 根据示例1,以 ID为 1.2.17 为例,建议将DEBUG参数功能设置为false: 1.2.17 Edit the API server pod specification file /etc/kubernetes/manifests/kub on the control plane node and set the below parameter. --profiling=false 未知参数,可以通过CIS PDF查找到相应位置,并通过官网的官方文档-【参考-组件工具】进行Ctrl -F 搜索 文档:kube-apiserver | Kubernetes ![]() 解释:该参数是通过 Web 接口 host:port/debug/pprof/ 默认启用的性能分析服务,用来进行DEBUG作用
根据示例2,以 ID为 1.2.5 为例,通过更改配置文件,将告警等级进行降级: [code][root@k8s-master-1-71 ~]# vi /etc/kube-bench/cfg/cis-1.24/master.yaml ... - id: 1.2.5 text: "Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)" audit: "/bin/ps -ef | grep $apiserverbin | grep -v grep" tests: test_items: - flag: "--kubelet-certificate-authority" remediation: | Follow the Kubernetes documentation and setup the TLS connection between the apiserver and kubelets. Then, edit the API server pod specification file $apiserverconf on the control plane node and set the --kubelet-certificate-authority parameter to the path to the cert file for the certificate authority. --kubelet-certificate-authority=<ca-string> scored: false //将true设置为false。测试ID 1.2.5 从[FAIL] 变为 [WARN] [root@k8s-master-1-71 ~]# kube-bench run --targets=master | grep 1.2.5 [WARN] 1.2.5 Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated) [root@k8s-master-1-71 ~]# vi /etc/kube-bench/cfg/cis-1.24/master.yaml scored: false type: skip //增加type,值为skip。测试ID 1.2.5 从[WARN] 变为 [INFO] [root@k8s-master-1-71 ~]# kube-bench run --targets=master | grep 1.2.5 [INFO] 1.2.5 Ensure that the --kubelet-certificate-authority argument is set as appropriate (Automated)[/code]四、Ingress 配置证书4.1 Ingress介绍![]()
4.2 HTTPS重要性HTTPS是安全的HTTP,HTTP 协议中的内容都是明文传输,HTTPS 的目的是将这 些内容加密,确保信息传输安全。最后一个字母 S 指的是SSL/TLS 协议,它位于 HTTP 协议与 TCP/IP 协议中间。 HTTPS优势:
4.3 将一个项目对外暴露HTTPS访问配置ingress服务 [code]kubectl apply -f ingress-controller-1.1.yaml [root@k8s-master-1-71 ~]# kubectl get pods -n ingress-nginx NAME READY STATUS RESTARTS AGE ingress-nginx-controller-85cdb79d-srkrq 1/1 Running 0 52s [root@k8s-master-1-71 ~]# kubectl get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller NodePort 10.108.162.206 <none> 80:30513/TCP,443:32099/TCP 79d ingress-nginx-controller-admission ClusterIP 10.103.217.175 <none> 443/TCP 79d [/code]配置HTTPS步骤:
先前准备: [code]kubectl create deployment httpd-web --image=nginx --replicas=3 kubectl expose deployment httpd-web --port=80 --target-port=80[/code]步骤1:准备域名证书文件 [code]vi certs.sh cat > ca-config.json <<EOF # 根证书的配置文件 { "signing": { "default": { "expiry": "87600h" }, "profiles": { "kubernetes": { "expiry": "87600h", "usages": [ "signing", "key encipherment", "server auth", "client auth" ] } } } } EOF cat > ca-csr.json <<EOF # 根证书的请求颁发文件 { "CN": "kubernetes", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "Beijing", "ST": "Beijing" } ] } EOF # 通过以上相关根证书信息,为指定域名颁发客户端证书 cfssl gencert -initca ca-csr.json | cfssljson -bare ca - cat > web.hostname.cn-csr.json <<EOF { "CN": "web.hostname.cn", # 一定要与访问的实际域名保持一致 "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing" } ] } EOF cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes web.hostname.cn-csr.json | cfssljson -bare web.hostname.cn [root@k8s-master-1-71 ~]# mkdir ssl ; mv certs.sh ssl/ ; cd ssl/ [root@k8s-master-1-71 ssl]# bash certs.sh [/code]步骤2:将证书文件保存到Secret [code]kubectl create secret tls web-aliangedu-cn -- cert=web.aliangedu.cn.pem --key=web.aliangedu.cn-key.pem[/code]步骤3:Ingress规则配置tls [code][root@k8s-master-1-71 ~]# kubectl apply -f ingress-https.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-https spec: ingressClassName: nginx tls: # 添加tls - hosts: - httpd.hostname.cn secretName: web-hostname-cn rules: - host: httpd.hostname.cn http: paths: - path: / pathType: Prefix backend: service: name: httpd-web port: number: 80[/code]查看 kubectl get ingress [code][root@k8s-master-1-71 ~]# kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE ingress-https nginx httpd.hostname.cn 192.168.1.73 80, 443 65s [root@k8s-master-1-71 ~]# kubectl get svc -n ingress-nginx NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller NodePort 10.108.162.206 <none> 80:30513/TCP,443:32099/TCP 79d ingress-nginx-controller-admission ClusterIP 10.103.217.175 <none> 443/TCP 79d[/code]访问测试:https://httpd.hostname.cn ![]() 五、网络策略控制集群内部网络通信5.1 网络策略应用场景默认情况下,Kubernetes 集群网络没任何网络限制,Pod 可以与任何其他 Pod 通信,在某些场景下就需要进行网络控制, 减少网络攻击面,提高安全性,这就会用到网络策略。 网络策略(Network Policy):是一个K8s资源,用于限制Pod出入流量,提供Pod级别和Namespace级别网络访问控制。 网络策略的应用场景:
5.2 网络策略概述![]() 网络策略工作流程:
相关YAML文件:网络策略 | Kubernetes [code]apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test-network-policy namespace: default spec: podSelector: matchLabels: role: db policyTypes: - Ingress - Egress ingress: - from: - ipBlock: cidr: 172.17.0.0/16 except: - 172.17.1.0/24 - namespaceSelector: matchLabels: project: myproject - podSelector: matchLabels: role: frontend ports: - protocol: TCP port: 6379 egress: - to: - ipBlock: cidr: 10.0.0.0/24 ports: - protocol: TCP port: 5978[/code]
5.3 网络访问控制5个案例案例1:拒绝命名空间下所有Pod入、出站流量 需求:拒绝test命名空间下所有Pod入、出站流量 [code]apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all namespace: test spec: podSelector: {} # 匹配本命名空间所有Pod policyTypes: - Ingress - Egress # ingress 和 egress 没有指定规则,则不允许任何流量进出Pod[/code]案例2:拒绝其他命名空间Pod访问 需求:test命名空间下所有pod可以互相访问,也可以访问其他 命名空间Pod,但其他命名空间不能访问test命名空间Pod。 [code]apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all-namespace namespace: test spec: podSelector: {} policyTypes: - Ingress ingress: - from: - podSelector: {} # 匹配本命名空间所有Pod[/code]或者 [code]apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all-namespace namespace: test spec: podSelector: {} policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: name: test # 指定本命名空间[/code]案例3:允许其他命名空间Pod访问指定应用 需求:允许其他命名空间访问test命名空间指定Pod [code]apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all-namespaces namespace: test spec: podSelector: matchLabels: eun: web policyTypes: - Ingress ingress: - from: - namespaceSelector: {} # 匹配所有命名空间的Pod[/code]案例4:同一个命名空间下应用之间限制访问 需求:将test命名空间中标签为run=web的pod隔离, 只允许标签为 run=client1 的pod访问80端口 [code]apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: app-to-app namespace: test spec: podSelector: matchLabels: run: web policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: run: client1 ports: - protocol: TCP port: 80 [/code]案例5:只允许指定命名空间中的应用访问 需求:限制dev命名空间标签为 env=dev 的pod,
六、k8s证书续签K8s证书一般分为两套:K8s组件(apiserver)和 Etcd 假如按角色来分,证书分为管理节点和工作节点。
注意:使用kubeadm方式部署,证书有效期为1年,证书过期会导致集群无法正常工作,日志会给出证书过期错误(x509: certificate has expired or is not yet valid) ![]() 证书使用在组件之间的通信 红线:K8s自建证书颁发机构(CA), 需携带由它生成的客户端证书访问 apiserver 蓝色:Etcd自建证书颁发机构(CA), 需携带由它生成的客户端证书访问etcd 命令:查看证书有效期
例如: [code][root@k8s-master-1-71 pki]# kubeadm certs check-expiration [check-expiration] Reading configuration from the cluster... [check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' # 根证书颁发的客户端证书(毕业证) CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED admin.conf Mar 24, 2024 04:08 UTC 303d ca no apiserver Mar 24, 2024 04:06 UTC 303d ca no apiserver-etcd-client Mar 24, 2024 04:06 UTC 303d etcd-ca no apiserver-kubelet-client Mar 24, 2024 04:06 UTC 303d ca no controller-manager.conf Mar 24, 2024 04:07 UTC 303d ca no etcd-healthcheck-client Feb 16, 2024 14:22 UTC 266d etcd-ca no etcd-peer Feb 16, 2024 14:22 UTC 266d etcd-ca no etcd-server Feb 16, 2024 14:22 UTC 266d etcd-ca no front-proxy-client Mar 24, 2024 04:06 UTC 303d front-proxy-ca no scheduler.conf Mar 24, 2024 04:07 UTC 303d ca no # 根证书(大学、证书颁发机构)(根证书的有效期默认kubeadm设置为10年,一般情况下也不会变化) CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED ca Feb 13, 2033 14:22 UTC 9y no etcd-ca Feb 13, 2033 14:22 UTC 9y no front-proxy-ca Feb 13, 2033 14:22 UTC 9y no [root@k8s-master-1-71 ~]# cd /etc/kubernetes/pki/ [root@k8s-master-1-71 pki]# openssl x509 -in apiserver.crt -noout -dates notBefore=Feb 16 14:22:31 2023 GMT notAfter=Mar 24 04:06:51 2024 GMT # 或者 请求HTTPS查看服务续签变化 echo | openssl s_client -showcerts -connect 127.0.0.1:6443 -servername api 2>/dev/null | openssl x509 -noout -enddate notAfter=Mar 24 04:06:51 2024 GMT [/code]补充: 在kubeadm部署集群之前,需进行续签的方法:修改kubeadm源码中证书的默认有效期; 在kubeadm部署集群之后,需进行续签的方法:
命令:续签所有证书
示例:kubeadm部署方式续签 [code]# 查看证书有效期 [root@k8s-master-1-71 pki]# kubeadm certs check-expiration # 备份 [root@k8s-master-1-71 ~]# cp -r /etc/kubernetes/ /etc/kubernetes.bak [root@k8s-master-1-71 ~]# cp -r /var/lib/etcd/ /var/lib/etcd.bak # 续签所有证书 [root@k8s-master-1-71 ~]# kubeadm certs renew all # 重启生效证书 [root@k8s-master-1-71 ~]# kubectl delete pod kube-apiserver-k8s-master-1-71 kube-controller-manager-k8s-master-1-71 kube-scheduler-k8s-master-1-71 etcd-k8s-master-1-71 -n kube-system pod "kube-apiserver-k8s-master-1-71" deleted pod "kube-controller-manager-k8s-master-1-71" deleted pod "kube-scheduler-k8s-master-1-71" deleted pod "etcd-k8s-master-1-71" deleted # kubectl使用新配置文件 cp -f /etc/kubernetes/admin.conf $HOME/.kube/config [/code]注:如果多master,其他证书和配置文件拷贝过去覆盖或者做上述同样操作 课后作业:1、网络策略 需求1:在test命名空间创建一个名为deny-all的网络策略,拒绝本命名空间所有Pod的 Ingress和Egress流量 需求2:限制dev命名空间标签为env=dev的pod,只允许prod命名空间中的pod访问和 其他所有命名空间app=client1标签pod访问 2、使用kube-bench工具检查集群组件配置文件存在的问题与修复,并重启对应组件确保 新配置生效。 小结本篇为 【Kubernetes CKS认证 Day1】的学习笔记,希望这篇笔记可以让您初步了解到 CIS及Kube-beach的使用、了解Ingress配置证书、网络策略等;课后还有扩展实践,不妨跟着我的笔记步伐亲自实践一下吧! Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解。 免责声明:本内容来源于网络,如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |