K8s 学习笔记(七):安全与 RBAC

写在前面

本文是 K8s 学习笔记系列的第七篇,介绍 K8s 的安全机制:Namespace 隔离、RBAC 权限控制、SecurityContext 和安全最佳实践。前置知识:调度与扩缩(第六篇)。


一、Namespace 隔离

Namespace 是 K8s 资源隔离的基本单位。

1.1 Namespace 的作用

1
2
3
4
资源隔离    — 不同团队/环境的资源互相不可见
权限控制    — RBAC 按 Namespace 授权
资源配额    — 限制每个 Namespace 的资源使用
命名隔离    — 不同 Namespace 中资源可以同名

Namespace 只隔离资源对象,不隔离网络(默认情况下 Pod 可以跨 Namespace 通信)。

1.2 Namespace 管理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 查看所有 Namespace
kubectl get ns

# 创建
kubectl create ns dev
kubectl create ns staging
kubectl create ns prod

# 查看某个 Namespace 的所有资源
kubectl get all -n dev

# 在指定 Namespace 操作
kubectl apply -f deploy.yaml -n dev

1.3 环境划分示例

1
2
3
4
5
6
default       — 默认命名空间(别放正式资源)
dev           — 开发环境
staging       — 预发环境
prod          — 生产环境
kube-system   — 系统组件(kube-apiserver、CoreDNS 等)
monitoring    — 监控组件(Prometheus、Grafana)

1.4 ResourceQuota(资源配额)

限制 Namespace 的总资源使用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-quota
  namespace: dev
spec:
  hard:
    requests.cpu: "10"              # 总 CPU 上限
    requests.memory: "20Gi"         # 总内存上限
    limits.cpu: "20"
    limits.memory: "40Gi"
    pods: "50"                      # 最大 Pod 数
    services: "20"                  # 最大 Service 数
    persistentvolumeclaims: "20"    # 最大 PVC 数

1.5 LimitRange(默认资源限制)

给 Namespace 中的 Pod 设置默认 resources:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: v1
kind: LimitRange
metadata:
  name: dev-limits
  namespace: dev
spec:
  limits:
  - max:
      cpu: "2"
      memory: "2Gi"
    min:
      cpu: "50m"
      memory: "64Mi"
    default:
      cpu: "500m"
      memory: "256Mi"
    defaultRequest:
      cpu: "100m"
      memory: "128Mi"
    type: Container

二、RBAC 权限控制

RBAC(Role-Based Access Control)控制谁能在集群中做什么。

2.1 RBAC 核心概念

1
2
3
4
Role          — 角色,定义权限(Namespace 级别)
ClusterRole   — 集群角色,定义权限(集群级别)
RoleBinding   — 把角色绑定给用户/组(Namespace 级别)
ClusterRoleBinding — 把集群角色绑定给用户/组(集群级别)

2.2 Role 示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: dev-developer
  namespace: dev
rules:
- apiGroups: ["", "apps"]        # "" = core API, "apps" = Deployment 等
  resources: ["pods", "deployments", "services", "configmaps"]
  verbs: ["get", "list", "watch", "create", "update", "delete"]
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list"]          # Secret 只读

2.3 RoleBinding 示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-developer-binding
  namespace: dev
subjects:
- kind: User
  name: zhangsan                  # 绑定给用户
- kind: ServiceAccount
  name: dev-sa                    # 绑定给 ServiceAccount
roleRef:
  kind: Role
  name: dev-developer
  apiGroup: rbac.authorization.k8s.io

2.4 ClusterRole 示例

1
2
3
4
5
6
7
8
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

2.5 常用 verbs

1
2
3
4
5
6
7
8
get       — 获取单个资源
list      — 列出资源
watch     — 监听资源变化
create    — 创建资源
update    — 更新资源
delete    — 删除资源
patch     — 部分更新
*         — 所有操作

2.6 常用 ClusterRole 绑定场景

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 给用户只读权限
kubectl create clusterrolebinding zhangsan-view \
  --clusterrole=view \
  --user=zhangsan

# 给用户 admin 权限(限于某个 Namespace)
kubectl create rolebinding zhangsan-admin \
  --clusterrole=admin \
  --user=zhangsan \
  --namespace=dev

三、ServiceAccount

ServiceAccount 是 Pod 访问 K8s API 的身份。

3.1 默认 ServiceAccount

每个 Namespace 都有一个默认的 ServiceAccount(default),Pod 默认使用它。

3.2 创建 ServiceAccount

1
2
3
4
5
apiVersion: v1
kind: ServiceAccount
metadata:
  name: app-sa
  namespace: dev

3.3 Pod 指定 ServiceAccount

1
2
3
spec:
  serviceAccountName: app-sa     # 指定 ServiceAccount
  automountServiceAccountToken: true

3.4 应用场景

1
2
3
Pod 调用 K8s API   → 用 ServiceAccount + RBAC 授权
CI/CD 部署         → 用 ServiceAccount 的 kubeconfig
第三方集成         → 用 ServiceAccount 认证

四、SecurityContext

SecurityContext 控制 Pod 和容器的安全设置。

4.1 Pod 级别

1
2
3
4
5
spec:
  securityContext:
    runAsNonRoot: true           # 不允许以 root 运行
    runAsUser: 1000              # 以 UID 1000 运行
    fsGroup: 2000                # 文件系统组

4.2 容器级别

1
2
3
4
5
6
7
8
spec:
  containers:
  - name: app
    securityContext:
      allowPrivilegeEscalation: false   # 不允许提权
      readOnlyRootFilesystem: true      # 只读根文件系统
      capabilities:
        drop: ["ALL"]                   # 去掉所有 Linux capabilities

4.3 安全最佳实践

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 安全的 Pod 配置
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 2000
  containers:
  - name: app
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop: ["ALL"]

五、Secret 安全

5.1 Secret 风险

1
2
3
默认只是 base64 编码,不是加密
etcd 中明文存储(除非开启加密)
任何人有权限就能解码查看

5.2 安全措施

1
2
3
4
1. 开启 etcd 加密(EncryptionConfiguration)
2. 使用外部密钥管理(HashiCorp Vault、AWS Secrets Manager)
3. RBAC 限制 Secret 访问权限
4. 审计日志记录 Secret 访问

5.3 开启 Secret 加密

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
  - secrets
  providers:
  - aescbc:
      keys:
      - name: key1
        secret: <base64-encoded-secret>
  - identity: {}

六、安全检查清单

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
Pod 安全:
  □ 不以 root 运行(runAsNonRoot: true)
  □ 只读文件系统(readOnlyRootFilesystem: true)
  □ 去掉 capabilities(drop ALL)
  □ 设置 resources limits(防止资源耗尽)

RBAC:
  □ 不用 cluster-admin 给普通用户
  □ 按 Namespace 和角色分配最小权限
  □ ServiceAccount 按需创建,不用 default

Secret:
  □ 敏感信息用 Secret 不用 ConfigMap
  □ 开启 etcd 加密
  □ RBAC 限制 Secret 访问

网络:
  □ 使用 NetworkPolicy 限制 Pod 间通信
  □ Ingress 配置 TLS
  □ 不暴露不必要的 NodePort

七、小结

本文学习了 K8s 的安全机制:

  • Namespace 隔离和资源配额
  • RBAC 权限控制(Role、ClusterRole、Binding)
  • ServiceAccount 身份管理
  • SecurityContext 容器安全
  • Secret 安全和加密
  • 安全检查清单

下一篇将学习排错与运维:排错方法、监控告警和 Helm 包管理。