在Kubernetes中API Server是访问和管理资源对象的唯一入口。所有客户端均要通过API Server访问或者改变集群状态以及完成数据存储,API Server会对每一次请求进行合法性校验,校验包括:用户身份验证、操作权限验证以及操作是否符合全局规范约束等。所有检查均正常完成才能访问或存储数据到etcd。如下图所示:

客户端认证操作由API Server配置的一到多个认证插件完成,收到请求后API Server会串行调用这些插件,直到一个插件可以成功识别用户身份为止。授权操作同样由一到多个授权插件完成,也是串行被调用,直到其中一个插件验证权限成功,这些插件负责检测用户是否有权限执行发出的资源操作请求。最后,通过授权检测的用户的相关修改请求还要经由一到多个准入控制器插件的遍历式检测,例如:补全资源对象缺失字段默认值、检查资源对象字段值是或否符合要求等,任何一个插件检测失败都会导致请求被拒绝。
下面分别介绍一下认证、授权和准入
k8s将所有客户端发起的请求的请求主体分为两类:用户账户(User Account)和服务账户(Service Account)
k8s使用身份验证插件对API请求进行身份验证,它允许管理员自定义服务账户和用户账户要启用的插件,并支持各自同时启用多种认证机制。如果启用了多种认证机制,账户认证过程由认证插件以串行的方式进行,直到其中一个认证机制成功完成即结束。若认证失败,服务器香影401状态码,反之请求者会被k8s识别为某个具体的用户,并且该连接上的后续操作都会以此用户身份进行。
k8s支持的认证方式有如下几种,但不仅限于这些方式:
为了校验用户的操作许可,成功通过身份验证后的请求还要交给授权插件进行权限检查,以确保其拥有执行相应操作的许可。API Server主要支持以下4类内置的授权插件来检查用户的操作权限:
目前默认启用Node和RBAC两个插件,可以通过kube-apiserver的–authorization-mode选项指定要启用的插件,多个值以逗号分割。
准入控制器(admission controller)用于客户端请求在通过身份验证和权限检查之后,将对象数据保存到etcd数据库之前拦截请求,从而实现在资源的创建、修改和删除操作期间强制执行对象的语义验证等功能,读取资源信息的请求不会经过准入控制器检查。API Server内置了许多准入控制器,常用的包括以下几种:
可以通过kube-apiserver的–enable-admission-plugins指定要启用的准入控制插件,通过–disable-admission-plugins指定要禁用的准入控制插件
RBAC是一种权限管理模型,它把附加在“资源对象”上的“动作”称为“许可权限”,这些权限能够按需组合在一起构建出“角色“”,并通过为“用户账户或组账户”分配一到多个角色完成授权。这些能够发出操作用户在RBAC中也称为“主体”。如下图所示:

