K8s——安全机制

1 机制说明

Kubernetes 的安全机制本质是"身份认证 → 权限控制 → 资源隔离 → 网络隔离 → 数据加密"五层防护体系,保证谁能访问、能做什么、在哪访问、数据是否安全。

Kubernetes安全机制主要包括五个方面:

1️⃣ Authentication :身份认证(证书、Token、OIDC)

2️⃣ Authorization :RBAC权限控制

3️⃣ Admission Controller :准入控制

4️⃣ NetworkPolicy :Pod 网络隔离

5️⃣ Encryption:TLS通信和etcd数据加密

2 安全机制流程

2.1 流程图

bash 复制代码
# 当客户端(如 kubectl)向 API Server 请求资源时
 请求:连接认证		# 通过证书ca.crt连接
  ↓  
认证:身份认证		# 解决的问题:谁可以访问 API Server
  ↓  
鉴权:权限认证		# 解决的问题:认证通过之后,能干什么
  ↓  
准入控制		  		# 解决的问题:请求是否合理
  ↓  
资源写入 etcd

2.2 Prometheus 访问举例

无论是k8s内部的服务访问还是外部的服务访问,都需要进行以上过程

  • 内部服务访问:连接认证(ca.crt)和身份认证(Token)自动生成,权限认证(RBAC)需要配置
  • 外部服务访问:连接认证(ca.crt)需要复制,身份认证(Token)需要生成,权限认证(RBAC)需要配置
2.2.1 外部 Prometheus(集群外)

1️⃣ 拷贝k8s的ca.crt 到Prometheus服务器上

bash 复制代码
scp /etc/kubernetes/pki/ca.crt root@master01:/etc/prometheus

2️⃣ 获取 Token

bash 复制代码
SECRET_NAME=$(kubectl -n monitoring get sa/prometheus-sa -o jsonpath='{.secrets[0].name}')
TOKEN=$(kubectl -n monitoring get secret $SECRET_NAME -o jsonpath='{.data.token}' | base64 --decode)
echo $TOKEN > /etc/prometheus/k8s-token

3️⃣ Prometheus 配置使用 Token

bash 复制代码
vim /etc/prometheus/prometheus.yml
-----------------------------------------------------------------------------------------
scrape_configs:
- job_name: 'kubernetes-pods'
  kubernetes_sd_configs:
    - api_server: https://<K8S_API_SERVER>:6443
      role: pod
      bearer_token_file: /etc/prometheus/k8s-token   # 这里引用 token 文件
      tls_config:
        ca_file: /etc/prometheus/ca.crt
        insecure_skip_verify: false

4️⃣ 创建 ServiceAccount

bash 复制代码
kubectl -n monitoring create serviceaccount prometheus-sa

5️⃣ 创建 RBAC 权限并绑定 SA(只读访问 Pods/Services/Endpoints)

bash 复制代码
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus-readonly
rules:
- apiGroups: [""]
  resources: ["pods","services","endpoints"]
  verbs: ["get","list","watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus-sa-binding
subjects:
- kind: ServiceAccount
  name: prometheus-sa
  namespace: monitoring
roleRef:
  kind: ClusterRole
  name: prometheus-readonly
  apiGroup: rbac.authorization.k8s.io
EOF

✅ 说明:Prometheus 启动后会用 Token 向 API Server 认证身份,然后 RBAC 判断权限


2.2.2 内部 Prometheus(Pod 内)
  • Kubernetes 会自动挂载 Token 到 Pod:
bash 复制代码
/var/run/secrets/kubernetes.io/serviceaccount/token
  • Prometheus 配置使用 ConfigMap 进行管理,只需指向挂载路径:
bash 复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: monitoring
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
    scrape_configs:
    - job_name: 'kubernetes-pods'
      kubernetes_sd_configs:
        - role: pod
          bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
          tls_config:
            ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
            insecure_skip_verify: false
      relabel_configs:
        - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
          action: keep
          regex: true
        - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port]
          action: replace
          target_label: __address__
          regex: (.+)
          replacement: $1
