View a markdown version of this page

EKS 控制面板 - Amazon EKS

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

EKS 控制面板

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

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

EKS 架构

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

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

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

EKS 数据平面网络连接

连接

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

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

建议

查看以下建议。

监控控制平面指标

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

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

您可以使用以下方式查看暴露的指标kubectl

kubectl get --raw /metrics

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

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

你可以在这里找到 Kubernetes API 服务器指标。https://github.com/kubernetes/apiserver/blob/master/pkg/endpoints/metrics/metrics.go例如,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)识别

rest_client_request_duration_seconds*

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

rest_client_requests_total

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

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

etcd

指标 说明

etcd_request_duration_seconds*

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

apiserver_storage_db_total_size_in_bytesapiserver_storage_size_bytes(从 EKS v1.28 开始)

etcd 数据库大小。

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

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

重要

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

集群身份验证

EKS 目前支持两种类型的身份验证:bearer/service账户令牌和使用 webhook 令牌身份验证的 IAM 身份验证。当用户调用 Kubernetes API 时,网络挂钩会将请求中包含的身份验证令牌传递给 IAM。该令牌是一个基于 64 位的签名网址,由 AWS 命令行接口 (A WS CLI) 生成。

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

如果您错误配置了 aws-auth configmap 并失去了对集群的访问权限,您仍然可以使用集群创建者的用户或角色来访问您的 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 有两种类型的准入网络挂钩:验证准入网络挂钩和变异准入网络挂钩。这些允许用户扩展 kubernetes API 并在 API 接受对象之前对其进行验证或变异。这些 Webhook 的配置不当会阻塞集群的关键操作,从而破坏 EKS 控制平面的稳定。

为了避免影响集群的关键操作,要么避免设置如下所示的 “包罗万象” 网络挂钩:

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

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

使用不安全 s ysctl 屏蔽 Pod

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

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

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

考虑使用 OPA Gatekeeper Kyverno 来拒绝不安全的 Pod。sysctls

处理集群升级

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

集群终端节点连接

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

注意

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

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

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

  • 实施 DNS 重新解析

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

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

    • 使用 kubectl 的示例 1:

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

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

运行大型集群

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

其他资源: