为生产准备 Google Kubernetes Engine 环境

为生产准备 Google Kubernetes Engine 环境

2024.09.09

本文档介绍如何以更安全可靠、更经济实惠的方式将自己的容器化工作负载添加到 Google Kubernetes Engine (GKE)。它提供了为集群配置管理和网络访问权限的指南。 本文假定您对 Kubernetes 资源和集群管理有一定的了解,并熟悉 Google Cloud 网络功能。

示例架构

下图展示了用于部署 GKE 集群的灵活和高可用性结构示例。

项目

Google Cloud 在项目实体中创建其所有资源。

您可以使用项目表示各种操作环境。例如,您的运营团队可能拥有 production 和 staging 项目,而开发者可能拥有 development 项目。您可以对包含最关键、最敏感的数据和工作负载的项目应用更精细、更严格的政策。然后,您可以为 development 环境中的开发者应用更宽松和灵活的政策进行实验。

集群

一个项目可以包含多个集群。如果要部署多个工作负载,可选择为这些工作负载使用一个共享集群或多个单独集群。

网络和子网

在每个项目中,您可以拥有一个或多个 VPC 网络,这些网络是物理网络的虚拟版本。每个 VPC 网络都是一个全局资源,包含其他与网络相关的资源,例如子网、外部 IP 地址、防火墙规则、路由、VPN 和 Cloud Router。在 VPC 网络中,您可以使用子网(地区性资源)来隔离和控制进出 GKE 集群间每个地区的流量。

每个项目都配有一个默认网络。您可以创建和配置其他网络以映射到现有的 IP 地址管理 (IPAM) 惯例。然后,您可以为此网络应用防火墙规则,以过滤进出 GKE 节点的流量。默认情况下,系统会拒绝进入您的 GKE 节点的所有外部流量。

如需控制子网之间的通信,您必须创建防火墙规则以允许流量在子网之间传递。在集群或节点池创建期间使用 –tags 标志适当地标记 GKE 节点,使防火墙规则生效。如果需要,您还可以使用标记在子网之间创建路由。

地区和集群

您可以创建标准集群和 Autopilot 集群。Autopilot 集群是地区级集群。标准集群是地区级集群或区域级集群。区域级集群可以是单区域集群,也可以是多区域集群。多地区和区域性集群在一个区域内的多个地区中分布资源,从而提高集群的可用性和弹性。

区域级集群具有以下属性:

地区级集群具有以下属性:

您可以在创建集群时选择创建区域级或地区级集群。您也可以将新可用区添加到现有集群,以使其成为多可用区级集群。但是,您无法将现有可用区级集群更改为区域级集群,也无法将区域级集群更改为可用区级集群。

Compute Engine 服务等级协议 (SLA) 涵盖 GKE 管理的集群中节点的服务可用性。

如需详细了解区域级和地区级集群,请参阅 GKE 文档

管理身份和访问权限

Identity and Access Management (IAM) 角色和群组

除了为单个用户授予 IAM 角色之外,您还可以使用来简化角色的应用。

下图是一个 IAM 政策布局,它显示为 dev 项目和 prod 项目提供最小权限原则;其中第一个项目设置供开发者用来开发和测试他们即将推出的功能和问题修复,第二个项目用于处理生产流量:

如下表所示,组织中有 4 组用户,分别具有 2 个项目中不同级别的权限,这些权限通过 IAM 角色授予:

团队IAM 角色项目权限
开发者roles/container.developerdev可以为项目中的现有集群创建 Kubernetes 资源,但不允许创建或删除集群。
运维roles/container.adminprod对项目中运行的集群和 Kubernetes 资源有完整的管理员权限。
安全roles/container.viewer roles/compute.securityAdminprod创建、修改和删除防火墙规则和 SSL 证书,以及查看在每个集群中创建的资源,包括正在运行的 pod 的日志。
网络roles/compute.networkAdminprod创建、修改和删除网络资源,防火墙规则和 SSL 证书除外。

除了有权访问 prod 项目的 3 个团队之外,还有一个额外的服务帐号被授予了 prod 项目的 container.developer 角色,这样,该服务帐号就可以创建、列出和删除集群中的资源。服务帐号可用于为自动脚本或部署框架提供代表您执行操作的能力。 对生产项目和集群的部署应该通过自动化流水线进行。

