一、安全机制说明
在k8s集群中,API Server是集群内部各个通信组件的中介,是外部控制的入口,所以k8s的安全机制主要是针对保护API Server来设置。
二、认证
1、常见认证方式
Kubernetes 集群的客户端认证方式主要分为以下几种:
1. 客户端证书认证(X.509 Client Certificates)
- 
原理:通过为客户端签发 X.509 证书,并在请求时携带该证书,API Server 使用预先配置的 CA 证书进行验证。 
- 
配置方式 :证书和私钥配置在 kubeconfig 文件中,API Server 启动时通过 --client-ca-file指定 CA 证书。
- 
特点:安全性高,支持双向 TLS 认证,常用于 kubectl 和集群组件间通信。 
2. 静态 Token 认证(Static Token File)
- 
原理 :API Server 启动时加载一个包含用户名、用户组、Token 等信息的静态文件(通过 --token-auth-file指定)。
- 
使用方式 :客户端在 HTTP Header 中加入 Authorization: Bearer <token>进行认证。
- 
特点:简单但不灵活,Token 长期有效,修改需重启 API Server。 
3. Service Account Token 认证
- 
原理:Kubernetes 自动为每个命名空间创建 ServiceAccount,并为其生成 JWT Token。 
- 
使用场景:Pod 内进程访问 API Server 时使用,Token 自动挂载到 Pod 中。 
- 
特点:适用于集群内部服务认证,Token 由 API Server 签发并验证。 
4. Bootstrap Token 认证
- 
原理:用于节点加入集群时的认证,Token 通过 Secret 存储在 kube-system 命名空间中。 
- 
使用场景:集群扩容或新节点加入时使用。 
5. OpenID Connect(OIDC)Token 认证
- 
原理:基于 OAuth 2.0 和 OIDC 协议,通过外部身份提供商(如 Google、Azure AD)进行认证。 
- 
配置方式 :API Server 启动参数中配置 --oidc-issuer-url、--oidc-client-id等。
- 
特点:适用于与外部身份系统集成,支持单点登录(SSO)。 
6. Webhook Token 认证
- 
原理:通过远程 Webhook 服务验证 Bearer Token,API Server 将 Token 转发给 Webhook 服务进行认证。 
- 
配置方式 :API Server 启动参数中配置 --authentication-token-webhook-config-file指定 Webhook 服务的 kubeconfig 文件。
- 
特点:可扩展性强,支持自定义认证逻辑和外部身份系统(如 LDAP、SAML)。 
7. 身份认证代理(Authenticating Proxy)
- 
原理:通过反向代理(如 Nginx、OAuth2 Proxy)在请求头中注入用户身份信息,API Server 信任代理并提取用户信息。 
- 
配置方式 :API Server 通过 --requestheader-username-headers等参数配置信任的头信息。
- 
特点:适用于统一认证网关场景,减少客户端配置复杂度。 
8. HTTP Basic 认证
- 
原理:通过用户名和密码进行认证,信息以 Base64 编码后放在 HTTP Header 中。 
- 
特点:简单但不安全,通常需配合 HTTPS 使用,生产环境较少使用。 
9. 匿名认证
- 
原理:允许未经认证的请求访问集群资源,默认关闭。 
- 
配置方式 :通过 API Server 启动参数 --anonymous-auth=true开启。
- 
特点:存在安全风险,生产环境建议关闭。 
10. client-go 凭据插件(Exec Credential Plugins)
- 
原理:通过外部命令动态获取认证凭据(如 Token 或证书),支持自定义认证协议(如 LDAP、Kerberos)。 
- 
配置方式 :在 kubeconfig 文件中配置 exec字段,指定外部命令及其参数。
- 
特点:灵活性高,支持与外部身份系统集成。 
| 认证方式 | 安全性 | 适用场景 | 配置复杂度 | 备注 | 
|---|---|---|---|---|
| 客户端证书 | 高 | kubectl、组件通信 | 中 | 默认推荐方式 | 
| 静态 Token | 中 | 简单场景 | 低 | Token 长期有效 | 
| Service Account | 中 | Pod 内服务认证 | 低 | 自动挂载 | 
| Bootstrap Token | 中 | 节点加入集群 | 低 | 临时 Token | 
| OIDC Token | 高 | 外部身份系统集成 | 高 | 支持 SSO | 
| Webhook Token | 高 | 自定义认证逻辑 | 高 | 可扩展性强 | 
| 身份认证代理 | 高 | 统一认证网关 | 中 | 需配置代理信任 | 
| HTTP Basic | 低 | 测试环境 | 低 | 不安全,需 HTTPS | 
| 匿名认证 | 低 | 公开访问 | 低 | 建议关闭 | 
| client-go 插件 | 高 | 复杂外部系统集成 | 高 | 支持动态认证 | 
2、部分认证方式讲解
由于k8s中支持的认证方式较多,我选择其中三个较常用的认证方式进行讲解
2.1HTTPS证书认证(客户端证书)
精简总结:HTTPS证书认证就是在客户端和服务端均信任的 CA 架构下,实现 TLS 双向握手进行身份认证和授权的方式。
客户端和服务器端向二者均信任的 CA 架构进行证书请求,CA 架构下发证书后,二者实现 TLS 双向握手(客户端发起 HTTPS → 服务端返回自己的证书 → 客户端验证服务端证书 →服务端要求客户端证书 → 客户端发送自己的证书 → 服务端用公钥对客户端证书做链式验证 → 握手完成,建立加密通道),由由 API Server 验证,并把证书的 CN/O 映射到 RBAC 身份即可。
①、HTTPS 认证方式(补充)
Ⅰ、HTTPS 单向认证
客户端认证服务端,如访问百度等等的网页。
首先客户端向服务端发送请求(包含客户端支持的https版本),服务器选择二者均支持的https版本并向客户端发送公钥/证书,然后客户端拿着自己的 CA 架构对服务端发来的公钥进行安全认证,如果公钥不可信会提醒客户端该网页的证书不可信,可能存在什么虚假信息等等,如果可信则客户端向服务器端发送自己的对称加密的算法,接着服务器端从中选择合适的算法返还给客户端,至此客户端和服务器端就形成了自己的加密算法,客户端在收到后会创建随机字符串作为加密密钥,再对此经过加密,向服务器端发送公钥,服务器端拿到后对此进行解密,得到对称加密的密钥