简单来说,RBAC就是一种访问控制模型,它以角色为中心界定了“谁”(subject)能够对哪个或哪类“对象”(object)执行哪些“操作”(verb)。动作的发出这是“主体”,在k8s上,可以是普通账户也可以是服务账户。“动作”用于表明要执行的具体操作,包括增删改查等,对API Server来说就是POST、GET、PUT、DELETE等请求方法。而“对象”则指管理操作能够施加的目标主体,对k8s来说主要是各类资源对象以及非资源型URL
k8s的RBAC授权插件将角色分为Role和ClusterRole两类,它们都是内置的资源类型,Role作用于名称空间级别,用于承载名称空间内的资源权限集合,而ClusterRole作用于集群级别,能够同时承载名称空间级别和集群级别资源权限集合。Role无法承载集群级别资源的权限,这类资源包括集群级别资源(例如node、pv等)和非资源类型的url(例如/healthz)
利用Role和ClusterRole进行授权时还需要借助RoleBinding和ClusterRoleBinding这两种资源,它们同样是内置的资源类型。RoleBinding用于将Role绑定到一个或一组用户上,它仅能作用于其所在的名称空间。RoleBinding可以引用同一名称空间中的Role,也可以引用集群级别的ClusterRole,但引用ClusterRole时 ClusterRole上的权限只能在RoleBinding所在名称空间生效。ClusterRoleBinding用于将ClusterRole绑定到用户或组,它作用于集群全局,且仅能引用ClusterRole。
Role和ClusterRole都是内置的资源类型,它们的资源规范基本一致,区别是Role需要指定名称空间,ClusterRole不需要,它们都没有spec字段,直接使用rules字段指定授权规则,规则的基本要素是动作(verb)和规则生效的目标资源。rules字段可嵌套使用的字段如下:
RoleBinding负责在名称空间级别向普通账户、服务账户或组分配Role或ClusterRole,而ClusterRoleBinding只能在集群级别向账户或组分配ClusterRole。两者的配置规范基本一致,RoleBinding需要指定名称空间,它们都没有spec字段,直接使用subjects和roleRef字段,subjects用于指定要绑定的主体,roleRef用于指定要绑定的Role或ClusterRole。
subjects字段可嵌套使用的字段如下:
roleRef可嵌套使用的字段如下:
k8s内置了一些默认的ClusterRole,其中大部分以system开头,是预留给集群使用的。另一部分不以system开头是面向用户的需求而设计的,包括集群管理员cluster-admin,以及用于授予名称空间特定权限的admin、view和edit。它们各自的权限说明如下表所示:
| 默认ClusterRole | 说明 |
|---|---|
| cluster-admin | 超级管理员,拥有操作所有资源的权限 |
| admin | 名称空间管理员,拥有指定名称空间中所有资源的管理权限,包括Role和RoleBinding,但不包括名称空间本身和资源配置 |
| edit | 允许读写访问一个名称空间中的大部分资源,但不允许查看或修改Role和RoleBinding |
| view | 允许读写一个名称空间内的大部分资源,但不允许查看或修改Role或RoleBinding,以及Secret资源 |
在多租户或多项目的环境下,用户应该获得名称空间级别大多数资源的管理(admin)、编辑(edit)和只读(view)权限,可以通过在名称空间中创建RoleBinding引用内置的ClusterRole完成快速授权
kubeconfig配置文件保存一到多个k8s集群的配置信息,用于访问k8s集群时使用。简单来说,kubeconfig文件包含多个k8s集群的API Server信息和多个身份认证信息,然后指定了用户应该以什么身份访问哪个k8s集群。
如下图所示,一个kubeconfig文件主要包含4部分:

kubeconfig是一个文本文件,可以使用kubectl config及其子命令来设置其内容。kubectl config可用的子命令如下:
kubectl config命令的操作针对加载的单个kubeconfig文件进行,它根据优先级高低,依次搜索–kubeconfig指定的文件,KUBECONIFG环境变量指定的文件和默认的$HOME/.kube/config文件。
客户端请可以携带证书访问API Server用于认证,认证完成后证书的主体标识(Subject)会被识别为用户表示,其中的字段CN的值是用户名,字段O的值是用户所属的组。例如例如 /CN=ilinux/O=admin中,用户名是ilinux,它属于admin组。
在这种认证方式下,客户端的证书需要API Server信任的CA根证书签发,kube-apiserver的–client-ca-file用于指定信任的根证书,默认是集群自己的CA。

下面测试利用集群的CA签发一个客户端证书用于访问API Server。
先为客户端签发证书:
#生成私钥
(umask 077; openssl genrsa --out client-jack.key 2048)
#生成证书证书签发请求文件,CN设置为jack,O设置为developers
openssl req -new -key client-jack.key \
-out .certs/client-jack.csr \
-subj "/CN=jack/O=developers"
#使用k8s集群的CA签发证书
openssl x509 -req -days 365 \
-CA /etc/kubernetes/ssl/ca.pem \
-CAkey /etc/kubernetes/ssl/ca-key.pem -CAcreateserial \
-in client-jack.csr -out client-jack.crt
设置一个新的kubeconfig文件
#添加集群信息,保存到一个新的文件test-kubeconfig中
kubectl config set-cluster k8s-cluster1 \
--server https://192.168.122.188:6443 \
--embed-certs=true \
--certificate-authority=/etc/kubernetes/ssl/ca.pem \
--kubeconfig ./test-kubeconfig
#添加访问凭据
kubectl config set-credentials jack \
--client-certificate client-ca/client-jack.crt \
--client-key client-ca/client-jack.key \
--embed-certs=true --kubeconfig ./test-kubeconfig
#添加context
kubectl config set-context jack@k8s-cluster1 \
--cluster k8s-cluster1 --user jack \
--kubeconfig test-kubeconfig
#设置当前使用的context
kubectl config use-context jack@k8s-cluster1 --kubeconfig test-kubeconfig
查看test-kubeconfig内容

