综述
API Server 是一个标准的 RESTful Server,核心功能是提供 kubernetes 各类资源对象(如 Pod、RC)的增、删、改、查、watch 等 HTTP REST 接口。它是集群内各个功能模块之间数据交互和通信的中心枢纽,是整个 kubernetes 系统的数据总线和数据中心。它提供了完备的集群安全机制,默认情况下 8080 端口为 HTTP 端口,6443 端口为 HTTPS 端口。
针对一个请求的处理过程简单来说依次包含以下步骤:
- 认证
- 鉴权
- 准入(admission)
- Mutating
- Validating
- 持久化
更加详细的流程如图所示(图中红色的尖头),包含:
- 认证(authentication)
- 审计(audit)
- 限流
- 鉴权(authorization)
- 路由
- 准入(Mutating、Validating)
- 持久化
下面依次对这些流程做个概述。
认证
开启 TLS 之后,所有的请求都需要先认证。认证过程主要是确定 username 的过程,也就是看看你是谁。如果认证成功,则用户的 username 会传入授权模块做进一步授权验证,而对于认证失败的请求则返回 HTTP 401。
Kubernetes 支持多种认证机制,并支持同时开启多个认证插件(只要有一个认证通过即可)。更加完整的认证概述,可参见官方文档 用户认证 。
-
X509 证书
在证书认证的时候,其 CN 域被作为用户名,而 O 域(组织机构域)被作为 group 名。使用 x509 客户端证书需要 API Server 启动时配置 --client-ca-file=$。
-
ServiceAccount
kubernetes Pod 中的程序访问 APIServer 时常用,会自动挂载到容器的 /run/secrets/kubernetes.io/serviceaccount 目录中。
-
静态 token 文件
文件为 csv 格式,每行至少包括 3 列 token、username、user id。在请求时带上相应的 token 即可。
token,user,uid,“group1,group2,group2”
-
启动引导 token
-
OpenID Connect(OIDC)
OAuth 2.0 的认证机制。
-
Webhook 令牌身份认证
会用到 TokenReview API 资源。
静态密码文件:不推荐。
鉴权
鉴权是看谁对什么资源有操作权限。它主要用于对集群资源的访问控制,通过检查请求包含的相关属性值,与相对应的访问策略相比较,请求必须满足某些策略才能被处理。
与认证类似,Kubernetes 支持多种鉴权机制,并支持同时开启多个授权插件(只要有一个验证通过即可)。如果授权成功,则用户的请求会发送到准入模块做进一步的请求验证;对于授权失败的请求则返回 HTTP 403。
Kubernetes 支持以下鉴权插件:
-
RBAC(Role-Based Access Control)
RBAC 在 Kubernetes 中被映射为 API 资源和操作,通过 API 资源就可以进行授权操作。
-
ABAC(Attribute Based Access Control)
在 Kubernetes 中的实现比较难于管理和理解:需要 Master 所在节点的 SSH 和文件系统权限,并且要使得对授权的变更成功有效,还需要重新启动 API Server。
-
Webhook
-
Node
Kubernetes 鉴权模块主要对以下的请求属性进行判断:
- User, group, extra
- API、请求方法(get、post、update、patch、delete)和请求路径(如 api/)
- 请求资源和子资源
- Namespace
- API Group
更加完整的鉴权概述,可参见官方文档 鉴权概述。
准入
准入控制(Admission Control)是指在请求通过认证和鉴权后、对象被持久化之前,对请求中的对象做进一步的验证或添加默认参数。准入控制仅对创建、更新、删除对象的请求有效,对读(get、watch 或 list)对象的请求无效。准入控制支持同时开启多个插件,它们依次调用,只有全部插件都通过的请求才可以进入系统。
准入控制中的操作,主要分为两类:
- Mutating(变更):对请求中的对象进行更改。
- Validating(验证):对请求中的对象进行验证。
Admission Controller(准入控制器)
Admission Controller 是 Kubernetes API Server 内置的一组插件,它们会在资源对象被创建、更新或删除前对其进行修改和验证,也就是分为了 mutaling 和 validating 两种类型。下面列举一些内置的 Admission Controller,更完整的请查看官网文档 准入控制器参考。
- AlwaysAdmit:接受所有请求。
- AlwaysPullImages:总是拉取最新镜像,在多租户场景下非常有用。
- DenyEscalatingExec:禁止特权容器的 exec 和 attach 操作。
- ImagePolicyWebhook:通过 webhook 决定 image 策略,需要同时配置 --admission-control-config-file
- ServiceAccount:自动创建默认 ServiceAccount,并确保 Pod 引用的 ServiceAccount 已经存在
- SecurityContextDeny:拒绝包含非法 SecurityContext 配置的容器
- ResourceQuota:限制 Pod 的请求不会超过配额,需要在 namespace 中创建一个 ResourceQuota 对象
- LimitRanger:为 Pod 设置默认资源请求和限制,需要在 namespace 中创建一个 LimitRange 对象
- InitialResources:根据镜像的历史使用记录,为容器设置默认资源请求和限制
- NamespaceLifecycle:确保处于 termination 状态的 namespace 不再接收新的对象创建请求,并拒绝请求不存在的 namespace
- DefaultStorageClass:为 PVC 设置默认 StorageClass
- DefaultTolerationSeconds:设置 Pod 的默认 forgiveness toleration 为 5 分钟
- PodSecurityPolicy:使用 Pod Security Policies 时必须开启
- NodeRestriction:限制 kubelet 仅可访问 node、endpoint、pod、service 以及 secret、configmap、PV 和 PVC 等相关的资源
Admission Webhook
Admission Webhook 是一种自定义的 Admission Controller 扩展机制,允许用户通过 HTTP webhook 的方式将自己的逻辑注入到 Kubernetes 的准入控制流程中。详细可参考官方文档 动态准入控制。
Admission Webhook 跟 Admission Controller 类似,也会有两种类型:mutaling 和 validating。mutaling 类型的 Webhook 会先被调用,修改完成之后,validating 类型的 Webhook 才会被调用。
配置使用 Admission Webhook 的流程如下所示:
-
首先确保启用 MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook 控制器,以及启用了
admissionregistration.k8s.io/v1
API。 -
编写 Webhook 服务器,demo 为:https://github.com/kubernetes/kubernetes/blob/release-1.21/test/images/agnhost/webhook/main.go。
-
部署 Webhook 服务器,有两种方式:
-
一种是在集群内部部署 Webhook 服务器,这个时候可以使用 deployment + service 的方式;
-
另一种是在集群外部署 Webhook 服务器。
-
-
之后根据 Webhook 服务器的功能,创建相应的 Webhook Configuration:MutatingWebhookConfiguration 或 ValidatingWebhookConfiguration。如果 Webhook 服务器实现了 mutating 和 validating,那么这两个资源都需要创建。
apiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: name: "pod-policy.example.com" webhooks: - name: "pod-policy.example.com" rules: - apiGroups: [""] apiVersions: ["v1"] operations: ["CREATE"] resources: ["pods"] scope: "Namespaced" clientConfig: service: namespace: "example-namespace" name: "example-service" caBundle: <CA_BUNDLE> admissionReviewVersions: ["v1"] sideEffects: None timeoutSeconds: 5
这步的主要作用是将 Webhook 服务器的信息配置到 API Server 中,这样 API Server 在准入控制相应对象的时候会调用相应的 Admission Webhook。比如,针对上述例子,API Servrer 在收到与
rules
相匹配的请求时,API Server 就可以按照clientConfig
中指定的方式向 Webhook 服务器发送一个admissionReview
请求。这个过程如图所示,