在 dev 项目中,有多个开发者在同一个集群中处理同一个应用。集群用户可以通过创建命名空间来实现此操作。如此一来,每个开发者都可以在自己的命名空间中创建资源,从而避免命名冲突。此外,他们还可以为其部署重复使用相同的 YAML 配置文件,以使开发迭代期间的配置尽可能相似。

不仅如此,命名空间还可用于为集群创建 CPU、内存和存储空间配额,确保一个开发者不会在集群中使用太多资源。如需详细了解如何使用命名空间,请参阅 Kubernetes 最佳做法:在 YAML 中指定命名空间

下一部分介绍对用户在某些命名空间中的操作实施的限制。

基于角色的访问权限控制

运行 Kubernetes 1.6 及更高版本的 GKE 集群可采用进一步的措施来限制用户在各集群中有权执行的操作。IAM 可以为用户提供对完整集群及其中资源的访问权限,但通过 Kubernetes 基于角色的访问权限控制 (RBAC),您可使用 Kubernetes API 进一步限制用户在其集群中可执行的操作。

通过 RBAC,集群管理员可以将精细政策应用于其集群中的各个命名空间或整个集群。Kubernetes kubectl 工具使用 gcloud CLI 中的有效凭据,使集群管理员能够将角色映射到 Google Cloud 身份(用户、服务帐号和 Google 群组)作为 RoleBinding 中的主体。

借助 Google RBAC 群组,您可以将群组与 Kubernetes RBAC 搭配使用。要使用此功能,您必须配置 Google 工作区 Google 群组,创建启用了该功能的集群,然后使用 RoleBinding 将您的群组与您要将它们绑定到的角色相关联。如需了解详情,请参阅基于角色的访问权限控制

例如,下图中有两名用户 user-a 和 user-b,他们已在 app-a 命名空间中被授予 config-reader 和 pod-reader 角色。

还有一个例子是 Google Cloud 项目级的 IAM 角色,它使特定用户能够访问项目中的所有集群。此外,通过 RBAC 添加单独的命名空间和集群级层角色绑定,可以实现对特定集群或命名空间内的资源的精细访问。

Kubernetes 包含一些默认角色,但作为集群管理员,您可以自行创建与您组织的需求更加贴合的角色。以下示例角色仅允许用户查看、修改和更新 ConfigMap,但由于不包含 delete 谓词,因此禁止删除:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: config-editor
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list", "watch", "create", "update", "patch"]

定义角色后,可以通过绑定将这些角色应用于集群或命名空间。绑定会将角色与其用户、组或服务帐号进行关联。以下示例展示了如何将先前创建的角色 (config-editor) 绑定到 [email protected] 用户和 development 命名空间。

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: config-editors
  namespace: development
subjects:
- kind: User
  name: [email protected]
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: config-editor
  apiGroup: rbac.authorization.k8s.io

如需详细了解 RBAC,请参阅 GKE 文档

映像访问和共享

Container RegistryArtifact Registry 中的映像存储在 Cloud Storage 中。

本部分介绍共享映像的以下方法:

注意:由于 Artifact Registry 是管理容器映像的推荐服务,因此本文档中的以下部分将仅重点介绍 Artifact Registry。

如果启用了专用集群,则使用 Artifact Registry 非常重要。在专用集群中,除非您设置 Cloud NAT,否则集群的容器运行时无法直接从外部容器注册表中拉取容器映像。容器运行时可以从专用集群中的 Artifact Registry 中拉取映像,而无需 Cloud NAT 或专用 Google 访问通道。如果节点需要直接与 Artifact Registry 通信(例如,节点需要创建新工件并将其存储在 Artifact Registry 中),则必须将节点放置在启用了专用 Google 访问通道的子网中。如需了解详情,请参阅从映像注册表中拉取容器映像

在 Artifact Registry 中公开映像

您可以通过在 Artifact Registry 中公开其对象和存储分区来公开映像。如需了解详细说明,请参阅 Artifact Registry 访问权限控制文档

如果必须使用公共映像,请考虑验证可部署到集群中的公共映像集。(如需了解详情,请参阅 Binary Authorization 部分。)

在 Artifact Registry 中跨项目访问映像

确保 Kubernetes 节点使用服务帐号后,您可以在项目间共享容器映像。您可以向服务帐号授予访问权限作为astorage.viewer使用 Artifact Registry 的项目。使用具有受限权限的自定义服务帐号,因为默认服务帐号对整个项目拥有 Editor 访问权限

如需为集群使用其他服务帐号,请在创建集群或节点池时使用 –service- account 标志提供服务帐号。

如需了解详情,请参阅配置访问权限控制

