06-Kubernetes冰山揭秘-第五层第二部分

举报
kaliarch 发表于 2022/08/13 15:11:22 2022/08/13
【摘要】 MultitenancyKubernetes的多租户不是一个容易解决的问题。部分原因是Kubernetes来自谷歌,多租户通常不是单一公司领域的必需品。然而,人们已经尝试做多租户Kubernetes一段时间了。对于如何做到这一点,有一些解决方案和蓝图。我会试着列出实现这一目标的主要方法,以及它们的利弊。在这些示例中,我们将假设我们仍然在讨论单个公司,租户是该公司内部的不同团队。 Multi...

Multitenancy

Kubernetes的多租户不是一个容易解决的问题。部分原因是Kubernetes来自谷歌,多租户通常不是单一公司领域的必需品。
然而,人们已经尝试做多租户Kubernetes一段时间了。对于如何做到这一点,有一些解决方案和蓝图。我会试着列出实现这一目标的主要方法,以及它们的利弊。
在这些示例中,我们将假设我们仍然在讨论单个公司,租户是该公司内部的不同团队。

Multitenancy with namespaces

在Kubernetes中实现多租户的一种方法是通过名称空间。
每个团队(租户)获得自己的名称空间。使用RBAC,我们可以只为团队成员分配其团队名称空间的权限。

  • 优点:
    很容易做到。一个新的团队来了-创建一个新的命名空间。
    不需要任何额外的软件进行维护。
    集中式团队很容易为使用此集群的所有团队强制执行一些规则和标准集。
  • 缺点:
    • 隔离并不理想。
      用户访问是通过RBAC进行管理的,但是即使在不同的命名空间中,工作负载仍然可以看到其他负载并相互交谈。
      工作负载还将在共享基础结构上运行,因此一个工作负载中的内存泄漏或容器逃逸等问题很容易影响其他租户的工作负载。
      一些集群范围内的资源(如操作员)可能会相互冲突,因为有许多团队但只有一个集群,而且集群中只能有一个这样的资源。
    • 需要额外的管理
      由于手工提供多个集群很快就会变得相当乏味,因此该解决方案几乎总是需要在所有Kubernetes集群之上添加一个额外的管理层。这可能是任何云提供商(AWS EKS、Azure AKS、GCP)或一些自托管解决方案,如VMware Tanzu TKG或Rancher。

Multitenancy via different clusters

另一种在Kubernetes做多租户的方法是…不在Kubernetes做多租户。只需为每个租户提供不同的集群。

  • 优点:
    隔离得好。一个租户的工作量出现问题不会影响其他租户。
    很好的自主性。每个团队都是他们集群的所有者,他们可以做任何他们喜欢的事情。
  • 缺点:
    昂贵。每个集群对主节点和其他系统组件都有一些资源开销。使用这种方法,这个成本乘以团队的数量。
    对于一个集中的权威机构来说,更难对组织中的每个集群强制执行相同的规则集,因为将会有许多集群。

Multitenancy via virtual clusters

这种做法旨在两全其美。它涉及到部署一个额外的层,该层抽象您的名称空间,并使它们看起来像外部的独立集群。
现有的解决方案是由loft.sh开发的vcluster项目。
简而言之,它的工作方式是让用户访问集群,集群只是主集群中的一个命名空间。用户可以在那里部署工作负载,但它们永远不会被调度,因为它们实际上将在主集群的主命名空间中被调度。
这样,它给租户提供了自主权,同时还为集群管理员提供了一种实施集中规则和策略的简单方法。

Cert-manager

cert-manager是Kubernetes的X.509证书控制器。
可以将其配置为从公共颁发者(如Let’s Encrypt)或私有颁发者获得证书。它还负责保持证书是最新的,因此它将尝试续订任何过期的证书。
现在,对公共连接使用TLS是强制性的,但即使对专用服务到服务通信也建议使用TLS。cert-manager是一个很有价值的项目,它可以帮助您在这方面更加安全。

