u1timate
发布于 2025-12-31 / 3 阅读
0
0

2 kubernetes 介绍

0x01 实验环境安装

kind 是一个使用 Docker 容器“节点”运行本地 Kubernetes 集群的工具。kind 最初主要为测试 Kubernetes 本身而设计,但也可用于本地开发或持续集成 (CI)。

文档

系统环境: Ubuntu 22.04

  • 先安装 docker

  • 安装 Kind

curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind

root@dev-1-35:/home/u1timate# kind version
kind v0.32.0-alpha+81afcd0e84b596 go1.25.5 linux/amd64
  • 创建多节点集群

# kind-multi-node.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
  - role: worker
  - role: worker
root@dev-1-35:/home/u1timate# kind create cluster --name dev --config kind-multi-node.yaml
Creating cluster "dev" ...
 ✓ Ensuring node image (kindest/node:v1.35.0) 🖼
 ✓ Preparing nodes 📦 📦 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
 ✓ Joining worker nodes 🚜
Set kubectl context to "kind-dev"
You can now use your cluster with:
  • 安装 kubectl 工具

sudo apt update
sudo apt install -y ca-certificates curl apt-transport-https
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key \
  | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] \
https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /" \
  | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt update
sudo apt install -y kubectl

# 验证
root@dev-1-35:/home/u1timate# kubectl get nodes
NAME                STATUS   ROLES           AGE     VERSION
dev-control-plane   Ready    control-plane   3m18s   v1.35.0
dev-worker          Ready    <none>          3m8s    v1.35.0
dev-worker2         Ready    <none>          3m8s    v1.35.0

0x02组件与安全

一个典型的Kubernetes集群由一组Master节点(或Control Plane节点)和一组Worker节点组成。这些节点协同工作,通过一系列核心组件来管理和运行容器化应用。

1.1 K8s核心组件概览

components-of-kubernetes.svg

  • API Server: K8s集群的“前门”,提供HTTP API服务,所有组件和外部用户都通过它与集群交互。它是控制平面的核心。

  • etcd: 一个高可用、分布式、一致性的键值存储,用于保存K8s集群的所有配置数据、状态数据和元数据。可以理解为K8s集群的“大脑”或“数据库”。

  • Controller Manager: 运行多种控制器进程,负责集群的各种资源对象(如Deployment、ReplicaSet、Namespace等)的生命周期管理和状态维护。

  • Scheduler: 负责监听新创建的Pod,并为其选择一个合适的Worker节点进行调度。

  • Kubelet: 运行在每个Worker节点上,负责与API Server通信,接收Pod的指令,并确保Pod中容器的运行状态符合预期。

  • Kube-proxy: 运行在每个Worker节点上,负责为Service提供网络代理和负载均衡功能,实现Service的网络可达性。

  • Container Runtime: 运行在每个Worker节点上,负责真正运行容器的软件(如Docker、Containerd、CRI-O等)。

1.2 各组件威胁分析

API Server

  • 功能: 集群的统一入口,处理所有REST请求。

  • 安全风险:

    • 认证绕过: 弱认证机制或配置错误可能允许未经授权的访问。

    • 授权滥用: RBAC策略配置不当,可能赋予用户或服务账户过高的权限,导致特权升级。

    • 准入控制器绕过: 恶意或配置错误的准入控制器可能允许不安全的配置或操作。

    • DDoS攻击: 大量请求可能导致API Server过载,影响集群可用性。

  • 威胁建模: 假想攻击者通过窃取ServiceAccount Token或伪造kubeconfig文件来访问API Server,然后利用授权漏洞创建恶意Pod或修改集群配置。

etcd

  • 功能: 存储所有K8s集群数据,包括Secrets、ConfigMaps、Pod定义、RBAC策略等。

  • 安全风险:

    • 数据泄露: 未加密的etcd数据或未经授权的访问可能导致敏感信息(如Secrets)泄露。

    • 数据篡改: 恶意修改etcd中的数据可能破坏集群功能或引入后门。

    • 拒绝服务: etcd服务中断将导致整个K8s集群功能失效。

  • 威胁建模: 攻击者获取了对etcd集群的网络访问权限,尝试直接从etcd中读取或修改存储的Secrets信息。

