为生产准备 Google Kubernetes Engine 环境

本解决方案提供了一种蓝图和方法,能够将您的工作负载更安全可靠且经济高效地传入 Google Kubernetes Engine。它提供了为集群配置管理和网络访问权限的指南。本文假定您对 Kubernetes 资源和集群管理有一定的了解,并熟悉 Google Cloud Platform (GCP) 网络功能。

构建项目、虚拟私有云 (VPC) 网络和集群

下图展示了项目、VPC 网络、区域、子网、地区和集群的最佳结构。

项目、网络和集群结构

项目

GCP 在项目实体中创建其所有资源。项目是计费单位,允许管理员将 Cloud Identity and Access Management (Cloud IAM) 角色与用户进行关联。在项目层级应用角色时,角色将应用于项目中封装的所有资源。

您应使用项目来封装各种操作环境。例如,您的运营团队可能拥有处于 productionstaging 阶段的项目,而开发者可能拥有处于 test-dev 阶段的项目。您可以对包含最关键、最敏感的数据和工作负载的项目应用更精细、更严格的政策,同时为 test-dev 环境的开发者应用宽松灵活的政策以便他们开展实验。

集群

一个项目可能包含多个集群。如果要部署多个工作负载,则可以选择为这些工作负载使用单个共享集群或多个单独集群。请参考选择 GKE 集群的大小和范围中的最佳做法,有助于您做出决定。

网络和子网

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

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

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

多地区和区域性集群

默认情况下,集群会在您创建时指定的单个地区中创建其集群主实例和节点。您可以通过创建多地区或区域性集群来提高集群的可用性和灵活性。多地区和区域性集群在一个区域内的多个地区中分布 Kubernetes 资源。

多地区集群:

  • 在一个地区中创建单个集群主实例。
  • 在多个地区中创建节点。

区域性集群:

  • 跨三个地区创建三个集群主实例。
  • 默认情况下在三个地区创建节点,或根据需要在多个地区中创建节点。

区域性集群和多地区集群之间的主要区别在于区域性集群创建三个主实例,而多地区集群仅创建一个主实例。请注意,在这两种情况下,您都需要为跨地区的节点到节点流量付费。

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

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

管理身份和访问权限

项目级层访问权限

上一部分指出您可以在项目级层为用户绑定 IAM 角色。除了为单个用户授予角色之外,您还可以使用来简化角色的应用。

下图为 IAM 政策布局,该布局为 dev 项目(此项目为开发者开发和测试他们即将推出的功能以及修复错误而设),以及 prod 项目(用于处理生产流量)提供了最小权限原则:

Identity and Access Management

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

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

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

dev 项目中,有多个开发者在同一个集群中处理同一个应用。集群用户可以通过创建命名空间来实现此操作。如此一来,每个开发者都可以在自己的命名空间中创建资源,从而避免命名冲突。此外,他们还可以为其部署重复使用相同的 YAML 配置文件,以使开发迭代期间的配置尽可能相似。不仅如此,命名空间还可用于为集群创建 CPU、内存和存储空间配额,确保一个开发者不会在集群中使用太多资源。下一部分介绍限制用户在某些命名空间内进行操作。

RBAC 授权

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

通过 RBAC,集群管理员可以将精细政策应用于其集群中的各个命名空间或整个集群。Kubernetes 命令行界面 kubectl 使用 gcloud 工具的活动凭据,允许集群管理员将角色映射到 GCP 身份(用户和服务帐号)作为 RoleBindings 中的主题。

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

RBAC 授权

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

IAM 角色绑定

Kubernetes 包含一些默认角色,但作为集群管理员,您可以根据组织需求创建自己的角色。下面是一个示例角色,它仅允许用户查看、修改和更新 ConfigMaps,但不允许删除,因为其不包含 delete 动词:

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

定义角色后,可以通过绑定将这些角色应用于集群或命名空间。绑定会将角色与其用户、组或服务帐号进行关联。以下是将我们以前创建的角色 (config-editor) 绑定到 bob@example.org 用户和 development 命名空间的示例。

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: config-editors
  namespace: development
subjects:
- kind: User
  name: bob@example.org
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: config-editor
  apiGroup: rbac.authorization.k8s.io

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

映像访问和共享

Container Registry 中的映像存储在 Cloud Storage 中。本部分介绍共享映像的两种方法。一种方法是公开映像,另一种方法是在项目间共享映像。

公开映像

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

跨项目访问映像

确保 Kubernetes 节点使用服务帐号后,您可以在项目间共享容器映像。与项目关联的默认服务帐号的格式为 [PROJECT_ID]-compute@developer.gserviceaccount.com。拥有此标识符后,您可以在要使用 Container Registry 的项目上以 storage.viewer 的身份为其授予访问权限。但是,请使用具有受限权限的自定义服务帐号,因为默认服务帐号拥有对整个项目的编辑者权限

要为集群使用其他服务帐号,请使用 --service-account 标志在创建集群或节点池时提供该服务帐号。例如,要在项目 my-project 中使用 gke-sa 服务帐号,请执行以下命令:

gcloud container clusters create west --service-account \
  gke-sa@my-project.google.com.iam.gserviceaccount.com

配置网络

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

在同一集群中进行通信

服务发现

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

DNS

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

