

 **帮助改进此页面** 

要帮助改进本用户指南，请选择位于每个页面右侧窗格中的**在 GitHub 上编辑此页面**链接。

# Kubernetes 概念
<a name="kubernetes-concepts"></a>

Amazon Elastic Kubernetes Service（Amazon EKS）是一项基于开源 [Kubernetes](https://kubernetes.io/) 项目的 Amazon 托管服务。虽然需要了解 Amazon EKS 服务如何与 Amazon Cloud 集成（尤其是首次创建 Amazon EKS 集群时），但只要启动并运行起来，您就可以像使用任何其他 Kubernetes 集群那样使用自己的 Amazon EKS 集群。因此，要开始管理 Kubernetes 集群和部署工作负载，您至少需要对 Kubernetes 概念有基本的了解。

本页将 Kubernetes 概念分为三个部分：“[为何选择 Kubernetes？](#why-kubernetes)”“[集群](#concepts-clusters)”和“[工作负载](#workloads)”。第一部分介绍了运行 Kubernetes 服务的价值，尤其是作为托管服务（如 Amazon EKS）运行的价值。“工作负载”部分介绍如何构建、存储、运行和管理 Kubernetes 应用程序。“集群”部分列出构成 Kubernetes 集群的不同组件，以及您在创建和维护 Kubernetes 集群方面的责任。

**Topics**
+ [为何选择 Kubernetes？](#why-kubernetes)
+ [集群](#concepts-clusters)
+ [工作负载](#workloads)
+ [后续步骤](#next-steps)

在浏览本内容时，如果您想深入了解我们在此处介绍的任何主题，则链接将引导您进一步了解 Amazon EKS 和 Kubernetes 文档中的 Kubernetes 概念。有关 Amazon EKS 如何实施 Kubernetes 控制面板和计算功能的详细信息，请参阅 [Amazon EKS 架构](eks-architecture.md)。

## 为何选择 Kubernetes？
<a name="why-kubernetes"></a>

Kubernetes 旨在提高运行任务关键型、生产质量容器化应用程序时的可用性和可扩展性。Kubernetes 不仅仅是在一台计算机上运行 Kubernetes（尽管可以这样做），还通过允许您在可以扩缩来满足需求的计算机组上运行应用程序来实现这些目标。Kubernetes 内含的功能有助于执行以下操作：
+ 在多台机器上部署应用程序（使用部署在容器组（pod）中的容器）
+ 监控容器运行状况并重启失败的容器
+ 根据负载纵向扩展和缩减容器
+ 使用新版本更新容器
+ 在容器之间分配资源
+ 平衡计算机间的流量

通过让 Kubernetes 自动执行这些类型的复杂任务，应用程序开发人员可以专注于构建和改进其应用程序工作负载，而不必担心基础设施。开发人员通常会创建格式为 YAML 文件的配置文件，这些文件用于描述应用程序的所需状态。这可能包括要运行的容器、资源限制、容器组（pod）副本数量、CPU/内存分配、关联性规则等等。

### Kubernetes 属性
<a name="attributes-of-kubernetes"></a>

为实现其目标，Kubernetes 具有以下属性：
+  **容器化** – Kubernetes 是一种容器编排工具。要使用 Kubernetes，您必须先将应用程序容器化。根据应用程序的类型，它可以是一组*微服务*、批处理作业或其他形式。然后，您的应用程序可以利用包含庞大工具生态系统的 Kubernetes 工作流，在该工作流中，容器可以作为[映像存储在容器注册表中](https://kubernetes.io/docs/concepts/containers/images/#multi-architecture-images-with-image-indexes)，部署到 Kubernetes [集群](https://kubernetes.io/docs/concepts/architecture/)，然后在可用[节点](https://kubernetes.io/docs/concepts/architecture/nodes/)上运行。在将各个容器部署到 Kubernetes 集群之前，您可以使用 Docker 或其他[容器运行时](https://kubernetes.io/docs/setup/production-environment/container-runtimes/)在本地计算机上构建和测试这些容器。
+  **可扩缩** – 如果对应用程序的需求超过这些应用程序正在运行的实例容量，则 Kubernetes 可以纵向扩展。根据需要，Kubernetes 可以判断应用程序是否需要更多 CPU 或内存，并通过自动扩展可用容量或使用更多的现有容量来做出响应。如果有足够的计算能力来运行更多的应用程序实例（[水平容器组（pod）自动缩放](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/)），则可以在容器组（pod）级别进行扩展；如果需要调出更多节点来处理增加的容量（[集群 Autoscaler](https://github.com/kubernetes/autoscaler/tree/master/cluster-autoscaler) 或 [Karpenter](https://karpenter.sh/)），则可以在节点级别进行扩展。由于不再需要容量，这些服务可以删除不必要的容器组（pod）并关闭不需要的节点。
+  **可用** – 如果某个应用程序或节点运行状况不佳或不可用，Kubernetes 可以将正在运行的工作负载移至其他可用节点。您只需删除正在运行的工作负载实例或正在运行您的工作负载的节点即可强制解决问题。这里的底线是，如果工作负载不能再在当前位置运行，则可以将其调到其他位置。
+  **声明式** – Kubernetes 使用主动协调来持续检查您为集群声明的状态是否与实际状态相符。例如，通过将 [Kubernetes 对象](https://kubernetes.io/docs/concepts/overview/working-with-objects/)应用于集群（通常通过 YAML 格式的配置文件），您可以要求启动要在集群上运行的工作负载。您可以稍后更改配置，执行使用更高版本的容器或分配更多内存这样的操作。Kubernetes 将尽其所能建立所需的状态。这可能包括启动或关闭节点、停止和重启工作负载，或拉取更新的容器。
+  **可组合** – 由于应用程序通常由多个组件组成，因此您会希望能够将某个组件组合（通常由多个容器表示）统一管理。虽然 Docker Compose 提供使用 Docker 直接执行此操作的方法，但 [Kompose](http://kompose.io/) 命令可以帮助您使用 Kubernetes 执行该操作。有关如何执行此操作的示例，请参阅[将 Docker Compose 文件翻译成 Kubernetes 资源](https://kubernetes.io/docs/tasks/configure-pod-container/translate-compose-kubernetes/)。
+  **可扩展** – 与专有软件不同的是，Kubernetes 开源项目采用开放设计，能让您以所需方式扩展 Kubernetes 来满足需求。API 和配置文件可以直接修改。我们鼓励第三方编写自己的[控制器](https://kubernetes.io/docs/concepts/architecture/controller/)，以同时扩展基础设施和最终用户 Kubernetes 功能。[Webhook](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) 使您能够设置集群规则，以强制执行策略并适应不断变化的条件。有关如何扩展 Kubernetes 集群的更多想法，请参阅[扩展 Kubernetes](https://kubernetes.io/docs/concepts/extend-kubernetes/)。
+  **可移植** – 许多组织已将其在 Kubernetes 上的操作标准化，从而能够以相同的方式管理所有应用程序需求。开发人员可以使用相同的管道来构建并存储容器化应用程序。然后，可以将这些应用程序部署到在本地、云、餐厅的销售点终端上，或分散在公司远程站点的 IOT 设备上运行的 Kubernetes 集群中。开源性质使人们有可能开发这些特殊的 Kubernetes 发行版，以及管理这些发行版所需的工具。

### 管理 Kubernetes
<a name="managing-kubernetes"></a>

Kubernetes 源代码免费提供，因此您可以使用自己的设备自行安装和管理 Kubernetes。但是，自行管理 Kubernetes 需要深厚的运营专业知识，并且需要时间和精力来维护。出于这些原因，大多数部署生产工作负载的人员都会选择云提供商（例如 Amazon EKS）或本地提供商（例如 Amazon EKS Anywhere），这些提供商拥有经过测试的 Kubernetes 发行版和 Kubernetes 专家支持。这使您可以卸下维护集群所需的大量千篇一律的工作，包括：
+  **硬件** – 如果您不具备可根据要求运行 Kubernetes 的硬件，则 Amazon Amazon EKS 等云提供商可以为您节省前期成本。借助 Amazon EKS，这意味着您可以使用 Amazon 提供的最佳云资源，包括计算机实例（Amazon Elastic Compute Cloud）、您自己的私有环境（Amazon VPC）、中央身份和权限管理（IAM）和存储（Amazon EBS）。Amazon 管理计算机、网络、数据中心和运行 Kubernetes 所需的所有其他物理组件。同样，您不必计划数据中心在需求最高的时期处理最大容量。对于 Amazon EKS Anywhere 或其他本地 Kubernetes 集群，您负责管理 Kubernetes 部署中使用的基础设施，但您仍然可以依靠 Amazon 让 Kubernetes 保持最新状态。
+  **控制面板管理** – Amazon EKS 负责管理 Amazon 托管的 Kubernetes 控制面板的安全性和可用性，控制面板负责调度容器、管理应用程序的可用性以及其他关键任务，让您能够专注于应用程序工作负载。如果您的集群中断，则 Amazon 应该有办法将集群恢复到运行状态。对于 Amazon EKS Anywhere，您将自己管理控制面板。
+  **经过测试的升级** – 升级集群时，Amazon EKS 或 Amazon EKS Anywhere 会提供其经测试的 Kubernetes 发行版。
+  **附加组件** – 有数百个项目为扩展和使用 Kubernetes 而构建，您可以将其添加到集群的基础设施中，也可以用它们来辅助工作负载的运行。Amazon 并未自己构建和管理这些附加组件，而是提供可用于集群的 [Amazon EKS 附加组件](eks-add-ons.md)。Amazon EKS Anywhere 提供[精选软件包](https://anywhere.eks.amazonaws.com/docs/packages/)，其中包括许多热门开源项目的版本。因此，您不必自己构建软件，也不必管理关键的安全补丁、漏洞修复或升级。同样，如果默认设置满足您的需求，则通常只需要对这些插件进行很少的配置。有关使用插件扩展集群的详细信息，请参阅[扩展集群](#extend-clusters)。

### Kubernetes 的实际应用
<a name="kubernetes-in-action"></a>

下图显示您作为 Kubernetes 管理员或应用程序开发人员在创建和使用 Kubernetes 集群时要执行的关键活动。在此过程中，以 Amazon 云作为底层云提供商为例，说明了 Kubernetes 组件是如何相互交互的。

![\[操作中的 Kubernetes 集群。\]](http://docs.amazonaws.cn/eks/latest/userguide/images/k8sinaction.png)


Kubernetes 管理员使用特定于将在其上构建集群的提供商类型的工具来创建 Kubernetes 集群。此示例使用 Amazon 云作为提供商，提供名为 Amazon EKS 的托管 Kubernetes 服务。此托管式服务会自动分配创建集群所需的资源，包括为集群创建两个新的虚拟私有云（Amazon VPC）、设置联网以及将 Kubernetes 权限直接映射到用于云资产管理的新 VPC。此托管式服务还会确认存在可用于运行控制面板服务的空间，并分配零个或多个 Amazon EC2 实例以作为运行工作负载的 Kubernetes 节点。Amazon 会管理用于控制面板的一个 Amazon VPC 本身，而另一个 Amazon VPC 则包含运行工作负载的客户节点。

Kubernetes 管理员今后的许多任务都是使用 `kubectl` 之类的 Kubernetes 工具完成的。该工具直接向集群的控制面板发出服务请求。因此，对集群进行查询和更改的方式与您在任何 Kubernetes 集群上执行查询和更改的方式非常相似。

想要将工作负载部署到此集群的应用程序开发人员可以执行多项任务。开发人员需要将应用程序构建到一个或多个容器映像中，然后将这些映像推送到 Kubernetes 集群可以访问的容器注册表。Amazon 为此提供 Amazon Elastic Container Registry（Amazon ECR）。

要运行应用程序，开发人员可以创建 YAML 格式的配置文件，告诉集群如何运行应用程序，包括要从注册表中提取哪些容器以及如何将这些容器封装在容器组（pod）中。控制面板（调度程序）将容器调度到一个或多个节点，每个节点上的容器运行时实际上会拉取并运行所需的容器。开发人员还可以设置应用程序负载均衡器，以均衡在每个节点上运行的可用容器的流量，并公开应用程序，使其可以在公共网络上对外开放。完成所有操作后，想要使用应用程序的人可以连接到应用程序端点进行访问。

以下部分将从 Kubernetes 集群和工作负载的角度详细介绍每项功能。

## 集群
<a name="concepts-clusters"></a>

如果作业是启动和管理 Kubernetes 集群，则应了解如何创建、增强、管理和删除 Kubernetes 集群。您还应该了解构成集群的组件是什么，以及需要做些什么来维护这些组件。

用于管理集群的工具可以处理 Kubernetes 服务与底层硬件提供商之间的重叠问题。因此，这些任务的自动化往往由 Kubernetes 提供商（例如 Amazon EKS 或 Amazon EKS Anywhere）使用特定于提供商的工具来完成。例如，要启动 Amazon EKS 集群，您可以使用 `eksctl create cluster`，而对于 Amazon EKS Anywhere，您可以使用 `eksctl anywhere create cluster`。请注意，虽然这些命令创建 Kubernetes 集群，但它们是特定于提供商的，而不是 Kubernetes 项目本身的一部分。

### 集群创建和管理工具
<a name="cluster-creation-and-management-tools"></a>

Kubernetes 项目提供手动创建 Kubernetes 集群的工具。因此，如果要在单台计算机上安装 Kubernetes，或者在计算机上运行控制面板并手动添加节点，则可以使用 Kubernetes [安装工具](https://kubernetes.io/docs/tasks/tools/)下列出的 [kind](https://kind.sigs.k8s.io/)、[minikube](https://kubernetes.io/docs/tutorials/hello-minikube/) 或 [kubeadm](https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/) 之类的 CLI 工具。要简化和自动执行集群创建和管理的整个生命周期，使用现有 Kubernetes 提供商（例如 Amazon EKS 或 Amazon EKS Anywhere）支持的工具要容易得多。

在 Amazon Cloud 中，您可以使用 CLI 工具（例如 [eksctl](https://eksctl.io/)）或更多声明性工具（例如 Terraform）创建 [Amazon EKS](https://docs.amazonaws.cn/eks/) 集群（请参阅 [Terraform 的 Amazon EKS 蓝图](https://github.com/aws-ia/terraform-aws-eks-blueprints)）。您还可以从 Amazon Web Services 管理控制台中创建集群。要了解使用 Amazon EKS 能够获得的能力，请参阅 [Amazon EKS 功能](https://www.amazonaws.cn/eks/features/)。Amazon EKS 代您承担的 Kubernetes 职责包括：
+  **托管式控制面板** – Amazon 为您管理控制面板并使其跨 Amazon 可用区可用，从而确保 Amazon EKS 集群可用且可扩缩。
+  **节点管理** – 您可以使用托管式节点组（请参阅[使用托管式节点组简化节点生命周期](managed-node-groups.md)）或 [Karpenter](https://karpenter.sh/)，让 Amazon EKS 根据需要自动创建节点，而无需手动添加节点。托管节点组已与 Kubernetes [集群自动扩缩](https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md)集成。使用节点管理工具，您可以利用[竞价型实例](https://docs.amazonaws.cn/AWSEC2/latest/UserGuide/using-spot-instances.html)、节点整合及可用性等优势来节省成本，并使用[计划](https://karpenter.sh/docs/concepts/scheduling/)功能来设置工作负载的部署方式和节点的选择方式。
+  **集群联网** – `eksctl` 使用 CloudFormation 模板在 Kubernetes 集群中的控制面板和数据面板（节点）组件之间设置联网。它还设置可以通过其进行内部和外部通信的端点。有关详细信息，请参阅[揭秘 Amazon EKS 工作线程节点的集群联网](https://www.amazonaws.cn/blogs/containers/de-mystifying-cluster-networking-for-amazon-eks-worker-nodes)。Amazon EKS 中容器组（pod）之间的通信使用 Amazon EKS 容器组身份完成（请参阅[了解 EKS 容器组身份如何向容器组（pod）授予对 Amazon 服务的访问权限](pod-identities.md)），这提供了一种让容器组（pod）利用 Amazon 云方法来管理凭证和权限的方式。
+  **附加组件** – 使用 Amazon EKS，您无需构建和添加支持 Kubernetes 集群的常用软件组件。例如，当您从 Amazon Web Services 管理控制台创建 Amazon EKS 集群时，系统会自动添加 Amazon EKS kube-proxy（[在 Amazon EKS 集群中管理 `kube-proxy`](managing-kube-proxy.md)）、适用于 Kubernetes 的 Amazon VPC CNI 插件（[使用 Amazon VPC CNI 将 IP 分配给容器组（pod）](managing-vpc-cni.md)）和 CoreDNS（[在 Amazon EKS 集群中管理 DNS 的 CoreDNS](managing-coredns.md)）附加组件。有关这些附加组件的更多信息，包括可用附件组件列表，请参阅 [Amazon EKS 附加组件](eks-add-ons.md)。

为了在您自己的本地计算机和网络上运行集群，Amazon 提供了 [Amazon EKS Anywhere](https://anywhere.eks.amazonaws.com/)。您可以选择使用自己的设备在 [VMWare vSphere](https://anywhere.eks.amazonaws.com/docs/getting-started/vsphere/)、[裸机](https://anywhere.eks.amazonaws.com/docs/getting-started/baremetal/)（[Tinkerbell 提供程序](https://tinkerbell.org)）、[Snow](https://anywhere.eks.amazonaws.com/docs/getting-started/snow/)、[CloudStack](https://anywhere.eks.amazonaws.com/docs/getting-started/cloudstack/) 或 [Nutanix](https://anywhere.eks.amazonaws.com/docs/getting-started/nutanix/) 平台上运行 Amazon EKS Anywhere，而不是将 Amazon Cloud 作为提供商。

Amazon EKS Anywhere 基于 Amazon EKS 使用的相同 [Amazon EKS Distro](https://distro.eks.amazonaws.com/) 软件。但是，Amazon EKS Anywhere 依赖 [Kubernetes 集群 API](https://cluster-api.sigs.k8s.io/)（CAPI）接口的不同实现来管理 Amazon EKS Anywhere 集群中计算机的整个生命周期（例如 vSphere 的 [CAPV](https://github.com/kubernetes-sigs/cluster-api-provider-vsphere) 和 CloudStack 的 [CAPC](https://github.com/kubernetes-sigs/cluster-api-provider-cloudstack)）。由于整个集群都在您的设备上运行，因此您还要承担管理控制面板和备份其数据的额外责任（请参阅本文档后面的 `etcd`）。

### 集群组件
<a name="cluster-components"></a>

Kubernetes 集群组件分为两个主要区域：控制面板和 Worker 节点。[控制面板组件](https://kubernetes.io/docs/concepts/overview/components/#control-plane-components)管理集群并提供对其 API 的访问权限。Worker 节点（有时简称为“节点”）提供运行实际工作负载的地方。[节点组件](https://kubernetes.io/docs/concepts/overview/components/#node-components)由在每个节点上运行的服务组成，这些服务用于与控制面板通信并运行容器。您的集群的 Worker 节点组称为*数据面板*。

#### 控制面板
<a name="concepts-control-plane"></a>

控制面板由一组管理集群的服务组成。这些服务可能全部在单台计算机上运行，也可能分布在多台计算机上。在内部，它们被称为控制面板实例（CPI）。CPI 的运行方式取决于集群的大小和对高可用性的要求。随着集群中的需求增加，控制面板服务可以扩展以提供该服务的更多实例，并在实例之间实现请求的负载均衡。

Kubernetes 控制面板组件执行的任务包括：
+  **与集群组件（API 服务器）通信** – API 服务器（[kube-apiserver](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-apiserver/)）会公开 Kubernetes API，因此可以从集群内部和外部都发出对集群的请求。换句话说，添加或更改集群对象（容器组（pod）、服务、节点等）的请求可能来自外部命令，例如来自 `kubectl` 的运行容器组（pod）的请求。同样，可以从 API 服务器向集群内的组件发出请求，例如向 `kubelet` 服务查询容器组（pod）的状态。
+  **存储有关集群的数据（`etcd` 键值存储）** – `etcd` 服务提供了跟踪集群当前状态的关键功能。如果 `etcd` 服务变得不可访问，则您将无法更新或查询集群的状态，尽管工作负载会继续运行一段时间。因此，关键集群通常会同时运行多个负载均衡的 `etcd` 服务实例，并定期备份 `etcd` 键值存储以防数据丢失或损坏。请记住，在 Amazon EKS 中，这一切都是默认自动为您处理的。Amazon EKS Anywhere 提供 [etcd 备份和恢复](https://anywhere.eks.amazonaws.com/docs/clustermgmt/etcd-backup-restore/)的说明。请参阅 [etcd Data Model](https://etcd.io/docs/v3.5/learning/data_model/)，以了解 `etcd` 管理数据的方式。
+  **将容器组（pod）调度到节点（调度程序）**– 有关启动或停止 Kubernetes 中容器组（pod）的请求会被定向到 [Kubernetes 调度器](https://kubernetes.io/docs/concepts/scheduling-eviction/kube-scheduler/)（[kube-scheduler](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-scheduler/)）。由于一个集群可能有多个能够运行容器组（pod）的节点，因此应由调度程序来选择容器组（pod）应在哪个节点（或哪些节点，如果是副本）上运行。如果没有足够的可用容量在现有节点上运行所请求的容器组（pod），除非您进行了其他规定，否则请求将失败。此类预置可能包括启用托管式节点组（[使用托管式节点组简化节点生命周期](managed-node-groups.md)）或 [Karpenter](https://karpenter.sh/) 之类的服务，这些服务可以自动启动新节点来处理工作负载。
+  **将组件保持在所需状态（控制器管理器）**– Kubernetes 控制器管理器作为进程守护程序（[kube-controller-manager](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-controller-manager/)）运行，可监视集群的状态，以及更改集群来重新建立预期状态。特别是，有几个控制器可以监视不同的 Kubernetes 对象，包括 `statefulset-controller`、`endpoint-controller`、`cronjob-controller`、`node-controller`。
+  **管理云资源（云控制器管理器）**– Kubernetes 与执行底层数据中心资源请求的云提供商之间的交互由[云控制器管理器](https://kubernetes.io/docs/concepts/architecture/cloud-controller/)（[cloud-controller-manager](https://github.com/kubernetes/kubernetes/tree/master/cmd/cloud-controller-manager)）处理。由云控制器管理器管理的控制器可以包括路由控制器（用于设置云网络路由）、服务控制器（用于使用云负载均衡服务）和节点生命周期控制器（用于在节点的整个生命周期让节点与 Kubernetes 保持同步）。

#### Worker 节点（数据面板）
<a name="worker-nodes-data-plane"></a>

对于单节点 Kubernetes 集群，工作负载与控制面板在同一台计算机上运行。但是，更标准的配置是拥有一个或多个专门用于运行 Kubernetes 工作负载的独立计算机系统（[节点](https://kubernetes.io/docs/concepts/architecture/nodes/)）。

首次创建 Kubernetes 集群时，您可以使用某些集群创建工具，配置一定数量的节点添加到集群中（通过识别现有的计算机系统或让提供商创建新的计算机系统）。在向这些系统添加任何工作负载之前，向每个节点添加服务以实现以下功能：
+  **管理每个节点 (`kubelet`)** – 此 API 服务器会与每个节点上运行的 [kubelet](https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/) 服务进行通信，以确保节点已正确注册且调度程序请求的容器组正在运行。kubelet 可以读取容器组（pod）清单，并在本地系统上设置容器组（pod）所需的存储卷或其他功能。它还可以检查本地运行的容器的运行状况。
+  **在节点上运行容器（容器运行时）**– 每个节点上的[容器运行时](https://kubernetes.io/docs/setup/production-environment/container-runtimes/)管理分配给节点的每个容器组所请求的容器。这意味着它可以从相应的注册表中拉取容器映像、运行容器、停止容器，并响应有关容器的查询。默认的容器运行时是 [containerd](https://github.com/containerd/containerd/blob/main/docs/getting-started.md)。截至 Kubernetes 1.24，可以用作容器运行时的 Docker (`dockershim`) 的特殊集成已从 Kubernetes 中删除。虽然您仍然可以使用 Docker 在本地系统上测试和运行容器，但要将 Docker 与 Kubernetes 结合使用，您现在必须在每个节点上[安装 Docker 引擎](https://docs.docker.com/engine/install/#server)才能将其与 Kubernetes 结合使用。
+  **管理容器之间的联网 (`kube-proxy`)** – 为了能够支持容器组（pod）之间的通信，Kubernetes 使用一种功能来设置可跟踪与这些容器组（pod）关联的 IP 地址和端口的容器组（pod）网络，此功能称为[服务](https://kubernetes.io/docs/concepts/services-networking/service/)。[kube-proxy](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-proxy/) 服务在每个节点上运行，以允许容器组（pod）之间进行通信。

### 扩展集群
<a name="extend-clusters"></a>

您可以添加一些服务到 Kubernetes 中来支持集群，但不能在控制面板中运行这些服务。这些服务通常直接在 kube-system 命名空间或其自己的命名空间中的节点上运行（就像第三方服务提供商经常做的那样）。一个常见的例子是 CoreDNS 服务，它为集群提供 DNS 服务。有关如何查看集群上的 kube-system 中正在运行哪些集群服务的信息，请参阅[发现内置服务](https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster-services/)。

您可以考虑向集群添加不同类型的附加组件。为了保持集群正常运行，您可以添加使您能够执行日志记录、审计等操作的可观测性功能（请参阅[监控集群性能并查看日志](eks-observe.md)），以及指标。使用这些信息，您就可以对发生的问题进行排查，通常通过相同的可观测性接口排查。这些类型的服务的示例包括 [Amazon GuardDuty](https://docs.amazonaws.cn/guardduty/latest/ug/runtime-monitoring.html)、CloudWatch（请参阅 [使用 Amazon CloudWatch 监控集群数据](cloudwatch.md)）、[适用于 OpenTelemetry 的 Amazon Distro](https://aws-otel.github.io/)、适用于 Kubernetes 的 Amazon VPC CNI 插件（请参阅[使用 Amazon VPC CNI 将 IP 分配给容器组（pod）](managing-vpc-cni.md)）和 [Grafana Kubernetes 监控](https://grafana.com/docs/grafana-cloud/monitor-infrastructure/kubernetes-monitoring/configuration/config-aws-eks/)。对于存储（请参阅[使用集群的应用程序数据存储](storage.md)），相关 Amazon EKS 附加组件包括 Amazon Elastic Block Store CSI 驱动程序（请参阅 [将 Kubernetes 卷存储与 Amazon EBS 结合使用](ebs-csi.md)）、Amazon Elastic File System CSI 驱动程序（请参阅 [将弹性文件系统存储与 Amazon EFS 结合使用](efs-csi.md)）和多种第三方存储附加组件（例如 适用于 NetApp ONTAP 的 Amazon FSx CSI 驱动程序 [将适用于 NetApp ONTAP 的 FSx 与高性能应用程序存储结合使用](fsx-ontap.md)）。

有关可用的 Amazon EKS 附加组件的更完整列表，请参阅 [Amazon EKS 附加组件](eks-add-ons.md)。

## 工作负载
<a name="workloads"></a>

Kubernetes 将[工作负载](https://kubernetes.io/docs/concepts/workloads/)定义为“在 Kubernetes 上运行的应用程序”。该应用程序可以由一组在[容器组（pod）](https://kubernetes.io/docs/reference/glossary/?fundamental=true#term-pod)中作为[容器](https://kubernetes.io/docs/reference/glossary/?fundamental=true#term-container)运行的微服务组成，也可以作为批处理作业或其他类型的应用程序运行。Kubernetes 的作业是确保您为要设置或部署的对象发出的请求得到执行。作为部署应用程序的人，您应该了解容器是如何构建的、容器组（pod）是如何定义的，以及您可以使用哪些方法来部署它们。

### 容器
<a name="containers"></a>

您在 Kubernetes 中部署和管理的应用程序工作负载中最基本的元素是*[容器组（pod）](https://kubernetes.io/docs/concepts/workloads/pods/)*。容器组（pod）代表一种保存应用程序组件以及定义描述容器组（pod）属性的规范的方法。与此形成鲜明对比的是 RPM 或 Deb 软件包，后者将适用于 Linux 系统的软件打包在一起，但其本身并不作为一个实体运行。

由于容器组（pod）是最小的可部署单元，因此它通常只能容纳一个容器。但是，如果容器紧密耦合，则一个容器组（pod）中可以有多个容器。例如，Web 服务器容器可能被打包在带有 [sidecar](https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/) 类型的容器的容器组（pod）中，该容器类型可以提供日志记录、监控或其他与 Web 服务器容器紧密相关的服务。在这种情况下，位于同一容器组（pod）中可确保对于容器组（pod）的每个正在运行的实例，两个容器始终在同一个节点上运行。同样，容器组（pod）中的所有容器共享同一个环境，容器组（pod）中的容器就像在同一个隔离主机中一样运行。这样做的效果是，容器共享一个提供对容器组（pod）的访问权限的 IP 地址，并且容器可以像在自己的本地主机上运行一样相互通信。

容器组（pod）规范（[PodSpec](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec)）定义容器组（pod）的所需状态。您可以通过使用工作负载资源管理[容器组（pod）模板](https://kubernetes.io/docs/concepts/workloads/pods/#pod-templates)来部署单个或多个容器组（pod）。工作负载资源包括[部署](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)（用于管理多个容器组（pod）副本）、[StatefulSets](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/)（用于部署需要具有唯一性的容器组（pod），例如数据库容器组（pod））和 [DaemonSets](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/)（其中容器组（pod）需要在每个节点上持续运行）。稍后会详细介绍。

虽然容器组（pod）是您部署的最小单元，但容器是您构建和管理的最小单元。

#### 构建容器
<a name="building-containers"></a>

容器组（pod）实际上只是围绕一个或多个容器的结构，每个容器本身都包含文件系统、可执行文件、配置文件、库和其他用于实际运行应用程序的组件。由于 Docker Inc. 的公司率先推广了容器，因此也有人将容器称为 Docker 容器。但是，[开放容器计划](https://opencontainers.org/)此后为该行业定义了容器运行时、映像和分发方法。再加上容器是由许多现有的 Linux 功能创建的这一事实，另一些人通常将容器称为 OCI 容器、Linux 容器或仅仅是容器。

当您构建容器时，通常会从 Dockerfile（字面意思）着手开始。在那个 Dockerfile 中，您可以识别：
+  **基础映像** – 基础容器映像是一种容器，通常由操作系统（例如 [Red Hat Enterprise Linux](https://catalog.redhat.com/software/base-images) 或 [Ubuntu](https://gallery.ecr.aws/docker/library/ubuntu)）的最小文件系统版本或经过增强以提供运行特定类型应用程序（例如 [nodejs](https://catalog.redhat.com/software/container-stacks/detail/611c11fabd674341b5c5ed64) 或 [python](https://gallery.ecr.aws/docker/library/python) 应用程序）所需软件的最小系统构建。
+  **应用程序软件** – 您可以将应用程序软件添加到容器中，方法与将其添加到 Linux 系统中的方法大致相同。例如，在您的 Dockerfile 中，您可以运行 `npm` 和 `yarn` 安装 Java 应用程序，或运行 `yum` 和 `dnf` 安装 RPM 软件包。换句话说，在 Dockerfile 中使用 RUN 命令，您可以运行基础映像文件系统中提供的任何命令，以在生成的容器映像中安装软件或配置软件。
+  **指令** – [Dockerfile 参考](https://docs.docker.com/reference/dockerfile/)描述了在配置 Dockerfile 时可以将其添加到 Dockerfile 中的指令。这些指令包括用于构建容器本身（本地系统的 `ADD` 或 `COPY` 文件）中的内容、识别容器运行时要执行的命令（`CMD` 或 `ENTRYPOINT`），以及将容器连接到其运行的系统（通过识别要运行的身份 `USER`、要挂载的本地 `VOLUME` 或要 `EXPOSE` 的端口）的指令。

虽然传统上使用 `docker` 命令和服务来构建容器（`docker build`，但其他可用于构建容器映像的工具包括 [podman](https://docs.podman.io/en/stable/markdown/podman-build.1.html) 和 [nerdctl](https://github.com/containerd/nerdctl)。要了解如何构建容器，请参阅 [Building Better Container Images](https://www.amazonaws.cn/blogs/containers/building-better-container-images)或 [Overview of Docker Build](https://docs.docker.com/build/)。

#### 存储容器
<a name="storing-containers"></a>

构建容器镜像后，可以将其存储在工作站上的容器[分发注册表](https://distribution.github.io/distribution/)或公共容器注册表中。在工作站上运行私有容器注册表可使您在本地存储容器映像，使它们随时可供您使用。

要以更公开的方式存储容器映像，可以将其推送到公共容器注册表。公共容器注册表为存储和分发容器映像提供了一个中心位置。公共容器注册表的示例包括 [Amazon Elastic Container Registry](https://www.amazonaws.cn/ecr/)、[Red Hat Quay](https://quay.io/) 注册表和 [Docker Hub](https://hub.docker.com/) 注册表。

在 Amazon Elastic Kubernetes Service（Amazon EKS）上运行容器化工作负载时，建议您拉取存储在 Amazon Elastic Container Registry 中的 Docker 官方映像的副本。自 2021 年以来，Amazon ECR 一直在存储这些映像。您可以在 [Amazon ECR 公开映像浏览馆](https://gallery.ecr.aws/)中搜索常用容器映像，在 [Amazon ECR Docker 映像浏览馆](https://gallery.ecr.aws/docker/)中搜索 Docker Hub 映像。

#### 正在运行的容器
<a name="running-containers"></a>

由于容器是以标准格式构建的，因此容器可以在任何可运行容器运行时（例如 Docker）且其内容与本地计算机的架构（例如 `x86_64` 或 `arm`）相匹配的计算机上运行。要测试容器或者只是在本地桌面上运行它，您可以使用 `docker run` 或 `podman run` 命令在本地主机上启动容器。但是对于 Kubernetes，每个 Worker 节点都部署了容器运行时，它可以依据 Kubernetes 请求节点运行容器。

将容器分配到某个节点上运行后，该节点将查看节点上是否已存在所请求的容器映像版本。如果没有，则 Kubernetes 告诉容器运行时从相应的容器注册表中拉取该容器，然后在本地运行该容器。请记住，*容器映像*是指在笔记本电脑、容器注册表和 Kubernetes 节点之间移动的软件包。*容器*是指该映像的运行实例。

### 容器组（pod）
<a name="pods"></a>

容器准备就绪后，使用容器组（pod）的操作包括配置、部署和使容器组（pod）可访问。

#### 配置容器组（pod）
<a name="configuring-pods"></a>

当您定义容器组（pod）时，会为其分配一组属性。这些属性必须至少包含容器组（pod）名称和要运行的容器映像。但是，您还需要使用容器组（pod）定义配置许多其他内容（有关可以进入容器组（pod）的内容的详细信息，请参阅 [PodSpec](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec) 页面）。这些方法包括：
+  **存储** – 停止并删除正在运行的容器后，该容器中的数据存储将消失，除非您设置了更持久的存储。Kubernetes 支持许多不同的存储类型，并在[卷](https://kubernetes.io/docs/concepts/storage/volumes/)的保护下对其进行抽象。存储类型包括 [CephFS](https://kubernetes.io/docs/concepts/storage/volumes/#cephfs)、[NFS](https://kubernetes.io/docs/concepts/storage/volumes/#nfs)、[iSCSI](https://kubernetes.io/docs/concepts/storage/volumes/#iscsi) 等。您甚至可以在本地计算机上使用[本地块设备](https://kubernetes.io/docs/concepts/storage/volumes/#local)。使用集群中提供的其中一种存储类型，您可以将存储卷挂载到容器文件系统中的选定挂载点。[永久卷](https://kubernetes.io/docs/concepts/storage/persistent-volumes/)是指删除容器组（pod）后继续存在的卷，而[临时卷](https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/)在容器组（pod）被删除时会被删除。如果集群管理员为集群创建了不同的[存储类](https://kubernetes.io/docs/concepts/storage/storage-classes/)，则可以选择所用存储的属性，例如：卷在使用后是删除还是回收，卷是否会在需要更多空间时扩展，甚至卷是否满足某些性能要求。
+  **密钥**：通过在容器组（pod）规范中向容器提供[密钥](https://kubernetes.io/docs/concepts/configuration/secret/)，您可以提供这些容器访问文件系统、数据库或其他受保护资产所需的权限。密钥、密码和令牌是可以作为密钥存储的项目之一。通过使用密钥，您不必将这些信息存储在容器映像中，而只需要将密钥提供给正在运行的容器即可。与密钥相似的是 [ConfigMaps](https://kubernetes.io/docs/concepts/configuration/configmap/)。`ConfigMap` 往往会保存不太重要的信息，例如用于配置服务的键值对。
+  **容器资源** – 用于进一步配置容器的对象可以采用资源配置的形式。对于每个容器，您可以请求其可以使用的内存和 CPU 量，以及对容器可以使用的资源总量设置限制。有关示例，请参阅[容器组（pod）和容器的资源管理](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/)。
+  **中断** – 容器组可以被非自愿中断（节点关闭），也可以自愿中断（需要升级）。通过配置[容器组（pod）中断预算](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/#pod-disruption-budgets)，您可以在一定程度上控制发生中断时应用程序的可用性。有关示例，请参阅[为您的应用程序指定中断预算](https://kubernetes.io/docs/tasks/run-application/configure-pdb/)。
+  **命名空间** – Kubernetes 提供不同的方法来相互隔离 Kubernetes 组件和工作负载。在同一个[命名空间](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/)中运行特定应用程序的所有容器组（pod）是共同保护和管理这些容器组（pod）的常用方法。您可以创建自己的命名空间以供使用，也可以选择不指定命名空间（这会导致 Kubernetes 使用 `default` 命名空间）。Kubernetes 控制面板组件通常在 [kube-system](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/) 命名空间中运行。

刚才所说的配置通常汇集在要应用于 Kubernetes 集群的 YAML 文件中。对于个人 Kubernetes 集群，您可以将这些 YAML 文件存储在本地系统上。但是，对于更关键的集群和工作负载，[GitOps](https://www.eksworkshop.com/docs/automation/gitops/) 是自动存储和更新工作负载和 Kubernetes 基础设施资源的常用方式。

用于将容器组（pod）信息收集在一起并进行部署的对象由以下部署方法之一定义。

#### 部署 Pod
<a name="deploying-pods"></a>

您为部署容器组（pod）而选择的方法取决于您计划使用这些容器组（pod）运行的应用程序的类型。以下是您的一些选择：
+  **无状态应用程序** – 无状态应用程序不会保存客户端的会话数据，因此另一个会话无需重新引用前一个会话发生的情况。这样一来，能更容易地在容器组（pod）运行不正常时将其替换为新的容器组（pod）或者在不保存状态的情况下移动它们。如果您运行的是无状态应用程序（例如 Web 服务器），则可以使用[部署](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)来部署[容器组（pod）](https://kubernetes.io/docs/concepts/workloads/pods/)和 [ReplicaSets](https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/)。ReplicaSet 定义您想同时运行容器组（pod）的多少个实例。尽管您可以直接运行 ReplicaSet，但通常是在部署中直接运行副本，以定义一个容器组（pod）一次应该运行多少个副本。
+  **有状态应用程序** – 有状态应用程序是看重容器组（pod）的身份和容器组（pod）的启动顺序的应用程序。这些应用程序需要稳定的永久存储，并且需要以一致的方式进行部署和横向缩减。要在 Kubernetes 中部署有状态应用程序，可以使用 [StatefulSets](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/)。通常以 StatefulSet 形式运行的应用程序的一个示例是数据库。在 StatefulSet 中，您可以定义副本、容器组（pod）及其容器、要挂载的存储卷以及容器中存储数据的位置。有关将数据库部署为 ReplicaSet 的示例，请参阅[运行已复制的有状态应用程序](https://kubernetes.io/docs/tasks/run-application/run-replicated-stateful-application/)。
+  **每节点应用程序** – 有时您需要在 Kubernetes 集群中的每个节点上运行应用程序。例如，您的数据中心可能要求每台计算机都运行监控应用程序或特定的远程访问服务。对于 Kubernetes，您可以使用 [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) 确保所选应用程序在集群中的每个节点上运行。
+  **应用程序运行至完成** – 您希望运行一些应用程序来完成特定的任务。这可能包括运行月度状态报告或清理旧数据的应用程序。[Job](https://kubernetes.io/docs/concepts/workloads/controllers/job/) 对象可用于设置应用程序以启动和运行，然后在任务完成后退出。[CronJob](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/) 对象允许您使用由 Linux [crontab](https://man7.org/linux/man-pages/man5/crontab.5.html) 格式定义的结构将应用程序设置为在特定的小时、分钟、一月中的某一天、月份或一周中的某一天运行。

#### 使应用程序可以从网络访问
<a name="making-applications-accessible-from-the-network"></a>

由于应用程序通常部署为一组会移动到不同地方的微服务，因此 Kubernetes 需要一种方法让这些微服务能够找到彼此。此外，为了让其他人访问 Kubernetes 集群之外的应用程序，Kubernetes 需要一种在外部地址和端口上公开该应用程序的方法。这些与联网相关的功能分别通过 Service 和 Ingress 对象完成：
+  **服务**：容器组（pod）可以移动到不同的节点和地址，因此需要与第一个容器组（pod）通信的另一个容器组（pod）可能会很难找到它的位置。要解决此问题，Kubernetes 可以让您将应用程序表示为[服务](https://kubernetes.io/docs/concepts/services-networking/service/)。使用服务，您可以识别具有特定名称的一个容器组（pod）或一组容器组（pod），然后指明哪个端口从容器组（pod）中公开该应用程序的服务，以及其他应用程序可以使用哪些端口来联系该服务。集群中的另一个容器组（pod）只需按名称请求服务，然后 Kubernetes 将该请求定向到运行该服务的容器组（pod）实例的正确端口。
+  **入口** – [入口](https://kubernetes.io/docs/concepts/services-networking/ingress/)让 Kubernetes 服务代表的应用程序可供集群外的客户端使用。Ingress 的基本功能包括负载均衡器（由 Ingress 管理）、Ingress 控制器以及将请求从控制器路由到服务的规则。Kubernetes 中有多个 [Ingress 控制器](https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/)可供选择。

## 后续步骤
<a name="next-steps"></a>

了解基本 Kubernetes 概念及其与 Amazon EKS 的关系将有助于您浏览 [Amazon EKS 文档](https://docs.amazonaws.cn/eks/)和 [Kubernetes 文档](https://kubernetes.io/docs)，以找到您管理 Amazon EKS 集群和向这些集群部署工作负载所需的信息。要开始使用 Amazon EKS，请从以下选项中进行选择：
+  [开始使用 Amazon EKS – `eksctl`](getting-started-eksctl.md) 
+  [创建一个 Amazon EKS 集群。](create-cluster.md) 
+  [在 Linux 上部署示例应用程序](sample-deployment.md) 
+  [组织和监控集群资源](eks-managing.md) 