Administrator
Administrator
发布于 2026-10-28 / 0 阅读
0
0

Kubernetes 故障排查(02):Forbidden:会登录集群,为什么还是不能看 Pod 日志

面向初级运维,使用 Linux 节点和稳定 Kubernetes API。命令按 Bash 编写。本文为教学故障场景,日志及结果为示意,不冒充生产实测;执行前确认 context、命名空间和权限。

一、遭遇情况:get pods 正常,logs 却被拒绝

部署账号能查看 Pod 列表,执行 kubectl logs 却收到 Forbidden。错误大意是某个身份不能在指定命名空间读取 pods/log。

这不是“集群连接不上”,也不是应用没有日志。请求已经到达授权判断阶段,当前权限没有允许这项操作。本篇场景是一份 Role 只授予 pods 的读取,没有授予日志子资源。

二、原因分析:身份正确,不代表能做所有操作

RBAC 根据身份、API 组、资源、动词和范围授权。pods 与 pods/log 是不同的授权目标;允许列出 Pod,不自动允许读取日志,更不自动允许 exec 进入容器。

RBAC 故障需要核对的四个维度

Role 定义命名空间内规则,RoleBinding 把身份与规则关联。ClusterRole 可以被 RoleBinding 用于命名空间范围,也可以通过 ClusterRoleBinding 绑定为集群范围;选择哪一种应取决于任务范围,而不是哪种更省事。

三、排查思路:把错误拆成可验证的字段

kubectl auth can-i get pods -n 目标命名空间
kubectl auth can-i get pods --subresource=log -n 目标命名空间
kubectl get role,rolebinding -n 目标命名空间

命名空间是占位符,先替换为实际值。can-i 判断指定操作是否获准,不验证某个 Pod 是否存在或日志是否正常。某些账号也无权读取 Role;此时把错误中的必要字段交给负责授权的人,而不是要求开放全部管理权限。

检查 RoleBinding 的 subject 类型、名称与 namespace,ServiceAccount 身份通常对应 system:serviceaccount:命名空间:账号名。绑定错命名空间,是“规则看起来对但还是不生效”的常见原因。

四、实践:只在专用命名空间授权一个演示账号

以下需要具备创建这些实验 RBAC 对象的权限。实验通过 --as 模拟 ServiceAccount,执行者还需有相应 impersonate 权限;没有该权限时,应使用已有受控测试身份,不要临时提升为集群管理员。

保存为 kt02-rbac.yaml:

apiVersion: v1
kind: Namespace
metadata:
  name: kt02
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: observer
  namespace: kt02
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
  namespace: kt02
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: observer-pod-reader
  namespace: kt02
subjects:
  - kind: ServiceAccount
    name: observer
    namespace: kt02
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pod-reader

应用并比较两项权限:

kubectl apply -f kt02-rbac.yaml
kubectl auth can-i list pods -n kt02 --as=system:serviceaccount:kt02:observer
kubectl auth can-i get pods --subresource=log -n kt02 --as=system:serviceaccount:kt02:observer

预期分别为 yes 与 no,前提是没有其他现有绑定额外授予该身份权限。RBAC 许可会叠加,不能只看这一份 Role 就认定账号的全部能力。

五、修复实践:补日志权限,不补集群管理员

编辑实验 Role,将原来的读取规则保留,再增加日志子资源的 get 权限。以下是完整的 Role 更新文件 kt02-role-fixed.yaml:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
  namespace: kt02
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get"]
kubectl apply -f kt02-role-fixed.yaml
kubectl auth can-i get pods --subresource=log -n kt02 --as=system:serviceaccount:kt02:observer

预期变为 yes。该修改并没有授予写 Pod、读取 Secret 或 exec 权限。真实环境应先确认日志是否属于该账号的任务范围,再做对应授权。

六、验证与总结

最后用真实目标身份读取一个确实存在、允许访问的 Pod 日志。再测试一项明确不应允许的操作,例如 can-i delete pods;仅看日志读取成功,还不能证明授权没有过宽。

不要把长效管理员 token 复制给应用来绕过 Forbidden。ServiceAccount 凭据管理与 Role 规则是两件事,日志内容本身也可能含业务敏感信息。

这类故障的排查顺序是:读身份 → 读动词和资源 → 读命名空间 → 核对绑定 → 最小修复 → 正反两面验证。认证成功是起点,授权始终需要精确到操作。

官方参考


上一篇 · 系列目录 · 下一篇


评论