一、Api Server
kube-apiserver是 Kubernetes 最重要的核心组件之一,主要提供以下的功能:
-
提供集群管理的REST API接口,包括认证授权、数据校验以及集群状态变更等;
-
提供其他模块之间的数据交互和通信的枢纽(其他模块通过API Server 查询或修改数据,只有API Server才直接操作
etcd)。
Kubernetes API的每个请求都会经过多阶段的访问控制之后才会被接受,这包括认证、授权以及准入控制(Admission Control)等。
二、认证
开启TLS时,所有的请求都需要首先认证。Kubernetes支持多种认证机制,并支持同时开启多个认证插件(只要有一个认证通过即可)。如果认证成功,则用户的username会传入授权模块做进一步授权验证;而对于认证失败的请求则返回HTTP 401。
2.1 认证插件
- X509证书
使用X509客户端证书只需要 AP Server
启动时配置–client-ca-file=SOMEFILE。在证书认证时,其CN域用作用户名,而组织机构域则用作 group名。 - 静态 Token 文件
使用静态 Token 文件认证只需要API Server 启动时配置
–token-auth-file=SOMEFILE。 ·该文件为csv格式,每行至少包括三列 token,username,user id,token,user,uid,“group1,group2,group3” - 引导 Token
为了支持平滑地启动引导新的集群,Kubernetes包含了一种动态管理的持有者令牌类型,称作启动引导令牌(Bootstrap Token)。 ·这些令牌以Secret的形式保存在kube-system 名字空间中,可以被动态管理和创建。控制器管理器包含的TokenCleaner控制器能够在启动引导令牌过期时将其删除。 ·在使用 kubeadm 部署 Kubernetes时,可通过 kubeadm token list 命令查询。 - 静态密码文件
需要API Server 启动时配置 --basic-auth-file=SOMEFILE,文件格式为csV,每行至少三列password,user,uid,后面是可选的 group 名 password,user,uid,"group1,group2,group3"。 - ServiceAccount
ServiceAccount是Kubernetes自动生成的,并会自动挂载到容器的/run/secrets/kubernetes.io/serviceaccount 目录中。 - OpenID
OAuth 2.0的认证机制 - Webhook令牌身份认证
–authentication-token-webhook-config-file 指向一个配置文件,其中描述如何访问远程的Webhook 服务。
·–authentication-token-webhook-cache-ttl用来设定身份认证决定的缓存时间。默认时长为2分钟。
下面是X509认证的示例:
通过openssl生成key和csr
openssl genrsa -out myuser.key 2048
openssl req -new -key myuser.key -out myuser.csr
encode csr
cat myuser.csr | base64 | tr -d "\n"
replace request and create csr
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: myuser
spec:
request: xxx # encode csr
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 86400 # one day
usages:
- client auth
EOF
approve csr
kubectl certificate approve myuser
extract csr
kubectl get csr myuser -o jsonpath='{.status.certificate}'| base64 -d > myuser.crt
set credential
kubectl config set-credentials myuser --client-key=myuser.key --client-certificate=myuser.crt --embed-certs=true
grant permition
kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods
kubectl create rolebinding developer-binding-myuser --role=developer --user=myuser
认证成功后在kubeconfig中能看到myuser用户的认证信息。
三、授权
授权主要是用于对集群资源的访问控制,通过检查请求包含的相关属性值,与相对应的访问策略相比较,API请求必须满足某些策略才能被处理。
跟认证类似,Kubernetes 也支持多种授权机制,并支持同时开启多个授权插件(只要有一个验证通过即可)。
如果授权成功,则用户的请求会发送到准入控制模块做进一步的请求验证;对于授权失败的请求则返回HTTP 403。
目前,Kubernetes支持以下授权插件:
- ABAC
- RBAC
- Webhook
- Node
3.1 RBAC
3.2 Role 与 ClusterRole
Role(角色)是一系列权限的集合,例如一个角色可以包含读取Pod的权限和列出Pod的权限。Role 只能用来给某个特定namespace 中的资源作鉴权,对多 namespace 和集群级的资源或者是非资源类的API(如/healthz)使用ClusterRole。
kind:Role
apiVersion:rbac.authorization.k8s.io/v1
metadata:
namespace:default
name:pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: bind-pod-reader
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: test
RoleBinding将默认namespace的pod只读权限赋给了用户test。
四、准入
准入控制(Admission Control)在授权后对请求做进一步的验证或添加默认参数。不同于授权和认证只关心请求的用户和操作,准入控制还处理请求的内容,并且仅对创建、更新、删除或连接(如代理)等有效,而对读操作无效。
准入控制支持同时开启多个插件,它们依次调用,只有全部插件都通过的请求才可以放过进入系统。
4.1 准入控制插件
- AlwaysAdmit:接受所有请求。
- AlwaysPulllmages:总是拉取最新镜像,在多租户场景下非常有用。
- DenyEscalatingExec:禁止特权容器的exec和 attach操作。
- ResourceQuota:限制Pod的请求不会超过配额,需要在namespace 中创建一个ResourceQuota 对象。
- LimitRanger:为Pod 设置默认资源请求和限制,需要在namespace 中创建一个 LimitRange 对象。
k8s自带的准入控制插件很多,这里只列举几个,下面是ResourceQuata的示例,现在default namespace只能创建一个configmap:
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-counts
namespace: default
spec:
hard:
configmaps: "1"
除默认的准入控制插件以外,Kubernetes 预留了准入控制插件的扩展点,用户可自定义准入控制插件实现自定义准入功能。
MutatingWebhookConfiguration:变形插件,支持对准入对象的修改。
ValidatingWebhookConfiguration:校验插件,只能对准入对象合法性进行校验,不能修改。