Controller Manager & Scheduler

  • 功能: 自动化集群操作和资源调度。

  • 安全风险:

    • 权限过高: 这些组件需要高权限来管理集群资源,如果其ServiceAccount被泄露,可能导致集群被完全控制。

    • 逻辑漏洞: 控制器逻辑中的漏洞可能被利用来执行非预期操作。

  • 威胁建模: 攻击者通过某种方式获取了Controller Manager的kubeconfig凭证,然后利用其权限创建持久化的恶意资源。

Kubelet

  • 功能: 运行在每个Worker节点上,负责Pod的生命周期管理和节点资源监控。

  • 安全风险:

    • 节点逃逸: Pod中的漏洞可能被利用,导致容器逃逸,进而控制整个Worker节点。

    • API未授权访问: Kubelet API(如只读端口或认证未强制执行)可能被恶意访问,获取节点或容器信息。

    • 特权容器滥用: 运行特权容器可能放大逃逸攻击的危害。

  • 威胁建模: 恶意容器利用内核漏洞实现容器逃逸,进而获取Kubelet的宿主机权限,并进一步扩散至其他Pod或节点。

Kube-proxy

  • 功能: 维护网络规则,实现Service的网络转发。

  • 安全风险:

    • 网络策略绕过: Kube-proxy的配置或漏洞可能导致网络隔离失效。

    • 资源消耗: 大量Service或Endpoint可能导致Kube-proxy资源消耗过大。

  • 威胁建模: 攻击者试图通过操纵Kube-proxy的网络规则,将特定服务的流量重定向到恶意端点。

Container Runtime

  • 功能: 运行容器。

  • 安全风险:

    • 运行时漏洞: 容器运行时本身(如Docker、Containerd)的漏洞可能被利用进行容器逃逸或权限提升。

    • 不安全镜像: 基础镜像包含已知漏洞或恶意软件。

    • 配置错误: 运行时配置不当(如暴露了不必要的端口、挂载了敏感目录)可能引入风险。

  • 威胁建模: 攻击者运行一个包含特定漏洞利用程序的容器,当调度到存在相应漏洞的Container Runtime的节点时,尝试利用该漏洞获得宿主机权限。

0x03 访问控制

Kubernetes的基于角色的访问控制(Role-Based Access Control, RBAC)提供了一种强大的访问控制机制。

概念

RBAC在Kubernetes中主要由以下几个核心对象构成:

  • Subject(主体): 代表请求操作的实体,可以是:

    • User(用户): 由外部系统管理,如身份提供商。Kubernetes不直接管理用户,而是信任外部身份认证系统。通常通过kubeconfig文件中的证书或Token来标识。

    • Group(组): 一组用户的集合,方便统一授权。同样由外部系统管理。

    • ServiceAccount(服务账户): Kubernetes内部管理的一种特殊账户,通常用于Pod内部进程对API的访问。每个命名空间都有一个默认的default服务账户。

  • Role(角色): 定义了一组在特定命名空间内被允许执行的权限。一个Role包含一个规则列表,每个规则指定了允许的资源(apiGroups, resources, resourceNames)和操作(verbs)。

  • ClusterRole(集群角色): 类似于Role,但其权限定义适用于整个集群。ClusterRole可以用于:

    • 定义跨所有命名空间的资源权限(如nodes、PersistentVolumes)。

    • 定义非资源型API(如/healthz)。

    • 定义命名空间级别但作用于所有命名空间的资源权限(如允许在所有命名空间中列出Pod)。

  • RoleBinding(角色绑定): 将一个Role(或ClusterRole)授予一个或多个Subject,作用范围限定在RoleBinding所在的命名空间。

  • ClusterRoleBinding(集群角色绑定): 将一个ClusterRole授予一个或多个Subject,作用范围覆盖整个集群。