-----------------------------------------------------------------------------------------
# 在创建 Prometheus 的 Deployment中挂载 ConfigMap
volumeMounts:
- name: prometheus-config
  mountPath: /etc/prometheus/prometheus.yml
  subPath: prometheus.yml

volumes:
- name: prometheus-config
  configMap:
    name: prometheus-config

无需手动创建或拷贝 Token,RBAC 权限认证同上。

3 身份认证(Authentication)

🔑 解决的问题:谁可以访问 API Server

Kubernetes 所有操作都必须经过 API Server,所以第一步是确认访问者身份。

3.1 支持的认证方式

  • HTTP Token 认证:在 HTTP Header 携带一个难以仿冒的长 Token;API Server 维护 Token 与用户名的映射。
  • HTTP Basic 认证 :用户名:密码 使用 Base64 编码后放入 Header 的 Authorization 字段。
  • HTTPS 证书认证(最严格) :基于 CA 根证书签名(CA = ca.crt + ca.key)的双向 TLS 认证。

注:Token 与 Basic 仅支持服务端对客户端单向 认证;HTTPS 证书可实现双向认证。

3.2 ServiceAccount(SA)

用于 Pod 中容器访问 API Server 的身份。由于 Pod 动态创建/销毁,为每个 Pod 手动发证书不可行,故使用 Service Account 解决 Pod 到 API Server 的认证。

ServiceAccount 中包含三部分:

  • Token:由 API Server 私钥签名的 Token,用于服务端认证来访主体;
  • ca.crt:CA 根证书,供客户端验证 API Server 的证书;
  • namespace:该 service-account-token 的命名空间作用域。

默认每个命名空间都有一个 SA;若创建 Pod 时未指定 SA,将使用所属命名空间的 default SA。创建 Pod 后,系统会自动将以下内容挂载到容器:

bash 复制代码
/var/run/secrets/kubernetes.io/serviceaccount/
  ├─ ca.crt		# 连接认证
  ├─ namespace
  └─ token		# 身份认证
  
# 查看 Service Account
kubectl get sa

4 权限控制(Authorization)

🔐 解决的问题:认证通过之后,能干什么

Kubernetes使用 RBAC权限模型

资源 作用
Role namespace级权限
ClusterRole 集群级权限(跨namespace)
RoleBinding 绑定Role
ClusterRoleBinding 绑定ClusterRole

4.1 什么时候需要 RBAC 认证

pod需要对其他pod进行增删改查的操作时,才需要设置权限

例如:

Prometheus 监控k8s时,需要查看权限,所以需要进行RBAC的权限认证

4.2 RBAC 认证逻辑

bash 复制代码
Role/ClusterRole	# 设置权限
     │
     ├───── RoleBinding/ClusterRoleBinding	# 将权限绑定到SA账户
     ↓
ServiceAccount		# 拿到权限
     ↓
用户 / Pod			# 用 SA 账户进行访问
     ↓
API Server
     ↓
RBAC判断
     ↓
允许 or 拒绝

5 准入控制(Admission Control)

🔐 解决的问题:请求是否合理

认证 + 授权之后,还会经过 Admission Controller

举个例子:

bash 复制代码
# 当创建一个pod时,当返回
// 请求合理,允许创建
pod/nginx-ok created	

// 请求不合理,拒绝创建
Error from server (Forbidden):
pod nginx-bad rejected: must specify resources limits

6 网络安全(Network Security)

🌐 解决的问题:Pod之间是否可以通信

默认:

bash 复制代码
Pod ↔ Pod 全部互通

6.1 安全方案

NetworkPolicy------限制 Pod 网络访问。

示例逻辑:

bash 复制代码
# 只允许带有t=t1 标签的pod/namespace 访问 带有t=t2 标签的pod/namespace,禁止其他的访问

