[kubernetes]Kube-APIServer

API Server

API Server是什么

  • 提供集群管理的REST API接口,包括认证授权、数据校验以及集群状态变更等
  • 提供其他模块之间的数据交互和通信的枢纽(其他模块通过API Server查询或修改数据,只有API Server才直接操作etcd)

访问控制概览

在这里插入图片描述

访问控制细节

在这里插入图片描述

认证

  • 如果认证成功,则用户的username会
    传入授权模块做进一步授权验证;而对于认证失败的请求则返回HTTP 401

认证插件

  • X509证书

    • 使用X509客户端证书只需要API 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,group
  • 引导Token

    • 为了支持平滑地启动引导新的集群,Kubernetes 包含了一种动态管理的持有者令牌类型, 称作 启动引导令牌(BootstrapToken)
    • 这些令牌以 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 分钟
    • 匿名请求

      • 如果使用AlwaysAllow以外的认证模式,则匿名请求默认开启,但可用–anonymous-auth=false禁止匿名请求

基于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": "janedoe@example.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 403
  • Kubernetes授权仅处理以下的请求属性
    • user, group, extra
    • API、请求方法(如get、post、update、patch和delete)和请求路径(如/api)
    • 请求资源和子资源
    • Namespace
    • API Group
  • Kubernetes支持以下授权插件
    • 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.io
apiVersion: 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通讯需要的身份
      • 用户可以创建自定的ServiceAccount,kubernetes也为每个namespace创建default
        ServiceAccount
      • Default ServiceAccount通常需要给定权限以后才能对apiserver做写操作

实现方案

  • 在cluster创建时,创建自定义的role,比如namespace-creator
  • Namespace-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可能无法操作某对象
  • Tips:SSH到master节点通过insecure port访问apiserver可绕过鉴权,当需要做管理操作又没
    有权限时可以使用

准入

准入控制

  • 为资源增加自定义属性

    • 作为多租户集群方案中的一环,我们需要在namespace的准入控制中,获取用户信息,并将用
      户信息更新的namespace的annotation
    • 只有当namespace中有有效用户信息时,我们才可以在namespace创建时,自动绑定用户权限,namespace才可用
  • 准入控制(Admission Control)在授权后对请求做进一步的验证或添加默认参数。不同于授权和认证只关心请求的用户和操作,准入控制还处理请求的内容,并且仅对创建、更新、删除或连接(如代理)等有效,而对读操作无效

  • 准入控制支持同时开启多个插件,它们依次调用,只有全部插件都通过的请求才可以放过进入系统

  • 准入控制插件

    • 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等相关的资源

准入控制插件的开发

  • ResourceQuota:限制Pod的请求不会超过配额,需要在namespace中创建一个ResourceQuota对象
  • LimitRanger:为Pod设置默认资源请求和限制,需要在namespace中创建一个Lim itRange对象
  • 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等相关的资源
  • 除默认的准入控制插件以外,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 的流控 qos
    • staging/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 可以对应多个 FS,PL 中维护了一个 QueueSet,用于缓存不能及时处理的请求,请求不会因为超出 PL 的并发限
制而被丢弃。
• FS 中的每个 Flow 通过 shuffle sharding 算法从 QueueSet 选取特定的 queues 缓存请求。
• 每次从 QueueSet 中取请求执行时,会先应用 fair queuing 算法从 QueueSet 中选中一个 queue,然后从这个 queue
中取出 oldest 请求执行。所以即使是同一个 PL 内的请求,也不会出现一个 Flow 内的请求一直占用资源的不公平现象

概念

• 传入的请求通过FlowSchema 按照其属性分类,并分配优先级。
• 每个优先级维护自定义的并发限制,加强了隔离度,这样不同优先级的请求,就不会相互饿死。
• 在同一个优先级内,公平排队算法可以防止来自不同flow 的请求相互饿死。
• 该算法将请求排队,通过排队机制,防止在平均负载较低时,通信量突增而导致请求失败

优先级

• 如果未启用 APF,API 服务器中的整体并发量将受到 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: Limited

FlowSchema

  • 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-gates=AllAlpha=true \--runtime-config=api/all=true \--requestheader-allowed-names=front-proxy-client \--client-ca-file=/etc/kubernetes/pki/ca.crt \--allow-privileged=true \--experimental-bootstrap-token-auth=true \--storage-backend=etcd3 \--requestheader-username-headers=X-Remote-User \--requestheader-extra-headers-prefix=X-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-hooks=NamespaceLifecycle,LimitRanger,ServiceAccount,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota \--requestheader-group-headers=X-Remote-Group \--kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key \--secure-port=6443 \--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname \--service-cluster-ip-range=10.96.0.0/12 \--advertise-address=192.168.0.20 \--etcd-servers=http://127.0.0.1:2379

