EKS 控制面板 - Amazon EKS

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

EKS 控制面板

Amazon Elastic Kubernetes Service (EKS) 是一项托管 Kubernetes 服务,可让您轻松地在 AWS 上运行 Kubernetes,而无需安装、操作和维护自己的 Kubernetes 控制平面或工作节点。它在上游 Kubernetes 上游运行,并已通过 Kubernetes 标准认证。这种一致性可确保 EKS 支持 KubernetesAPIs,就像你可以在本地或本地安装的开源社区版本一样。 EC2 在上游 Kubernetes 上运行的现有应用程序与 Amazon EKS 兼容。

EKS 会自动管理 Kubernetes 控制平面节点的可用性和可扩展性,并自动替换不健康的控制平面节点。

EKS 架构

EKS 架构旨在消除任何可能影响 Kubernetes 控制平面可用性和耐久性的单点故障。

由 EKS 管理的 Kubernetes 控制平面在 EKS 托管的 VPC 内运行。EKS 控制平面包括 Kubernetes API 服务器节点、etcd 集群。运行 API 服务器、调度器等组件并在自动缩放组kube-controller-manager中运行的 Kubernetes API 服务器节点。EKS 在 AWS 区域内的不同可用区 (AZs) 中至少运行两个 API 服务器节点。同样,为了持久起见,etcd 服务器节点也在跨越三个的自动缩放组中运行。 AZsEKS 在每个可用区运行一个 NAT 网关,API 服务器和 etcd 服务器在私有子网中运行。这种架构可确保单个可用区中的事件不会影响 EKS 集群的可用性。

当您创建新集群时,Amazon EKS 会为托管 Kubernetes API 服务器创建一个高度可用的终端节点,用于与集群通信(使用诸如此类的工具)。kubectl托管端点使用 NLB 对 Kubernetes API 服务器进行负载平衡。EKS 还配置了两个不同的 ENI AZs ,以方便与您的工作节点通信。

EKS 数据平面网络连接

连接

你可以配置你的 Kubernetes 集群的 API 服务器是可以从公共互联网(使用公共终端节点)还是通过你的 VPC(使用 EKS ENIs 托管)访问,或者两者兼而有之。

无论用户和工作节点使用公共终端节点还是 EKS 管理的 ENI 连接到 API 服务器,都有冗余的连接路径。

建议

查看以下建议。

监控控制平面指标

监控 Kubernetes API 指标可以让你深入了解控制平面性能并发现问题。不健康的控制平面可能会影响集群内运行的工作负载的可用性。例如,写得不好的控制器会使 API 服务器过载,从而影响应用程序的可用性。

Kubernetes 在端点公开了控制平面指标。/metrics

您可以使用以下方式查看公开的指标kubectl

kubectl get --raw /metrics

这些指标以 Prometheus 文本格式表示。

您可以使用 Prometheus 来收集和存储这些指标。2020 年 5 月,在 Container Insights 中CloudWatch 增加了对监控 Prometheus 指标的支持。 CloudWatch因此,您也可以使用 Amazon CloudWatch 来监控 EKS 控制平面。您可以使用添加新 Prometheus 抓取目标教程:Prometheus KPI 服务器指标来收集指标并创建仪表板来监控集群的控制平面。 CloudWatch

你可以在这里找到 Kubernetes API 服务器指标。例如,apiserver_request_duration_seconds可以指示 API 请求需要多长时间才能运行。

考虑监控以下控制平面指标:

API 服务器

指标 描述

apiserver_request_total

对于每个动词、试运行值、组、版本、资源、范围、组件和 HTTP 响应代码划分的 apiserver 请求的计数器。

apiserver_request_duration_seconds*

每个动词、试运行值、组、版本、资源、子资源、范围和组件的响应延迟直方图(以秒为单位)。

apiserver_admission_controller_admission_duration_seconds*

准入控制器延迟直方图(以秒为单位),按名称标识,并按每个操作以及 API 资源和类型(验证或承认)进行细分。

apiserver_admission_webhook_rejection_count

Webhook 被拒绝的入场次数。由名称、操作、拒绝代码、类型(验证或承认)、错误类型(calling_webhook_error、apiserver_internal_error、no_error、no_error、no_error)标识