Ⅱ、HTTPS 双向认证(mTLS)
客户端和服务端互相认证,如ATM取钱。
https的双向认证和单向认证差不多,只不过是多了服务端认证客户端,确保是正确可执行的用户。
k8s中的API Server就是使用的HTTPS 的双向认证。
2.2HTTP Token认证(静态 Token)
精简总结:HTTP Token 认证就是用一个通过特殊编码方式的且难以被模仿的字符串------ Token 来进行身份认证的方式。
Token 是一个很长很复杂的字符串,存储在 API Server 的可访问文件中,每当客户端发起 API 的调用请求时,要在 HTTP Header 中放入 Token,之后 API 会去寻找你的 Token是否在可访问文件中存在,如果存在且匹配则身份认证成功,不存在就拒绝调用请求。
2.3HTTP Basic 认证
精简总结:HTTP Basic 认证就是通过用户名和密码进行认证的方式。
将用户名和密码信息以 Base64 编码后生成的字符串放在 HTTP Header 中,将其发给服务端,服务端再次进行编码得到你的用户名和密码,如果正确且相互匹配则身份认证成功,否则失败,拒绝请求。
3、必须认证+mTLS的组件/角色
3.1需认证不需mTLS
其余 常驻 Master 节点且与 API Server 同机 的组件,默认走本地非安全端口 127.0.0.1:8080,不强制 双向 TLS,但生产环境仍建议关掉 8080 端口,全部强制 mTLS。
3.2需认证需mTLS
在 Kubernetes 集群里,只要"客户端 ≠ API Server 本机" ,就必须走 HTTPS 6443 端口 + 双向 TLS(mTLS) ;换句话说,下面这些组件/角色 无一例外 都要做双向认证:
- 
kubelet(每个节点)【自动颁发证书】 
- 
kube-proxy(每个节点)【手动颁发证书】 
- 
kubectl(任何一台管理机)【手动颁发证书】 
- 
以 Pod 形式运行、但 使用自己证书 的扩展控制器/Operator(如 Calico-kube-controllers、metrics-server 等) 
- 
外部调用方(CI/CD、Webhook、自定义 Controller)------只要它不在 Master 本机 
精简总结:较安全环境可走非安全地址端口,非安全环境必须mTLS,生产环境强制mTLS。
| 组件/场景 | 必须 mTLS | 默认端口 | 备注 | 
|---|---|---|---|
| kubelet → API Server | ✅ | 6443 | 自动轮换证书 | 
| kube-proxy → API Server | ✅ | 6443 | DaemonSet 挂载证书 | 
| kubectl → API Server | ✅ | 6443 | kubeconfig 证书或 token | 
| Controller/Scheduler → API Server | ✅ | 6443 | 1.20+ 已无 8080 | 
| Pod(ServiceAccount Token)→ API Server | ❌(只需单向 TLS) | 6443 | 非 mTLS,但强制 TLS | 
| 自定义/外部 Controller → API Server | ✅ | 6443 | 客户端证书或 Token | 
3.3补充SA
ServiceAccount 是 Kubernetes 用来给 "Pod 内进程" 提供 "集群内身份 + 调用 API Server 的凭据" 的原生对象。
主要包括:
- 
ca.crt:集群根证书,用于Pod确定API Server的安全性 
- 
token:用于API Server确认Pod的安全性 
- 
namespace:标识Pod的作用域 
            
            
              bash
              
              
            
          
            # 1. 创建
  # 创建语句可直接 kubectl create sa <你的SA名称> -n <要放在的命名空间>
  kubectl create serviceaccount api-bot -n dev
  
  # 2. 赋权(RBAC),下方授权有讲
  kubectl create role dev-reader --verb=get,list --resource=pods -n dev
  kubectl create rolebinding dev-reader-binding \
    --role=dev-reader --serviceaccount=dev:api-bot -n dev
  
  # 3. 在 Pod 里引用
  apiVersion: v1
  kind: Pod
  metadata:
    name: job-pod
    namespace: dev
  spec:
    serviceAccountName: api-bot        # 关键字段
    containers:
    - image: bitnami/kubectl:latest
      command: ["kubectl","get","pods"]4、kubeconfig