Certificate renewal

证书续订是续订SSL证书的过程。这是必要的,因为每个SSL证书都有过期日期,过期后证书无效。
过去,证书颁发者常常颁发具有巨大有效期(例如5年)的证书。这现在被认为是一种不好的做法,浏览器通常会拒绝有效期超过1年或2年的证书。
让我们加密颁发只有效期为三个月的证书。这是为了鼓励在续订证书时使用自动化。
如果使用的是cert-manager,它可以自动处理证书续订过程。

cluster-autoscaler

Kubernetes cluster-autoscaler是一种基于几个因素(如节点利用率和故障吊舱)自动调整集群大小(节点数)的工具。
它确保所有豆荚都有一个运行的位置,同时它不会使用比它可能使用的更多的节点。
对于大多数主要的云提供商,如AWS、Azure或外部的out-of-tree提供商,都有一个可用的实现。

Egress gateway

出口网关是用于出口业务的网关。
出口网关允许您限制工作负载的传出流量。这可能是防止攻击者与外部世界进行恶意网络连接的有用安全功能。
这不是原生的Kubernetes概念,但它是由一些Kubernetes网络实现(CNI)实现的,比如Calico和Cilium,或者由像Istio这样的服务网格实现的。

descheduler

descheduler是Kubernetes组件,负责分配工作负载。
这可能有多种原因:

  • 有些节点未得到充分利用或过度利用。
  • 污点或标签被添加到节点或从节点中移除,节点/节点亲和力要求不再满足。
  • 一些节点失败,它们的吊舱移动到其他节点。
  • 新节点被添加到集群中。

在descheduler对豆荚进行了descheduler之后,它们返回到调度器,他有责任再次对它们进行重新调度。

Custom Resources validation and conversion

CustomResourceDefinitions是一种定义自定义资源从而扩展Kubernetes API的方法。
每个自定义资源定义都通过OpenAPI规范定义其字段。例如,用户CRD可以具有以下API规范:

schema:
  openAPIV3Schema:
    type: object
    properties:
      spec:
        type: object
        properties:
          id:
            type: string
          name:
            type: string

我们看到用户有两个属性-id和name,都是String类型。
资源的Open API规范可以扩展为指定字段的额外验证。例如,您可以通过required参数定义required属性,或者通过pattern参数为字符串值指定regex验证器:

id:
  type: string
  required: true

这些字段的验证将由Kubernetes API自动执行,如果用户试图创建违反这些规则的对象,则请求将失败。

etcd cluster management

etcd是分布式键值存储。默认情况下,Kubernetes使用etcd作为保存所有数据的地方。例如,当我们创建一个Pod资源时,它会被持久化到etcd中。
由于etcd是按设计的分布式数据存储,大多数生产环境都运行多个etcd实例。这样,即使其中一个死亡,我们的数据在其他数据中也是安全的。
为了协同工作,etcd实例需要相互了解并能够相互通信。这需要在启动集群时进行一些配置。
这里描述了配置etcd集群时需要知道的大多数重要事项,如服务发现、DNS和TLS配置等。
最后,etcd的一个好的安全措施是在专用的主节点上运行它,这些主节点不是公开可用的,并且通过网络策略配置为只有API服务器可以访问。这是因为我们永远不应该直接与etcd交互,只能通过API服务器。此外,如果攻击者获得了对etcd的访问权限,他们可能会破坏我们的集群(例如,通过删除资源)

Kubernetes Upgrade

