Day 20 - ServiceAccount、镜像安全与 Pod Security
📘 Day 20:ServiceAccount、镜像安全与 Pod Security
🎯 今日目标
- 理解 Pod 默认挂载 SA Token 的含义
- 能用 imagePullSecrets 拉取私有镜像
- 能用 SecurityContext 控制容器权限
- 理解 privileged/restricted/baseline 三个级别
🧠 理论精讲(30 分钟)
ServiceAccount 自动挂载
1 | # 每个 Pod 默认会自动挂载 SA Token: |
SecurityContext 可控制的内容
| 配置 | 说明 |
|---|---|
runAsUser / runAsGroup |
指定容器运行用户 |
runAsNonRoot |
强制非 root 运行 |
privileged |
特权模式(尽量不用) |
allowPrivilegeEscalation |
是否允许提权 |
readOnlyRootFilesystem |
根文件系统只读 |
capabilities |
Linux Capabilities 管理 |
Pod Security Standards(PSS)
| 级别 | 说明 | 适用场景 |
|---|---|---|
| Privileged | 无限制 | 系统组件 |
| Baseline | 禁止已知风险(hostPath、特权) | 普通应用 |
| Restricted | 严格限制(非 root、只读根文件系统) | 安全要求高 |
🔧 动手实操(120 分钟)
练习 20.1:ServiceAccount 与 Token 管理
1 | # 1. 查看 Pod 默认挂载的 SA Token |
练习 20.2:SecurityContext 安全上下文
1 | # 1. 非 root 用户运行 |
练习 20.3:私有镜像仓库拉取
1 | # 1. 创建 Docker Registry Secret |
🐛 排错练习(30 分钟)
场景 1:镜像拉取失败(ErrImagePull / ImagePullBackOff)
1 | # 排查步骤 |
场景 2:Pod 启动后立即退出(Permission Denied)
1 | # 可能是因为 SecurityContext 限制了权限 |
🏆 赛题模拟(40 分钟)
⚠️ 严格限时 35 分钟
题目:Pod 安全加固
1 | 【操作要求】 |
📋 命令速查
| 命令 | 功能 | 注解 |
|---|---|---|
kubectl get sa -A |
列出所有 ServiceAccount | 每个 NS 有默认 default SA |
kubectl describe sa <name> -n <ns> |
SA 详情 | 查看关联的 Secrets 和镜像拉取密钥 |
kubectl create sa <name> -n <ns> |
创建 ServiceAccount | SA 创建后需绑定 Role 才有权限 |
kubectl create token <sa> -n <ns> |
生成 SA 临时 Token(1.24+) | 有时效性,用于外部访问 apiserver |
kubectl create token <sa> -n <ns> --duration=1h |
指定 Token 有效期 | 默认 1h,最长 48h |
kubectl get pod <pod> -o jsonpath='{.spec.serviceAccountName}' |
查看 Pod 使用的 SA | 默认使用 default SA |
kubectl get podsecurity |
查看 Pod Security Admission 配置 | 1.25+ 替代 PSP,三个等级:privileged/baseline/restricted |
kubectl label ns <ns> pod-security.kubernetes.io/enforce=restricted |
设置命名空间安全等级 | restricted 最严格,禁止特权容器、hostPath 等 |
kubectl label ns <ns> pod-security.kubernetes.io/warn=baseline |
设置安全警告等级 | 仅警告不拒绝 |
kubectl get secret | grep <sa>-docker |
查找镜像拉取密钥 | 私有仓库认证 |
kubectl create secret docker-registry <name> --docker-server=<url> --docker-username=<user> --docker-password=<pass> |
创建镜像拉取密钥 | 在 Pod spec 中通过 imagePullSecrets 引用 |
kubectl patch sa default -n <ns> -p '{"imagePullSecrets":[{"name":"<secret>"}]}' |
给默认 SA 添加镜像拉取密钥 | 该 NS 所有使用 default SA 的 Pod 自动携带 |
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}' |
列出所有 Pod 的镜像 | 审计镜像版本 |
kubectl set image deploy/<name> <container>=<image>@sha256:<digest> |
使用镜像摘要更新 | 比 tag 更安全,防止标签篡改 |
📚 参考来源
| 来源 | 链接 / 说明 |
|---|---|
| Kubernetes 官方:ServiceAccount | https://kubernetes.io/docs/concepts/security/service-accounts/ |
| Kubernetes 官方:Pod Security Admission | https://kubernetes.io/docs/concepts/security/pod-security-admission/ |
| Kubernetes 官方:Pod 安全标准 | https://kubernetes.io/docs/concepts/security/pod-security-standards/ |
| Kubernetes 官方:镜像拉取密钥 | https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ |
| Kubernetes 官方:镜像安全最佳实践 | https://kubernetes.io/docs/concepts/security/ |