确定正确的映像拉取政策

Kubernetes 中的 imagePullPolicy 属性确定 kubelet 是否会在启动 pod 时尝试拉取映像。配置适当的 imagePullPolicy 设置,以指定容器映像。例如,您可以指定以下映像拉取政策:

imagePullPolicy: IfNotPresent

在这种情况下,Kubelet 仅当映像在节点的缓存中不可用时才检索映像的副本。

如需详细了解您可以指定的潜在映像拉取政策,请参阅 Kubernetes 文档中的容器映像

使用动态管理控制器来强制执行政策

动态准入控制器是 Kubernetes 控制平面的一部分。它们可以拦截向 API 服务器发出的传入请求。准入控制器是一款强大的工具,可帮助您在 GKE 集群中强制执行特定于企业的自定义政策。

Kubernetes 支持两种类型的准入控制器:更改准入控制器和验证准入控制器。

更改准入控制器会拦截准入请求,并且会更改请求。然后将请求传递到 API 服务器。

验证准入控制器可以检查请求,并根据您指定的规则确定请求是否有效。如果在集群中配置任何验证准入控制器,则会在 API 服务器验证请求后调用它们。验证准入控制器可以拒绝请求,以确保符合控制器中定义的政策。

例如,您可使用更改准入控制器来强制实时映像拉取政策,确保无论提交 pod 创建请求的开发者指定的 imagePullPolicy 设置如何,该政策均设置为 Always。

使用 Google Cloud Marketplace 中的预封装应用

您还可以考虑从 Google Cloud Marketplace 部署预封装的 Kubernetes 应用。Google Cloud Marketplace 上列出的 Kubernetes 应用已经过 Google 测试和审核,其中包括适用于维护和支持的漏洞扫描以及合作伙伴协议。

此外,请务必采用良好的映像版本控制做法:使用良好的标记惯例,并在适用的情况下考虑使用摘要(而不是标记)。

使用 Workload Identity 与 Google Cloud 服务 API 进行交互

通常,企业架构涉及跨云服务(云代管式服务和托管式服务)的架构组件。它是 GKE 应用或服务与 Google Cloud 代管式服务(如 Cloud Storage 和 BigQuery)通信的常用模式。例如,在通过 GKE 中的批量作业将客户记录处理到 BigQuery 中供后续分析之后,您可能需要存储这些记录。

Workload Identity 允许 GKE 集群中的 Kubernetes 服务帐号充当 IAM 服务帐号。访问 Google Cloud API 时,使用已配置 Kubernetes 服务帐号的 Pod 会自动作为 IAM 服务帐号进行身份验证。请注意,这假设您已授予访问 Google Cloud 服务帐号所需的服务访问权限级别。

管理集群安全

安全是一项多方面的准则,在 GKE 集群的企业部署中至关重要。本部分介绍了可用于强化集群安全的几个因素。

映像的漏洞扫描

Artifact Registry 可以扫描映像中是否存在已知的安全漏洞。支持的映像包括 Ubuntu、Debian、RedHat 等(如需查看完整列表,请参阅漏洞来源)。我们建议您扫描您计划在 GKE 集群中使用的映像。

如果可能,请启用 Container Analysis,以进一步降低安全风险。

如需查看映像的漏洞,请参阅自动扫描映像

如果对 Artifact Registry 代码库进行更改,您的组织将能够从自动跟踪通知和接收通知中受益。例如,您可以在创建新映像或删除映像时收到通知。您可以构建流水线,其中应用侦听器可订阅 Artifact Registry 事件发布到的 Pub/Sub 主题。然后,您可以使用这些事件触发构建或自动部署。如需了解详情,请参阅 Artifact Registry 文档

Binary Authorization

使用 Kubernetes 时,您必须确定映像是否应以及何时可用于部署到集群。对于此任务,您可以使用 Binary Authorization。这是一种部署时构造,它让您定义一个工作流,该工作流必须强制执行签名,才能为您的集群部署签名(证明)。

工作流根据政策进行定义。当您通过 CI/CD 流水线移动代码并因此移动容器映像时,Binary Authorization 会对 Binary Authorization 政策中定义的每个阶段记录证明。这些证明用于验证映像已成功传递定义的里程碑。

Binary Authorization 与 GKE 部署 API 集成,并可确保映像的部署受拥有全部所需证明的映像的约束。系统会自动记录失败的部署尝试,而且集群管理员可以查看和审核。