升级Kubernetes集群是集群生命周期中的一件重要事情。新的Kubernetes小版本(V1.xx.0)每四个月发布一次,补丁版本(V1.24.xx)更经常发布,以解决bug和安全漏洞。
新的Kubernetes版本提供了新的特性,而旧的Kubernetes版本最终会失效,对它们的支持也会被放弃。您应该始终运行受支持的Kubernetes版本。
对于运行托管Kubernetes(例如,EKS、AKS、GKE、Rancher等)的用户来说,升级Kubernetes集群就像在cloud-provider UI中的下拉菜单中切换一个值一样简单。
如果您自己管理Kubernetes集群,情况就不是这样了。如果是这样,则需要手动升级群集。我所说的“手动”是指有一个有用的工具可以管理大部分繁重的工作,但您仍然有责任正确地使用它。
该工具被称为kubeadm,它不仅有助于升级集群,还有助于设置集群。
这里详细描述了升级群集的过程,但要遵循的基本步骤如下:

  • 备份你的数据!
  • 逐个升级您的主节点
  • 升级CNI
  • 逐个升级工作节点

IaC for Grafana (dashboards, data sources)

IaC代表作为代码的基础设施。这种范例包括用文本文件(代码)描述您的基础结构,并有一个工具,该工具将根据该文件的内容和对它的更改提供/销毁资源。这类工具有Terraform,Pulumi和其他工具。
大多数IaC工具,如Terraform,只要有提供商,就可以提供绝对的一切。提供程序是一种基于代码提供基础结构的实现。
Grafana有这样的提供者。使用它,您可以将仪表板和数据源描述为代码,并通过IaC工具为您自动创建这些代码。
例如,这是一个Terraform代码片段,它将基于grafana-dashboard.JSON JSON文件创建一个Grafana仪表板:

resource "grafana_dashboard" "metrics" {
  config_json = file("grafana-dashboard.json")
}

也可以手动配置仪表板,然后导出仪表板的Terraform代码。通过这种方式,您可以获得两个世界的最佳选择–由IaC工具维护的手动配置。

Advanced control plane configuration

Kubernetes控制平面及其组件(api-server、controller-manager、scheduler和etcd)根据用户的需要支持一些定制。
每个组件的定制是不同的,但如果我必须指出每个组件的一些最重要的事情:

API server

  • 审计日志配置-最大大小,要存储的地方,保留,等等。
  • TLS证书
  • 领导选举算法的构造
  • 启用和禁用可选功能
  • 度量标准

Controller manager

  • TLS证书
  • 领导选举算法的构造
  • 启用和禁用可选功能
  • 度量标准

Scheduler

  • TLS证书
  • 领导选举算法的构造
  • 启用和禁用可选功能
  • 度量标准

etcd

  • TLS证书
  • 度量标准
  • 群集配置

Customizable monitoring for all Kubernetes objects

完全监视所有Kubernetes对象是至关重要的,这样才能完全了解集群的状态,并能够在需要时采取相应的行动。
Kubernetes为您提供了两种监视资源的方法。第一个是resource metrics pipeline,它为您提供了与集群组件相关的有限的度量集。它们保存在短期内存度量服务器中,并通过metrics.k8s.io API或kubectl top实用程序公开。
第二个是完整的度量管道,它更加复杂,可以使用更多的度量。通过实现custom.metrics.k8s.io或external.metrics.k8s.io API来公开这些文件。
这些API的CNCF支持的实现是Prometheus。

Long-term Prometheus

Prometheus是一个开源的监视和警报工具包。
它用于度量的收集和聚合。
它还可以与本地或远程文件存储集成,以实现更大的数据保留。
文件存储选项是通过–storage.xxx命令行参数配置的。
当使用长期存储时,为了节省空间,建议减少时间序列的刮擦次数(也是因为您可能不关心6个月前的度量数据的逐秒变化)。

Prometheus Query Caching

普罗米修斯查询是用PROMQL编写的。
PromQL非常强大,可以做很多事情,如求和、求平均值、聚合等等。如果在大型数据集上执行这些操作,可能需要大量的CPU和内存才能完成。
这就是为什么像Grafana这样的Prometheus前端(以及Prometheus本身)支持查询缓存,例如,将给定查询的结果保存一段时间,如果另一个用户对相同的数据运行相同的查询,它将返回缓存的结果。这加快了获取数据的过程,并避免了不必要的计算。
当然,这是一种权衡,因为在像普罗米修斯这样的实时系统中,数据会以秒为单位变化,所以我们不能设置太大的缓存TTL而不冒向用户显示过时数据的风险。

