免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

Kubernetes 用户认证授权实战:为开发人员创建受限 Namespace 的 kubeconfig 文件

Kubernetes 用户认证授权实战:为开发人员创建受限 Namespace 的 kubeconfig 文件 教程云原生容器编排【免费下载链接】kubernetes-handbookKubernetes 架构与生态从云原生到 AI 原生基础设施的构建指南项目地址https://gitcode.com/gh_mirrors/ku/kubernetes-handbook点击查看免费下载当 Kubernetes 集群搭建完成、管理员通过kubectl完成各种运维操作之后必然面临一个问题如何把kubectl安全地交付给普通用户使用直接分发管理员 kubeconfig 无异于把集群的钥匙交给所有人而正确的做法是为每个用户签发独立的客户端证书、生成专属的 kubeconfig 文件并通过 RBAC基于角色的访问控制将其权限限制在指定的 namespace 内。本文以 Kubernetes Handbook 中 创建用户认证授权的 kubeconfig 文件 为核心骨架完整演示创建 devuser 用户并将其绑定到 dev 和 test 两个 namespace的端到端流程从使用 cfssl 签发 CA 签名的用户证书到用kubectl config系列命令组装 kubeconfig再到通过RoleBinding完成细粒度授权与最终验证。读完本文你将掌握一套可复制、可脚本化的证书签发 kubeconfig 生成 RBAC 授权用户交付方案。总体思路与前置条件在开始之前需要明确整个流程的三个环节认证Authentication通过 X509 客户端证书证明我是谁。kube-apiserver 启动时带有--client-ca-file/etc/kubernetes/ssl/ca.pem参数见 apiserver 配置文件因此只有被集群 CA 签名的客户端证书才能通过认证证书中的 CNCommon Name被提取为用户名OOrganization被提取为用户组。凭证封装Credential把集群地址、CA 证书、用户证书与私钥打包成一个 kubeconfig 文件交给用户使用。授权Authorization通过 RBAC 的 RoleBinding 把角色如admin绑定到该用户将其操作范围限定在指定 namespace。执行本文操作需要满足以下前置条件集群已启用 RBAC 授权模式--authorization-modeRBAC见 apiserver 配置集群的 CA 证书与私钥ca.pem、ca-key.pem以及 cfssl 的配置文件ca-config.json已生成并统一放置在/etc/kubernetes/ssl目录下master 节点已安装 cfssl 与 cfssljson 工具且可以正常访问集群的 kube-apiserver执行授权命令的账号本身拥有cluster-admin权限即属于system:masters组。其中 CA 证书与 cfssl 配置文件的具体生成过程请参考 创建 TLS 证书和秘钥。该文档强调了一个关键设计cfssl 生成证书时使用的ca-config.json中定义了kubernetesprofile包含signing、key encipherment、server auth、client auth四种用途后续所有客户端证书admin、kube-proxy、普通用户都必须使用-profilekubernetes签名才能被 apiserver 的客户端证书校验逻辑接受。第一步为 devuser 创建 CA 签名的用户证书Kubernetes 的普通用户并没有对应的 API 对象管理员通过签发证书的方式在外部创建用户身份——apiserver 从 X509 客户端证书中提取 CN 作为用户名、O 作为组名详见 Kubernetes 中的用户与身份认证授权。因此创建用户的第一步就是为其准备一份证书签名请求CSR。创建devuser-csr.json文件内容如下{ CN: devuser, hosts: [], key: { algo: rsa, size: 2048 }, names: [ { C: CN, ST: BeiJing, L: BeiJing, O: k8s, OU: System } ] }字段说明CN即用户登录名。apiserver 认证通过后请求的 User 就是devuser后续 RoleBinding 的--userdevuser与之对应hosts客户端证书不需要绑定 IP 或域名服务器证书才需要保持为空数组即可key.algo/key.sizeRSA 2048 位密钥O组织字段apiserver 会将其作为用户所属的 Group。本示例为k8s它是一个普通的组名不会带来任何额外权限只有system:masters等特殊组才对应预置的集群角色。在 创建 TLS 证书和秘钥 一节中生成的证书与私钥被放置在 master 节点的/etc/kubernetes/ssl目录下。接下来同样在该目录下为 devuser 签发证书。执行命令前请先确认该目录已包含以下文件ca-key.pem ca.pem ca-config.json devuser-csr.json然后执行$ cfssl gencert -caca.pem -ca-keyca-key.pem -configca-config.json -profilekubernetes devuser-csr.json | cfssljson -bare devuser 2017/08/31 13:31:54 [INFO] generate received request 2017/08/31 13:31:54 [INFO] received CSR 2017/08/31 13:31:54 [INFO] generating key: rsa-2048 2017/08/31 13:31:55 [INFO] encoded CSR 2017/08/31 13:31:55 [INFO] signed certificate with serial number 43372632012323103879829229080989286813242051309 2017/08/31 13:31:55 [WARNING] This certificate lacks a hosts field. This makes it unsuitable for websites. For more information see the Baseline Requirements for the Issuance and Management of Publicly-Trusted Certificates, v.1.1.6, from the CA/Browser Forum (https://cabforum.org); specifically, section 10.2.3 (Information Requirements).命令要点-ca指定签发用的 CA 证书-ca-key指定 CA 私钥-config指定 cfssl 配置文件-profilekubernetes选择 创建 TLS 证书和秘钥 中定义的签名 profilecfssljson -bare devuser将输出直接落盘为以devuser为前缀的三个文件。命令执行完毕后会生成如下文件devuser.csr devuser-key.pem devuser.pem其中devuser.csr是证书签名请求后续不再使用devuser.pem是签发出的客户端证书devuser-key.pem是用户私钥。日志末尾的 WARNING 提示该证书没有hosts字段、不适合作为网站证书使用——对于纯客户端认证证书这是预期行为可以忽略。第二步生成 devuser 的 kubeconfig 文件有了用户证书之后下一步是把集群端点、CA 信任链和用户凭据组织成一个 kubeconfig 文件。kubeconfig 是 kubectl 与集群交互的唯一配置载体它由四个部分组成clusters集群端点与 CA、users客户端凭据、contexts集群/用户/namespace 的命名组合以及current-context默认使用的上下文详细结构说明可参考 使用 kubeconfig 文件配置跨集群认证。在 master 节点上依次执行以下四条命令# 设置集群参数 export KUBE_APISERVERhttps://172.20.0.113:6443 kubectl config set-cluster kubernetes \ --certificate-authority/etc/kubernetes/ssl/ca.pem \ --embed-certstrue \ --server${KUBE_APISERVER} \ --kubeconfigdevuser.kubeconfig # 设置客户端认证参数 kubectl config set-credentials devuser \ --client-certificate/etc/kubernetes/ssl/devuser.pem \ --client-key/etc/kubernetes/ssl/devuser-key.pem \ --embed-certstrue \ --kubeconfigdevuser.kubeconfig # 设置上下文参数 kubectl config set-context kubernetes \ --clusterkubernetes \ --userdevuser \ --namespacedev \ --kubeconfigdevuser.kubeconfig # 设置默认上下文 kubectl config use-context kubernetes --kubeconfigdevuser.kubeconfig逐条解释设置集群参数--server指定 apiserver 地址示例为https://172.20.0.113:6443请替换为你的集群实际端点--certificate-authority指定验证 apiserver 服务端证书所用的 CA--embed-certstrue将 CA 证书内容直接内嵌进 kubeconfig 文件而非仅记录文件路径保证该文件拷贝到任意机器上都能独立使用设置客户端认证参数将 devuser 的客户端证书devuser.pem与私钥devuser-key.pem关联到名为devuser的 credential 上同样通过--embed-certstrue内嵌设置上下文参数定义一个名为kubernetes的 context把集群kubernetes、用户devuser与默认 namespacedev绑定在一起设置默认上下文将刚创建的 context 设为该 kubeconfig 文件的默认上下文此后使用该文件的所有 kubectl 命令都会自动以 devuser 身份、针对 dev namespace 发出请求。需要特别说明--kubeconfigdevuser.kubeconfig的作用kubectl 默认读写$HOME/.kube/config通过该参数可以指定输出到独立文件避免污染管理员自己的配置。生成的devuser.kubeconfig就是最终要交付给用户的文件。此时如果直接查看当前 kubectl 的 context看到的仍然是管理员身份kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes kubernetes admin default-context default-cluster default-admin这是因为 kubectl 默认使用了$HOME/.kube/config作为 context 配置与刚生成的devuser.kubeconfig无关。要切换到 devuser 身份只需用新文件替换默认配置cp -f ./devuser.kubeconfig /root/.kube/config提示如果不想覆盖管理员配置也可以在使用时显式指定--kubeconfigdevuser.kubeconfig或通过环境变量KUBECONFIG指定文件路径。关于 kubeconfig 文件的加载与合并规则命令行参数、$KUBECONFIG、~/.kube/config的优先级请参考 使用 kubeconfig 文件配置跨集群认证。第三步通过 RoleBinding 将用户限制在指定 Namespace证书只解决了你是谁的问题还没有解决你能做什么。kube-apiserver 启用 RBAC 授权模式后--authorization-modeRBAC见 apiserver 配置任何未授权操作都会被拒绝。此时 devuser 虽然能通过认证但默认没有访问任何资源的权限。要授予 devuser 对 dev 和 test 两个 namespace 的完全访问权限分别创建两个 RoleBinding将内置的adminClusterRole 绑定到该用户kubectl create rolebinding devuser-admin-binding --clusterroleadmin --userdevuser --namespacedev kubectl create rolebinding devuser-admin-binding --clusterroleadmin --userdevuser --namespacetest这条命令的含义拆解如下详见 基于角色的访问控制--clusterroleadmin引用内置的adminClusterRole。它允许对命名空间内大部分资源的读写访问包括在该 namespace 内创建 Role 与 RoleBinding 的能力但不允许修改 resource quota 或 namespace 本身--userdevuser授权主体是证书认证得到的用户 devuser--namespacedev/--namespacetest绑定生效的范围。由于使用的是 RoleBinding而非 ClusterRoleBinding即使被引用的角色是集群范围的 ClusterRole实际授权范围也被限制在绑定所在的 namespace 内。执行完这两条命令后devuser 用户对 dev 和 test 两个 namespace 拥有完全访问权限namespace 之外的操作仍会被拒绝。需要说明的是示例中的两个 RoleBinding 使用了相同的名字devuser-admin-binding它们分属不同 namespace因此互不冲突如果在同一个 namespace 内重复使用相同名称则需要在创建前先删除旧的绑定。第四步验证用户权限边界替换默认 kubeconfig 并完成授权后进行如下验证# 获取当前的 context kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes kubernetes devuser dev * kubernetes kubernetes devuser test # 无法访问 default namespace kubectl get pods --namespace default Error from server (Forbidden): User devuser cannot list pods in the namespace default. (get pods) # 默认访问的是 dev namespace您也可以重新设置 context 让其默认访问 test namespace kubectl get pods No resources found.验证结果说明三点当前 context 的用户已变为devuser默认 namespace 为dev访问 dev/test 之外的 namespace如 default会收到Forbidden错误证明权限边界生效——这是 RBAC 授权器给出的 403 拒绝kubectl get pods默认落在 dev namespace返回No resources found说明认证与授权链路均已打通如果认证失败会返回Unauthorized。若希望默认访问 test namespace只需将 context 中的 namespace 改为 testkubectl config set-context kubernetes --clusterkubernetes --userdevuser --namespacetest --kubeconfig/root/.kube/config kubectl config use-context kubernetes --kubeconfig/root/.kube/config一键化用 create-user.sh 脚本完成创建与授权上述建证书 → 生成 kubeconfig → 建 namespace → 绑定角色的流程完全可以通过脚本固化。仓库的 create-user.sh 脚本正是为此设计的使用说明见 在 Kubernetes 中创建用户并授予用户 namespace 的 admin 权限。脚本的用法为./create-user.sh api_server username例如./create-user.sh https://172.22.1.1:6443 brand从脚本源码tools/create-user/create-user.sh可以看到它完整封装了本文的全部步骤参数校验第一个参数是 apiserver 地址KUBE_APISERVER第二个参数是用户名USER用户名同时作为 namespace 名称环境检查通过ifExist函数逐一校验/etc/kubernetes/ssl目录下是否存在ca-key.pem、ca.pem、ca-config.json动态生成 CSRcreateCSR函数用 here-doc 写入user-csr.json模板再用sed -i s/USER/$USER/g将模板中的USER占位符替换为真实用户名随后在/etc/kubernetes/ssl目录下执行与本文第一步完全相同的cfssl gencert ... -profilekubernetes命令生成 kubeconfig依次执行kubectl config set-cluster、set-credentials、set-context、use-context其中 context 的默认 namespace 直接取用户名--namespace$USER创建 namespace 并授权kubectl create ns $USER创建与用户同名的 namespace随后执行kubectl create rolebinding ${USER}-admin-binding --clusterroleadmin --user$USER --namespace$USER --serviceaccount$USER:default注意这条命令同时把该 namespace 的 admin 权限授予了用户$USER和该 namespace 下的默认 service accountdefault输出结果最后打印kubectl config get-contexts结果并提示生成的$USER.kubeconfig文件名。使用该脚本的前提是所有证书文件位于/etc/kubernetes/ssl目录下且执行脚本的主机拥有集群最高管理员权限。脚本在编写时以用户名与 namespace 同名为约定适合为组织或个人快速划分独立 namespace 的场景。原理纵深认证、凭证与授权的底层机制X509 证书如何映射为 Kubernetes 用户apiserver 通过--client-ca-file启用 X509 客户端证书认证见 apiserver 配置 中的--client-ca-file/etc/kubernetes/ssl/ca.pem。当客户端提交证书时认证插件验证其由指定 CA 签名后会从证书的CN 字段提取用户名、从O 字段提取用户组。这意味着本文创建的 devuser 证书CN 为devuser因此所有请求的 User 都是devuser若把 O 字段设为system:masters则该用户直接获得集群超级管理员权限预置的 ClusterRoleBindingcluster-admin将组system:masters与cluster-admin角色绑定见 创建 TLS 证书和秘钥 中 admin 证书的说明。这也是为什么给普通用户签发证书时 O 必须使用普通组织名如示例中的k8s而不能使用system:前缀——system:前缀是保留给 Kubernetes 系统组件使用的。RBAC 如何决定能做什么RBAC 授权模型由四个对象组成Role/ClusterRole权限集合与RoleBinding/ClusterRoleBinding权限授予。关键区别在于作用域RoleRoleBinding只作用于单个 namespaceClusterRole作用于整个集群但被RoleBinding引用时其权限会被收缩到绑定所在的 namespaceClusterRoleBinding则在集群范围内生效。本文使用的admin是 Kubernetes 预置的面向用户的 ClusterRole配合RoleBinding使用时可以在指定 namespace 内提供接近完全的管理权限仍不能修改 resource quota 与 namespace 本身。如果需要更细粒度的控制例如只读权限view、读写但不含 RBAC 管理edit或者自定义 Role 精确到某个资源如只允许get/list/watchpods都可以参考 基于角色的访问控制 中 Role 与 rules 的写法将本文的--clusterroleadmin替换为相应角色即可。kubeconfig 文件的可移植性设计生成的devuser.kubeconfig之所以可以直接交付给用户核心在于--embed-certstrue将 CA 证书、客户端证书与私钥全部以 PEM 文本内嵌进 YAML。最终文件形如apiVersion: v1 kind: Config clusters: - cluster: certificate-authority-data: base64 编码的 CA 证书 server: https://172.20.0.113:6443 name: kubernetes contexts: - context: cluster: kubernetes namespace: dev user: devuser name: kubernetes current-context: kubernetes users: - name: devuser user: client-certificate-data: base64 编码的 devuser.pem client-key-data: base64 编码的 devuser-key.pem用户拿到该文件后只需放置到~/.kube/config或通过--kubeconfig指定路径即可无缝使用。关于 kubeconfig 中 cluster、user、context、current-context 各字段的完整语义、多文件加载合并规则以及kubectl config view等管理命令可深入阅读 使用 kubeconfig 文件配置跨集群认证。安全注意事项私钥即身份devuser-key.pem与 kubeconfig 文件包含用户私钥分发时必须通过安全渠道如企业内部加密传输且文件权限建议设置为600最小权限原则如果用户只需要查看资源优先授予view而非admin如果不需要跨 namespace务必使用 RoleBinding 而非 ClusterRoleBinding撤销机制X509 客户端证书没有在线撤销机制一旦用户离职应删除其所有 RoleBinding并从集群 CA 层面停用该证书区分交付场景如果用户需要登录 Kubernetes Dashboard 而非直接使用 kubectl则 kubeconfig 文件中还需追加token字段将用户所属 service account 的 token 内嵌进去否则 Dashboard 认证不会通过详见 使用 kubeconfig 或 token 进行用户身份认证。参考创建用户认证授权的 kubeconfig 文件本文主体来源创建 TLS 证书和秘钥使用 kubeconfig 文件配置跨集群认证使用 kubeconfig 或 token 进行用户身份认证基于角色的访问控制Kubernetes 中的用户与身份认证授权create-user 一键创建用户脚本 与 使用说明赞分享教程云原生容器编排【免费下载链接】kubernetes-handbookKubernetes 架构与生态从云原生到 AI 原生基础设施的构建指南项目地址https://gitcode.com/gh_mirrors/ku/kubernetes-handbook点击查看免费下载相关推荐kubernetes-handbook 实战使用 create-user.sh 为 Kubernetes 创建用户并授予 Namespace 级 admin 权限kubernetes handbook 实战使用 create user.sh 为 Kubernetes 创建用户并授予 Namespace 级 admin教程云原生容器编排如何在Nushell中实现安全的用户权限管理从基础到高级指南如何在Nushell中实现安全的用户权限管理从基础到高级指南 Nushell作为一款创新的现代shell不仅提供了强大的数据处理能力还通过内置的安全机制保CLI开发工具kubeasz 客户端 kubeconfig 管理实战用 ezctl kcfg-adm 签发限权限、限时限的用户证书kubeasz 客户端 kubeconfig 管理实战用 ezctl kcfg adm 签发限权限、限时限的用户证书 kubeasz 集群安装完成后默认生成的云原生集群管理运维创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表