Pod 安全上下文(Security Context)
安全上下文 (SecurityContext) 用于定义 Pod 或容器的安全相关属性,包括运行用户、用户组、文件系统权限、Linux capabilities、是否特权运行等。
Kubernetes 提供了两层级的配置:
Pod 级别 securityContext → 影响该 Pod 内所有容器。
容器级别 securityContext → 只影响某个容器(优先级高于 Pod 级别)。
常用字段:
runAsUser
:指定容器运行的 Linux 用户 ID。runAsGroup
:指定容器运行的 Linux 用户组 ID。fsGroup
:指定挂载卷的文件系统组。privileged
:是否启用特权模式(root 权限,几乎等同于宿主机 root)。readOnlyRootFilesystem
:是否将容器的根文件系统挂载为只读。allowPrivilegeEscalation
:是否允许提权。
使用方式
只需要在 Pod/容器的 YAML 中添加 securityContext
配置即可,例如:
- Pod 级别:
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
- 容器级别:
containers:
- name: app
image: busybox
securityContext:
runAsUser: 1000
实例
(1) 容器以普通用户运行
apiVersion: v1
kind: Pod
metadata:
name: run-as-user
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "id && sleep 3600"]
securityContext:
runAsUser: 1000 # 指定 UID 1000 用户
runAsGroup: 3000 # 指定 GID 3000 用户组
allowPrivilegeEscalation: false
运行后 id
命令会显示容器是以 UID 1000 运行,而不是 root。
(2) 容器启用特权
apiVersion: v1
kind: Pod
metadata:
name: privileged-pod
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "sleep 3600"]
securityContext:
privileged: true # 允许特权运行
这种模式下容器几乎等同宿主机 root,可以操作内核模块、网络接口,风险很大,一般只在调试/特殊场景下使用。
(3) 设置只读文件系统
apiVersion: v1
kind: Pod
metadata:
name: readonly-fs
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "echo hello > /tmp/test || sleep 3600"]
securityContext:
readOnlyRootFilesystem: true # 根文件系统只读
此时容器根目录无法写入,提升安全性,常用于无状态服务。若需要写入数据,可挂载 emptyDir
或 PersistentVolume
。
网络策略 (Network Policy)
NetworkPolicy 是 Kubernetes 中用于 控制 Pod 网络通信的对象(谁可以访问谁)。
实现方式
K8s 只是定义了 API 资源,实际的隔离效果要由 CNI 插件 实现(如 Calico、Cilium、Weave Net)。如果 CNI 插件不支持网络策略,那么配置了也不会生效。
核心机制:通过标签选择器 (Label Selector) 和命名空间选择器 (NamespaceSelector) 来匹配 Pod,并定义允许的入站 (Ingress) 和出站 (Egress) 规则。默认是白名单模式:规则存在时,只允许符合条件的流量,其余全部拒绝。
网络策略资源介绍
典型结构:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: example-policy
namespace: default
spec:
podSelector: # 匹配哪些 Pod
matchLabels:
app: web
policyTypes: # 作用范围
- Ingress
- Egress
ingress: # 入站规则
- from:
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 80
egress: # 出站规则
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 443
说明:
podSelector
:选择哪些 Pod 应用策略。policyTypes
:控制 入站/出站。ingress
:允许哪些来源访问。egress
:允许 Pod 访问哪些目标。
默认策略
Kubernetes 默认情况:所有 Pod 之间流量全部允许。
没有任何 NetworkPolicy → 全部放行。
只要有一条 NetworkPolicy 作用于某个 Pod → 默认拒绝未匹配规则的流量。
可以创建一个“默认拒绝所有流量”的策略,比如:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: default
spec:
podSelector: {} # 匹配命名空间下所有 Pod
policyTypes:
- Ingress
- Egress
限制策略
(1) 不同级别限制(细粒度)
按 Pod 限制:通过
podSelector
精确控制。按 Namespace 限制:通过
namespaceSelector
控制某个命名空间的 Pod。按端口限制:只允许指定端口通信。
按协议限制:TCP/UDP/ICMP 等。
例如只允许同一命名空间内带 role=db
的 Pod 访问:
ingress:
- from:
- podSelector:
matchLabels:
role: db
(2) IP 段限制
可以通过 ipBlock
指定允许的网段:
ingress:
- from:
- ipBlock:
cidr: 192.168.1.0/24
except:
- 192.168.1.5/32 # 排除某个 IP
(3) 出站流量限制
默认 Pod 出站是全放行的。如果要限制,可以显式配置 egress
。
例如只允许访问外部 HTTPS:
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: TCP
port: 443
如果只配置了 egress
而没有 ingress
,那么:
出站会按规则过滤。
入站仍然默认放行,除非设置
policyTypes: [Ingress, Egress]
。
实际上,生产环境里大多数情况下只限制 入站 (Ingress),因为 Pod 出站需要访问外部 API、数据库等,不方便严格控制。
但对于安全敏感的应用(如零信任架构),也可能会限制出站。
总结:
- 网络策略 = Pod 的防火墙规则,由 CNI 插件实现。
- 默认情况:所有流量允许,一旦有策略匹配 Pod,默认拒绝未允许的流量。
- 可以按 Pod、Namespace、IP 段、端口、协议 等维度精细限制。
- 一般主要限制 入站,但也可限制 出站。