4.1kubeconfig 是什么
- 
作用:告诉 kubectl/任何 client-go 程序「连哪个集群、用什么身份、默认命名空间」。 
- 
本质:一个 YAML(默认 ~/.kube/config),可内嵌或引用证书、Token、Exec 插件。 
4.2文件结构
以下给出一个大致yaml文件,如果想看自己的可以进入主节点(control plane)使用cat ~/.kube/config查看
            
            
              bash
              
              
            
          
            # 1. 集群列表
  apiVersion: v1
  clusters:
    - cluster:
      certificate-authority-data: LS0tLS1CRUdJTiBD...   # 当前集群 CA 证书
      server: https://10.0.0.10:6443        # 当前集群地址和端口
      name: kind-my-multi-node-cluster1     # 由于我是用kind创建的集群,所以我的集群名字前带有kind
  # 2. 用户列表(身份)
  users:
  - name: kind-my-multi-node-cluster1
    user:
      client-certificate-data: LS0tLS1CRUdJTiBD...      # 用户证书
      client-key-data: LS0tLS1CRUdJTiBSU0Eg...          # 用户私钥
  - name: bob-token
    user:
      token: eyJhbGciOiJSUzI1NiIsIm...
  
  # 3. 上下文(把 cluster + user + 默认 ns 绑定)
  contexts:
  - context:
      cluster: kind-my-multi-node-cluster1
      user: kind-my-multi-node-cluster1
    name: kind-my-multi-node-cluster1
  current-context: kind-my-multi-node-cluster1
  kind: Config
  preferences: {}
  
  # 4. 当前默认上下文
  current-context: prod-alice注意以上四大项顺序可能不同
