作者简介:万宏明,KubeSphere 外围贡献者,专一于云原生平安畛域。
KubeSphere 是在 Kubernetes 之上构建的面向云原生利用的容器混合云管理系统。反对多云与多集群治理,提供全栈的自动化运维能力,帮忙企业用户简化 DevOps 工作流,提供了运维敌对的向导式操作界面,帮忙企业疾速构建一个弱小和功能丰富的容器云平台。
KubeSphere 为用户提供构建企业级 Kubernetes 环境所需的多项性能,例如多云与多集群治理、Kubernetes 资源管理、DevOps、利用生命周期治理、微服务治理(服务网格)、日志查问与收集、服务与网络、多租户治理、监控告警、事件与审计查问、存储管理、拜访权限管制、GPU 反对、网络策略、镜像仓库治理以及平安治理等。
得益于 Kubernetes 优良的架构与设计,KubeSphere 舍短取长采纳了更为轻量的架构模式,灵便的整合资源,进一步丰盛了 K8s 生态。
KubeSphere 外围架构
KubeSphere 的外围架构如下图所示:
外围组件次要有三个:
- ks-console 前端服务组件
- ks-apiserver 后端服务组件
- ks-controller-manager 资源状态保护组件
KubeSphere 的后端设计中沿用了 K8s 申明式 API 的格调,所有可操作的资源都尽可能的形象成为 CustomResource。与命令式 API 相比,申明性 API 的应用更加简洁,并且提供了更好的抽象性, 通知程序最终的冀望状态(做什么),而不关怀怎么做。
典型地,在申明式 API 中:
- 你的 API 蕴含相对而言为数不多的、尺寸较小的对象(资源)。
- 对象定义了利用或者基础设施的配置信息。
- 对象更新操作频率较低。
- 通常须要人来读取或写入对象。
- 对象的次要操作是 CRUD 格调的(创立、读取、更新和删除)。
- 不须要跨对象的事务反对:API 对象代表的是冀望状态而非确切理论状态。
命令式 API(Imperative API)与申明式有所不同。 以下迹象表明你的 API 可能不是申明式的:
- 客户端收回“做这个操作”的指令,之后在该操作完结时取得同步响应。
- 客户端收回“做这个操作”的指令,并取得一个操作 ID,之后须要判断申请是否胜利实现。
- 你会将你的 API 类比为 RPC。
- 间接存储大量数据。
- 在对象上执行的惯例操作并非 CRUD 格调。
- API 不太容易用对象来建模。
借助 kube-apiserver、etcd 实现数据同步和数据长久化,通过 ks-controller-manager 保护这些资源的状态,以达到最终状态的一致性。如果你相熟 K8s,能够很好的了解申明式 API 带来的益处,这也是 KubeSphere 最为外围的局部。
例如 KubeSphere 中的流水线、用户凭证、用户实体、告警告诉的配置,都能够形象为资源实体,借助 K8s 成熟的架构与工具链,能够不便的与 K8s 进行联合,升高各组件之间的耦合,升高零碎的复杂度。
ks-apiserver 的外围架构
ks-apiserver 是 KubeSphere 外围的后端组件,负责前后端数据的交互、申请的代理散发、认证与鉴权。下图是 ks-apiserver 的外围架构:
ks-apiserver 的开发应用了 go-restful 框架,能够在申请链路中减少多个 Filter 用于动静的拦挡申请和响应,实现认证、鉴权、审计逻辑转发和反向代理性能,KubeSphere 的 API 格调也尽可能的学习 K8s 的模式,方便使用 RBAC 进行权限管制。
借助 CRD + controller 的形式进行解耦,能够极大的简化与第三方工具、软件的集成形式。
K8s 社区也提供了丰盛的工具链,借助 controller-runtime 和 kubebuiler 能够迅速的搭建起开发脚手架。
API 聚合与权限管制
能够通过拓展 ks-apiserver 实现 API 的聚合,进一步实现性能拓展、聚合查问等性能。在 API 的开发过程中中须要遵循以下标准,以便与 KubeSphere 的租户体系、资源体系进行整合。
- API 聚合
- 权限管制
- CRD + controller
API 标准
# 通过 api group 进行分组/apis/{api-group}/{version}/{resources}# 示例/apis/apps/v1/deployments/kapis/iam.kubesphere.io/v1alpha2/users# api core/api/v1/namespaces# 通过 path 辨别不同的动作/api/{version}/watch/{resources}/api/{version}/proxy/{resources}/{resource}# 通过 path 辨别不同的资源层级/kapis/{api-group}/{version}/workspaces/{workspace}/{resources}/{resource}/api/{version}/namespaces/{namespace}/{resource}
标准 API 的目标:
- 更好的对资源进行形象,形象为 Object 更适宜申明式 API
- 更好的对 API 进行治理,版本、分组、分层,更不便 API 的拓展
- 更好的与权限管制进行整合,能够不便的从申请中获取元数据,apigroup,scope,version,verb
权限管制
KubeSphere 权限管制的外围是 RBAC 基于角色的访问控制。
要害的对象有: Role、User、RoleBinding。
Role 定义了一个角色能够拜访的资源。
角色是依据资源层级进行划分的,cluster role、workspace role、namespace role 不同层级的角色定义了该角色在以后层级能够拜访的资源。
apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: role-grantorrules:- apiGroups: ["rbac.authorization.k8s.io"] resources: ["rolebindings"] verbs: ["create"]- apiGroups: ["rbac.authorization.k8s.io"] resources: ["clusterroles"] verbs: ["bind"] # 疏忽 resourceNames 意味着容许绑定任何 ClusterRole resourceNames: ["admin","edit","view"]- nonResourceURLs: ["/healthz", "/healthz/*"] # nonResourceURL 中的 '*' 是一个全局通配符 verbs: ["get", "post"]
RoleBinding 可绑定角色到某主体(Subject)上。 主体能够是组,用户或者服务账户。
apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRoleBindingmetadata: name: role-grantor-bindingroleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: role-grantorsubjects:- apiGroup: rbac.authorization.k8s.io kind: User name: user-1
CRD + controller
自定义资源(Custom Resource) 是对 Kubernetes API 的扩大,能够通过动静注册的形式拓展 K8s API。用户能够应用 kubectl 来创立和拜访其中的对象,就像操作内置资源一样。
通过 CRD 对资源进行形象,再通过 controller 监听资源变动保护资源状态, controller 的外围是 Reconcile,与他的意思一样,通过被动、定时触发的形式对资源状态进行保护,直至达到申明的状态。
以 User 资源为例,咱们能够定义一下构造的 CRD 对 User 进行形象:
apiVersion: iam.kubesphere.io/v1alpha2kind: Usermetadata: annotations: iam.kubesphere.io/last-password-change-time: "2021-05-12T05:50:07Z" name: admin resourceVersion: "478503717" selfLink: /apis/iam.kubesphere.io/v1alpha2/users/admin uid: 9e438fcc-f179-4254-b534-e913dfd7a727spec: email: admin@kubesphere.io lang: zh description: 'description' password: $2a$10$w312tzLTvXObnfEYiIrk9u5Nu/reJpwQeI66vrM1XJETWtpjd1/q2status: lastLoginTime: "2021-06-08T06:37:36Z" state: Active
对应的 API 为:
# 创立POST /apis/iam.kubesphere.io/v1alpha2/users# 删除DELETE /apis/iam.kubesphere.io/v1alpha2/users/{username}# 批改PUT /apis/iam.kubesphere.io/v1alpha2/users/{username}PATCH /apis/iam.kubesphere.io/v1alpha2/users/{username}# 查问GET /apis/iam.kubesphere.io/v1alpha2/usersGET /apis/iam.kubesphere.io/v1alpha2/users/{username}
ks-apiserver 负责将这些数据写入 K8s 再由 informer 同步到各个正本中。
ks-controller-manager 通过监听数据变动,对资源状态进行保护,以创立用户为例, 通过 POST /apis/iam.kubesphere.io/v1alpha2/users
创立用户之后, user controller 会对用户资源状态进行同步。
func (c *userController) reconcile(key string) error { // Get the user with this name user, err := c.userLister.Get(key) if err != nil { // The user may no longer exist, in which case we stop // processing. if errors.IsNotFound(err) { utilruntime.HandleError(fmt.Errorf("user '%s' in work queue no longer exists", key)) return nil } klog.Error(err) return err } if user, err = c.encryptPassword(user); err != nil { klog.Error(err) return err } if user, err = c.syncUserStatus(user); err != nil { klog.Error(err) return err } // synchronization through kubefed-controller when multi cluster is enabled if c.multiClusterEnabled { if err = c.multiClusterSync(user); err != nil { c.recorder.Event(user, corev1.EventTypeWarning, controller.FailedSynced, fmt.Sprintf(syncFailMessage, err)) return err } } c.recorder.Event(user, corev1.EventTypeNormal, successSynced, messageResourceSynced) return nil}
通过申明式的 API 将简单的逻辑放到 controller 进行解决,不便解耦。能够很不便的与其余零碎、服务进行集成,例如:
/apis/devops.kubesphere.io/v1alpha2/namespaces/{namespace}/pipelines/apis/devops.kubesphere.io/v1alpha2/namespaces/{namespace}/credentials/apis/openpitrix.io/v1alpha2/namespaces/{namespace}/applications/apis/notification.kubesphere.io/v1alpha2/configs
对应的权限控制策略:
定义一个能够增删改查 user 资源的角色。
apiVersion: rbac.authorization.k8s.io/v1kind: ClusterRolemetadata: name: user-managerrules:- apiGroups: ["iam.kubesphere.io"] resources: ["users"] verbs: ["create","delete","patch","update","get","list"]
定义一个能够创立 pipeline 资源的角色。
apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: name: devops-managerrules:- apiGroups: ["devops.kubesphere.io"] resources: ["pipelines"] verbs: ["create","delete","patch","update","get","list"]
本文由博客一文多发平台 OpenWrite 公布!