rest_client_request_duration_seconds*

请求延迟直方图(以秒为单位)。按动词和网址细分。

rest_client_requests_total

HTTP 请求数,按状态码、方法和主机分区。

  • 直方图指标包括 _bucket、_sum 和 _count 后缀。

etcd

指标 描述

etcd_request_duration_seconds*

每种操作和对象类型的 Etcd 请求延迟直方图(以秒为单位)。

apiserver_storage_db_total_size_in_bytes或者apiserver_storage_size_bytes(从 EKS v1.28 开始)

etcd 数据库大小。

  • 直方图指标包括 _bucket、_sum 和 _count 后缀。

考虑使用 Kubernetes 监控概述控制面板来可视化和监控 Kubernetes API 服务器请求以及延迟和 etcd 延迟指标。

重要

当超过数据库大小限制时,etcd 会发出空格警报并停止接受进一步的写入请求。换句话说,集群变为只读,所有变异对象(例如创建新 Pod、扩展部署等)的请求都将被集群的 API 服务器拒绝。

集群认证

EKS 目前支持两种类型的身份验证:持有人 /服务账户令牌和使用 webh ook 令牌身份验证的 IAM 身份验证。当用户调用 Kubernetes API 时,Webhook 会将请求中包含的身份验证令牌传递给 IAM。该令牌是一个基于 64 的签名 URL,由 AWS 命令行界面 (A WS CLI) 生成。

创建 EKS 集群的 IAM 用户或角色会自动获得对集群的完全访问权限。您可以通过编辑 aws-auth 配置映射来管理对 EKS 集群的访问权限。

如果您错误配置了aws-auth配置映射并失去了对集群的访问权限,您仍然可以使用集群创建者的用户或角色来访问您的 EKS 集群。

万一您无法在 AWS 区域使用 IAM 服务,也可以使用 Kubernetes 服务账户的不记名令牌来管理集群。

创建一个允许在集群中执行所有操作的super-admin账户:

kubectl -n kube-system create serviceaccount super-admin

创建赋予超级管理员集群管理员角色的角色绑定:

kubectl create clusterrolebinding super-admin-rb --clusterrole=cluster-admin --serviceaccount=kube-system:super-admin

获取服务账号的秘密:

SECRET_NAME=`kubectl -n kube-system get serviceaccount/super-admin -o jsonpath='{.secrets[0].name}'`

获取与密钥关联的代币:

TOKEN=`kubectl -n kube-system get secret $SECRET_NAME -o jsonpath='{.data.token}'| base64 --decode`

将服务账号和令牌添加到kubeconfig

kubectl config set-credentials super-admin --token=$TOKEN

将当前上下文设置kubeconfig为使用超级管理员帐户:

kubectl config set-context --current --user=super-admin

决赛kubeconfig应该是这样的:

apiVersion: v1 clusters: - cluster: certificate-authority-data:<REDACTED> server: https://<CLUSTER>.gr7.us-west-2.eks.amazonaws.com name: arn:aws:eks:us-west-2:<account number>:cluster/<cluster name> contexts: - context: cluster: arn:aws:eks:us-west-2:<account number>:cluster/<cluster name> user: super-admin name: arn:aws:eks:us-west-2:<account number>:cluster/<cluster name> current-context: arn:aws:eks:us-west-2:<account number>:cluster/<cluster name> kind: Config preferences: {} users: #- name: arn:aws:eks:us-west-2:<account number>:cluster/<cluster name> # user: # exec: # apiVersion: client.authentication.k8s.io/v1beta1 # args: # - --region # - us-west-2 # - eks # - get-token # - --cluster-name # - <<cluster name>> # command: aws # env: null - name: super-admin user: token: <<super-admin sa's secret>>

入学网络挂钩

Kubernetes 有两种类型的准入 webhook:验证准入 webhook 和变更准入 web hook。它们允许用户扩展 kubernetes API,并在对象被 API 接受之前对其进行验证或变异。这些 webhook 的配置不佳可能会阻塞集群的关键操作,从而破坏 EKS 控制平面的稳定。

