移动通网站建设,品牌推广方案包括哪些,wordpress百度地图插件下载,跨境电商运营平台API Server
API Server是什么
提供集群管理的REST API接口#xff0c;包括认证授权、数据校验以及集群状态变更等提供其他模块之间的数据交互和通信的枢纽#xff08;其他模块通过API Server查询或修改数据#xff0c;只有API Server才直接操作etcd#xff09;
访问控制…API Server
API Server是什么
提供集群管理的REST API接口包括认证授权、数据校验以及集群状态变更等提供其他模块之间的数据交互和通信的枢纽其他模块通过API Server查询或修改数据只有API Server才直接操作etcd
访问控制概览 访问控制细节 认证
如果认证成功则用户的username会 传入授权模块做进一步授权验证而对于认证失败的请求则返回HTTP 401
认证插件 X509证书 使用X509客户端证书只需要API Server启动时配置–client-ca-fileSOMEFILE。在证书认证时其CN域用作用名而组织机构域则用作group名。 静态Token文件 使用静态Token文件认证只需要API Server启动时配置–token-auth-fileSOMEFILE。该文件为csv格式每行至少包括三列token,username,user id token,user,uid,group1,group2,group 引导Token 为了支持平滑地启动引导新的集群Kubernetes 包含了一种动态管理的持有者令牌类型 称作 启动引导令牌BootstrapToken这些令牌以 Secret 的形式保存在 kube-system 名字空间中可以被动态管理和创建控制器管理器包含的 TokenCleaner 控制器能够在启动引导令牌过期时将其删除在使用kubeadm部署Kubernetes时可通过kubeadm token list命令查询 静态密码文件 需要API Server启动时配置–basic-auth-fileSOMEFILE文件格式为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 分钟 匿名请求 如果使用AlwaysAllow以外的认证模式则匿名请求默认开启但可用–anonymous-authfalse禁止匿名请求
基于webhook的认证服务集成
构建符合Kubernetes规范的认证服务需要依照Kubernetes规范构建认证服务用来认证tokenreview request
{ apiVersion: authentication.k8s.io/v1beta1, kind: TokenReview,
spec: { token: (BEARERTOKEN) } }解码过程
{
apiVersion: authentication.k8s.io/v1beta1,
kind: TokenReview,
status: {
authenticated: true,
user: {
username: janedoeexample.com,
uid: 42,
groups: [
developers,qa
]}}
}配置apiserver 可以是任何认证系统 • 但在用户认证完成后生成代表用户身份的token • 该token通常是有失效时间的 • 用户获取该token以后以后将token配置进kubeconfig 修改apiserver设置开启认证服务apiserver保证将所有收到的请求中的token信息发给认证服务进行验证 token信息发给认证服务进行验证 • --authentication-token-webhook-config-file该文件描述如何访问认证服务 • --authentication-token-webhook-cache-ttl默认2分钟 配置文件需要mount进Pod 配置文件中的服务器地址需要指向authService
生产系统中遇到的陷阱
基于Keystone的认证插件导致Keystone故障且无法恢复
Keystone是企业关键服务
Kubernetes以Keystone作为认证插件
Keystone在出现故障后会抛出401错误
Kubernetes发现401错误后会尝试重新认证
大多数controller都有指数级back off重试间隔越来越慢
但gophercloud针对过期token会一直retry
大量的request积压在Keystone导致服务无法恢复
Kubernetes成为压死企业认证服务的最后一根稻草解决方案 • Circuit break • Rate limit
鉴权
授权主要是用于对集群资源的访问控制Kubernetes也支持多种授权机制并支持同时开启多个授权插件对于授权失败的请求则返回HTTP 403Kubernetes授权仅处理以下的请求属性 • user, group, extra • API、请求方法如get、post、update、patch和delete和请求路径如/api • 请求资源和子资源 • Namespace • API GroupKubernetes支持以下授权插件 • ABAC • RBAC • Webhook • Node
RBAC
RBAC 的授权策略可以利用 kubectl 或者 Kubernetes API 直接进行配置。RBAC 可以授权给用户 让用户有权进行授权管理这样就可以无需接触节点直接进行授权管理。RBAC 在 Kubernetes 中被映射为 API 资源和操作
Role与ClusterRole
# Role示例
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:namespace: defaultname: pod-reader
rules:
- apiGroups: [] # indicates the core API groupresources: [pods]verbs: [get, watch, list]cluster role
# ClusterRole示例
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:# namespace omitted since ClusterRoles
are not namespacedname: secret-reader
rules:
- apiGroups: []resources: [secrets]verbs: [get, watch, list]binding
# RoleBinding示例引用ClusterRole
# This role binding allows dave to read secrets in the development
namespace.
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:name: read-secretsnamespace: development # This only grants permissions within the
development namespace.
subjects:
- kind: Username: daveapiGroup: rbac.authorization.k8s.io
roleRef:kind: ClusterRolename: secret-readerapiGroup: rbac.authorization.k8s.io账户组的管理
角色绑定Role Binding是将角色中定义的权限赋予一个或者一组用户它包含若干 主体用户、组或服务账户的列表和对这些主体所获得的角色的引用组的概念 • 当与外部认证系统对接时用户信息UserInfo可包含Group信息授权可针对用户群组 • 当对ServiceAccount授权时Group代表某个Namespace下的所有ServiceAccount
针对群租授权
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager # name 是区分大小写的
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.ioapiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
subjects:
- kind: Group
name: system:serviceaccounts:qa
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io规划系统角色
Use 管理员 所有资源的所有权限 普通用户 SystemAccount是开发者kubernetes developer或者domain developer创建应用后应 用于apiserver通讯需要的身份用户可以创建自定的ServiceAccountkubernetes也为每个namespace创建default ServiceAccountDefault ServiceAccount通常需要给定权限以后才能对apiserver做写操作
实现方案
在cluster创建时创建自定义的role比如namespace-creatorNamespace-creator role定义用户可操作的对象和对应的读写操作创建自定义的namespace admission controller 当namespace创建请求被处理时获取当前用户信息并annotate到namespace 创建RBAC controller • Watch namespace的创建事件 • 获取当前namespace的创建者信息 • 在当前namespace创建rolebinding对象并将namespace-creator 角色和用户绑定
与权限相关的其他最佳实践
ClusterRole是非namespace绑定的针对整个集群生效通常需要创建一个管理员角色并且绑定给开发运营团队成员ThirdPartyResource和CustomResourceDefinition是全局资源普通用户创建ThirdPartyResource以后需要管理员授予相应权限后才能真正操作该对象针对所有的角色管理建议创建spec用源代码驱动 虽然可以通过edit操作来修改权限但后期会导致权限管理混乱可能会有很多临时创建出来的角色和角色绑定对象重复绑定某一个资源权限 权限是可以传递的用户A可以将其对某对象的某操作抽取成一个权限并赋给用户B防止海量的角色和角色绑定对象因为大量的对象会导致鉴权效率低同时给apiserver增加负担ServiceAccount也需要授权的否则你的component可能无法操作某对象TipsSSH到master节点通过insecure port访问apiserver可绕过鉴权当需要做管理操作又没 有权限时可以使用
准入
准入控制 为资源增加自定义属性 作为多租户集群方案中的一环我们需要在namespace的准入控制中获取用户信息并将用 户信息更新的namespace的annotation只有当namespace中有有效用户信息时我们才可以在namespace创建时自动绑定用户权限namespace才可用 准入控制Admission Control在授权后对请求做进一步的验证或添加默认参数。不同于授权和认证只关心请求的用户和操作准入控制还处理请求的内容并且仅对创建、更新、删除或连接如代理等有效而对读操作无效 准入控制支持同时开启多个插件它们依次调用只有全部插件都通过的请求才可以放过进入系统 准入控制插件 AlwaysAdmit: 接受所有请求。AlwaysPullImages: 总是拉取最新镜像。在多租户场景下非常有用。DenyEscalatingExec: 禁止特权容器的exec和attach操作。ImagePolicyWebhook: 通过webhook决定image策略需要同时配置–admission-control-config-fileServiceAccount自动创建默认ServiceAccount并确保Pod引用的ServiceAccount已经存在SecurityContextDeny拒绝包含非法SecurityContext配置的容器ResourceQuota限制Pod的请求不会超过配额需要在namespace中创建一个ResourceQuota对象LimitRanger为Pod设置默认资源请求和限制需要在namespace中创建一个LimitRange对象InitialResources根据镜像的历史使用记录为容器设置默认资源请求和限制NamespaceLifecycle确保处于termination状态的namespace不再接收新的对象创建请求并拒绝请求不存在的namespaceDefaultStorageClass为PVC设置默认StorageClassDefaultTolerationSeconds设置Pod的默认forgiveness toleration为5分钟PodSecurityPolicy使用Pod Security Policies时必须开启NodeRestriction限制kubelet仅可访问node、endpoint、pod、service以及secret、configmap、PV和PVC等相关的资源
准入控制插件的开发
ResourceQuota限制Pod的请求不会超过配额需要在namespace中创建一个ResourceQuota对象LimitRanger为Pod设置默认资源请求和限制需要在namespace中创建一个Lim itRange对象InitialResources根据镜像的历史使用记录为容器设置默认资源请求和限制NamespaceLifecycle确保处于termination状态的namespace不再接收新的对象创建请求并拒绝请求不存在的namespaceDefaultStorageClass为PVC设置默认StorageClassDefaultTolerationSeconds设置Pod的默认forgiveness toleration为5分钟PodSecurityPolicy使用Pod Security Policies时必须开启NodeRestriction限制kubelet仅可访问node、endpoint、pod、service以及secret、configmap、PV和PVC等相关的资源除默认的准入控制插件以外Kubernetes预留了准入控制插件的扩展点用户可自定义准入控制插件实现自定义准入功能MutatingWebhookConfiguration变形插件支持对准入对象的修改ValidatingWebhookConfiguration校验插件只能对准入对象合法性进行校验不能修改
准入控制
为资源增加自定义属性 • 作为多租户集群方案中的一环我们需要在namespace的准入控制中获取用户信息并将 用户信息更新的namespace的annotation只有当namespace中有有效用户信息时我们才可以在namespace创建时自动绑定用户权限namespace才可用
# {{if eq .k8snode_validating enabled}}
apiVersion:
admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: ns-mutating.webhook.k8s.io
webhooks:
- clientConfig:
caBundle: {{.serverca_base64}}
url:
https://admission.local.tess.io/apis/admissio
n.k8s.io/v1alpha1/ ns-mutating
failurePolicy: Fail
name: ns-mutating.webhook.k8s.io
namespaceSelector: {}
rules:
- apiGroups:
-
apiVersions:
- *
operations:
- CREATE
resources:
- nodes
sideEffects: Unknown
# {{end}}配额管理 原因资源有限如何限定某个用户有多少资源 方案 预定义每个Namespace的ResourceQuota并把spec保存为configmap Ø 用户可以创建多少个Pod Ø BestEffortPod Ø QoSPod Ø 用户可以创建多少个service Ø 用户可以创建多少个ingress Ø 用户可以创建多少个service VIP创建ResourceQuota Controller 监控namespace创建事件当namespace创建时在该namespace创建对应的ResourceQuota 对象 apiserver中开启ResourceQuota的admission plugin
限流
APIServer中的限流 max-requests-inflight 在给定时间内的最大 non-mutating 请求数max-mutating-requests-inflight: 在给定时间内的最大 mutating 请求数调整 apiserver 的流控 qosstaging/src/k8s.io/apiserver/pkg/server/filters/maxinflight.go:WithMaxInFlightLimit()
API Priority and Fairness
• APF 以更细粒度的方式对请求进行分类和隔离。
• 它还引入了空间有限的排队机制因此在非常短暂的突发情况下API 服务器不会拒绝任何请求。
• 通过使用公平排队技术从队列中分发请求这样 一个行为不佳的控制器就不会饿死其他控制器即使优先级相同。 • APF的核心 多等级,多队列 • APF 的实现依赖两个非常重要的资源 FlowSchema, PriorityLevelConfiguration • APF 对请求进行更细粒度的分类每一个请求分类对应一个 FlowSchema (FS) • FS 内的请求又会根据 distinguisher 进一步划分为不同的 Flow. • FS 会设置一个优先级 (Priority Level, PL)不同优先级的并发资源是隔离的。所以不同优先级的资源不会相互排挤。特定 优先级的请求可以被高优处理。 • 一个 PL 可以对应多个 FSPL 中维护了一个 QueueSet用于缓存不能及时处理的请求请求不会因为超出 PL 的并发限 制而被丢弃。 • FS 中的每个 Flow 通过 shuffle sharding 算法从 QueueSet 选取特定的 queues 缓存请求。 • 每次从 QueueSet 中取请求执行时会先应用 fair queuing 算法从 QueueSet 中选中一个 queue然后从这个 queue 中取出 oldest 请求执行。所以即使是同一个 PL 内的请求也不会出现一个 Flow 内的请求一直占用资源的不公平现象
概念
• 传入的请求通过FlowSchema 按照其属性分类并分配优先级。 • 每个优先级维护自定义的并发限制加强了隔离度这样不同优先级的请求就不会相互饿死。 • 在同一个优先级内公平排队算法可以防止来自不同flow 的请求相互饿死。 • 该算法将请求排队通过排队机制防止在平均负载较低时通信量突增而导致请求失败
优先级
• 如果未启用 APFAPI 服务器中的整体并发量将受到 kube-apiserver 的参数 --max-requests-inflight 和 --max-mutating-requests-inflight 的限制。 • 启用 APF 后将对这些参数定义的并发限制进行求和然后将总和分配到一组可配置的优先级 中。 每个传入的请求都会分配一个优先级 • 每个优先级都有各自的配置设定允许分发的并发请求数。 • 例如默认配置包括针对领导者选举请求、内置控制器请求和 Pod 请求都单独设置优先级。这表示即使异常的 Pod 向 API 服务器发送大量请求也无法阻止领导者选举或内置控制器的操作执行成功
排队
• 即使在同一优先级内也可能存在大量不同的流量源。 • 在过载情况下防止一个请求流饿死其他流是非常有价值的 尤其是在一个较为常见的场景中一个有故障的客户端会疯狂地向 kube-apiserver 发送请求 理想情况下这个有故障的客户端不应对其他客户端产生太大的影响。 • 公平排队算法在处理具有相同优先级的请求时实现了上述场景。 • 每个请求都被分配到某个 流 中该流由对应的 FlowSchema 的名字加上一个 流区分项FlowDistinguisher 来标识。 • 这里的流区分项可以是发出请求的用户、目标资源的名称空间或什么都不是。 • 系统尝试为不同流中具有相同优先级的请求赋予近似相等的权重。 • 将请求划分到流中之后APF 功能将请求分配到队列中。 • 分配时使用一种称为 混洗分片Shuffle-Sharding 的技术。 该技术可以相对有效地利用队列隔离低强度流与高强流。 • 排队算法的细节可针对每个优先等级进行调整并允许管理员在内存占用、 公平性当总流量超标时各个独立的流将都会取得进展、 突发流量的容忍度以及排队引发的额外延迟之间进行权衡
豁免请求
某些特别重要的请求不受制于此特性施加的任何限制。这些豁免可防止不当的流控配置完全禁用API 服务器
默认配置 system 用于 system:nodes 组即 kubelets的请求 kubelets 必须能连上 API 服务器以便工作负载能够调度到其上。 leader-election 用于内置控制器的领导选举的请求 特别是来自 kube-system 名称空间中 system:kube-controller-manager 和system:kube-scheduler 用户和服务账号针对 endpoints、configmaps 或 leases 的请求。将这些请求与其他流量相隔离非常重要因为领导者选举失败会导致控制器发生故障并重新启动这反过来会导致新启动的控制器在同步信息时流量开销更大。 workload-high • 优先级用于内置控制器的请求。 workload-low • 优先级适用于来自任何服务帐户的请求通常包括来自 Pods 中运行的控制器的所有请求。 global-default • 优先级可处理所有其他流量例如非特权用户运行的交互式 kubectl 命令。 exempt 优先级的请求完全不受流控限制它们总是立刻被分发。 特殊的 exempt FlowSchema把 system:masters 组的所有请求都归入该优先级组 catch-all 优先级与特殊的 catch-all FlowSchema 结合使用以确保每个请求都分类一般不应该依赖于 catch-all 的配置而应适当地创建自己的 catch-all FlowSchema 和PriorityLevelConfigurations或使用默认安装的 global-default 配置为了帮助捕获部分请求未分类的配置错误强制要求 catch-all 优先级仅允许5个并发份额并且不对请求进行排队使得仅与 catch-all FlowSchema 匹配的流量被拒绝的可能性更高并显示 HTTP 429 错误
PriorityLevelConfiguration
一个 PriorityLevelConfiguration 表示单个隔离类型每个 PriorityLevelConfigurations 对未完成的请求数有各自的限制对排队中的请求数也有限制
apiVersion:
flowcontrol.apiserver.k8s.io/v1beta1
kind: PriorityLevelConfiguration
metadata:name: global-default
spec:limited:assuredConcurrencyShares: 20limitResponse:queuing:handSize: 6queueLengthLimit: 50queues: 128type: Queue
type: LimitedFlowSchema
FlowSchema 匹配一些入站请求并将它们分配给优先级每个入站请求都会对所有 FlowSchema 测试是否匹配 首先从 matchingPrecedence 数值最低的匹配开始我们认为这是逻辑上匹配度最高 然后依次进行直到首个匹配出现
apiVersion: flowcontrol.apiserver.k8s.io/v1beta1
kind: FlowSchema
metadata:name: kube-scheduler
spec:distinguisherMethod:type: ByNamespacematchingPrecedence: 800priorityLevelConfiguration:name: workload-highrules:- resourceRules:- resources:- *verbs:- *subjects:- kind: Useruser:name: system:kube-scheduler调试
• /debug/api_priority_and_fairness/dump_priority_levels —— 所有优先级及其当前状态 的列表 kubectl get --raw /debug/api_priority_and_fairness/dump_priority_levels • /debug/api_priority_and_fairness/dump_queues —— 所有队列及其当前状态的列表 kubectl get --raw /debug/api_priority_and_fairness/dump_queues • /debug/api_priority_and_fairness/dump_requests ——当前正在队列中等待的所有请求 的列表
kubectl get --raw /debug/api_priority_and_fairness/dump_requests
高可用APIServer
启动apiserver示例
kube-apiserver \--feature-gatesAllAlphatrue \--runtime-configapi/alltrue \--requestheader-allowed-namesfront-proxy-client \--client-ca-file/etc/kubernetes/pki/ca.crt \--allow-privilegedtrue \--experimental-bootstrap-token-authtrue \--storage-backendetcd3 \--requestheader-username-headersX-Remote-User \--requestheader-extra-headers-prefixX-Remote-Extra- \--service-account-key-file/etc/kubernetes/pki/sa.pub \--tls-cert-file/etc/kubernetes/pki/apiserver.crt \--tls-private-key-file/etc/kubernetes/pki/apiserver.key \--kubelet-client-certificate/etc/kubernetes/pki/apiserver-kubelet-client.crt \--requestheader-client-ca-file/etc/kubernetes/pki/front-proxy-ca.crt \--enabled-hooksNamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota \--requestheader-group-headersX-Remote-Group \--kubelet-client-key/etc/kubernetes/pki/apiserver-kubelet-client.key \--secure-port6443 \--kubelet-preferred-address-typesInternalIP,ExternalIP,Hostname \--service-cluster-ip-range10.96.0.0/12 \--advertise-address192.168.0.20 \--etcd-servershttp://127.0.0.1:2379构建高可用的多副本apiserver
apiserver是无状态的Rest Server无状态所以方便Scale Updown负载均衡 在多个apiserver实例之上配置负载均衡证书可能需要加上Loadbalancer VIP重新生成
预留充足的CPU、内存资源
- 随着集群中节点数量不断增多APIServer对CPU和内存的开销也不断增大。过少的CPU资源会降低其处理效率过少的内存资源会导致Pod被OOMKilled直接导致服务不可用。在规划APIServer资源时不能仅看当下需求也要为未来预留充分 善用速率限制RateLimit
APIServer的参数“–max-requests-inflight”和“–max-mutating-requests-inflight”支持 在给定时间内限制并行处理读请求包括Get、List和Watch操作和写请求包括Create、 Delete、Update和Patch操作的最大数量。当APIServer接收到的请求超过这两个参数设定的 值时再接收到的请求将会被直接拒绝。通过速率限制机制可以有效地控制APIServer内存的使 用。如果该值配置过低会经常出现请求超过限制的错误如果配置过高则APIServer可能会因 为占用过多内存而被强制终止因此需要根据实际的运行环境结合实时用户请求数量和 APIServer的资源配置进行调优客户端在接收到拒绝请求的返回值后应等待一段时间再发起重试无间隔的重试会加重 APIServer的压力导致性能进一步降低。针对并行处理请求数的过滤颗粒度太大在请求数量比 较多的场景重要的消息可能会被拒绝掉自1.18版本开始社区引入了优先级和公平保证 Priority and Fairness功能以提供更细粒度地客户端请求控制。该功能支持将不同用户或 不同类型的请求进行优先级归类保证高优先级的请求总是能够更快得到处理从而不受低优先 级请求的影响
设置合适的缓存大小
APIServer与etcd之间基于gRPC协议进行通信gRPC协议保证了二者在大规模集群中的数据高速 传输。gRPC基于连接复用的HTTP/2协议即针对相同分组的对象APIServer和etcd之间共享相 同的TCP连接不同请求由不同的stream传输一个HTTP/2连接有其stream配额 配额的大小限制了能支持的并发请求。APIServer提供了集 群对象的缓存机制当客户端发起查询请求时APIServer默认会将其缓存直接返回给客户端。缓 存区大小可以通过参数“–watch-cache-sizes”设置。针对访问请求比较多的对象适当设置 缓存的大小极大降低对etcd的访问频率节省了网络调用降低了对etcd集群的读写压力从 而提高对象访问的性能但是APIServer也是允许客户端忽略缓存的例如客户端请求中ListOption中没有设置 resourceVersion这时APIServer直接从etcd拉取最新数据返回给客户端。客户端应尽量避免此 操作应在ListOption中设置resourceVersion为0APIServer则将从缓存里面读取数据而不 会直接访问etcd
客户端尽量使用长连接
当查询请求的返回数据较大且此类请求并发量较大时容易引发TCP链路的阻塞导致其他查询 操作超时。因此基于Kubernetes开发组件时例如某些DaemonSet和Controller如果要查询 某类对象应尽量通过长连接ListWatch监听对象变更避免全量从APIServer获取资源。如果在 同一应用程序中如果有多个Informer监听APIServer资源变化可以将这些Informer合并减 少和APIServer的长连接数从而降低对APIServer的压力
如何访问APIServe
对外部客户user/client/admin)永远只通过LoadBalancer访问 只有当负载均衡出现故障时管理员才切换到apiserver IP进行管理 内部客户端优先访问cluster IP
搭建多租户的Kubernetes集群
授信 认证 禁止匿名访问只允许可信用户做操作 授权 基于授信的操作防止多用户之间互相影响比如普通用户删除Kubernetes核心服务或者A用户删除或修改B户的应用 隔离 可见行隔离:用户只关心自己的应用无需看到其他用户的服务和部署资源隔离:有些关键项目对资源需求较高需要专有设备不与其他人共享应用访问隔离:用户创建的服务按既定规则允许其他用户访问 资源管理 Quota管理:谁能用多少资源
认证
企业现有认证系统集成选择认证插件 选择webhook作为认证插件选择Keystone作为认证插件以Microsoft Ad作为backend搭建keystone服务一旦认证完成Kubernetes即可获取当前用户信息主要是用户名并针对该用户做授权。授权和准入控制完成后该用户的请求完成。
注册APIService
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:labels:kube-aggregator.kubernetes.io/automanaged: onstartname: v1.
spec:groupPriorityMinimum: 18000version: v1versionPriority: 1
status:conditions:- lastTransitionTime: 2020-08-16T05:35:33Zmessage: Local APIServices are always availablereason: Localstatus: Truetype: AvailableRBAC:参考上文图解
规划系统角色
User 管理员普通用户 SystemAccount SystemAccount是开发者kubernetes developer或者domain developer创建应用后应用于apiserver通讯需要的身份用户可以创建自定的ServiceAccountkubernetes也为每个namespace创建defaultServiceAccountDefault ServiceAccount通常需要给定权限以后才能对apiserver做写操作
实现方案
在cluster创建时kube-up.sh创建自定义的role比如namespace-creator namespace-creator role定义用户可操作的对象和对应的读写操作namespace-creator role定义用户可操作的对象和对应的读写操作创建自定义的namespace admission controller • 当namespace创建请求被处理时获取当前用户信息并annotate注释到namespace创建RBAC controller • Watch namespace的创建事件 • 获取当前namespace的创建者信息 • 在当前namespace创建rolebinding对象并将namespace-creator 角色和用户绑定
apimachinery
回顾GKV
GroupKindVersion Internel version 和External version版本转换
如何定义Group
pkg/apis/core/register.go
定义group
GroupName
定义groupversion
var SchemeGroupVersion schema.GroupVersion{Group: GroupName, Version:
runtime.APIVersionInternal}
定义SchemeBuilder
var (
SchemeBuilder runtime.NewSchemeBuilder(addKnownTypes)
AddToScheme SchemeBuilder.AddToScheme
)
将对象加入SchemeBuild
func addKnownTypes(scheme *runtime.Scheme) error {
if err : scheme.AddIgnoredConversionType(metav1.TypeMeta{}, metav1.TypeMeta{}); err ! nil {
return err
}
scheme.AddKnownTypes(SchemeGroupVersion,
Pod{},
PodList{},
}}定义对象类型 types.go
List 单一对象数据结构 • TypeMeta • ObjectMeta • Spec • Status
代码生成Tags Global Tags 定义在doc.go中:/ k8s:deepcopy-genpackage Local Tags: 定义在types.go中的每个对象里
// k8s:deepcopy-gen:interfacesk8s.io/apimachinery/pkg/runtime.Object
// genclient
// genclient:nonNamespaced
// genclient:noVerbs
// genclient:onlyVerbscreate,delete
//
genclient:skipVerbsget,list,create,update,patch,delete,deleteCollection,watc
h
//
genclient:methodCreate,verbcreate,resultk8s.io/apimachinery/pkg/apis/
meta/v1.Status实现etcd storage
package storageimport (github.com/kubernetes/kubernetes/pkg/apigithub.com/kubernetes/kubernetes/pkg/apis/configmapgithub.com/kubernetes/kubernetes/pkg/genericregistrygithub.com/kubernetes/kubernetes/pkg/printersprintersinternal github.com/kubernetes/kubernetes/pkg/printers/internalversiongithub.com/kubernetes/kubernetes/pkg/runtimegithub.com/kubernetes/kubernetes/pkg/storagegithub.com/kubernetes/kubernetes/pkg/storage/printerstorage
)func NewREST(optsGetter generic.RESTOptionsGetter) *REST {store : genericregistry.Store{NewFunc: func() runtime.Object { return api.ConfigMap{} },NewListFunc: func() runtime.Object { return api.ConfigMapList{} },DefaultQualifiedResource: api.Resource(configmaps),CreateStrategy: configmap.Strategy,UpdateStrategy: configmap.Strategy,DeleteStrategy: configmap.Strategy,TableConvertor: printerstorage.TableConvertor{TableGenerator: printers.NewTableGenerator().With(printersinternal.AddHandlers),},}options : generic.StoreOptions{RESTOptions: optsGetter}if err : store.CompleteWithOptions(options); err ! nil {panic(err) // TODO: Propagate error up}return REST{store}
}创建和更新对象时的业务逻辑-Strategy
func (strategy) PrepareForCreate(ctx context.Context, obj runtime.Object) {_ obj.(*api.ConfigMap)
}func (strategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {cfg : obj.(*api.ConfigMap)return validation.ValidateConfigMap(cfg)
}func (strategy) PrepareForUpdate(ctx context.Context, newObj, oldObj runtime.Object) {_ oldObj.(*api.ConfigMap)_ newObj.(*api.ConfigMap)
}subresource
statusStore.UpdateStrategy pod.StatusStrategyvar StatusStrategy podStatusStrategy{Strategy}func (podStatusStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object) {newPod : obj.(*api.Pod)oldPod : old.(*api.Pod)newPod.Spec oldPod.SpecnewPod.DeletionTimestamp nil// dont allow the pods/status endpoint to touch owner references since old kubelets corrupt them in a way// that breaks garbage collectionnewPod.OwnerReferences oldPod.OwnerReferences
}注册APIGroup
configMapStorage : configmapstore.NewREST(restOptionsGetter)
restStorageMap : map[string]rest.Storage{configMaps: configMapStorage,
}apiGroupInfo.VersionedResourcesStorageMap[v1] restStorageMapif err : m.GenericAPIServer.InstallLegacyAPIGroup(genericapiserver.DefaultLegacyAPIPrefix, apiGroupInfo); err ! nil {klog.Fatalf(Error in registering group versions: %v, err)
}代码生成
deepcopy-gen • 为对象生成DeepCopy方法用于创建对象副本 client-gen • 创建Clientset用于操作对象的CRUD informer-gen • 为对象创建Informer框架用于监听对象变化 lister-gen • 为对象构建Lister框架用于为Get和List操作构建客户端缓存 coversion-gen • 为对象构建Conversion方法用于内外版本转换以及不同版本号的转换
refer云原生训练营
常联系,如果您看完了
wx: tutengdihuang群如下