如需查看教程了解如何使用 Cloud Build 为 GKE 实现 Binary Authorization,请参阅使用 Cloud Build 和 GKE 实现 Binary Authorization

在 GKE Sandbox 中使用 gVisor 安全访问

容器有一层安全和内核隔离,但可能仍然容易遭到攻击,进而导致攻击者获得对主机操作系统 (OS) 的访问权限。要在容器与其主机操作系统之间实现安全隔离,更灵活的一种方法是另外创建一个分离层。一种方法是使用 GKE Sandbox

GKE Sandbox 使用 gVisor,它是 Google 发布的开源容器运行时。gVisor 在内部创建容器与之互动的虚拟内核,即可抽象出容器与主机内核的覆盖率。此外,它还控制容器可以执行的文件操作和网络操作。

由于 GKE Sandbox 会产生额外的隔离层,因此可能会需要额外的内存和产生额外的 CPU 开销。在使用 GKE Sandbox 之前,请考虑哪些工作负载需要这种高级别的安全措施。通常情况下,最好选择基于外部映像的服务。

如需了解如何创建启用了 GKE 的节点池,请参阅使用 GKE Sandbox 强化工作负载隔离

审核日志记录

Kubernetes 审核日志记录会记录对 Kubernetes API 服务器发出的所有 API 请求。此日志记录有助于您检测异常情况以及异常的访问和配置设置模式。以下是您可能想要查看和提醒的示例:

GKE 将 Kubernetes 审核日志记录与 Cloud Audit LogsCloud Logging 集成。访问这些日志的方式与访问 Cloud 项目中运行的资源的日志的方式相同。可以记录向 Kubernetes API 服务器发出的 API 请求,您可以使用这些请求来查看 API 活动模式。

Kubernetes API 服务器捕获的每个请求(事件)都会使用您定义的一个或多个政策进行处理。这些政策可以是 Kubernetes 审核政策(确定记录哪些事件),也可以是 Google Kubernetes Engine 审核政策(确定事件是记录在管理员活动日志中还是记录在数据日志中)。管理员活动日志默认启用。如果需要记录有关集群中读取或写入的元数据和数据的详细信息,您还可以启用数据访问日志记录。请注意,启用数据访问日志记录可能会产生额外费用。如需了解详情,请参阅价格文档。

Pod 安全政策

一种常见的攻击途径是部署拥有已升级特权的 pod 来试图访问 Kubernetes 集群。Gatekeeper 是一种准入控制器,它使用的政策概述了 Pod 可执行的操作。您可以使用它来限制对命名空间的使用方式、卷类型的使用方式以及底层操作系统功能的访问权限。

容器安全注意事项

Kubernetes 服务的基础构件是容器。这使得容器安全在规划集群安全和政策时成为关键因素。请仔细注意下列各项:

如需了解详情和最佳做法,请参阅构建操作容器的文档。

配置网络

Kubernetes 提供了服务抽象,其中包含集群内多组 pod 以及集群外运行的旧系统之间的负载平衡和服务发现。以下部分介绍了在 Kubernetes pod 之间以及与其他系统(包括其他 Kubernetes 集群)之间进行通信的最佳做法。

VPC 原生集群与基于路由的集群的对比

根据 GKE 集群将流量从一个 pod 路由到另一个 pod 的方式,这些集群可以分为两类。

VPC 原生集群使用 pod 网络的别名 IP 地址范围。这意味着控制平面会自动管理 pod 的路由配置,而不是为 GKE 集群中的每个节点配置和维护静态路由。借助别名 IP 地址范围,您可以配置多个内部 IP 地址来表示虚拟机中托管的容器或应用,无需定义单独的网络接口。Google Cloud 将自动安装 VPC 网络路由,以便为主要网络接口的子网获得主要和别名 IP 地址范围。这大幅简化了 pod 之间的流量路由。

此外,VPC 原生集群不受路由配额的限制。在集群结构中利用别名 IP 地址范围可直接访问 Google 服务,例如 Cloud Storage 和 BigQuery;否则,只能通过 NAT 网关进行访问。

让 GKE 集群与本地的应用和服务生态系统安全地通信是企业采用的一种常见模式。别名 IP 地址范围允许这样做,因为别名 IP 地址可以通过 Cloud VPNCloud Interconnect 发现。这有助于为您的本地基础架构和 Google Cloud 基础架构提供安全连接。

