Kubernetes

Kubernetes容器存储接口CSI插件controller

前面文章介绍了CSI插件node-agent组件,node-agent主要实现了需要在主机节点上才能进行的操作功能,包含了LVMNode, LVMVolume, LVMSnapshot三个自定义资源控制器和NodeServer接口服务。那么LVMVolume,LVMSnapshot这些自定义资源又是由谁创建的呢?今天我们一起看一下OpenEBS LVM存储插件的Controller部分,了解Controller如何被编排调度系统Container Orchestration system(CO)侧Kubernetes调用,Controller又如何创建自定义资源给Node-Agent调谐的。 之前我们了解到CO侧Kubernetes开发了一系列组件如external-provisioner,external-attacher,external-snapshotter,external-resizer,这些组件通过Sidecar的方式和Plugin插件驱动侧一起运行,直接调用插件Controller的gRPC服务,实现存储卷的管理。下面我们来看一下Controller的接口服务。 Controller Interface包括以下方法 // ControllerServer is the server API for Controller service. type ControllerServer interface { // 创建存储卷,创建自定义资源LVMVolume实例 CreateVolume(context.Context, *CreateVolumeRequest) (*CreateVolumeResponse, error) // 删除存储卷,删除LVMVolume实例 DeleteVolume(context.Context, *DeleteVolumeRequest) (*DeleteVolumeResponse, error) // 挂接存储卷到指定节点,因为LVM是本地设备,末实现 ControllerPublishVolume(context.Context, *ControllerPublishVolumeRequest) (*ControllerPublishVolumeResponse, error) // 卸载存储卷,末实现 ControllerUnpublishVolume(context.Context, *ControllerUnpublishVolumeRequest) (*ControllerUnpublishVolumeResponse, error) // 验证是否支持存储卷访问模式,比如支持单/多机读写,Read-Write-Once ValidateVolumeCapabilities(context.Context, *ValidateVolumeCapabilitiesRequest) (*ValidateVolumeCapabilitiesResponse, error) // 列出所有的存储卷,末实现 ListVolumes(context.Context, *ListVolumesRequest) (*ListVolumesResponse, error) // 返回指定节点的容量信息,可用存储空间 GetCapacity(context.Context, *GetCapacityRequest) (*GetCapacityResponse, error) // 返回controller支持的功能,比如创建/删除存储卷,扩展存储卷,创建删除快照,获取容量 ControllerGetCapabilities(context.Context, *ControllerGetCapabilitiesRequest) (*ControllerGetCapabilitiesResponse, error) // 创建指定存储卷快照 CreateSnapshot(context.

继续阅读

Kubernetes容器存储接口CSI插件node-agent

