K8s访问控制(二)
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: 1000runAsGroup: 3000fsGroup: 2000
- 容器级别:
containers:
- name: appimage: busyboxsecurityContext:runAsUser: 1000
实例
(1) 容器以普通用户运行
apiVersion: v1
kind: Pod
metadata:name: run-as-user
spec:containers:- name: appimage: busyboxcommand: ["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: appimage: busyboxcommand: ["sh", "-c", "sleep 3600"]securityContext:privileged: true # 允许特权运行
这种模式下容器几乎等同宿主机 root,可以操作内核模块、网络接口,风险很大,一般只在调试/特殊场景下使用。
(3) 设置只读文件系统
apiVersion: v1
kind: Pod
metadata:name: readonly-fs
spec:containers:- name: appimage: busyboxcommand: ["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-policynamespace: default
spec:podSelector: # 匹配哪些 PodmatchLabels:app: webpolicyTypes: # 作用范围- Ingress- Egressingress: # 入站规则- from:- podSelector:matchLabels:role: frontendports:- protocol: TCPport: 80egress: # 出站规则- to:- ipBlock:cidr: 10.0.0.0/24ports:- protocol: TCPport: 443
说明:
podSelector
:选择哪些 Pod 应用策略。policyTypes
:控制 入站/出站。ingress
:允许哪些来源访问。egress
:允许 Pod 访问哪些目标。
默认策略
Kubernetes 默认情况:所有 Pod 之间流量全部允许。
没有任何 NetworkPolicy → 全部放行。
只要有一条 NetworkPolicy 作用于某个 Pod → 默认拒绝未匹配规则的流量。
可以创建一个“默认拒绝所有流量”的策略,比如:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:name: deny-allnamespace: default
spec:podSelector: {} # 匹配命名空间下所有 PodpolicyTypes:- 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/24except:- 192.168.1.5/32 # 排除某个 IP
(3) 出站流量限制
默认 Pod 出站是全放行的。如果要限制,可以显式配置 egress
。
例如只允许访问外部 HTTPS:
egress:
- to:- ipBlock:cidr: 0.0.0.0/0ports:- protocol: TCPport: 443
如果只配置了 egress
而没有 ingress
,那么:
出站会按规则过滤。
入站仍然默认放行,除非设置
policyTypes: [Ingress, Egress]
。
实际上,生产环境里大多数情况下只限制 入站 (Ingress),因为 Pod 出站需要访问外部 API、数据库等,不方便严格控制。
但对于安全敏感的应用(如零信任架构),也可能会限制出站。
总结:
- 网络策略 = Pod 的防火墙规则,由 CNI 插件实现。
- 默认情况:所有流量允许,一旦有策略匹配 Pod,默认拒绝未允许的流量。
- 可以按 Pod、Namespace、IP 段、端口、协议 等维度精细限制。
- 一般主要限制 入站,但也可限制 出站。