您需要确定哪种集群类型最适合您的网络拓扑。主要因素是网络中 IP 地址的可用性、企业中的集群(节点)扩展计划,以及与生态系统中其他应用的连接性。VPC 原生集群在网络中往往会消耗更多的 IP 地址,因此您应考虑到这一点。请注意,您无法在创建并将基于路由的集群迁移到 VPC 原生集群后再将 VPC 原生集群迁移到基于路由的集群,因此请务必了解所选选项的影响,然后再实现它。

控制平面访问的授权网络

授权网络选项限制从您指定的 CIDR 范围访问控制层面端点(API 服务器),并确保只有您网络中的团队才能管理您的集群。

这些功能具有以下要求:

专用集群

默认情况下,GKE 集群中的所有节点都具有公共 IP 地址。一个好的做法是创建专用集群,使所有工作器节点仅获得专用 RFC 1918 IP 地址。专用集群会强制执行网络隔离,从而降低集群面临的风险。使用专用集群意味着在默认情况下,只有网络中的客户端才能访问集群中的服务。为了允许外部服务访问集群中的服务,您可以使用 HTTP(S) 负载均衡器或网络负载均衡器。

如果要开放对 VPC 网络外部控制层面的访问权限,您可以将专用集群用于已获授权的网络。启用授权网络后,集群控制层面端点将获得两个 IP 地址:一个内部(专用)地址和一个公共地址。内部 IP 地址可供同一地区中您网络内部的任何内容使用。控制平面的公共 IP 地址可供您网络外部的任何用户或进程使用,这些用户或进程来自允许的 CIDR 范围或 IP 地址。您还可以将此功能与 Cloud Interconnect 或 Cloud VPN 结合使用,以便仅从私有数据中心访问控制平面。

数据渗漏防护

此外,您还可以使用 VPC Service Controls 来帮助降低数据渗漏的风险。通过 VPC Service Controls,可定义用于访问这些服务的服务边界,从而帮助您保护一个或多个项目中的代管式 Google Cloud 服务。您可以设置适当的访问权限级别,向 GKE 集群中运行的应用授予访问这些代管式服务的权限。您还可以使用 VPC Service Controls 来保护 GKE 集群创建控制平面。

在同一集群中进行通信

服务发现

Kubernetes 允许您根据一组标签来定义对集群中运行的 pod 分组的服务。使用 DNS 可以在集群中发现此组 pod。如需详细了解 Kubernetes 中的服务发现,请转至连接应用和服务文档。

DNS

本地集群 DNS 服务器 kube-dns 部署在每个 GKE 集群中,用于将服务名称映射到运行状况良好的 pod IP 地址。默认情况下,Kubernetes DNS 服务器返回服务的集群 IP 地址。 此 IP 地址在服务的整个生命周期内是静态的。向此 IP 地址发送流量时,节点上的 iptables 将在与服务选择器匹配的就绪 pod 中对数据包进行负载均衡。这些 iptables 由每个节点上运行的 kube-proxy 服务自动编写。

如需详细了解 kube-dns,请参阅服务发现和 DNS。 如需了解扩缩,请参阅 DNS 扩缩

数据包流:ClusterIP

下图展示了标准 Kubernetes 服务的 DNS 响应和数据包流。虽然 pod IP 地址可从集群外部路由,但服务的集群 IP 地址只能在集群中访问。这些虚拟 IP 地址通过在每个 Kubernetes 节点中执行目的网络地址转换 (DNAT) 来实现。 在每个节点上运行的 kube-proxy 服务使每个节点上的转发规则保持最新,以将集群 IP 地址映射到集群中运行状况良好的 pod 的 IP 地址。如果本地节点上运行了该服务的 pod,则使用该 pod,否则将随机选择集群中的某个 pod。

如需详细了解如何实现 ClusterIP,请转到 Kubernetes 文档

无头服务

如果您要使用服务发现和运行状况监控,但却要 DNS 服务返回 pod 的 IP 地址而不是虚拟 IP 地址,您可将 ClusterIP 字段设置为 None,这会将该服务预配为无头服务。

在这种情况下,DNS 服务器返回 A 记录列表,此列表将服务的 DNS 名称映射到与服务定义的标签选择器匹配的就绪 pod 的 A 记录。响应中的记录进行轮替以便在各个 pod 上传播负载。但请注意,某些客户端 DNS 解析器可能会缓存 DNS 应答,导致 A 记录轮替无效。如需了解使用 ClusterIP 的优点,请参阅 Kubernetes 文档。如需详细了解如何在 GKE 中使用 ClusterIP,请参阅使用 Service 公开应用