构建高可用的多副本apiserver

  • apiserver是无状态的Rest Server
  • 无状态所以方便Scale Up/down
  • 负载均衡
    • 在多个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为0,APIServer则将从缓存里面读取数据,而不
    会直接访问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:33Z"message: Local APIServices are always availablereason: Localstatus: "True"type: Available
  • RBAC:参考上文图解

规划系统角色

  • User
    • 管理员
    • 普通用户
  • SystemAccount
    • SystemAccount是开发者(kubernetes developer或者domain developer)创建应用后,应用于apiserver通讯需要的身份
    • 用户可以创建自定的ServiceAccount,kubernetes也为每个namespace创建defaultServiceAccount
    • Default 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

  • Group
  • Kind
  • Version
    • 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-gen=package
  • Local Tags:

    • 定义在types.go中的每个对象里
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +genclient
// +genclient:nonNamespaced
// +genclient:noVerbs
// +genclient:onlyVerbs=create,delete
//
+genclient:skipVerbs=get,list,create,update,patch,delete,deleteCollection,watc
h
//
+genclient:method=Create,verb=create,result=k8s.io/apimachinery/pkg/apis/
meta/v1.Status

实现etcd storage

package storageimport ("github.com/kubernetes/kubernetes/pkg/api""github.com/kubernetes/kubernetes/pkg/apis/configmap""github.com/kubernetes/kubernetes/pkg/genericregistry""github.com/kubernetes/kubernetes/pkg/printers"printersinternal "github.com/kubernetes/kubernetes/pkg/printers/internalversion""github.com/kubernetes/kubernetes/pkg/runtime""github.com/kubernetes/kubernetes/pkg/storage""github.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// don't 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
  • 群如下
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/577300.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开源自托管导航页配置服务Dashy本地搭建结合内网穿透远程访问

开源自托管导航页配置服务Dashy本地搭建结合内网穿透远程访问 简介1. 安装Dashy2. 安装cpolar3.配置公网访问地址4. 固定域名访问 简介 Dashy 是一个开源的自托管的导航页配置服务,具有易于使用的可视化编辑器、状态检查、小工具和主题等功能。你可以将自己常用的一…

Mongodb基础介绍与应用场景

NoSql 解决方案第二种 Mongodb MongoDB 是一款开源 高性能 无模式的文档型数据库 当然 它是NoSql数据库中的一种 是最像关系型数据库的 非关系型数据库 首先 最需要注意的是 无模式的文档型数据库 这个需要后面我们看到它的数据才能明白 其次是 最像关系型数据库的非关系型数据…

RK3588平台开发系列讲解(AI 篇)RKNN 数据结构详解

文章目录 一、rknn_sdk_version二、rknn_input_output_num三、rknn_tensor_attr四、rknn_perf_detail五、rknn_perf_run六、rknn_mem_size七、rknn_tensor_mem八、rknn_input九、rknn_output沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇章主要讲解 RKNN 相关的数…

Autosar CAN开发02(入门Autosar)

Autosar架构 想起当时刚毕业进入公司之后,我的岗位是Autosar Bsw软件工程师。 看着这个什么“Autosar”,真的是一脸懵。 后来才知道,按照我的理解:Autosar就是一个软件架构。它分为ASW和BSW。ASW负责实现应用层功能&#xff08…

“React学习之旅:从入门到精通的点滴感悟“

在探索和学习React的过程中,我逐渐领悟到了前端开发的魅力与挑战。React,作为Facebook推出的开源JavaScript库,以其独特的思维方式和强大的功能,引领着前端开发的潮流。在这篇文章中,我将分享我的React学习心得&#x…

test assert-01-Google Truth 断言

Truth Truth 是用于Java测试的断言框架,灵感来自于FEST,并受到一些可扩展性需求的驱动,几乎完全由谷歌员工在业余时间编写,或者作为Java核心图书馆管理员的身份做出贡献。 作用 作为工程师,我们花费大部分的时间来阅…

《C++避坑神器·二十四》简单搞懂json文件的读写之根据键值对读写Json

c11 json解析库nlohmann/json.hpp文件整个代码由一个头文件组成 json.hpp,没有子项目,没有依赖关系,没有复杂的构建系统,使用起来非常方便。 json.hpp库在文章末尾下载 读写主要有两种方式,第一种根据键值对读写&…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Progress进度条组件

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Progress进度条组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Progress组件 进度条也是UI开发最常用的组件之一,进度条组件…

OpenAI换血大震动始末:“ChatGPT之父”奥特曼,缘何被“扫地出门”?

近期,AI业界发生了一场“大地震”。作为聊天机器人ChatGPT的开发者,OpenAI无疑是最受关注的人工智能公司之一。就是这家公司的联合创始人、CEO、有“ChatGPT之父”之称的阿尔特曼在“疯狂的5天”里,经历了被闪电免职、加入微软、最终又官复原…

影响嵌入式项目成功的一些要素

选择了嵌入式开发这个技术领域,就相当于选择了一条充满挑战的技术开发道路。 对于工程师而言,项目的成功和失败对他们十分重要。因为一行行代码他们不知道熬了多少个通宵,脑细胞死了多少而写出来的。 如果项目失败了,就意味着辛辛…

移动开发新的风口?Harmony4.0鸿蒙应用开发基础+实践案例

前段时间鸿蒙4.0引发了很多讨论,不少业内人士认为,鸿蒙将与iOS、安卓鼎足而三了。 事实上,从如今手机操作系统竞赛中不难看出,安卓与iOS的形态、功能逐渐趋同化,两大系统互相取长补短,综合性能等差距越来越…

【Element】el-select下拉框实现选中图标并回显图标

一、背景 需求&#xff1a;在下拉框中选择图标&#xff0c;并同时显示图标和文字&#xff0c;以便用户可以直观地选择所需的图标。 二、功能实现 <template><div><el-table ref"table" :data"featureCustom2List" height"200"…

分享71个Java源码总有一个是你想要的

分享71个Java源码总有一个是你想要的 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 链接&#xff1a;https://pan.baidu.com/s/1frK-W3GT8WrydSlQ-E3o6A?pwd6666 提取码&#xff1a;6666 UI代码 def __init__(self):import …

Text2SQL学习整理(五)将Text-to-SQL任务与基本语言模型结合

导语 上篇博客&#xff1a;Text2SQL学习整理&#xff08;四&#xff09;将预训练语言模型引入WikiSQL任务简要介绍了两个借助预训练语言模型BERT来解决WIkiSQL数据集挑战的方法&#xff1a;SQLOVA和X-SQL模型。其中&#xff0c;借助预训练语言模型的强大表示能力&#xff0c;S…

【Gitlab】CICD流水线自动化部署教程

第一步&#xff0c;准备 GitLab 仓库 这个不用多说&#xff0c;得先保证你的项目已经托管在一个 GitLab 仓库中。 第二步&#xff0c;定义 .gitlab-ci.yml 文件 在你的项目根目录中创建一个 .gitlab-ci.yml 文件。这个文件将定义所有 CI/CD 的工作流程&#xff0c;包括构建、测…

C++中的内存锁定

内存锁定(memory locking)是确保进程保留在主内存中并且免于分页的一种方法。在实时环境中&#xff0c;系统必须能够保证将进程锁定在内存中&#xff0c;以减少数据访问、指令获取、进程之间的缓冲区传递等的延迟。锁定内存中进程的地址空间有助于确保应用程序的响应时间满足实…

OCP NVME SSD规范解读-1

OCP&#xff08;Open Compute Project&#xff09;是一个由Facebook于2011年发起的开源项目。其目标是重新设计和优化数据中心的硬件&#xff0c;包括服务器、存储、网络设备等&#xff0c;以提高效率&#xff0c;降低运营成本&#xff0c;并推动技术的创新和标准化。 在OCP中&…

C++ Qt开发:Charts绘制各类图表详解

Qt 是一个跨平台C图形界面开发库&#xff0c;利用Qt可以快速开发跨平台窗体应用程序&#xff0c;在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置&#xff0c;实现图形化开发极大的方便了开发效率&#xff0c;本章将重点介绍TreeWidget与QCharts的常用方法及灵活运用。 …

部署谷歌的Gemini大模型

前言 本文将介绍如何使用Docker、Docker-Compose私有化部署谷歌的Gemini大模型&#xff0c;以及没有服务器的情况下如何使用Vercel来部署。 Demo: 使用新加坡云服务器部署&#xff1a;Gemini Pro Chat (snowice.eu.org) 使用Vercel部署&#xff1a;Gemini Pro Chat (snowice.eu…

[足式机器人]Part2 Dr. CAN学习笔记-自动控制原理Ch1-5比例积分控制器Proportional-Intefral Controller

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-自动控制原理Ch1-5比例积分控制器Proportional-Intefral Controller 消除稳态误差——设计新的控制器