为特定命名空间中的开发者授权

假设我们有一个名为dev-team-a的命名空间,我们想允许一个名为developer-zhang的服务账户在该命名空间中创建、读取、更新、删除Pod和Deployment。

  • 创建 namespace

kubectl create namespace dev-team-a

#查看当前namespace
root@dev-1-35:/home/u1timate# kubectl get ns
NAME                 STATUS   AGE
default              Active   9m15s
dev-team-a           Active   2m28s
kube-node-lease      Active   9m15s
kube-public          Active   9m16s
kube-system          Active   9m16s
local-path-storage   Active   9m11s
  • 首先,创建Role:

# dev-pod-manager-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-and-deployment-manager
  namespace: dev-team-a # 作用于dev-team-a命名空间
rules:
- apiGroups: ["", "apps"] # "" 代表核心API组 (Pod), "apps" 代表 Deployment 等
  resources: ["pods", "deployments"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

  • 用户绑定角色

# dev-pod-manager-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: developer-zhang-pod-manager
  namespace: dev-team-a # 作用于dev-team-a命名空间
subjects:
- kind: ServiceAccount
  name: developer-zhang # 绑定给名为developer-zhang的服务账户
  namespace: dev-team-a
roleRef:
  kind: Role
  name: pod-and-deployment-manager
  apiGroup: rbac.authorization.k8s.io
  • 创建这些资源:

kubectl apply -f dev-pod-manager-role.yaml
kubectl apply -f dev-pod-manager-rolebinding.yaml

# 确认资源创建成功
root@dev-1-35:/home/u1timate# kubectl get role -n dev-team-a
NAME                         CREATED AT
pod-and-deployment-manager   2025-12-31T09:37:13Z

root@dev-1-35:/home/u1timate# kubectl get rolebinding -n dev-team-a
NAME                          ROLE                              AGE
developer-zhang-pod-manager   Role/pod-and-deployment-manager   35s
  • 验证权限

# 检查developer-zhang在dev-team-a命名空间中是否能创建Pod:

root@dev-1-35:/home/u1timate# kubectl auth can-i create pods --as=system:serviceaccount:dev-team-a:developer-zhang -n dev-team-a
yes

可以使用kubectl auth can-i命令来验证某个用户或服务账户是否拥有特定权限。

文档

创建集群级别的只读审计员

创建一个auditor集群角色,允许其在所有命名空间中只读访问所有资源。

  • 创建集群角色

# cluster-auditor-clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: read-only-auditor
rules:
- apiGroups: ["*"] # 匹配所有API组
  resources: ["*"] # 匹配所有资源
  verbs: ["get", "list", "watch"]
  • 绑定角色

# cluster-auditor-clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: auditor-group-binding
subjects:
- kind: Group
  name: auditors # 绑定给名为auditors的组(K8s 不会创建组,组由认证系统提供)
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: read-only-auditor
  apiGroup: rbac.authorization.k8s.io

kind: Group 只是一个标签,Kubernetes 不会创建它。  

只有当用户的认证信息里包含这个 group 时,绑定才会生效。

0x04 Pod安全标准

Pod安全标准(PSS)是Kubernetes自1.23版本起推出的,用于替代废弃的Pod安全策略(Pod Security Policy, PSP)。它提供了一组预定义的Pod安全配置规范,帮助用户轻松地为Pod强制执行不同的安全级别。PSS的目标是确保Pod在运行时不会获得不必要的权限或访问敏感资源,从而减少潜在的攻击面。

PSS定义了三个安全级别:

  1. Privileged(特权)

    • 此策略不加限制。允许已知和未知的权限提升。通常用于系统级的Pod,如集群网络插件或存储驱动。

  2. Baseline(基线)

    • 此策略旨在防止已知的特权升级,同时允许大部分常见的应用工作负载正常运行。它会限制一些高风险的Pod配置,例如禁止使用hostPath卷、privileged模式、Linux capabilities提升等。

  3. Restricted(受限)

    • 此策略是高度受限的,旨在强制实施当前Pod强化最佳实践。它会限制更多敏感的Pod配置,例如要求Pod以非root用户运行、禁止任何capabilities修改、禁用特权容器等。通常用于对安全性要求极高的应用工作负载。

使用 PSS

使用内置的安全准入控制器进行控制,并允许您在命名空间(Namespace)级别配置PSS的策略和执行模式。通过在命名空间上设置特定的标签,您可以定义该命名空间中的Pod将如何遵守PSS。

主要有3种执行模式:

  1. Enforce(强制执行):属于阻断模式。如果 Pod 违反策略,API Server 会直接拒绝创建请求。

  2. Audit(审计):属于记录模式。允许 Pod 创建,但在集群的审计日志中记录违规事件,主要用于管理员后台分析。

  3. Warn(警告):属于提示模式。允许 Pod 创建,但在用户执行(如 kubectl apply)操作时,会直接在客户端终端显示警告信息,提醒用户该 Pod 违规。

 给 Namespace 启用 Kubernetes Pod Security Standards (PSS),并且设置为 restricted(最严格)级别,同时开启 enforce / audit / warn 三种模式。

三个都开了,意味着:

  • enforce:阻止不安全 Pod

  • warn:用户会看到警告

  • audit:审计系统会记录违规

apiVersion: v1
kind: Namespace
metadata:
  name: my-secure-namespace
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: latest
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/audit-version: latest
    pod-security.kubernetes.io/warn: restricted
    pod-security.kubernetes.io/warn-version: latest

0x05 网络策略

络策略是Kubernetes中用于定义Pod之间以及Pod与外部网络之间如何通信的规范。它们是基于标签选择器(Label Selectors)的,通过控制Ingress(入站)和Egress(出站)流量,实现Pod级别的网络隔离,有效减少横向移动攻击的风险。

要使用网络策略,您的Kubernetes集群必须部署一个支持NetworkPolicy资源的CNI插件,例如Calico、Cilium或Kube-router。

当为某个Pod或一组Pod定义了网络策略后,只有符合策略中定义的规则的流量才会被允许。默认情况下,如果没有为Pod定义任何网络策略,则该Pod允许所有入站和出站流量。但一旦为某个Pod定义了至少一个网络策略,该Pod的默认行为就会变为“拒绝所有不被策略显式允许的流量”。

一个网络策略通常包含以下关键字段:

  • podSelector:选择应用此策略的Pod。

  • policyTypes:指定策略是应用于Ingress(入站)、Egress(出站)还是两者。如果未指定,默认只应用于Ingress。

  • ingress:定义允许进入所选Pod的入站规则。

  • egress:定义允许从所选Pod发出的出站规则。

允许特定命名空间和特定端口的出站流量

只允许backend pod 它向database命名空间中的db服务(端口3306)发出请求。

# allow-egress-to-db.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-backend-to-db
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: database
      podSelector:
        matchLabels:
          app: db
    ports:
    - protocol: TCP
      port: 3306

拒绝所有入站网络

# deny-all-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress-to-nginx
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: nginx
  policyTypes:
    - Ingress
  ingress: [] # 空的ingress规则表示拒绝所有入站流量
  • podSelector 选中了 app=nginx 的 Pod

  • policyTypes: [Ingress] 表示只控制入站流量

  • ingress: [] 表示 没有任何允许规则 → 默认拒绝所有入站流量

  • 这个策略只拒绝 ingress,不影响 egress

验证

# 启动一个 web pod,并设置标签
kubectl run nginx --image=nginx --labels="app=nginx"

# 启动一个客户端 
kubectl run test --image=busybox --restart=Never -- sh -c "sleep 3600"
kubectl exec test -- wget -qO- http://nginx #可能直接卡主,或者超时

标签是关键: PSS和网络策略都高度依赖标签。保持清晰、一致的标签策略对于有效管理这些安全规则至关重要。


评论