无头服务的一个典型使用场景是 StatefulSets。StatefulSets 非常适合运行必须为其副本提供稳定存储空间和网络连接的有状态应用。此类部署预配具有稳定网络标识的 pod,这意味着其主机名可以在集群中进行解析。虽然 pod 的 IP 地址可能会更改,但其主机名 DNS 条目会保持最新且可解析。 以下是无头服务的 DNS 响应和流量模式的示例。通过默认 Google Cloud 子网路由表即可路由 Pod IP 地址,您的应用还可直接访问这些地址。

网络政策

您可以使用 GKE 网络政策强制执行功能来控制集群的 pod 与 Service 之间的通信。要在 GKE 上定义网络政策,可以使用 Kubernetes Network Policy API 创建 Pod 级层的防火墙规则。这些防火墙规则确定了哪些 pod 和 Service 可以在集群内相互访问。

网络政策可增强集群上运行的工作负载的安全性。例如,您可以创建网络政策,以确保应用中受侵的前端服务无法直接与低了几个级层的结算或记帐服务进行通信。

您还可以使用网络政策来隔离属于不同租户的工作负载。例如,您可以通过定义一个模型,使每个命名空间都有一个租户,来提供安全的多租户。在此类模型中,网络政策规则可确保给定命名空间中的 Pod 和服务无法访问其他命名空间中的其他 Pod 或服务。

从 Google Cloud 内部连接到 GKE 集群

如需从集群外部但在 Google Cloud 网络的专用 IP 地址空间内连接到您的服务,请使用内部负载均衡。在 Kubernetes 中创建具有 type: Load Balancer 和 cloud.google.com/load-balancer-type: Internal 注释的服务时,系统会在您的 Google 项目中创建内部网络负载平衡器,并将其配置为在 pod 之间分配 TCP 和 UDP 流量。

从集群内部连接到外部服务

在许多情况下,有必要将在 Kubernetes 内运行的应用与集群外部的服务、数据库或应用连接起来。您有 3 种选择,如以下部分所述。

选项说明
存根网域在 Kubernetes 1.6 及更高版本中,您可以配置集群内部 DNS 服务 (kube-dns) 以将特定网域的 DNS 查询转发到外部 DNS 服务器。如果您拥有授权 DNS 服务器,并应从中查询 Kubernetes pod 必须使用的网域时,这会非常有用。
外部名称服务外部名称服务允许您将 DNS 记录映射到集群中的服务名称。在这种情况下,集群内服务的 DNS 查找会返回您选择的 CNAME 记录。如果您只有几条记录需要映射回现有的 DNS 服务,请使用此方法。
无选择器的服务您可以创建无选择器的服务,然后手动向其添加端点,以使用正确的值填充服务发现。此方案允许您为集群内的服务使用相同的服务发现机制,同时确保仍可通过 DNS 访问没有服务发现的系统。虽然这种方法最灵活,但从长远来看,它需要最多的配置和维护。

如需详细了解 DNS,请转到 Kubernetes DNS Pod 和服务文档页面。

在 Kubernetes 中配置服务以接收互联网流量

您可以使用 NodePort、ClusterIP 和 LoadBalancer 公开 Kubernetes 服务。

但是,如果您有许多面向外部的服务,则可以考虑使用 Kubernetes Ingress 资源。Ingress 为集群提供了入口点,并允许您定义路由规则,以将传入请求路由到集群中的一个或多个后端服务。在 GKE 中,GKE Ingress 控制器将 Ingress 资源实现为 Google Cloud HTTP(S) 负载均衡器,并根据 Ingress 资源及其关联服务中的信息对其进行配置。 如需了解详情,请参阅配置 Ingress 以进行外部负载均衡

只有在应用通过 HTTP(S) 处理流量时,才能使用 Kubernetes Ingress 资源。如果后端服务使用 TCP 或 UDP 协议,则必须改为使用网络负载平衡器。例如,如果您需要将数据库作为服务公开,可能就需要这样做。

后端配置

BackendConfig 是一种自定义资源定义,可以提供 Kubernetes Ingress 控制器使用的其他规范配置。在 GKE 集群中部署 Ingress 对象时,Kubernetes Ingress 控制器将配置 HTTP(S) 负载平衡器,以便将传入请求路由到您在 Ingress 清单中指定的后端服务。 您可以使用如下规范补充负载平衡器的配置:

如需详细了解如何在 GKE 中配置 BackendConfig 自定义资源,请参阅 Ingress 功能

