保障Kubernetes安全:从容器到访问控制
立即解锁
发布时间: 2025-08-25 02:04:20 阅读量: 3 订阅数: 6 

### 保障 Kubernetes 安全:从容器配置到权限控制
#### 1. 容器配置与非根用户运行
为了能在本地使用 Docker 运行容器,并将其部署到 Kubernetes 生产环境,同时避免在 Dockerfile 中进行特定环境的更改,我们需要更新 Dockerfile,给予组 0 写权限。以下是更新后的 Dockerfile:
```dockerfile
FROM python:3.12
ENV PYTHONUNBUFFERED 1
COPY . /app
WORKDIR /app
RUN mkdir logs
RUN chgrp -R 0 logs \
&& chmod -R g+rwX logs
CMD python3 server.py
```
若要在将容器部署到 Kubernetes 之前,使用非根用户在本地 Docker 中测试运行该容器,可以在运行时设置用户:
```bash
docker run --user 1001:0 $CONTAINER_NAME
```
现在,我们修订后的容器(发布为版本 7)可以作为非根用户愉快地运行。部署相应配置,即可看到它正常运行。若想查看为使容器和配置以非根用户运行所做的所有更改,可以使用 `diff` 命令进行对比:
```bash
cd Chapter12
diff -u timeserver6 timeserver7
diff -u 12.4_NonRootContainers/1_permission_error \
12.4_NonRootContainers/2_fixed
```
#### 2. 准入控制器
在前面的部分,我们手动为 Pod 添加了 `runAsNonRoot` 以防止其以根用户运行。若希望所有 Pod 都具备此设置,理想情况下,我们应能配置集群,拒绝任何未进行此配置的 Pod,甚至自动添加该配置。这就需要用到准入控制器。
准入控制器是在创建对象(如使用 `kubectl create`)时通过 Webhook 执行的代码片段。它分为两种类型:验证型和变异型。验证型准入 Webhook 可以接受或拒绝 Kubernetes 对象,例如拒绝未设置 `runAsNonRoot` 的 Pod;变异型准入 Webhook 可以在对象进入时对其进行更改,例如将 `runAsNonRoot` 设置为 `true`。
虽然你可以编写自己的准入控制器来实现所需的行为,但根据具体需求,可能并不需要这么做。Kubernetes 自带了一些准入控制器,此外,还有一些商业或开源的部署可供使用。
##### 2.1 Pod 安全准入
编写准入控制器并非易事。你需要配置证书,构建一个可以作为 Webhook 设置的应用程序,该应用程序要符合 Kubernetes 的请求/响应 API,并且需要有一个开发流程来确保其随着 Kubernetes 的频繁更新而保持最新。不过,大多数开发者并不需要编写自己的准入控制器,通常可以使用第三方或 Kubernetes 自带的控制器。
Kubernetes 包含了可以强制执行安全策略(如要求 `runAsNonRoot`)的准入控制器。在 Kubernetes v1.25 之前,`PodSecurityPolicy` 用于此目的,但它从未脱离 Beta 阶段并最终被移除。自 Kubernetes v1.25 起,Pod 安全准入是通过准入控制器强制执行安全策略的推荐方式。你甚至可以将其手动部署到运行旧版本 Kubernetes 的集群中,或者在平台运营商未启用该功能的集群中使用。
Pod 安全标准定义了三个在命名空间级别应用的安全策略级别:
- **特权级(Privileged)**:Pod 具有不受限制的管理访问权限,可以获得节点的根访问权限。
- **基线级(Baseline)**:Pod 不能提升权限以获得管理访问权限。
- **受限级(Restricted)**:强制执行当前的最佳实践进行加固(即深度防御),在基线配置文件的基础上增加额外的保护层,包括限制以根用户身份运行。
```mermaid
graph LR
A[kubectl create] --> B[OBJECT]
B --> C[Pod Spec]
C --> D[Webhook]
D --> E{Validating admission controller}
E -->|Accept| F[Accepted]
E -->|Reject| G[Rejected]
C --> H[Webhook]
H --> I[Mutating admission controller]
I --> J[Mutated PodSpec]
J --> K[Scheduled Pods]
```
一般来说,特权级仅应授予系统工作负载;基线级在安全性和兼容性之间提供了良好的平衡;受限级提供了额外的深度防御,但会牺牲一些兼容性,例如需要确保所有容器都能以非根用户身份运行。
##### 2.2 创建具有 Pod 安全策略的命名空间
为了实现最安全的配置,我们来创建一个使用受限策略的命名空间。这将要求 Pod 以非根用户身份运行,并强制执行其他一些安全最佳实践。
首先,创建一个新的命名空间 `team1`,并设置受限策略:
```yaml
apiVersion: v1
kind: Namespace
metadata:
name: team1
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: v1.28
```
这两个标签设置了我们要强制执行的策略以及策略的版本。由于随着新的安全风险被发现,策略的实际定义可能会发生变化,因此 `enforce-version` 标签是必要的。你可以指定 `latest` 来应用最新的策略,但 Kubernetes 版本之间的策略更改很可能会破坏现有的工作负载,因此建议始终选择一个特定的版本。理想情况下,你应该先在暂存命名空间或集群中测试较新的策略版本,然后再在生产环境中更新 `enforce-version`。
创建命名空间:
```bash
kubectl create -f Chapter12/12.5_PodSecurityAdmission/namespace.yaml
kubectl config set-context --current --namespace=team1
```
现在,如果尝试部署一个未设置 `runAsNonRoot` 的 Pod,该 Pod 将被拒绝:
```bash
$ kubectl create -f Chapter03/3.2.4_ThePodSpec/pod.yaml
Error from server (Forbidden): error when creating
"Chapter03/3.2.4_ThePodspec/pod.yaml": admission webhook
"pod-security-webhook.kubernetes.io" denied the request: pods "timeserver"
is forbidden: violates PodSecurity "restricted:v1.28":
allowPrivilegeEscalation != false (container "timeserver-container" must set
securityContext.allowPrivilegeEscalation=false), unrestricted capabilitie
(container "timeserver-container" must set
securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or
containe
```
0
0
复制全文
相关推荐