Kubernetes CSI插件包含两部分:controller, node-agent。今天我们一起来看一下OpenEBS的LVM存储插件,了解OpenEBS如何实现Kubernetes使用LVM逻辑卷存储数据的。LVM逻辑卷管理(Logical Volume Manager),建立在硬盘和分区之上的一个逻辑层,提高磁盘分区管理的灵活性。Kubernetes可以利用LVM本地磁盘提高存储性能,LVM具备快照功能,为KubeVirt虚拟机提供了基于Copy-On-Write的精简配置存储,是一个非常不错的轻量级超融合解决方案。 本文将包含以下几个部分:LVM基本概念,node-agent包含组件,node-agent代码实现。 LVM基本概念 PV物理卷(physical volume),LVM的基本存储逻辑块,一个PV对应一个硬盘或者硬盘分区。VG卷组(Volume Group)由物理卷组成。LV逻辑卷(Logical Volume),建立在卷组之上,一个卷组可以创建多个逻辑卷,一个逻辑卷对应一个卷组。 LVM卷快照(snapshot)用于从文件系统的时间点视图创建备份。从快照备份文件系统,卷本身供用户使用,快照最初包含自身相关的一些元数据,不包含源逻辑卷的实际数据。快照使用写时复制技术Copy-On-Write(COW)在原始数据块的数据发生更改时,复制源块中数据进行更改。 LVM精简卷Thin Provisioned Logical Volumes,精简配置逻辑卷对存储资源进行按需动态分配,即对存储进行了虚拟化管理。在卷组上建立精简池Thin Pool,在精简池上创建精简卷Thin Volume。 node-agent组件 node-agent包含:三个自定义资源控制器,一个gRPC服务。 gRPC服务 Kubelet调用node-agent的gRPC服务接口,将存储卷挂载到本机目录,kubelet创建容器时将目录文件挂载到容器。 NodeServer接口如下: type NodeServer interface { // 挂载存储卷到临时目录 NodeStageVolume(context.Context, *NodeStageVolumeRequest) (*NodeStageVolumeResponse, error) // 从临时目录卸载存储卷 NodeUnstageVolume(context.Context, *NodeUnstageVolumeRequest) (*NodeUnstageVolumeResponse, error) // 发布存储卷,LVM逻辑卷挂载到对应主机指定目录。 NodePublishVolume(context.Context, *NodePublishVolumeRequest) (*NodePublishVolumeResponse, error) // 取消发布存储卷,卸载对应主机上的LVM逻辑卷。 NodeUnpublishVolume(context.Context, *NodeUnpublishVolumeRequest) (*NodeUnpublishVolumeResponse, error) // 返回存储卷统计信息,容量,inodes。 NodeGetVolumeStats(context.Context, *NodeGetVolumeStatsRequest) (*NodeGetVolumeStatsResponse, error) // 扩展存储卷容量。 NodeExpandVolume(context.Context, *NodeExpandVolumeRequest) (*NodeExpandVolumeResponse, error) // 返回主机节点支持的能力,比如支持存储卷扩展,存储卷数据统计。 NodeGetCapabilities(context.Context, *NodeGetCapabilitiesRequest) (*NodeGetCapabilitiesResponse, error) // 返回主机节点信息,主要是Label标签里的拓扑信息。 NodeGetInfo(context.

继续阅读

Kubernetes如何使用不同厂商存储

今天我们一起来看一下Kubernetes如何使用不同厂商存储的,了解一下CSI基本的概念。 基本概念 CSI 容器存储接口Container Storage Interface规范,定义了一个行业标准,使用存储厂商开发的插件可以在多个容器编排系统运行。 PV 持久卷PersistentVolume,Kubernetes集群中的一块存储卷,提供给Pod容器存储数据,通过卷插件(provisioner)来管理,拥有独立于Pod的生命周期。 PVC 持久卷声明PersistentVolumeClaim,用户对存储的资源请求声明。 StorageClass 存储类,集群中可以提供的存储类型。管理员可以创建不同的存储类来对应不同的存储资源,卷插件和策略。 Porvisioner 卷插件根据资料请求信息完成存储设备的卷资源操作。 dynamic provisioning 动态卷配置,基于StorageClass的自动化存储资源的生命周期管理,按用户需求自动动态创建和调整存储资源,用户无需过多关注存储的管理。 下面我们一起来看一下,如何使用动态卷配置。 动态卷配置流程 1,创建一个StorageClass,指定卷插件,回收策略,存储卷绑定模式。 2,用户创建一个PVC持久卷声明,指定卷使用的存储类,读写模式,资源大小,卷类型。 3,卷插件创建持久卷。 4,Kubernetes绑定持久卷和持久卷声明。 5,容器启动时,挂载到容器中使用。 使用示例 创建CSIDriver 创建一个CSI存储插件,当我们的插件注册时会使用相同的名称,Kubernetes的组件根据名称调用插件服务。 --- # Create the CSI Driver object apiVersion: storage.k8s.io/v1 kind: CSIDriver metadata: name: local.csi.sukai.io spec: # do not require volumeattachment attachRequired: false podInfoOnMount: true storageCapacity: true 创建StorageClass 指定provisioner为local.csi.sukai.io apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: openebs-lvmsc allowVolumeExpansion: true parameters: volgroup: "lvmvg" provisioner: local.csi.sukai.io 默认的回收策略为Delete删除策略,当与PV绑定的PVC被删除的时候,删除PV存储资源。另一种策略为Retain保留策略。持久卷绑定模式为Immediate即刻绑定,立即创建持久卷并将其绑定到持久卷声明。WaitForFirstConsumer为首次使用时绑定,第一次被容器组使用时,才创建持久卷,并将其绑定到持久卷声明。

继续阅读

KubeVirt通过Kube-OVN使用Underlay网络

之前文章介绍了如何通过Kube-OVN实现Kubernetes网络租户隔离,今天我们一起看一下KubeVirt通过Kube-OVN使用Underlay网络,使虚拟机接入物理网络。 实践操作 检查Kubernetes使用的Pod网络地址段和Service网络地址段。 sukai@ubuntuserver:/etc/kubernetes/manifests$ sudo grep cidr kube-controller-manager.yaml - --allocate-node-cidrs=true - --cluster-cidr=10.244.0.0/16 sukai@ubuntuserver:/etc/kubernetes/manifests$ sudo grep range kube-controller-manager.yaml - --service-cluster-ip-range=10.211.0.0/16 检查kube-ovn-controller配置项是否正确 kube-ovn在版本v1.11.0开始支持keep-vm-ip参数,虚拟机使用固定IP地址。 Containers: kube-ovn-controller: Container ID: containerd://0f8d53403c9821c7b535c64d2c98e1ca130a15e1b2b878270cd9388c36d0e48a Image: kubeovn/kube-ovn:v1.11.0 Image ID: docker.io/kubeovn/kube-ovn@sha256:fea623e68a2a81ef78102c6cfe95b96c16c054c57f4c8b9d168bd3ff620b6779 Port: <none> Host Port: <none> Args: /kube-ovn/start-controller.sh --default-cidr=10.244.0.0/16 --default-gateway=10.244.0.1 --default-gateway-check=true --default-logical-gateway=false --default-exclude-ips= --node-switch-cidr=100.64.0.0/16 --service-cluster-ip-range=10.211.0.0/16 --network-type=geneve --default-interface-name= --default-vlan-id=100 --pod-nic-type=veth-pair --enable-lb=true --enable-np=true --enable-eip-snat=true --enable-external-vpc=true --keep-vm-ip=true 创建服务网络 指定物理服务器上访问物理网络的网卡。 apiVersion: kubeovn.io/v1 kind: ProviderNetwork metadata: name: office spec: defaultInterface: eno1 创建VLAN 创建在指定服务网络上创建一个VLAN,这里VLAN ID为0表示不属于任何VLAN。 apiVersion: kubeovn.

继续阅读

kube-ovn实现Kubernetes多租户网络管理

Kubernetes容器平台正在成为越来越多的数据中心基础平台,我们希望Kubernetes能够满足虚拟化平台的一些基本要求,比如实现了多租户的灵活的软件定义网络SDN。工作中一个项目在使用Kubernetes平台,所以考虑通过KubeVirt来管理虚拟机,同时使用kube-ovn来实现多租户网络隔离。下面我们一起来看看如何使用kube-ovn来管理网络。 基本概念 Underlay/Overlay网络 Underlay网络是指传统IT基础设施网络,是由交换机、路由器、负载均衡等设备组成的底层物理网络。Overlay网络是通过网络虚拟化技术,在Underlay网络上构建出的虚拟的逻辑网络。 OVS/OVN Open vSwitch(OVS)是一个多层软件交换机,OVS只里一个单机软件,没有集群的信息。Open Virtual Nework(OVN)提供了一个集中式的OVS控制器,从集群的角度对整个网络设施进行编排。 使用Kubernetes后会发现,Kubernetes网络功能缺少软件定义网络SDN能力,缺少VPC, Subnet, Nat, Route, SecurityGroup等常用功能。Kube-OVN基于OVN为Kubernetes网络提供了网络编排能力。 CNI 容器网络接口(Container Network Interface),由CoreOS提出的一种容器网络规范,主要内容是容器创建时的网络分配,和容器被删除时释放网络资源。CNI让网络层变得可插拔,只要遵循CNI的协议规范,容器管理平台就可以调用CNI插件可执行文件提供网络功能。Kubernetes网络模型采用了CNI容器网络接口规范。 macvlan macvlan是一种Linux内核的网络虚拟化技术,从一个主机接口虚拟出多个虚拟网络接口。macvlan可以在物理网卡构成的父接口上添加子接口,每个子接口都拥有独立的MAC地址和IP地址。容器可以通过绑定子接口,拥有与物理网络通信的能力。这解决了容器接入物理网络需求,比如我们需要通过docker运行gitlab服务,gitlab服务需要用到80,443,22端口,这些常用端口经常会产生冲突,那么我们可以通过docker命令创建一个macvlan驱动类型的网络来拥有独立MAC和IP地址。Kubernetes内置CNI插件包含了macvlan,配置使用macvlan CNI,可以让Kubernetes的Pod使用Underlay网络 。 Kube-OVN Kube-OVN插件将Kubernetes容器网络接入ovs网络。提供了vpc, router, switch, subnet管理能力。 Multus Multus CNI插件提供了Kubernetes Pod添加多块网卡的能力。容器同时接入多个不同的网络,解决了类似Ceph这种区分多个网络应用场景。 IPAM IP地址管理(IP Address Management),分配和维护IP地址,DNS,网关,路由等信息。CNI插件在执行过程中调用相应的IPAM插件,IPAM插件将IP相关信息返回到主CNI插件。IPAM插件减少了CNI插件重复编写相同代码管理IP的工作,而且解决了多个CNI插件统一集中IP管理的需求。 场景需求 1,通过VPC实现网络租户隔离 2,通过NAT网关SNAT访问外网 3,通过NAT网关DNAT暴露端口给外网访问 安装部署 安装Kube-OVN curl -O https://raw.githubusercontent.com/kubeovn/kube-ovn/release-1.10/yamls/crd.yaml curl -O https://raw.githubusercontent.com/kubeovn/kube-ovn/release-1.10/yamls/ovn.yaml curl -O https://raw.githubusercontent.com/kubeovn/kube-ovn/release-1.10/yamls/kube-ovn.yaml curl -O https://raw.githubusercontent.com/kubeovn/kube-ovn/master/charts/templates/kubeovn-crd.yaml sed -i 's/\$addresses/<Node IP>/g' ovn.yaml kubectl label node ubuntuserver1 kube-ovn/role=master kubectl apply -f crd.yaml kubectl apply -f kubeovn-crd.

继续阅读

Kubernetes资源类型发现

在基于Kubernetes平台开发过程中,经常需要访问不同Kuberntes版本的集群资源,这时就需要去获取所访问集群支持的资源版本信息。下面我们一起来看一下,如何来实现Kubernetes资源类型发现? 文章分为下面几部分为大家介绍: 1,kubectl命令查看Kubernetes集群资源 2,client-go库获取Kubernetes集群资源 3,controller-runtime动态获取Kubernetes集群资源 kubectl命令 kubectl命令行工具提供api-resources,api-versions命令来查看kubernetes集群当前支持的资源类型。 kubectl api-resources查看k8s所有资源和版本列表。 sukai@sukai:~$ kubectl api-resources NAME SHORTNAMES APIVERSION NAMESPACED KIND bindings v1 true Binding componentstatuses cs v1 false ComponentStatus configmaps cm v1 true ConfigMap endpoints ep v1 true Endpoints events ev v1 true Event limitranges limits v1 true LimitRange namespaces ns v1 false Namespace nodes no v1 false Node persistentvolumeclaims pvc v1 true PersistentVolumeClaim persistentvolumes pv v1 false PersistentVolume pods po v1 true Pod .

继续阅读

通过Karmada实现应用多Kubernetes集群管理--调度器

前面文章介绍了Karmada的控制器流程,了解了Karmada如何实现Kubernetes资源下发到成员集群的。今天我们一起看一下Karmada的调度器,看看Karmada如何实现Kubernetes资源下发调度的。 前面控制器流程里讲过,用户创建了Kubernetes资源对象模板,下发策略和差异策略后,由resourceDetector根据下发策略,创建ResourceBinding绑定资源与策略,再由BindingController根据ResourceBinding,查找并应用OverridePolicy,最终生成创建成员集群资源的Work,由ExecutionController在成员集群中执行Work完成Kubernetes资源操作。 在流程上,Karmada调度器工作在ResourceBinding创建生成后,BindingController控制器工作之前。在功能上,Karmada调度器主要负责Kubernetes资源对象在成员集群的分布,Karmada调度器通过算法得出在哪些成员集群上运行多少个副本数量的结果,将调度结果保存到ResourceBinding的Clusters参数中。 业务流程 1,监听事件加入队列:Informer监听资源绑定ResourceBinding, 下发策略PropagationPolicy事件,将对应的ResourceBinding资源加入工作队列。 2,取出队列中ResourceBinding对象:每秒中开启一个worker,从队列中取出ResourceBinding对象进行处理。循环处理工作队列,直到队列处理结束。 3,获取分布规则:根据ResourceBinding的Annotation中下发策略PropagationPolicy名称,获取下发策略的分布规则。分布规则包括:集群亲和,集群容忍,拓扑分布约束规则以及副本调度策略等信息。 4,判断是否进行ResourceBinding调度:比对新旧分布规则,判断是否需要进行ResourceBinding调度。 5,调度ResourceBinding,计算出成员集群分配副本数量: a,FilterPlugin过滤插件判断集群亲和和容忍是否匹配条件,得到匹配集群。 b,ScorePlugin计算匹配集群的得分,得到集群的优先级。 c,根据SpreadConstraint拓扑分布约束规则,得到最后的下发成员集群。 d,发配副本,副本调度策略类型分两种:Duplicated复制, Divided切分。如果是复制类型,每个成员集群部署与模板相同的资源副本数量。如果是切分类型,可以配置PreferenceWeighted权重优先和PreferenceAggregated聚合优先,前者会根据权重比例来进行切分,后者根据总的副本数量来判断是scaleUP还是scaleDown,再根据成员集群的最大可用副本数来分配副本数量。 6,更新ResourceBinding中的Clusters字段,设置为计算出的成员集群分配副本数量结果。 7,完成了一个ResourceBinding的处理,继续处理下一条。 代码实现 过滤和计分插件 构造调度算法实例,算法插件包括:集群亲和,污点容忍,已安装支持的资源API,已下发集群。 algorithm := core.NewGenericScheduler(schedulerCache, []string{clusteraffinity.Name, tainttoleration.Name, apiinstalled.Name, clusterlocality.Name}) 集群亲和:过滤插件,1,集群名称是否在亲和策略的排除集群列表中。2,集群的标签、字段过滤是否与亲和策略中的标签和字段过滤匹配。返回是否成功结果。 // Filter checks if the cluster matched the placement cluster affinity constraint. func (p *ClusterAffinity) Filter(ctx context.Context, placement *policyv1alpha1.Placement, resource *workv1alpha2.ObjectReference, cluster *clusterv1alpha1.Cluster) *framework.Result { affinity := placement.ClusterAffinity if affinity != nil { if util.ClusterMatches(cluster, *affinity) { return framework.NewResult(framework.Success) } return framework.NewResult(framework.Unschedulable, "cluster is not matched the placement cluster affinity constraint") } // If no clusters specified and it is not excluded, mark it matched return framework.

继续阅读

通过Karmada实现应用多Kubernetes集群管理--控制器

Karmada是华为云开源的,提供应用的跨云多集群统一管理和部署。今天一起来看一下Karmada的控制器,怎么来完成集群纳管和Kubernetes应用工作负载在成员集群创建的。 基本概念 Cluster 在Karmada集群管理中,将Kubernetes集群分为两种:控制面集群,成员集群。控制面集群是Karmada管理组件所在的集群。成员集群为纳管的业务集群。Cluster自定义资源指的是成员集群,指定成员集群的API地址,访问密钥,伪装身份,同步模式。同步模式分为Push和Pull,控制面集群能够主动建立与成员集群的连接,创建资源的为Push模式,控制面集群不能与成员集群主动建立连接的,成员集群建立与控制面集群的连接,监听控制面集群的资源事件,创建资源的为Pull模式。 PropagationPolicy Namespaced下发策略,Kubernetes资源对象下发到成员集群的策略,指定资源对象,成员集群。ClusterPropagationPolicy,非Namespaced下发策略。PropagationPolicy只能下发自己所在命名空间的资源,ClusterPropagationPolicy能够下发集群范围的除了系统保留命名空间外的任意命名空间的资源。 OverridePolicy Namespaced差异策略,Kubernetes资源对象下发到某些集群时,使用指定的参数值。ClusterOverridePolicy,非Namespaced差异策略。 ResourceBinding 根据下发策略生成ResourceBinding,指定具体版本的Kubernetes资源对象与下发策略PropagationPolicy绑定。ClusterResourceBinding绑定Kubernetes资源与ClusterPropagationPolicy。 Work 下发到成员集群的资源列表,可以为Deployment, Configmap, Service, Role, CRD等Kubernetes资源。控制面集群通过Work来实现对成员集群的资源控制。Push模式下,控制面集群监听Work资源事件,执行对成员集群的资源对象操作。Pull模式下,成员集群Agent监听Work资源事件,并在成员集群里执行资源对象的操作。 Karmada用户操作 1,添加成员集群,创建Cluster自定义资源的实例对象 2,创建Kubernetes的资源,这里就是Kubernetes原生的Deployment, Statefulset, Daemonset, Job, Configmap, Secret, Service等。 3,创建下发策略PropagationPolicy,指定资源对象部署到哪些集群中。 4,创建差异策略OverridePolicy,指定资源对象在哪些集群中覆盖哪些参数值。 Karmada用户操作完成后,由Karmada控制器进行资源调谐,最终完成在指定的成员集群中创建Kubernetes资源对象。 Karmada控制器 ClusterController 负责调谐Cluster自定义资源,创建集群对应的execution命名空间。Cluster为纳入管理的业务成员集群。 ClusterStatusController 负责调谐Cluster子资源Status,检测并更新成员集群的健康状态、资源使用信息、集群版本信息、集群主机资源信息以及支持的APIResource。 HpaController Pod水平自动扩展控制器,负责调谐HorizontalPodAutoscaler自定义资源。在成员集群创建对应的HorizontalPodAutoscaler。 BindingController 包括两个控制器,ResourceBindingController监听Work, OveridePolicy, ClusterOverridePolicy资源的事件,调谐ResourceBinding负责创建对应的Work,指定要创建的Kubernetes工作负载Workload。ClusterResourceBindingController主要调谐ClusterResourceBinding。 ExecutionController 负责调谐Work自定义资源,在指定集群创建用户定义的Kubernetes工作负载Workload。 WorkStatusController 负责调谐Work的子资源Status,将引用的资源信息保存到Status中。 NamespaceController 监听Cluster自定义资源事件,创建Work,指定创建namespace。 ServiceExportController 监听Work事件,启动对应集群的Informer,监听serviceexports,endpointslices事件,将事件处理后放入worker队列。 EndpointSliceController 监听Work事件,根据Work定义,创建对应的EndpointSlice。 ServiceImportController 调谐ServiceImport资源,创建Kubernetes Service资源对象。 UnifiedAuthController 监听Cluster, ClusterRole, ClusterRoleBinding资源事件,生成Work指定创建ClusterRole, ClusterRoleBinding资源对象。 FederatedResourceQuotaSyncController 调谐FederatedResourceQuota,监听Cluster事件,创建Work指定创建ResourceQuota资源。 FederatedResourceQuotaStatusController 调谐FederatedResourceQuota子资源Status,更新Status信息。 Karmada控制器执行流程 1,创建一个成员集群Cluster资源实例 2,ClusterController创建成员集群对应的执行命名空间executionNamespace。 3,UnifiedAuthController生成创建成员集群ClusterRole, ClusterRoleBinding的Work。 4,ExecutionController根据Work中的集群和资源对象,在成员集群中执行对应操作,比如创建ClusterRole, ClusterRoleBinding等。 5,ClusterStatusController更新成员集群的健康状态,集群及主机信息。 6,成员集群加入成功后,用户创建Kubernetes资源对象模板,下发策略PropagationPolicy,差异配置策略OverridePolicy。

继续阅读

Kubernetes应用系统API用户认证与鉴权 -- 鉴权篇

上篇文章讲了通过LDAP和Dex实现两种不同的API用户认证的方式,用户认证是识别API请求的来源,让系统知道请求的访问者是谁。应用系统可以根据请求的身份,来判断该用户可以访问哪些API接口获得数据,这就是用户鉴权。下面我们一起来看一下,在Kubernetes平台上,如何通过RBAC来实现资源访问限制,同样我们还是通过Kubesphere的代码来学习。 鉴权实现的过程: 1,构建一个HandlerChain,HandlerChain中包含了:WithAuthentication, WithRequestInfo和WithAuthorization用户认证和鉴权的三个Filter以及WithAuditing Filter用于审计日志。Filter可以理解为web 框架的Middleware。 2,filters.WithAuthentication上篇文章介绍过,完成用户身份识别和分发Token,将用户信息写入Context。 3,filters.WithRequestInfo处理API请求信息,将请求信息保存到context中。请求信息包括:Path, Verb, APIPrefix, APIGroup, APIVersion, Namespace, Resource, Name这些RBAC鉴权需要用到的资源信息,以及客户端信息等。 4,filters.WithAuthorization根据RequestInfo和RBAC规则,判断请求的合法性,终止或者允许请求继续下去。 代码实现: 1,HandlerChain处理请求 这里可以看到有两个鉴权,一个是pathAuthorizer,一个是RBACAuthorizer,pathAuthorizer定义了哪些URL Path不需要鉴权,RBACAuthorizer顾名思义就是通过RBAC鉴权,后面我们详细介绍这两个鉴权。 var authorizers authorizer.Authorizer switch s.Config.AuthorizationOptions.Mode { case authorization.AlwaysAllow: authorizers = authorizerfactory.NewAlwaysAllowAuthorizer() case authorization.AlwaysDeny: authorizers = authorizerfactory.NewAlwaysDenyAuthorizer() default: fallthrough case authorization.RBAC: excludedPaths := []string{"/oauth/*", "/kapis/config.kubesphere.io/*", "/kapis/version", "/kapis/metrics"} pathAuthorizer, _ := path.NewAuthorizer(excludedPaths) amOperator := am.NewReadOnlyOperator(s.InformerFactory, s.DevopsClient) authorizers = unionauthorizer.New(pathAuthorizer, rbac.NewRBACAuthorizer(amOperator)) } handler = filters.WithAuthorization(handler, authorizers) handler = filters.WithAuthentication(handler, authn) handler = filters.WithRequestInfo(handler, requestInfoResolver) s.

继续阅读

Kubernetes应用系统API用户认证与鉴权 -- 认证篇

前面文章介绍了Kubernetes应用系统用户管理,实现了外部用户存储(LDAP)与Kubernetes用户映射,下面以Kubesphere为参考,一起看一下如何实现Kubernetes应用系统用户的认证。 应用平台用户认证主要实现两个功能: 1,用户身份鉴别 用户身份认证可以通过LDAP进行用户名和密码认证,也可以通过第三方认证服务进行OAuth认证。 2,Token管理 Client端认证通过后,带上获取Token请求API。应用系统根据Token提取用户ID,进行请求权限鉴别。同时应用系统负责Token的生命周期管理。 基本概念: OpenID Connect(OIDC)是基于OAuth 2.0身份认证协议,增加了OAuth 2.0中末定义的规范,例如scope, Claim用户信息字段。 代码实现 基本认证方式 API路由 // legacy auth API legacy := &restful.WebService{} legacy.Path("/aiapis/iam.aiscope/v1alpha2/login"). Consumes(restful.MIME_JSON). Produces(restful.MIME_JSON) legacy.Route(legacy.POST(""). To(handler.login). Deprecate(). Doc("Aiscope APIs support token-based authentication via the Authtoken request header. The POST Login API is used to retrieve the authentication token. After the authentication token is obtained, it must be inserted into the Authtoken header for all requests."). Reads(LoginRequest{}). Returns(http.StatusOK, api.StatusOK, oauth.Token{}). Metadata(restfulspec.

继续阅读