使用服务网格

服务网格提供了一种统一的方式来连接、保护和管理 Kubernetes 集群中运行的微服务。例如,您可作为 GKE 插件添加的 Istio 服务网格可以管理服务到服务的身份验证和通信、强制执行访问政策,还能收集可用于审核和管理 GKE 集群的丰富的遥测数据点。

服务网格提供的主要功能包括:

总之,通过 Istio 等服务网格,您可以将系统级任务委托给网格基础架构,这有助于提高 Kubernetes 集群中运行的服务的整体敏捷性、稳健性以及松散耦合。

如需了解如何将服务网格与 Anthos 搭配使用,请参阅关于 Anthos Service Mesh

防火墙

GKE 节点在 Compute Engine 中配置为实例。因此,它们遵循与其他实例相同的有状态防火墙机制。这些防火墙规则通过使用标记在您的网络中应用于实例。每个节点池都将收到自己的一组标记,你可在规则中使用这些标记。默认情况下,属于节点池的每个实例都会收到一个标记,该标记标识此节点池所属的特定 Kubernetes Engine 集群。此标记用于 Kubernetes Engine 自动为您创建的防火墙规则。您可以使用 gcloud CLI 中的 –tags 标志在创建集群或节点池时添加自己的自定义标记。 例如,如需允许内部负载平衡器访问所有节点上的端口 8080,您可以使用以下命令:

gcloud compute firewall-rules create allow-8080-fwr \
    --target-tags allow-8080 \
    --allow tcp:8080 \
    --network gke \
    --source-range 130.211.0.0/22
gcloud container clusters create my-cluster --tags allow-8080

以下示例展示如何标记一个集群,以使互联网流量能够访问端口 30000 上的节点,同时另一集群被标记为允许来自 VPN 的流量访问端口 40000。当通过只能使用特权网络(如访问公司数据中心的 VPN)或从项目中的其他集群进行访问的 NodePort 公开服务时,这会非常有用。

连接到本地数据中心

您可以使用 Cloud InterconnectCloud VPN 连接到本地数据中心。这些方案不是互斥的,因此您可以根据工作负载和需求来组合使用:相关选项如下所示:

管理集群可操作性

本部分介绍在管理和操作 GKE 集群时需要考虑的关键因素。

资源配额

Kubernetes 资源配额提供的限制条件会限制集群中每个命名空间的总体允许资源消耗量。如果您的集群具有隔离业务功能或开发阶段的 Kubernetes 命名空间,则可以使用配额来限制各种资源,例如 CPU 利用率、内存或可在命名空间内创建的 pod 数量和服务数量。为了确保 GKE 集群的控制平面的稳定性,Kubernetes 会自动将默认的不可替换的资源配额应用于任何具有 5 个或更少节点的 GKE 集群中的每个命名空间。

资源限制

您可以使用 Kubernetes LimitRange 对象对创建容器和 pod 的最小和最大资源边界实施精细限制。以下示例展示了如何使用 LimitRange:

apiVersion: v1
kind: LimitRange
metadata:
  name: sample-limits
spec:
  limits:
    - max:
        cpu: "400m"
        memory: "1Gi"
      defaultRequest:
        cpu: "200m"
        memory: "500Mi"
      type: Container

Pod 中断预算

Pod 中断预算 (PDB) 有助于防止您的团队自愿删除或意外删除 pod 或部署。PDB 无法防止由节点关闭或重启而导致的非自愿中断。通常,操作员为应用创建一个 PDB,用于定义应用的 pod 的最小副本数。

如果在某家企业中开发者要处理多个应用,那么错误不可避免,而且开发者或管理员可能会意外运行用于删除 pod 或部署(也就是删除 Kubernetes 资源)的脚本。但是,通过定义 PDB,您可以始终确保为 Kubernetes 应用维持一组最低限度的有效资源。

GKE 升级期间会采用您为 GKE 集群配置的 PDB。这意味着,您可以在升级期间控制应用的可用性。以下示例展示了如何配置 PDB。

apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
  name: nginx-pdb
  spec:
    minAvailable: 4
    selector:
      matchLabels:
        app: nginx

管理 Kubernetes 升级

将 GKE 上的 Kubernetes 集群更新为符合您要求的最新版的 Kubernetes。您可以选择自动升级控制层面或节点,也可以自行控制升级。

您可以在控制台、Anthos 安全公告集群升级通知中查看升级通知。如果您要手动升级节点,我们建议您在查看发布内容并在沙盒化的运行集群中测试应用后,触发版本升级。