Ingress Monitoring

入口管理进入集群的外部流量。
它是我们系统的一个组成部分–如果入口关闭或无法伸缩,我们的整个系统将被阻塞,因为所有请求在进入它之前都要通过入口。
这就是为什么监控到位是很重要的,这样我们就可以知道在任何给定的时间有什么流量流入我们的系统,延迟是什么,是否有任何问题,等等。
由于入口资源是抽象资源,所有功能都由控制器实现。监控也是。不同的入口控制器实现提供了不同的监视构造,但它们都实现了相同的结果。
例如,如果您正在运行NGINX入口控制器,您可以通过-enable-prometheus-metrics标志启用度量,然后您可以使用这里列出的度量。

Ingress autoscaling

在启用入口度量之后,您可以将其提升到下一个级别,并基于这些度量自动缩放您的入口。例如,一旦出现流量高峰,网络延迟开始增加,就启动新实例。
适当地扩展入口是至关重要的,因为这是应用程序流量的入口点。如果缩放不正确,入口可能是一个瓶颈,它会减慢应用程序的速度,并给用户带来挫折。
就像监控一样,自动伸缩也是由控制器实现提供的。
例如,如果您正在运行NGINX入口控制器,则可以通过使用NGINX度量的KEDA自动缩放器来配置自动缩放。
如果一分钟内的平均连接数超过100个,则该对象将KEDA配置为自动伸缩NGINX吊舱。

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
 name: nginx-scale
spec:
 scaleTargetRef:
   kind: Deployment
   name: main-nginx-ingress
minReplicaCount: 1
maxReplicaCount: 20
cooldownPeriod: 30
pollingInterval: 1
triggers:
- type: prometheus
   metadata:
     serverAddress: http://prometheus-server
     metricName: nginx_connections_active_keda
     query: |
              sum(avg_over_time(nginx_ingress_nginx_connections_active{app="main-nginx-ingress"}[1m]))
     threshold: "100"

Resource sharing

Kubernetes在同一个物理/虚拟节点上运行多个工作负载。这意味着这些工作负载将共享底层主机资源。
Kubernetes提供了两个结构来控制如何共享这些资源–资源限制和资源请求。
我们在本系列的第2部分中讨论了资源限制,但现在我将更详细地介绍限制和请求以及两者之间的区别。
这些请求显示了工作负载将需要多少最小资源。kubelet将使用该信息来找到一个合适的节点来调度Pod(一个至少具有与对Pod的请求一样多的资源的节点)。吊舱可以在请求的资源下面或上面。
限制显示工作负载将需要多少最大资源。Kubernetes将不允许资源使用超过其限制。此限制由容器运行库强制执行,不允许资源超过此限制。

Dynamic StorageClass provisioning

在Kubernetes中创建卷时,指定其StorageClass。StorageClass显示卷的一些属性,例如,卷的服务质量级别、备份策略或群集管理员确定的其他策略。
您不局限于可以使用的StorageClass的数量,甚至可以通过创建该类型的新Kubernetes资源来定义自己的StorageClass。
这是一个示例StorageClass:

apiVersion: storage.k8s.io/v1
kind: StorageClass
provisioner: kubernetes.io/aws-ebs
metadata:
  name: standard
reclaimPolicy: Retain
allowVolumeExpansion: true
volumeBindingMode: Immediate
parameters:
  type: gp2
mountOptions:
  - debug

从它的属性中,我们可以看到这个类的卷是由AWS EBS提供的;它具有GP2类型、保留的回收策略等。参数取决于供应者,例如,AWS EBS有一组对该供应者有意义的参数,GCE PD有其他参数,等等。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。