测试访问集群, 如下图,已经可以访问集群,但是jack用户还未授权所以不能对资源进行任何操作。

创建ClusterRole和ClusterRoleBinding进行授权
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pv-admin
rules:
- apiGroups: [""] #对pv拥有所有操作权限
resources: ["persistentvolumes"]
verbs: ["*"]
- apiGroups: ["apps"] #对deploy具有增删改查的权限
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: pv-admin-for-jack
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: jack
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: pv-admin
然后通过jack用户访问集群,如下图,只能管理pv和deployment资源,符合ClusterRole的权限设定

ServiceAccount主要用于Pod中的应用程序访问API Server时进行认证,每个Pod对象都可以附加一个同名称空间下的ServiceAccount,只能附加一个,可以通过pod.spec.serviceAccountName字段指定要使用的ServiceAccount对象,忽略此字段时会由ServiceAccount准入控制器自动附加当前名称空间下的默认ServiceAccount对象。
首先创建一个ServiceAccount对象
kubectl create sa my-sa

创建ServiceAcount对应的Secret
apiVersion: v1
kind: Secret
metadata:
name: test
annotations:
kubernetes.io/service-account.name: test
type: kubernetes.io/service-account-token

获取ServiceAccount对应Secret中保存的Token
kubectl get secret/secret-for-my-sa -o jsonpath={.data.token} |base64 -d

设置kubeconfig文件
kubectl config set-credentials my-sa --token <token> --kubeconfig test-kubeconfig
kubectl config set-context my-sa@k8s-cluster1 --cluster k8s-cluster1 --user my-sa --kubeconfig test-kubeconfig
测试访问集群,如下图所示,已经可以通过Token访问API Server,但是由于没有对my-sa授权所以不能访问任何资源

创建Role和RoleBinding进行授权
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pods-reader
namespace: default
rules:
- apiGroups: [""] #核心API群组
resources: ["pods", "services", "pods/log"] #规则对pods、services和pods/log(pod的日志)资源生效
verbs: ["get", "list", "watch"] #仅能执行get、list和watch操作
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pods-reader-for-my-sa
namespace: default
subjects:
- kind: ServiceAccount
name: my-sa
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pods-reader
测试通过my-sa访问集群,如下图,只能查询default名称空间下的pod和service资源,符合Role的权限设定

上边的步骤将ServiceAccount的token直接保存在kubeconfig中用于访问API Server,正常情况下ServiceAccount主要用于Pod中的应用访问API Server时使用,Pod创建时会自动定义一个存储卷挂载在容器内/run/secrets/kubernetes.io/serviceaccount/目录下,如下图,主要包括3个文件:ca.crt、namespace和token。其中ca.crt是k8s集群的ca,可以用于访问API Server时校验API Server的证书;namspace是Pod所在的名称空间;token就是访问API Server的令牌,Pod中应用访问API Server时携带此token用于认证即可