t=t1  ───────▶ t=t2  ✅允许
t=t2  ───────▶ t=t1  ✅不受影响
其他   ───────▶ t=t1  ✅不受影响
t=t1  ───────▶ 其他   ✅不受影响
t=t2  ───────▶ 其他   ✅不受影响
其他   ───────▶ t=t2  ❌拒绝

必须配合网络插件:(Flannel不支持)

  • Calico

6.2 实例演示

bash 复制代码
# 实现结果(注:使用标签匹配,namespace也同理,标签自定义,需要以 键:值 的方式)
frontend (t=t1)
        │允许
        ▼
backend (access=backend)
        ▲
        │允许
prometheus (t=t1)

# 关键配置
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-monitor-and-frontend
spec:
  podSelector:
    matchLabels:
      role: backend        # 选择后端Pod

  policyTypes:
  - Ingress				# 只是语法规则,不是Ingress,代表的是 接受来自谁的访问
						#			  如果是egress,代表的是 只能访问到谁
  ingress:
  - from:
    - podSelector:
        matchLabels:
          t: t1           # 允许访问来源
-----------------------------------------------------------------------------------------
# 如果是 egress,代表 role: backend 只能访问到 t: t1  
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-monitor-and-frontend
spec:
  podSelector:
    matchLabels:
      role: backend        # 选择后端Pod

  policyTypes:
  - Egress
  
  egress:
  - to:
    - podSelector:
        matchLabels:
          t: t1

7 数据安全(Encryption)

🔒 解决的问题:数据是否加密

Kubernetes主要有两类数据加密:API 通信加密etcd数据加密

7.1 API 通信加密

所有组件通信使用:

bash 复制代码
TLS证书

例如:

bash 复制代码
kubectl → apiserver
kubelet → apiserver
controller → apiserver

7.2 etcd数据加密

7.2.1 概念

由于 K8s 的核心存储 etcd 默认明文存储 ,会导致存储在etcd 中的 Secrets 等敏感信息可能被访问,所以需要开启 EncryptionConfiguration 对 etcd 中的 Secrets 进行加密

7.2.2 配置方式
bash 复制代码
vim encryption-config.yaml
-----------------------------------------------------------------------------------------
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: <base64-encoded-key>
      - identity: {}
=========================================================================================
# 修改 kube-apiserver 启动参数, kube-apiserver 会自动重启,让配置生效
--encryption-provider-config=/etc/kubernetes/encryption-config.yaml

# secret: <base64-encoded-key> 的获取方式
head -c 32 /dev/urandom | base64
// 输出: y1ZpM3+4B1C5x1j2k3l4m5n6o7p8q9r0s1t2u3v4w5x=
相关推荐
yeflx2 小时前
Docker in Docker 实战
运维·docker·容器
Promise微笑2 小时前
2026年回路电阻测试仪厂家深度测评:电力安全与技术前瞻
安全
lcx_defender2 小时前
【Docker】Docker配置Redis单机模式
redis·docker·容器
xhyyvr2 小时前
VR科普学习一体机|开启智慧安全教育新时代
学习·安全·vr
@土豆3 小时前
Kafka on Kubernetes 有状态应用部署文档(KRaft 模式)
分布式·kafka·kubernetes
xuansec3 小时前
【JavaEE安全】Spring Boot 安全实战:JWT 身份鉴权与打包部署
spring boot·安全·java-ee
谢娘蓝桥3 小时前
Mac mini 4 docker 安装openclaw
运维·docker·容器
DevSecOps选型指南3 小时前
直击AI全生命周期安全治理,悬镜正式发布原创多模态AIST新品
人工智能·安全·自然语言处理
乾元3 小时前
本地大模型:如何在内网部署 Llama/Qwen 等安全增强模型
运维·网络·人工智能·安全·机器学习·llama·安全架构