当区域级集群的控制层面正在进行升级时,它不可用。这意味着您无法与 API 服务器进行互动来在集群中添加或移除资源。如果您无法忍受升级控制层面的停机时间,则可以通过部署地区性 GKE 集群来使控制层面具有高可用性。通过这种方法,您可以跨区域分布多个控制平面。当一个控制层面升级时,对 API 服务器的任何控制层面请求都会路由到其他控制层面。

当应用升级时,GKE 都会对工作器节点应用滚动更新:当有新的替换节点可用于响应传入的请求时,它会系统地排空、关闭和升级一个节点。

节点自动修复

GKE 节点自动修复功能用于管理 GKE 节点的健康检查。如果发现任何节点运行状况不佳,GKE 会启动节点修复进程。

如果您的 GKE 集群具有多个节点池,则自动修复功能可让您精确控制要为其启用节点自动修复功能的节点池。

自动扩缩 GKE 集群

对于在其 Kubernetes 集群中运行的应用,企业经常会遇到不同的传入负载。为了响应这些业务驱动的更改,您可以使 GKE 集群能够自动做出响应,并根据指标进行扩缩。

自动扩缩包括多个维度,如以下几个部分所述。

集群自动扩缩器

GKE 集群自动扩缩器会根据您的工作负载需求自动添加和移除集群节点。为单个节点池启用集群自动扩缩器。对于每个节点池,GKE 会检查是否有由于容量不足而等待调度的 pod。如果有,集群自动扩缩器会将节点添加到该节点池中。

集群自动扩缩程序会根据资源请求进行扩缩。如果节点利用率过低,并且正在运行的 pod 可被安排到具有容量的其他节点上,则利用率低下的节点会被排空并终止。

通过指定集群自动扩缩器可调节到的最小和最大节点数,您可以为节点池设置边界。

节点自动预配

通过节点自动预配功能,GKE 集群自动扩缩器能够在自动扩缩器确定需要其他节点池时自动预配这些节点池。如果这些节点池中没有节点,集群自动扩缩器也可以删除自动预配的节点池。

GKE 集群自动扩缩器会根据许多因素做出节点自动预配决策。这些因素包括 pod 请求的资源数量、您已指定的 pod 亲和性,以及 GKE 集群中定义的节点污点和容忍机制

如果您的 GKE 集群中运行各种工作负载,则节点自动预配功能非常有用。例如,如果您的 GKE 集群具有依赖于 GPU 的工作负载,则您可以在预配了支持 GPU 的节点的专用节点池中运行该集群。您可以指定最小和最大节点池大小来定义节点池扩缩边界。

如需详细了解节点自动预配功能以及启用时机,请参阅使用节点自动预配

Pod 横向自动扩缩

借助 Kubernetes,您可以创建横向 Pod 自动扩缩器,用于配置 Kubernetes 部署或 ReplicaSet 扩缩的方式以及扩缩决策应依据的指标。默认情况下,Pod 横向自动扩缩程序控制器根据 CPU 利用率作出自动扩缩决策。但是,Pod 横向自动扩缩程序控制器还可以根据自定义指标(例如 HTTP 请求数)来计算 pod 应该如何扩缩。要让横向 Pod 自动扩缩程序响应自定义指标,通常还需要其他监控插桩。

如需了解详情,请参阅 KubernetesGKE 文档。

Pod 纵向自动扩缩

借助 GKE 集群中的纵向 Pod 自动扩缩 功能,您可将为容器指定最佳 CPU 和内存请求的任务进行分流。必要时,Pod 纵向自动扩缩功能会调整对集群中容器的资源分配量。通过 Pod 纵向自动扩缩功能,您可以在每个节点的容器级层进行优化,从而优化集群的资源利用率。此外,这还将为您节省维护资源所需的管理时间。

Pod 纵向自动扩缩功能与下一部分中介绍的节点自动预配功能配合使用。

由于 Kubernetes 的限制,pod 上的资源请求只能在 pod 重启时更改。因此,要进行更改,Pod 纵向自动扩缩会逐出 Pod。如需了解详情,请参阅 GKEKubernetes 文档。

Autopilot

Autopilot 表示 GKE 代表您预配和管理集群的底层基础架构。使用 Autopilot 时管理以下项:

如果您要减少操作负载,并且不需要为更复杂的工作负载配置特定项,则 Autopilot 非常有用。

相關文章