1. SecurityContext
1.1. 概述
SecurityContext 是 Pod 或容器配置中的一个字段,用于设定操作系统级的安全属性。这些属性最终会传递给容器运行时(如 containerd、CRI-O),由它们来强制执行,确保容器进程在严格限制的权限下运行。
简单来说,它就是 Pod 或容器的 “安全身份证” 和 “行为准则”,告诉系统它应该以什么用户身份运行、能做什么、不能做什么。
1.2. 两个层级的作用域
SecurityContext 可以在两个级别上配置,其应用范围和优先级不同:
- Pod-level SecurityContext (
spec.securityContext
)- 应用于 Pod 内的所有容器。
- 设置一些影响整个 Pod 的属性,如用户/组ID、文件系统组、SELinux 选项等。
- 为 Pod 内所有容器提供默认的安全设置。
- Container-level SecurityContext (
spec.containers[].securityContext
)- 仅应用于特定的容器。
- 可以覆盖 Pod-level 的设置(如
runAsUser
)。 - 可以设置容器特有的属性,如能力(Capabilities)、权限提升、只读根文件系统等。
注意:容器级的配置会覆盖 Pod 级的相同配置。
1.3. 核心配置字段详解
以下是 SecurityContext 中最重要和最常用的字段:
用户和组身份 (User and Group Identity)
控制容器进程以什么用户和组身份运行,这是最基本的安全措施。
runAsUser
:指定容器进程的 UID(用户ID)。强制以非 root 用户(如 1000)运行是安全最佳实践。
securityContext:
runAsUser: 1000 # 不以 root (0) 运行
YAMLrunAsGroup
:指定容器进程的主 GID(组ID)
securityContext:
runAsGroup: 2000
YAMLrunAsNonRoot
:布尔值。这是一个安全开关,如果设为true
,Kubernetes 会检查镜像是否配置了非 root 用户(通过USER
指令)或runAsUser
是否非 0。如果检查失败,容器启动失败。
securityContext:
runAsNonRoot: true # 必须非root运行
YAMLsupplementalGroups
:为容器进程指定附加的组 GIDs。常用于访问特定组权限的持久卷(PV)。
权限能力 (Linux Capabilities)
Linux Capabilities 将 root 用户的超级权限划分为不同的单元,允许你赋予容器它所需的最小权限,而不是完整的 root 权限。这是实现“最小权限原则”的关键。
capabilities
:一个包含add
和drop
列表的对象。drop
:必须项。丢弃所有不必要的权限,通常首先丢弃ALL
。add
:可选项。在丢弃全部的基础上,只添加业务必须的个别权限。
securityContext:
capabilities:
drop: # 丢弃所有权限
- ALL
add: # 只添加一个网络相关权限(绑定低端口号)
- NET_BIND_SERVICE
YAML常见需添加的权限:
NET_BIND_SERVICE
:绑定到 1024 以下的端口。CHOWN
,DAC_OVERRIDE
: 文件所有权覆盖(某些应用需要)。SYS_TIME
: 修改系统时间。
特权模式 (Privileged Mode)
极度危险,应避免使用! 特权容器几乎拥有对宿主机的全部访问权限。
privileged
:如果设置为true
,容器将在特权模式下运行。
securityContext:
privileged: false # 永远不要设为 true,除非有极端特殊情况
YAML权限提升 (Privilege Escalation)
防止容器进程通过 suid
等机制提升其权限。
allowPrivilegeEscalation
:布尔值。应始终设为false
,除非有明确需求。如果privileged: true
或添加了CAP_SYS_ADMIN
能力,则此选项默认为true
。
securityContext:
allowPrivilegeEscalation: false # 禁止权限提升
YAML1.4. 示例
apiVersion: v1
kind: Pod
metadata:
name: secured-app
spec:
securityContext: # Pod级别的设置,是所有容器的默认值
runAsUser: 10000
runAsGroup: 10000
fsGroup: 10000 # 影响卷的文件组权限
seccompProfile:
type: RuntimeDefault
containers:
- name: nginx
image: nginx:1.25
securityContext: # 容器级别的设置,覆盖Pod级别的相同设置
allowPrivilegeEscalation: false
runAsNonRoot: true # 二次确认,虽然runAsUser已是非0
capabilities:
drop: ["ALL"]
add: ["NET_BIND_SERVICE"] # nginx需要绑定80端口
readOnlyRootFilesystem: true
volumeMounts:
- name: cache
mountPath: /var/cache/nginx # 为需要写入的目录挂载卷
- name: tmp
mountPath: /tmp
volumes:
- name: cache
emptyDir: {}
- name: tmp
emptyDir: {}
YAML2. PodSecurity
2.1. 概述
PodSecurity 是一个内置的准入控制器(Admission Controller),它基于命名空间(Namespace)的标签,对创建 Pod 的请求实施并强制遵守 Pod 安全标准(Pod Security Standards)。
2.2. Pod Security Standards (PSS) – 安全标准
PodSecurity 的实施基于三个预定义的安全级别标准:
- Baseline Policy:基准等级策略,限制性最弱,允许使用默认的(规定最少)Pod 权限配置,并禁止已知的权限提升。
- Restricted Policy:限制等级策略,限制性非常强,遵循当前的Pod安全防护的最佳实践。
- Privileged Policy:特权等级策略,提供最大可能范围的权限许可,此标准允许已知的权限提升。
2.3. 配置和使用 PodSecurity
确保 API Server 启用了准入控制器:
# PodSecurity 准入控制器在 Kubernetes v1.23+ 中默认启用。对于旧版本,你需要确保 API Server 的启动参数包含:
--enable-admission-plugins=...,PodSecurity
Bash为命名空间打标签:
# 配置的核心是为命名空间添加特定的标签。标签的格式为:
pod-security.kubernetes.io/<MODE>: <LEVEL>
# <LEVEL>:要实现的安全策略的名字,包括 baseline、restricted、privileged
# <MODE>:当违反安全策略后执行的动作。
# 以及一个可选的版本标签:
pod-security.kubernetes.io/<MODE>-version: <VERSION>
# <VERSION>:kubernetes 的版本号,因为 Pod 的安全策略的实现是与 kubernetes 版本相关的
BashMODE 包含的选项:
enforce
:- 拒绝任何违反政策的 Pod 创建请求。
- 这是强制执行的模式。
warn
:- 向用户发出警告(在 API 响应中返回警告信息),但允许创建违反政策的 Pod。
- 适用于试运行和过渡期。
audit
:- 在审计日志中记录违反政策的事件,但允许创建 Pod。
- 用于监控和发现集群中存在的不合规资源,而不中断业务。
一个命名空间可以同时配置这三种模式,例如:对 restricted
标准进行 enforce
,同时对 baseline
标准进行 audit
。
示例 1:对一个命名空间实施严格的 Restricted 策略
apiVersion: v1
kind: Namespace
metadata:
name: my-secure-app
labels:
# 核心:强制执行 restricted 标准
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: v1.31 # 可选:指定标准版本
# 同时,对 baseline 级别的违规进行审计和警告
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
YAML示例 2:对一个命名空间进行试运行(只警告和审计,不强制)
apiVersion: v1
kind: Namespace
metadata:
name: my-test-app
labels:
pod-security.kubernetes.io/warn: baseline
pod-security.kubernetes.io/audit: baseline
# 不设置 `enforce` 标签,表示不会拒绝创建 Pod
YAML在 my-secure-app 名称空间创建 Pod 测试效果:
# test-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: test
image: nginx:1.18
securityContext:
runAsUser: 0 # 尝试以 root 用户运行
YAML输出结果:
$ kubectl apply -f test-pod.yaml -n my-secure-app
Error from server (Forbidden): error when creating "test-pod.yaml": pods "test-pod" is forbidden: violates PodSecurity "restricted:v1.31": allowPrivilegeEscalation != false (container "test" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "test" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "test" must set securityContext.runAsNonRoot=true), runAsUser=0 (container "test" must not set runAsUser=0), seccompProfile (pod or container "test" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
Bash2.4. 豁免 (Exemptions)
PodSecurity 允许配置豁免,以避免对某些用户、服务账户或运行时类(如 virtlet
)进行安全检查。
注意: 豁免是在 Admission Configuration 中静态配置的,而不是通过命名空间标签。你需要创建一个配置文件供 API Server 加载。
示例:
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
configuration:
apiVersion: pod-security.admission.config.k8s.io/v1
kind: PodSecurityConfiguration
defaults:
enforce: "privileged"
enforce-version: "latest"
audit: "privileged"
audit-version: "latest"
warn: "privileged"
warn-version: "latest"
exemptions:
usernames: []
runtimeClasses: []
namespaces: []
YAML上述配置文件中的 exemptions 部分即对 Pod 的豁免声明,其中:
- usernames:表示要豁免的用户列表,即提交API请求时的用户名。
- runtimeClasses:表示要豁免的 runtimeclass 列表,即对这些 runtime class 的 Pod 实例进行豁免。
- namespaces:表示要豁免的命名空间列表。
此外,配置文件中的 defaults 部分是用来设置默认安全策略的,当我们给 Namespace 设置的标签中没有指定 Level 时,PodSecurity 就会使用这部分的默认值。
上述配置文件需要通过 --admission-control-config-file
参数让 API Server 加载此配置才能生效。
3. SecurityContext 与 PodSecurity 关系
PodSecurity 和 SecurityContext 是 Kubernetes 中相辅相成的两种安全机制,它们的关系是 “宏观策略控制” 与 “微观具体实现” 的关系。
- PodSecurity 是集群管理员制定的 “安全规则”(Policy)。它规定 Pod 必须或不得做什么。
- SecurityContext 是 Pod 或容器开发者定义的 “安全配置”(Configuration)。它具体设置 Pod 或容器 如何运行。
类比:建筑安全规范
- PodSecurity 就像是国家的建筑安全法规。
- 法规规定:“所有高层建筑必须使用防火材料”(这相当于
enforce: restricted
策略)。
- 法规规定:“所有高层建筑必须使用防火材料”(这相当于
- SecurityContext 就像是建筑师的设计图纸。
- 图纸上写明:“这栋大楼将使用钢筋混凝土和防火石膏板”(这相当于在 Pod 中设置
seccompProfile: RuntimeDefault
和allowPrivilegeEscalation: false
)。
- 图纸上写明:“这栋大楼将使用钢筋混凝土和防火石膏板”(这相当于在 Pod 中设置
- PodSecurity 准入控制器的工作就是检查“设计图纸”(Pod Spec)是否违反了“国家法规”(PS 策略)。如果图纸上写的是“使用木材”,它就会拒绝这个建筑申请。
示例:二者如何配合
- PodSecurity 策略(命名空间层级)
# 命名空间的策略:强制执行 restricted 标准
apiVersion: v1
kind: Namespace
metadata:
name: secure-app
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: v1.31
YAML- SecurityContext 配置(Pod 层级)
apiVersion: v1
kind: Pod
metadata:
name: nginx-secure
namespace: secure-app
spec:
securityContext: # Pod级别的安全上下文(影响所有容器和volumes)
runAsUser: 1000
runAsGroup: 3000
fsGroup: 3000
seccompProfile:
type: RuntimeDefault
containers:
- name: nginx
image: nginx
securityContext: # 容器级别的安全上下文(仅影响本容器)
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"] # 丢弃所有权限
readOnlyRootFilesystem: true
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
YAML- 解读:
- PodSecurity 的
restricted
策略要求 Pod 必须设置:runAsUser != 0
、allowPrivilegeEscalation: false
等一系列设置。 - Pod 的开发者就在
securityContext
中具体配置了这些值(runAsUser: 1000
,allowPrivilegeEscalation: false
)来满足要求。 - 如果没有配置,PodSecurity 会拒绝它。如果配置的值不对(如
runAsUser: 0
),PodSecurity 同样会拒绝它。
- PodSecurity 的
4. Pod 的网络安全
为了确保 Pod 的安全,Kubernetes 提供了相应的网络访问的安全控制机制。比如 Pod 有专门的网络地址段,它们不能被 Kubernetes 集群之外的主机访问;再如,位于不同 Namespace 的 Pod 如果需要相互访问,则必须知道对方的Namespace,否则也无法访问。为了实现更为严格的 Pod 网络安全,Kubernetes从v1.3版本开始,专门设计了 NetworkPolicy,并在后继版本中不断完善 NetworkPolicy 提供的安全特性。
4.1. Namespace 网络隔离
首先,必须明确一个最关键的概念:Kubernetes 的 Namespace 本身并不提供任何形式的网络隔离。
默认情况下,在一个集群中的 Pod 是在同一个局域网内,所以它们之间的网络是直通的,那么如何禁止不同业务之间的 Pod 之间的访问呢?
有一个简单的方案,就是利用 Service 和 Namespace,将不同业务的 Pod 和 Service 部署到不同的名称空间。这样 PodA 要访问 PodB 则需要知道 PodB 所在的名称空间才能通过 Service 的域名 <service-name>.<namespace>.svc.<clusterDomain> 访问。如果 PodA 想绕过 Service 直接通过 IP 访问 PodB 通常很难获取到 PodB 的 IP 地址,但还是有机会获取到,如通过网络地址和端口扫描工具等。
4.2. NetworkPolicy 网络隔离
NetworkPolicy 是 Kubernetes 中定义 Pod 网络隔离规则的核心 API 对象。它相当于 Pod 的防火墙,控制着进出 Pod 的流量。
NetworkPolicy 关键概念:
- 选择器 (Selector):NetworkPolicy 通过标签选择器 (
podSelector
) 来指定该策略适用于哪些 Pod(即保护谁)。 - 策略类型 (PolicyTypes):
Ingress
:控制进入 Pod 的流量(入站规则)。Egress
:控制 Pod发出的流量(出站规则)。
- 默认拒绝 (Default Deny):关键原则。一旦某个 Pod 被一个 NetworkPolicy 选中,它将默认拒绝所有未被该策略明确允许的流量(对于该策略指定的类型)。没有任何 NetworkPolicy 选中的 Pod 则默认允许所有流量。
示例:
- 示例 1:默认拒绝所有入站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {} # 空选择器,选中当前命名空间所有Pod
policyTypes:
- Ingress
# ingress 字段为空,表示不允许任何入站流量
# 但允许所有出站流量(因为没有指定egress策略)
YAML- 示例 2:允许来自特定 Pod 的流量
# 允许 frontend Pod 访问 backend Pod 的 6379 端口。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
spec:
podSelector:
matchLabels:
app: backend # 此策略保护标有 app=backend 的Pod
policyTypes:
- Ingress
ingress:
- from:
- podSelector: # 允许来自的Pod
matchLabels:
app: frontend
ports: # 允许访问的端口
- protocol: TCP
port: 6379
YAML- 示例 3:允许出站到外部 DNS
# 允许所有 Pod 访问外部 DNS 服务器(端口 53)。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-egress
spec:
podSelector: {} # 适用于所有Pod
policyTypes:
- Egress
egress:
- to:
- namespaceSelector: {} # 选中所有命名空间(但不匹配外部IP)
ports:
- protocol: UDP
port: 53
- to: # 更佳实践:直接指定外部CIDR块
- ipBlock:
cidr: 8.8.8.8/32 # 例如,允许访问Google DNS
ports:
- protocol: UDP
port: 53
YAML- 示例 4:跨命名空间访问
# 允许 monitoring 命名空间中带有 app=prometheus 标签的 Pod 访问当前命名空间中所有 Pod 的 9090 端口。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-prometheus
spec:
podSelector: {} # 允许Prometheus访问本命名空间所有Pod
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector: # 选择命名空间
matchLabels:
kubernetes.io/metadata.name: monitoring # 通过标签选择命名空间
podSelector: # 在选中的命名空间里再选择Pod
matchLabels:
app: prometheus
ports:
- protocol: TCP
port: 9090
YAMLNetworkPolicy 只是一个 API 定义,它本身不提供任何网络能力。策略的强制执行依赖于Container Network Interface (CNI) 插件。
支持 NetworkPolicy 的流行 CNI 插件:
- Calico:功能最丰富、性能极高的网络插件,支持复杂的网络策略。
- Cilium:基于 eBPF 技术的新一代网络插件,提供极强的可观测性和安全能力,性能卓越。
- Weave Net:易于安装和使用的插件,也提供网络策略支持。
- Antrea:基于 Open vSwitch,由 VMware 发起,是 CNCF 项目。
如果你的集群没有安装这些插件,那么你创建的 NetworkPolicy 将不会产生任何效果。