简单代码require'net/http'url=URI.parse('getjson/otherdatahere[link]')req=Net::HTTP::Get.new(url.to_s)res=Net::HTTP.start(url.host,url.port){|http|http.request(req)}putsres.body只是想知道如何在phpcURL中放置身份验证token,我是这样做的 curl_setopt($ch,CURLOPT_HTTPHEADER,array('Authorization:Bearerxxx'));//Bearertokenfora
谁能提供一个使用HTTParty和digestauth的例子?我在网上找不到例子,希望有人能提供一些帮助。谢谢。 最佳答案 您可以在定义类时使用digest_auth方法设置用户名和密码classFooincludeHTTPartydigest_auth'username','password'end 关于ruby-HTTParty摘要认证,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questi
Doorkeeper中Token和Grant的区别我搞不清楚。Doorkeeper在哪个时刻创建访问授权,何时创建访问token?文档似乎对此什么也没说,现在我正在阅读代码,但不是十几行。 最佳答案 我还建议阅读documentationofoauth2据我了解,Doorkeeper也是基于该文档中描述的协议(protocol)。在doorkeeper中,你会先获得accessgrant,然后是accesstoken。访问授权通常只存在很短的时间(doorkeeper中的默认值为10分钟)。您将通过向api-url/oauth/au
我正在尝试为自己创建一个直接连接到我的日历的应用程序……但我从不想参与重新验证。我只想编写一次身份验证代码并完成它。授权码如下:key=Google::APIClient::PKCS12.load_key(SERVICE_ACCOUNT_PKCS12_FILE_PATH,PASSWORD)asserter=Google::APIClient::JWTAsserter.new(SERVICE_ACCOUNT_EMAIL,'https://www.googleapis.com/auth/calendar',key)@client=Google::APIClient.new@client.a
我正在努力让google-api-ruby-clientgem按照这里的基本用法示例工作:基本用法require'google/apis/drive_v2'Drive=Google::Apis::DriveV2#Aliasthemoduledrive=Drive::DriveService.newdrive.authorization=...#SeeGoogleauthorSignetlibraries#SearchforfilesinDrive(firstpageonly)files=drive.list_files(q:"titlecontains'finances'")files
我正在使用Deviseauthtokengem用于验证我的Rails应用程序的某些部分。但是,当我尝试使用注册路径创建新用户时,出现以下错误{"errors":["Authorizedusersonly."]}。这是我用于测试的rspec代码,it'createsauserusingemail/passwordcombo'dopostapi_user_registration_path,{email:'xxx',password:'yyy',password_confirmation:'yyy'}putslast_response.bodyexpect(last_response.bo
有道无术,术尚可求,有术无道,止于术。本系列SpringBoot版本3.0.4本系列SpringSecurity版本6.0.2本系列SpringAuthorizationServer版本1.0.2源码地址:https://gitee.com/pearl-organization/study-spring-security-demo文章目录前言1.OAuth2AuthorizationServerMetadataEndpointFilter2.OAuth2AuthorizationEndpointFilter3.OidcProviderConfigurationEndpointFilter4.N
我正在寻找一个很好的基于角色的授权解决方案来与Authlogic一起使用。有人有什么好的建议吗?如果可能,请根据您的经验列出一些优缺点。 最佳答案 Acl9与AuthLogic配合得很好:http://github.com/be9/acl9/tree/master 关于ruby-on-rails-与Authlogic一起使用的一些好的角色授权解决方案是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.c
我正在为ruby使用googleapi,但不知道如何开始,请给我一个ABC示例,非常感谢? 最佳答案 如果您要创建服务帐户应用程序以访问GoogleAnalytics。通过https://code.google.com/apis/console向Google注册.在APIAccess选项卡上,单击CreateclientID,选择ServiceAccount。存储Google将生成的key文件,并记住该key的密码。这里有一些代码可以帮助您入门require'rubygems'require'google/api_client'
华为认证分等级的,相当于初中高三个等级,当然高级是比较难考的,也是含金量最高的。我就慢慢给你介绍一下。1.了解华为认证华为认证网络工程师是由华为公司认证与采购部推出的独立认证体系,与之前的华为认证不同,简称HCIA。同时华为认证是华为技术有限公司凭借多年信息通信技术人才培养经验,以及对行业发展的理解,以层次化的职业技术认证为指引,推出的覆盖IP、IT、CT以及ICT融合技术领域的认证体系,是ICT全技术领域认证体系。2.怎么考取华为认证网络工程师?要考取华为认证网络工程师必须选择最近的Prometric授权考试中心APTC报名并参加GB0-190的考试,考试通过后,以获得由华为统一签发的“华