官网文档
认证
是谁,识别用户
鉴权
有无操作对象资源的权限
准入
mutating 变形,添加默认值/属性
Admission
validating 对象是否合法,是否符合k8s规范
限流
API 对象实现
主要功能
- 提供管理集群的REST API接口,包括认证、鉴权、数据校验以及集群状态变更
- 提供其他模块之间数据交互和通信的枢纽(其他模块通过API查询或修改数据,只有API server才能直接操作etcd)
访问控制概览
HTTP handler
Authentication 是谁
Authorization 有无操作资源的权限
可以通过webhook自定义mutating和validating
访问控制细节
conversion 资源转换
Internal Version 面向自己的实现
External Version 面向用户
认证
kubernetes支持多种认证机制,并支持同时开启多个认证插件(只要有一个认证通过即可)。
如果认证成功,则用户的username会传入授权模块作进一步授权验证
对于认证失败的请求返回401
认证插件
x509证书 官网文档
API server启动时配置--client-ca-file=SOMEFILE。
在证书认证时,CN(Common Name)域用作用户名,组织机构(Ognization Name)用作group名。
如何将CAA配置到API server
静态token
API server启动时配置 --token-auth-file=SOMEFILE。
文件格式有3列,token, username, userid
静态密码文件
API Server启动时指定 --basic-auth-file=SOMEFILE
文件格式为csv,至少3列,group可选。passwd, user, uid,
ServiceAcount
ServiceAcount 是kubernetes自动生成的,并且会自动挂载到容器中。
用处:pod带着这个ServiceAccount去访问API server时,API可以识别是哪个namespace的那个pod
挂载目录/run/secrets/kubernetes.io/serviceaccount
启动引导令牌
为了支持平滑的启动引导新集群,kubernetes 包含了一种动态管理的持有令牌类型,称作启动引导令牌。
该令牌以Secret形式保存在kube-system命名空间中,可以被动态管理和创建。
控制器管理器包含的TokenCleaner控制器能够在启动引导令牌过期时将其删除。
在使用kubeadm部署kubernetes时可通过kubeadm token list 查询。
认证插件
webhook令牌身份认证--authentication-token-webhook-config-file 指向一个配置文件,其中描述如何访问webhook服务--authentication-token-webhook-cache-ttl 设置身份认证的访问时间,默认2分钟
匿名请求
使用AlwaysAllow以外的认证模式,则匿名请求默认开启,可以使用--anonymous-auth=false禁止匿名请求
基于webhook的认证服务集成
URL: http://authn.example.com/authenticateMethod: POSTInput:{"apiVersion": "authentication.k8s.io/v1","kind": "TokenReview","spec": {# 发送到 API 服务器的不透明持有者令牌"token": "014fbff9a07c...",# 提供令牌的服务器的受众标识符的可选列表。# 受众感知令牌验证器(例如,OIDC 令牌验证器)# 应验证令牌是否针对此列表中的至少一个受众,# 并返回此列表与响应状态中令牌的有效受众的交集。# 这确保了令牌对于向其提供给的服务器进行身份验证是有效的。# 如果未提供受众,则应验证令牌以向 Kubernetes API 服务器进行身份验证。"audiences": ["https://myserver.example.com", "https://myserver.internal.example.com"]}}OutPut:{"apiVersion": "authentication.k8s.io/v1","kind": "TokenReview","status": {"authenticated": true,"user": {# 必要"username": "janedoe@example.com",# 可选"uid": "42",# 可选的组成员身份"groups": ["developers", "qa"],# 认证者提供的可选附加信息。# 此字段不可包含机密数据,因为这类数据可能被记录在日志或 API 对象中,# 并且可能传递给 admission webhook。"extra": {"extrafield1": ["extravalue1","extravalue2"]}},# 验证器可以返回的、可选的用户感知令牌列表,# 包含令牌对其有效的、包含于 `spec.audiences` 列表中的受众。# 如果省略,则认为该令牌可用于对 Kubernetes API 服务器进行身份验证。"audiences": ["https://myserver.example.com"]}}
webhookserver
通过github的Personal access tokens进行身份认证
package mainimport ("context""encoding/json""log""net/http""github.com/google/go-github/github""golang.org/x/oauth2"authentication "k8s.io/api/authentication/v1beta1")func Authenticate(w http.ResponseWriter, r *http.Request) {var tr authentication.TokenReviewerr := json.NewDecoder(r.Body).Decode(&tr)if err != nil {log.Println("[Error]", err.Error())w.WriteHeader(http.StatusBadRequest)_ = json.NewEncoder(w).Encode(map[string]interface{}{"apiVersion": "authentication.k8s.io/v1beta1","kind": "TokenReview","status": authentication.TokenReviewStatus{Authenticated: false,Error: err.Error(),},})return}log.Print("receving request")// Check Usersts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: tr.Spec.Token},)oauthClient := oauth2.NewClient(context.Background(), sts)httpClient := github.NewClient(oauthClient)githubUser, _, err := httpClient.Users.Get(context.Background(), "")if err != nil {log.Println("[Error]", err.Error())w.WriteHeader(http.StatusUnauthorized)json.NewEncoder(w).Encode(map[string]interface{}{"apiVersion": "authentication.k8s.io/v1beta1","kind": "TokenReview","status": authentication.TokenReviewStatus{Authenticated: false,Error: err.Error(),},})return}log.Printf("[Success] login as %s", *githubUser.Login)w.WriteHeader(http.StatusOK)trs := authentication.TokenReviewStatus{Authenticated: true,User: authentication.UserInfo{Username: *githubUser.Login,UID: *githubUser.Login,Groups: []string{"default"},},}json.NewEncoder(w).Encode(map[string]interface{}{"apiVersion": "authentication.k8s.io/v1beta1","kind": "TokenReview","status": trs,})}func main() {http.HandleFunc("/authenticate", Authenticate)log.Println(http.ListenAndServe(":3000", nil))}
kubeadm创建的k8s集群默认的证书是1年,可通过脚本进行更新
查看证书情况
# 新版本(1.15+)kubeadm alpha certs check-expiration# openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text | grep GMT
https://github.com/yuyicai/update-kube-cert
授权
授权主要是用于集群资源的访问控制,通过检查属性包含的相关属性值,与对应的访问策略相比较,API请求必须满足某些策略才能被处理。
与认证类似,kubernetes也支持多种授权机制,并支持同时开启多个授权插件,只要有一个验证通过即可。
如果授权成功,则请求会进入准入控制模块做进一步请求验证;授权失败返回403。
kubernetes授权仅处理以下请求属性
- user,group,extra
- API、请求方法(get/post/update/patch/delete)和请求路径(如API)
- 请求资源和子资源
- Namespace
- API Group
kubernetes 支持以下授权插件
- ABAC
- RBAC(Role Base Access Control)
- webhook
- Node
RBAC
授权策略可以利用kubectl进行配置。
RBAC可以授权给用户,让用户有权限进行授权管理,实现权限传递。
Role 是一系列权限的集合,只能给特定的Namespace。对多namespace和集群级别的资源或者API使用ClusterRole。
ClusterRole、ClusterRoleBinding 是全局的
Role,RoleBinding 是命名空间内部的
user 可以通过RoleBinding绑定ClusterRole
Role和RoleBinding常见操作
# 查看当前namespace有哪些roleroot@kubernetes-master:~# kubectl get roleNAME CREATED ATdeveloper 2022-05-28T09:19:13Z# 查看指定role的详细信息root@kubernetes-master:~# kubectl get role developer -oyamlapiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata:creationTimestamp: "2022-05-28T09:19:13Z"name: developernamespace: defaultresourceVersion: "2897263"uid: 504adaf9-230a-4de6-b98f-e9a9fd2442a2rules:- apiGroups:- ""resources:- podsverbs:- create- get- list- update- delete# 创建roleroot@kubernetes-master:~/role# cat dev-role.ymlapiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata:name: dev-role-defaultnamespace: defaultrules:- apiGroups:- ""resources:- podsverbs:- create- get- list- update- deleteroot@kubernetes-master:~/role# kubectl create -f dev-role.ymlrole.rbac.authorization.k8s.io/dev created# 绑定roleroot@kubernetes-master:~/role# cat dev-role-binding.yamlapiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata:name: dev-rolebindingnamespace: defaultsubjects:- kind: Username: PoplarYangapiGroup: rbac.authorization.k8s.ioroleRef:kind: Rolename: dev-role-defaultapiGroup: rbac.authorization.k8s.ioroot@kubernetes-master:~/role# kubectl create -f dev-role-binding.yaml# 在线编辑权限root@kubernetes-master:~/role# kubectl edit role dev-role-default# 测试root@kubernetes-master:~# kubectl get pod --user githubuser

ClusterRole和ClusterRoleBinding常见操作
# 查看所有cluster roleroot@kubernetes-master:~# kubectl get clusterrole# 查看当前namespace有哪些cluster roleroot@kubernetes-master:~/role# cat dev-clusterrole.ymlapiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata:name: dev-clusterrolerules:- apiGroups:- ""resources:- podsverbs:- create- get- listroot@kubernetes-master:~/role# kubectl create -f dev-clusterrole.yml# 绑定cluster roleroot@kubernetes-master:~/role# cat dev-cluster-role-binding.yamlapiVersion: rbac.authorization.k8s.io/v1kind: RoleBindingmetadata:name: dev-cluster-rolebindingnamespace: defaultsubjects:- kind: Username: PoplarYangapiGroup: rbac.authorization.k8s.ioroleRef:kind: ClusterRolename: dev-clusterroleapiGroup: rbac.authorization.k8s.ioroot@kubernetes-master:~/role# kubectl create -f dev-cluster-role-binding.yaml# 测试root@kubernetes-master:~# kubectl get pod --user githubuser
测试页面有可以公开访问的minikube
https://v1-23.docs.kubernetes.io/zh/docs/test/
