Kubernetes 安全管理:保障工作负载安全的综合指南
1. 查看 Pod 日志与工具输出
首先,我们可以通过以下命令查看
amicontained
工具的输出:
$ kubectl logs amicontained
输出结果显示:
Container Runtime: kube
Has Namespaces:
pid: true
user: false
AppArmor Profile: docker-default (enforce)
Capabilities:
BOUNDING -> chown dac_override fowner fsetid kill setgid setuid setpcap
net_raw sys_chroot sys_time mknod audit_write setfcap
Seccomp: filtering
Blocked Syscalls (67):
SYSLOG SETUID SETGID SETPGID SETSID SETREUID SETREGID SETGROUPS
SETRESUID SETRESGID USELIB USTAT SYSFS VHANGUP PIVOT_ROOT_SYSCTL ACCT
SETTIMEOFDAY MOUNT UMOUNT2 SWAPON SWAPOFF REBOOT SETHOSTNAME
SETDOMAINNAME IOPL IOPERM CREATE_MODULE INIT_MODULE DELETE_MODULE
GET_KERNEL_SYMS QUERY_MODULE QUOTACTL NFSSERVCTL GETPMSG PUTPMSG
AFS_SYSCALL TUXCALL SECURITY LOOKUP_DCOOKIE VSERVER MBIND SET_MEMPOLICY
GET_MEMPOLICY KEXEC_LOAD ADD_KEY REQUEST_KEY KEYCTL MIGRATE_PAGES
FUTIMESAT UNSHARE MOVE_PAGES PERF_EVENT_OPEN FANOTIFY_INIT
NAME_TO_HANDLE_AT OPEN_BY_HANDLE_AT SETNS PROCESS_VM_READV
PROCESS_VM_WRITEV KCMP FINIT_MODULE KEXEC_FILE_LOAD BPF USERFAULTFD
PKEY_MPROTECT PKEY_ALLOC PKEY_FREE
Looking for Docker.sock
2. SecurityContext 挑战
使用
SecurityContext
需要理解很多内容,直接配置每个 Pod 的所有字段来应用一组基本的安全控制并不容易。AppArmor、seccomp 和 SELinux 配置文件和上下文的创建和管理不仅困难,还容易出错。一旦出错,可能会导致应用程序无法正常运行。不过,有一些工具可以从运行中的 Pod 生成 seccomp 配置文件,然后通过
SecurityContext
应用。例如,Security Profiles Operator 就可以轻松生成和管理 Seccomp 配置文件。
3. Pod 安全
Kubernetes 中已弃用的 PodSecurityPolicy (PSP) API 支持验证和突变功能。验证功能会阻止未应用特定
SecurityContext
的 Kubernetes 资源创建,而突变功能则会根据 PSP 应用的标准更改 Kubernetes 资源并应用特定的
SecurityContext
。由于 PSP 已被弃用,并将在 Kubernetes v1.25 中移除,我们将重点介绍其替代方案——Pod 安全。Pod 安全与 PSP 的主要区别在于,Pod 安全仅执行验证,不进行突变。
3.1 什么是 Pod 安全
Pod 安全允许为 Pod 声明不同的安全配置文件,即 Pod 安全标准,并在命名空间级别应用。这些标准是 Pod 规范中安全敏感字段(包括但不限于
SecurityContext
)及其关联值的集合。Pod 安全标准有三种,从严格到宽松依次为:
-
Baseline
:在便于新应用接入的同时,防止最常见的权限提升。
-
Restricted
:高度严格,遵循安全最佳实践,但可能导致工作负载无法正常运行。
-
Privileged
:开放且无限制。
目前,Pod 安全在 Kubernetes v1.23 中仍为 beta 功能,可能会发生变化。每个 Pod 安全标准都定义了 Pod 规范中的字段及其允许的值,部分涵盖的字段如下:
-
spec.securityContext
-
spec.containers[*].securityContext
-
spec.containers[*].ports
-
spec.volumes[*].hostPath
完整的字段列表可在官方文档中查看。
3.2 应用模式
每个标准可以通过以下三种模式应用于命名空间:
-
Enforce
:违反策略的 Pod 将被拒绝创建。
-
Warn
:违反策略的 Pod 仍可创建,但会向用户显示警告消息。
-
Audit
:违反策略的 Pod 将在审计日志中生成审计消息。
3.3 应用 Pod 安全标准
使用标签将 Pod 安全标准应用于命名空间,具体如下:
-
必需
:
pod-security.kubernetes.io/<MODE>: <LEVEL>
-
可选
:
pod-security.kubernetes.io/<MODE>-version: <VERSION>
(默认为最新版本)
以下是一个示例
baseline-ns.yaml
文件:
apiVersion: v1
kind: Namespace
metadata:
name: baseline-ns
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/enforce-version: v1.22
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/audit-version: v1.22
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: v1.22
可以使用以下命令应用该文件:
$ kubectl apply -f baseline-ns.yaml
首次部署策略可能是一项艰巨的任务,但 Pod 安全提供了一个简单的干运行命令,可查看现有工作负载是否违反 Pod 安全标准:
$ kubectl label --dry-run=server --overwrite ns \
--all pod-security.kubernetes.io/enforce=baseline
该命令会根据基线 Pod 安全标准评估 Kubernetes 集群上的所有 Pod,并在输出中以警告消息的形式报告违规情况。
为了演示 Pod 安全的实际应用,我们创建一个
kuard-pod.yaml
文件:
apiVersion: v1
kind: Pod
metadata:
name: kuard
labels:
app: kuard
spec:
containers:
- image: gcr.io/kuar-demo/kuard-amd64:blue
name: kuard
ports:
- containerPort: 8080
name: http
protocol: TCP
使用以下命令创建 Pod 并查看输出:
$ kubectl apply -f kuard-pod.yaml --namespace baseline-ns
输出结果会显示 Pod 是否违反了受限的 Pod 安全标准,以及具体的违规细节,方便我们进行修复。同时,由于我们配置了审计模式,API 服务器审计日志中也会显示相关消息。
4. 服务账户管理
服务账户是 Kubernetes 资源,为运行在 Pod 内的工作负载提供身份。可以对服务账户应用基于角色的访问控制 (RBAC),以控制其通过 Kubernetes API 访问资源的权限。如果应用程序不需要访问 Kubernetes API,应遵循最小权限原则禁用访问。默认情况下,Kubernetes 会在每个命名空间中创建一个默认服务账户,并自动将其设置为所有 Pod 的服务账户。该服务账户包含一个令牌,会自动挂载到每个 Pod 中,用于访问 Kubernetes API。若要禁用此行为,需在服务账户配置中添加
automountServiceAccountToken: false
。以下是一个为默认服务账户禁用自动挂载令牌的示例
service-account.yaml
文件:
apiVersion: v1
kind: ServiceAccount
metadata:
name: default
automountServiceAccountToken: false
服务账户在考虑 Pod 安全时常常被忽视,但它们可以直接访问 Kubernetes API。如果没有适当的 RBAC 控制,可能会使攻击者获得对 Kubernetes 的访问权限。因此,了解如何通过简单的配置更改限制服务账户令牌的使用至关重要。
5. 基于角色的访问控制 (RBAC)
在保障 Pod 安全的过程中,Kubernetes 的基于角色的访问控制 (RBAC) 非常重要。它可以补充工作负载的安全态势,具体内容可参考相关文档。
6. RuntimeClass
Kubernetes 通过容器运行时接口 (CRI) 与节点操作系统上的容器运行时进行交互。CRI 的创建和标准化催生了各种容器运行时,这些运行时提供不同级别的隔离,基于其实现方式提供更强的安全保障。例如,Kata Containers、Firecracker 和 gVisor 等项目采用了从嵌套虚拟化到更复杂的系统调用过滤等不同的隔离机制。
6.1 RuntimeClass API
RuntimeClass API 允许用户选择集群中支持的容器运行时。不同的 RuntimeClass 需要集群管理员进行配置,并且可能需要在工作负载中设置特定的
nodeSelectors
或
tolerations
,以确保工作负载能被调度到正确的节点。以下是一个指定 RuntimeClass 的 Pod 示例
kuard-pod-runtimeclass.yaml
文件:
apiVersion: v1
kind: Pod
metadata:
name: kuard
labels:
app: kuard
spec:
runtimeClassName: firecracker
containers:
- image: gcr.io/kuar-demo/kuard-amd64:blue
name: kuard
ports:
- containerPort: 8080
name: http
protocol: TCP
使用 RuntimeClass 可以让用户选择具有不同安全隔离级别的容器运行时,有助于提高工作负载的整体安全性,特别是在处理敏感信息或运行不可信代码时。
7. 网络策略
Kubernetes 的网络策略 API 允许为工作负载创建入站和出站网络策略。网络策略通过标签配置,可选择特定的 Pod 并定义它们与其他 Pod 和端点的通信方式。例如,Ingress 类型的网络策略本身并不附带相关的 Kubernetes 控制器,这意味着可以创建网络策略资源,但如果未安装相应的控制器,这些策略将不会生效。网络策略资源由网络插件(如 Calico、Cilium 和 Weave Net)实现。
网络策略资源是命名空间级别的,结构包含
podSelector
、
policyTypes
、
ingress
和
egress
部分,其中
podSelector
是唯一必需的字段。如果
podSelector
字段为空,则策略将匹配命名空间中的所有 Pod。该字段还可以包含
matchLabels
部分,其功能与服务资源类似,可通过标签匹配特定的 Pod 集合。
使用网络策略时,需要注意以下几点:
- 如果 Pod 与任何网络策略资源匹配,则必须明确定义其入站或出站通信,否则将被阻止。
- 如果 Pod 匹配多个网络策略资源,这些策略将累加生效。
- 如果 Pod 未与任何网络策略匹配,则允许所有流量通过。这一设计是为了方便新工作负载的接入。若希望默认阻止所有流量,可以为每个命名空间创建默认拒绝规则。
以下是一个创建和测试网络策略的示例流程:
1. 创建一个用于测试的命名空间:
$ kubectl create ns kuard-networkpolicy
-
创建一个
kuard-pod.yaml文件:
apiVersion: v1
kind: Pod
metadata:
name: kuard
labels:
app: kuard
spec:
containers:
- image: gcr.io/kuar-demo/kuard-amd64:blue
name: kuard
ports:
- containerPort: 8080
name: http
protocol: TCP
-
在
kuard-networkpolicy命名空间中创建kuardPod:
$ kubectl apply -f kuard-pod.yaml \
--namespace kuard-networkpolicy
-
将
kuardPod 暴露为服务:
$ kubectl expose pod kuard --port=80 --target-port=8080 \
--namespace kuard-networkpolicy
-
使用
kubectl run创建一个测试 Pod,并测试在未应用网络策略时对kuardPod 的访问:
$ kubectl run test-source --rm -ti --image busybox /bin/sh \
--namespace kuard-networkpolicy
在测试 Pod 中执行以下命令:
/ # wget -q kuard -O -
如果可以成功获取响应,说明可以正常访问
kuard
Pod。
-
创建一个默认拒绝策略文件
networkpolicy-default-deny.yaml:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
- 应用默认拒绝网络策略:
$ kubectl apply -f networkpolicy-default-deny.yaml \
--namespace kuard-networkpolicy
-
再次测试从测试 Pod 访问
kuardPod:
$ kubectl run test-source --rm -ti --image busybox /bin/sh \
--namespace kuard-networkpolicy
在测试 Pod 中执行以下命令:
/ # wget -q --timeout=5 kuard -O -
此时应该会出现下载超时的错误,说明由于默认拒绝网络策略,无法访问
kuard
Pod。
-
创建一个允许从测试 Pod 访问
kuardPod 的网络策略文件networkpolicy-kuard-allow-test-source.yaml:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: access-kuard
spec:
podSelector:
matchLabels:
app: kuard
ingress:
- from:
- podSelector:
matchLabels:
run: test-source
- 应用该网络策略:
$ kubectl apply \
-f code/chapter-security/networkpolicy-kuard-allow-test-source.yaml \
--namespace kuard-networkpolicy
-
再次验证测试 Pod 是否可以访问
kuardPod:
$ kubectl run test-source --rm -ti --image busybox /bin/sh \
--namespace kuard-networkpolicy
在测试 Pod 中执行以下命令:
/ # wget -q kuard -O -
如果可以成功获取响应,说明网络策略生效。
- 清理测试命名空间:
$ kubectl delete namespace kuard-networkpolicy
应用网络策略可以为工作负载提供额外的安全层,进一步贯彻纵深防御和最小权限原则。
7. 服务网格
服务网格可以提升工作负载的安全态势。它提供访问策略,允许基于服务配置协议感知的策略。例如,可以配置服务 A 通过 HTTPS 在端口 443 连接到服务 B。此外,服务网格通常在所有服务间通信中实现相互 TLS,不仅加密通信内容,还验证服务身份。
8. 安全基准测试工具
有一些开源工具可以对 Kubernetes 集群运行一系列安全基准测试,以确定集群配置是否符合预定义的安全基线。例如,
kube-bench
可以运行 Kubernetes 的 CIS 基准测试。虽然这些工具并非专门针对 Pod 安全,但可以发现集群配置中的错误,并提供修复建议。
运行
kube-bench
的命令如下:
$ kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench...
查看基准测试输出和修复建议的命令如下:
$ kubectl logs job/kube-bench
输出结果会显示各项测试的通过、失败或警告信息,以及相应的修复建议。例如,如果测试
4.2.6
失败,提示需要设置
--protect-kernel-defaults=true
,可以根据使用的配置方式(配置文件或命令行参数)进行相应修改,并重启 kubelet 服务。
使用
kube-bench
等工具结合 CIS 基准测试,可以帮助确定 Kubernetes 集群是否符合安全基线,并在需要时提供修复方案。
综上所述,通过综合运用 Pod 安全、服务账户管理、RuntimeClass、网络策略、服务网格和安全基准测试工具等多种技术手段,可以有效保障 Kubernetes 集群中工作负载的安全。在实际应用中,应根据具体的业务需求和安全要求,灵活选择和配置这些技术,构建多层次、全方位的安全防护体系。
Kubernetes 安全管理:保障工作负载安全的综合指南
8. 安全基准测试工具(续)
安全基准测试工具在 Kubernetes 安全管理中扮演着重要角色。以
kube-bench
为例,它能帮助我们发现集群配置中的潜在问题。以下是一个简单的流程图,展示了使用
kube-bench
进行安全基准测试的基本流程:
graph TD;
A[开始] --> B[运行 kube-bench 命令];
B --> C[查看测试输出];
C --> D{是否有失败项};
D -- 是 --> E[查看修复建议];
E --> F[进行配置修改];
F --> G[重启相关服务];
G --> C;
D -- 否 --> H[结束];
运行
kube-bench
后,我们可以通过查看 Pod 日志获取详细的测试结果。例如:
$ kubectl logs job/kube-bench
[INFO] 4 Worker Node Security Configuration
[INFO] 4.1 Worker Node Configuration Files
[PASS] 4.1.1 Ensure that the kubelet service file permissions are set to 644...
[PASS] 4.1.2 Ensure that the kubelet service file ownership is set to root ...
[PASS] 4.1.3 If proxy kubeconfig file exists ensure permissions are set to ...
[PASS] 4.1.4 Ensure that the proxy kubeconfig file ownership is set to root ...
[PASS] 4.1.5 Ensure that the --kubeconfig kubelet.conf file permissions are ...
[PASS] 4.1.6 Ensure that the --kubeconfig kubelet.conf file ownership is set...
[PASS] 4.1.7 Ensure that the certificate authorities file permissions are ...
[PASS] 4.1.8 Ensure that the client certificate authorities file ownership ...
[PASS] 4.1.9 Ensure that the kubelet --config configuration file has permiss...
[PASS] 4.1.10 Ensure that the kubelet --config configuration file ownership ...
[INFO] 4.2 Kubelet
[PASS] 4.2.1 Ensure that the anonymous-auth argument is set to false (Automated)
[PASS] 4.2.2 Ensure that the --authorization-mode argument is not set to ...
[PASS] 4.2.3 Ensure that the --client-ca-file argument is set as appropriate...
[PASS] 4.2.4 Ensure that the --read-only-port argument is set to 0 (Manual)
[PASS] 4.2.5 Ensure that the --streaming-connection-idle-timeout argument is...
[FAIL] 4.2.6 Ensure that the --protect-kernel-defaults argument is set to ...
[PASS] 4.2.7 Ensure that the --make-iptables-util-chains argument is set to ...
[PASS] 4.2.8 Ensure that the --hostname-override argument is not set (Manual)
[WARN] 4.2.9 Ensure that the --event-qps argument is set to 0 or a level ...
[WARN] 4.2.10 Ensure that the --tls-cert-file and --tls-private-key-file arg...
[PASS] 4.2.11 Ensure that the --rotate-certificates argument is not set to ...
[PASS] 4.2.12 Verify that the RotateKubeletServerCertificate argument is set...
[WARN] 4.2.13 Ensure that the Kubelet only makes use of Strong Cryptographic...
== Remediations node ==
4.2.6 If using a Kubelet config file, edit the file to set protectKernel...
If using command line arguments, edit the kubelet service file
/etc/systemd/system/kubelet.service.d/10-kubeadm.conf on each worker node and
set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.
--protect-kernel-defaults=true
Based on your system, restart the kubelet service. For example:
systemctl daemon-reload
systemctl restart kubelet.service
4.2.9 If using a Kubelet config file, edit the file to set eventRecordQPS...
If using command line arguments, edit the kubelet service file
/etc/systemd/system/kubelet.service.d/10-kubeadm.conf on each worker node and
set the below parameter in KUBELET_SYSTEM_PODS_ARGS variable.
Based on your system, restart the kubelet service. For example:
systemctl daemon-reload
systemctl restart kubelet.service
从上述输出中,我们可以清晰地看到各项测试的结果,以及针对失败和警告项的修复建议。以下是一个简单的表格,总结了部分测试项及其含义:
| 测试项编号 | 测试内容 | 结果类型 | 含义 |
| — | — | — | — |
| 4.2.1 | 确保 anonymous-auth 参数设置为 false | PASS | 表示该配置符合安全要求 |
| 4.2.6 | 确保 –protect-kernel-defaults 参数设置正确 | FAIL | 表示该配置不符合安全要求,需要修复 |
| 4.2.9 | 确保 –event-qps 参数设置为 0 或合适级别 | WARN | 表示该配置存在潜在风险,建议进行调整 |
9. 综合安全策略实施建议
为了更好地保障 Kubernetes 集群的安全,我们可以综合运用前面介绍的各种安全技术。以下是一些实施建议:
-
分层安全策略
:结合 Pod 安全标准、网络策略和服务网格,构建多层次的安全防护体系。例如,在命名空间级别应用 Pod 安全标准,限制 Pod 的权限;使用网络策略控制 Pod 之间的网络通信;通过服务网格加密服务间的通信并验证服务身份。
-
定期安全审计
:使用安全基准测试工具(如
kube-bench
)定期对集群进行安全审计,及时发现并修复配置问题。可以设置定期任务,例如每周或每月运行一次
kube-bench
测试。
-
最小权限原则
:在服务账户管理和 RBAC 配置中,始终遵循最小权限原则。只授予服务账户和用户完成其任务所需的最低权限,减少潜在的安全风险。
-
持续监控与响应
:建立持续监控机制,实时监测集群的安全状态。当发现安全事件时,能够及时响应并采取相应的措施,例如阻止异常访问、修复配置漏洞等。
10. 实际案例分析
假设我们有一个 Kubernetes 集群,运行着多个微服务应用。为了保障这些应用的安全,我们采取了以下措施:
1.
应用 Pod 安全标准
:在不同的命名空间中应用不同的 Pod 安全标准。例如,对于生产环境的命名空间,应用
Restricted
标准,确保工作负载遵循严格的安全要求;对于开发和测试环境的命名空间,应用
Baseline
标准,在保障基本安全的同时,便于新应用的快速部署和测试。
2.
配置网络策略
:创建默认拒绝的网络策略,阻止所有入站和出站流量。然后,根据业务需求,逐步开放必要的网络连接。例如,允许特定的服务之间进行通信,或者允许外部用户访问特定的服务。
3.
使用 RuntimeClass
:对于处理敏感数据的工作负载,选择具有更强安全隔离的 RuntimeClass,如
Firecracker
。这样可以确保敏感数据在更安全的环境中处理。
4.
定期安全审计
:每周运行一次
kube-bench
测试,检查集群配置是否符合安全基线。在一次测试中,发现
kubelet
的
--protect-kernel-defaults
参数未正确设置,根据修复建议进行了配置修改,并重启了
kubelet
服务。
通过以上措施的综合实施,我们有效地提高了 Kubernetes 集群的安全性,减少了潜在的安全风险。
11. 总结
Kubernetes 安全管理是一个复杂而重要的任务,需要综合运用多种技术手段。通过 Pod 安全标准、服务账户管理、RuntimeClass、网络策略、服务网格和安全基准测试工具等,我们可以构建多层次、全方位的安全防护体系。在实际应用中,应根据具体的业务需求和安全要求,灵活选择和配置这些技术,确保 Kubernetes 集群中工作负载的安全稳定运行。同时,持续的安全监控和定期的安全审计也是保障集群安全的关键。希望本文介绍的内容能够帮助你更好地管理 Kubernetes 集群的安全。
超级会员免费看
995

被折叠的 条评论
为什么被折叠?