为了避免影响集群的关键操作,要么避免像下面那样设置 “包罗万象” 的 webhook:

- name: "pod-policy.example.com" rules: - apiGroups: ["*"] apiVersions: ["*"] operations: ["*"] resources: ["*"] scope: "*"

或者确保 webhook 具有超时时间小于 30 秒的失效开放策略,以确保在您的 webhook 不可用时,它不会损害集群的关键工作负载。

使用不安全功能屏蔽 Pod sysctls

Sysctl是一个 Linux 实用程序,允许用户在运行时修改内核参数。这些内核参数控制操作系统行为的各个方面,例如网络、文件系统、虚拟内存和进程管理。

Kubernetes 允许为 Pod 分配sysctl配置文件。Kubernetes 将其归类systcls为安全和不安全。Safe sysctls 是容器或 Pod 中的命名空间,设置它们不会影响节点上的其他 Pod 或节点本身。相比之下,不安全的 sysctl 在默认情况下处于禁用状态,因为它们可能会中断其他 Pod 或使节点变得不稳定。

由于默认情况下不安全sysctls处于禁用状态,因此 kubelet 不会创建具有不安全sysctl配置文件的 Pod。如果你创建这样的 Pod,调度器会反复将这样的 Pod 分配给节点,而节点却无法启动它。这种无限循环最终会使集群控制平面紧张,从而使集群变得不稳定。

可以考虑使用 OPA GatekeeperKyverno 来拒绝不安全的 Pod。sysctls

处理集群升级

自 2021 年 4 月以来,Kubernetes 的发布周期已从每年发布四次(每季度一次)更改为每年发布三次。一个新的次要版本(比如 1. 21 或 1。 22) 大约每十五周发布一次。从 Kubernetes 1.19 开始,每个次要版本在首次发布后将获得大约十二个月的支持。随着 Kubernetes v1.28 的问世,控制平面和工作节点之间的兼容性偏差已从 n-2 扩展到 n-3 次要版本。要了解更多信息,请参阅集群升级的最佳实践

集群终端节点连接

使用 Amazon EKS(弹性 Kubernetes 服务)时,在 Kubernetes 控制平面扩展或修补等事件期间,您可能会遇到连接超时或错误。这些事件可能导致 kube-apiserver 实例被替换,从而可能导致在解析 FQDN 时返回不同的 IP 地址。本文档概述了 Kubernetes API 使用者保持可靠连接的最佳实践。

注意

实施这些最佳实践可能需要更新客户端配置或脚本,以有效处理新的 DNS 重新解析和重试策略。

主要问题源于 DNS 客户端缓存以及 EKS 端点的 IP 地址可能过时—— 公共端点的公共 NLB 或私有端点的 X-ENI。替换 kube-apiserver 实例后,完全限定域名 (FQDN) 可能会解析为新的 IP 地址。但是,由于 AWS 托管的 Route 53 区域中的 DNS 生存时间 (TTL) 设置设置为 60 秒,因此客户可能会在短时间内继续使用过时的 IP 地址。

为了缓解这些问题,Kubernetes API 使用者(例如 kubectl、 CI/CD 管道和自定义应用程序)应实施以下最佳实践:

  • 实施 DNS 重新解析

  • 使用退避和抖动实现重试。例如,请参阅这篇标题为 “失败发生” 的文章

  • 实现客户端超时。设置适当的超时时间,以防止长时间运行的请求阻塞您的应用程序。请注意,某些 Kubernetes 客户端库,尤其是由 OpenAPI 生成器生成的客户端库,可能不允许轻松设置自定义超时。

    • 使用 kubectl 的示例 1:

      kubectl get pods --request-timeout 10s # default: no timeout

通过实施这些最佳实践,您可以显著提高应用程序在与 Kubernetes API 交互时的可靠性和弹性。请记住对这些实现进行全面测试,尤其是在模拟的故障条件下,以确保它们在实际扩展或修补事件中按预期运行。

运行大型集群

EKS 会主动监控控制平面实例的负载,并自动扩展它们以确保高性能。但是,在运行大型集群时,您应该考虑 Kubernetes 中的潜在性能问题和限制,以及 AWS 服务中的配额。

其他资源: