本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
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.goapiserver_request_duration_seconds可以指示 API 请求需要多长时间才能运行。
考虑监控以下控制平面指标:
API 服务器
| 指标 | 说明 |
|---|---|
|
|
对于每个动词、试运行值、组、版本、资源、范围、组件和 HTTP 响应代码划分的 apiserver 请求的计数器。 |
|
|
每个动词、试运行值、组、版本、资源、子资源、子资源、范围和组件的响应延迟直方图(以秒为单位)。 |
|
|
准入控制器延迟直方图(以秒为单位),由名称标识,并按每项操作和 API 资源和类型(验证或准许)进行细分。 |
|
|
准入 webhook 被拒绝的次数。按名称、操作、拒绝码、类型(验证或承认)、错误类型(calling_webhook_error、apiserver_internal_error、no_error、no_error)识别 |
|
|
请求延迟直方图(以秒为单位)。按动词和 URL 细分。 |
|
|
HTTP 请求数,按状态码、方法和主机分区。 |
-
直方图指标包括 _bucket、_sum 和 _count 后缀。
etcd
| 指标 | 说明 |
|---|---|
|
|
每种操作和对象类型的 Etcd 请求延迟直方图(以秒为单位)。 |
|
|
etcd 数据库大小。 |
-
直方图指标包括 _bucket、_sum 和 _count 后缀。
考虑使用 Kubernetes 监控概览仪表板
重要
当超过数据库大小限制时,etcd 会发出空间不足警报并停止接收进一步的写入请求。换句话说,集群变为只读状态,所有更改对象的请求,例如创建新 pod、扩展部署等,都将被集群的 API 服务器拒绝。
集群身份验证
EKS 目前支持两种类型的身份验证:bearer/service账户令牌
创建 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 有两种类型的准入网络挂钩:验证准入网络挂钩和变异准入网络挂钩。
为了避免影响集群的关键操作,要么避免设置如下所示的 “包罗万象” 网络挂钩:
- 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 sysctls
处理集群升级
自2021年4月以来,Kubernetes的发布周期已从每年四次(每季度一次)更改为每年发布三次。一个新的次要版本(比如 1.21 或 1。22) 大约每十五周发布一次
集群终端节点连接
使用亚马逊 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
-
使用 Python 的示例 2:Kubernetes 客户端提供了 _request_timeout 参数
-
通过实施这些最佳实践,您可以显著提高应用程序在与 Kubernetes API 交互时的可靠性和弹性。请记住要对这些实现进行全面测试,尤其是在模拟故障条件下,以确保它们在实际扩展或修补事件中按预期运行。
运行大型集群
EKS 主动监控控制平面实例的负载并自动扩展它们以确保高性能。但是,在运行大型集群时,您应该考虑 Kubernetes 中潜在的性能问题和限制以及 AWS 服务的配额。
-
根据 ProjectCalico 团队进行的测试,拥有超过 1000 个服务的集群
kube-proxy在使用 iniptables模式时可能会遇到网络延迟。解决方案是切换到 kube-proxy在ipvs模式下运行。 -
如果 CNI 需要为 Pod 请求 IP 地址,或者您需要经常创建新的 EC2 实例,您也可能会遇到 EC2 API 请求限制。您可以通过将 CNI 配置为缓存 IP 地址来减少 EC2 API 的调用。您可以使用更大的 EC2 实例类型来减少 EC2 扩展事件。