当我们使用 kubectl 执行命令时,会去调用 ~/.kube/config的kubeconfig文件
三、授权
Kubernetes 提供了多种授权机制来控制用户和服务账户对集群资源的访问权限。
1、授权模式概述
Kubernetes 支持以下授权模式(可同时启用多个):
- 
Node Authorization - 专门授权 kubelet 
- 
ABAC (Attribute-Based Access Control) - 基于属性的访问控制 
- 
RBAC (Role-Based Access Control) - 基于角色的访问控制(最常用) 
- 
Webhook - 外部授权服务集成 
主流实现:RBAC(Role-Based Access Control) 。
2、RBAC(基于角色的访问控制)
2.1核心组件
RBAC提供了4个顶级资源对象:
- 
Role :定义在特定命名空间 中的权限集合 
- 
ClusterRole :定义在集群 范围的权限集合 
- 
RoleBinding :将角色绑定到用户/组/服务账户(命名空间 内) 
- 
ClusterRoleBinding :将集群角色绑定到用户/组/服务账户(集群 范围) 
以上四个均可通过kubectl与API进行操作
2.2配置文件举例
①、Role
            
            
              bash
              
              
            
          
            apiVersion: rbac.authorization.k8s.io/v1
  kind: Role
  metadata:
    namespace: default              # 命名空间
    name: pod-reader
  rules:
  - apiGroups: [""]                 # 空字符串表示核心API组
    resources: ["pods"]             # 操作的资源类型
    verbs: ["get", "watch", "list"]
  # 即将 "get", "watch", "list" 这些操作授予给一个 Role(命名空间级权限对象),名字叫 pod-reader,位于 default 命名空间。Role刚创建出来其权限是0,不存在一开始就有很多权限,Role只可以定义在一个命名空间,如果要跨命名空间则要创建ClusterRole。rules中的权限可增加多个。
②、ClusterRole
            
            
              bash
              
              
            
          
            
  apiVersion: rbac.authorization.k8s.io/v1
  kind: ClusterRole
  metadata:
                                 # 和 Role 的区别在于没有命名空间
    name: secret-reader
  rules:
  - apiGroups: [""]                 # 空字符串表示核心API组
    resources: ["secrets"]
    verbs: ["get", "watch", "list"]
  # 即将 "get", "watch", "list" 这些操作授予给一个 ClusterRole(集群级权限对象),名字叫 secret-reader③、RoleBinding
            
            
              bash
              
              
            
          
            apiVersion: rbac.authorization.k8s.io/v1
  kind: RoleBinding
  metadata:
    name: read-pods
    namespace: default
  subjects:                              # 绑定对象
  - kind: User                           # 授予身份1,绑定的是一个用户
    name: jane                           # 身份1的名字(自定义)
    apiGroup: rbac.authorization.k8s.io
  - kind: ServiceAccount                 # 授予身份2,绑定的是一个SA
    name: default                        # 身份2的名字(自定义)
    namespace: kube-system
  roleRef:                               # 要引用的角色(角色来源)
    kind: Role                           # 引用的是命名空间级的 Role(而非 ClusterRole)
    name: pod-reader                     # 引用的 Role 的名称叫 pod-reader
    # 该对象必须与 RoleBinding 位于同一个命名空间
    apiGroup: rbac.authorization.k8s.io  # 指定 Role 所属的 API 组,固定值
  # 即创建了一个 RoleBinding(命名空间级权限绑定),名字叫 read-pods,位于 default 命名空间。把 Role pod-reader 的权限授予两个身份 User 和 ServiceAccount④、ClusterRoleBinding
            
            
              bash
              
              
            
          
            apiVersion: rbac.authorization.k8s.io/v1
  kind: ClusterRoleBinding
  metadata:
    name: read-secrets-global
  subjects:                                # 绑定对象
  - kind: Group                            # 绑定的是一个组
    name: manager                          # 组的名称
    apiGroup: rbac.authorization.k8s.io
  roleRef:                                 # 要引用的角色(角色来源)
    kind: ClusterRole                      # 引用的是集群级的 ClusterRole(而非 Role)
    name: secret-reader                    # 引用的 ClusterRole 的名称叫 secret-reader 
    apiGroup: rbac.authorization.k8s.io
  # 即创建了一个 ClusterRoleBinding(集群级权限绑定),名字叫 read-secrets-global。把一个名称叫 secret-reader 的 ClusterRole 权限授予身份 Group2.3配合绑定关系
①、Role+RoleBinding
即在当前命名空间内,将角色绑定,最终是命名空间级别
②、ClusterRole+ClusterRoleBinding
即在当前集群内,将集群角色绑定,最终是集群级别
③、ClusterRole+RoleBinding
相当于降维,即在当前命名空间内,将集群角色绑定(可减小资源开销),最终是命名空间级别
2.4RBAC规则解析
①、rules字段结构
每个规则包含:
- 
apiGroups:资源所属的API组("" 表示核心组)
- 
resources:资源类型名称(复数形式)
- 
verbs:操作动词(如 get, list, create, update, delete, watch)
- 
resourceNames:可选,指定具体资源实例名称
- 
nonResourceURLs:非资源端点(如 "/healthz")
②、apiGroups(分组)
| 分组字符串 | 说明 / 常见资源 | 
|---|---|
| ""(空串) | 核心组(Core)。Pod、Service、ConfigMap、Secret、Node、Namespace、Event ... | 
| apps | Deployment、StatefulSet、DaemonSet、ReplicaSet、ControllerRevision | 
| batch | Job、CronJob | 
| autoscaling | HorizontalPodAutoscaler(HPA) | 
| networking.k8s.io | Ingress、NetworkPolicy、IngressClass | 
| policy | PodDisruptionBudget、PodSecurityPolicy(已弃用) | 
以上分组只是部分,详情请见官方文档
③、resources(资源)
- 
""组pods,services,configmaps,secrets,endpoints,events,persistentvolumeclaims,persistentvolumes,nodes,namespaces,serviceaccounts,resourcequotas,limitranges
- 
apps组deployments,statefulsets,daemonsets,replicasets,controllerrevisions
- 
batch组jobs,cronjobs
以上只列出每个分组最常用的;完整列表可用
kubectl api-resources -o wide。每个大资源其下会有子资源
④、verbs(动作)
| 动词 | 含义 | 典型组合 | 
|---|---|---|
| get | 读取单个资源 | 只读 | 
| list | 读取集合 | 只读 | 
| watch | 监听变化 | 只读 | 
| create | 新建资源 | 写 | 
| update | 整体更新资源 | 写 | 
| patch | 局部更新资源 | 写 | 
| delete | 删除单个资源 | 写 | 
| deletecollection | 批量删除集合 | 写 | 
| * | 所有动作(通配符) | 超级权限 | 
四、准入控制
当 API Server 已经通过 认证 & 鉴权 ,但在真正持久化之前 ,由一组 准入插件(Admission Webhook 或内置控制器) 再对资源做 "增删改"拦截或修改。
主要是对额外功能的添加以及有权限但不合理的行为的过滤。