如果您希望使用服务发现和运行状况监控,但希望 DNS 服务返回 pod 的 IP 而不是虚拟 IP,则可以将 ClusterIP 字段设置为“无”,以将该服务预配为无头服务。在这种情况下,DNS 服务器返回 A 记录列表,此列表将服务的 DNS 名称映射到与服务定义的标签选择器匹配的就绪 pod 的 A 记录。响应中的记录进行轮替以便在各个 pod 上传播负载。但请注意,某些客户端 DNS 解析器可能会缓存 DNS 应答,导致 A 记录轮替无效。如需了解使用 ClusterIP 的优点,请参阅 Kubernetes 文档

无头服务的一个典型使用场景是 StatefulSets。StatefulSets 非常适合运行必须为其副本提供稳定存储空间和网络连接的有状态应用。此类部署预配具有稳定网络标识的 pod,这意味着其主机名可以在集群中进行解析。虽然 pod 的 IP 地址可能会更改,但其主机名 DNS 条目将保持最新且可解析。

数据包流:ClusterIP

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

集群 IP 服务

如需详细了解如何实现服务 IP,请转至 Kubernetes 文档。如需深入了解 GKE 网络,请观看 YouTube 上的 Next 2017 讲座:

无头服务

以下是无头服务的 DNS 响应和流量模式的示例。通过默认 GCP 子网路由表即可路由 Pod IP 地址,并且您的应用可以直接访问该地址。

无头服务的 DNS 响应和流量模式示例

网络政策

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

网络政策是一种深度防御机制,可增强集群上运行的工作负载的安全性。例如,您可以创建网络政策,以确保应用中被破解的前端服务无法直接与低了几个级层的计费或记帐服务进行通信。

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

如需详细了解网络政策,请参阅 GKE 文档

从 Google Cloud Platform 内部连接到 GKE 集群

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

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

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

存根网域

在 Kubernetes 1.6 及更高版本中,您可以配置集群内部 DNS 服务 (kube-dns) 以将特定网域的 DNS 查询转发到外部 DNS 服务器。当您拥有用于查询您的 Kubernetes pod 需要利用的网域的授权 DNS 服务器时,这会非常有用。

外部名称服务

外部名称服务允许您将 DNS 记录映射到集群中的服务名称。在这种情况下,集群内服务的 DNS 查找会返回您选择的 CNAME 记录。如果您只有几条记录需要映射回现有的 DNS 服务,则应使用此方法。

无选择器的服务

您可以创建无选择器的服务,然后手动向其添加端点,以使用正确的值填充服务发现。此方案允许您为集群内的服务使用相同的服务发现机制,同时确保仍可通过 DNS 访问没有服务发现的系统。虽然这种方法最灵活,但从长远来看,它需要最多的配置和维护。

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

接收从互联网到集群的流量

来自互联网的流量可以通过两种不同的方法(即网络负载平衡或 HTTP 负载平衡)定向到您在 Kubernetes 中运行的服务。

应将 Kubernetes 服务创建为 LoadBalancer 类型,以使外部 TCP/UDP 实现负载平衡。Kubernetes 在您的 GCP 项目中创建网络负载平衡器,并将其映射到您的 Kubernetes Engine 集群的节点。这是一种使用最少配置为 TCP 和 UDP 工作负载实现负载平衡的简便方法。网络负载平衡器的范围限制在区域内,因此它只能针对同一区域内运行的 pod 平衡流量。

区域 us-west1 中的网络负载平衡器

对于 HTTP 负载平衡,您应利用 Google 的全局 HTTP 负载平衡器,它可以使用单个任播 IP 地址对多个区域的流量进行负载平衡。在 Kubernetes 中,您可以创建 Ingress 资源,以便将主机名和路径映射到集群中的服务。要使 Ingress 正常运行,必须使用 type: NodePort 创建服务。

在多个区域中实现负载平衡

防火墙

GKE 节点在 Compute Engine 中配置为实例。因此,它们遵循与其他实例相同的有状态防火墙机制。这些防火墙规则通过使用标记在您的网络中应用于实例。每个节点池都会收到一组您可以在规则中使用的标记。默认情况下,属于节点池的每个实例都会收到一个标记,该标记标识此节点池所属的特定 Kubernetes Engine 集群。此标记用于 Kubernetes Engine 自动为您创建的防火墙规则。您可以使用 gcloud 命令行中的 --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 Interconnect 方案可用于连接到本地数据中心。这些方案不是互斥的,因此您可以根据工作负载和需求来组合使用:

  1. 互联网,用于非数据密集型或延迟敏感型工作负载。Google 拥有超过 100 个连接到世界各地服务提供商的接入点 (PoP)。
  2. 直接对等互连,用于需要专用带宽、对延迟时间敏感,且需要访问所有 Google 服务(包括全套 GCP 产品)的工作负载。直接对等互连是第 3 层连接,通过交换 BGP 路由完成,因此需要已注册的 ASN。
  3. 运营商对等互连,与直接对等互连相同,但通过服务提供商完成。如果您没有已注册的 ASN,或者已与偏好的服务提供商建立关系,那么这会是一个绝佳方案。
  4. 如果需要 IPsec 加密,或者希望将专用网络扩展到专用 Compute Engine 网络,则可以通过第 3 层互连和互联网方案(1、2 和 3)来配置 Cloud VPN

后续步骤

  • 试用其他 Google Cloud Platform 功能。查阅我们的教程
此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
解决方案