将 Public NAT 与 GKE 搭配使用

本页介绍如何使用 Google Kubernetes Engine (GKE) 配置示例 Public NAT 设置。在设置 Public NAT 之前,请先阅读 Public NAT 概览

前提条件

在设置 Public NAT 之前,您需要执行以下操作。

获取 IAM 权限

通过 roles/compute.networkAdmin 角色,您有权在 Cloud Router 路由器上创建 NAT 网关、预留和分配 NAT IP 地址,以及指定哪些子网的流量应该使用 NAT 网关的网络地址转换。

设置 Google Cloud

开始之前,请先在 Google Cloud 中设置以下内容。

  1. 登录您的 Google Cloud 账号。如果您是 Google Cloud 新手,请创建一个账号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  3. 确保您的 Google Cloud 项目已启用结算功能

  4. 安装 Google Cloud CLI。
  5. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  6. 在 Google Cloud Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目

    转到“项目选择器”

  7. 确保您的 Google Cloud 项目已启用结算功能

  8. 安装 Google Cloud CLI。
  9. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init

设置 GKE 示例

如果您想查看使用 GKE 的简单 Public NAT 配置,请使用此示例。

第 1 步:创建 VPC 网络和子网

如果您已有网络和子网,则可以跳过此步骤。

控制台

  1. 在 Google Cloud 控制台中,转到 VPC 网络页面。

    转到“VPC 网络”页面

  2. 点击创建 VPC 网络

  3. 输入 custom-network1 作为名称

  4. 子网下,将子网创建模式设置为自定义

  5. 新子网下,输入 subnet-us-east-192 作为名称

  6. 地区中,选择 us-east4

  7. 输入 192.168.1.0/24 作为 IP 地址范围

  8. 点击完成,然后点击创建

gcloud

  1. 在项目中创建新的自定义模式 Virtual Private Cloud (VPC) 网络:

    gcloud compute networks create custom-network1 \
        --subnet-mode custom

    输出:

    NAME             MODE     IPV4_RANGE   GATEWAY_IPV4
    custom-network1  custom

  2. 为第一个地区指定子网前缀。在本例中,我们为地区 us-east4 分配了 192.168.1.0/24

    gcloud compute networks subnets create subnet-us-east-192 \
       --network custom-network1 \
       --region us-east4 \
       --range 192.168.1.0/24

    输出:

    NAME                REGION    NETWORK          RANGE
    subnet-us-east-192  us-east4  custom-network1  192.168.1.0/24

Terraform

您可以使用 Terraform 模块来创建自定义虚拟私有云网络和子网。

module "test-vpc-module" {
  source       = "terraform-google-modules/network/google"
  version      = "~> 9.0"
  project_id   = var.project_id # Replace this with your project ID in quotes
  network_name = "custom-network1"
  mtu          = 1460

  subnets = [
    {
      subnet_name   = "subnet-us-east-192"
      subnet_ip     = "192.168.1.0/24"
      subnet_region = "us-east4"
    }
  ]
}

第 2 步:创建专用集群

控制台

  1. 在 Google Cloud Console 中,转到 Kubernetes 集群页面。

    转到“Kubernetes 集群”页面

  2. 点击创建集群

  3. 对于名称,输入 nat-test-cluster

  4. 位置类型设置为区域

  5. 区域设置为 us-east4-c

  6. 在导航窗格中,点击网络

  7. 选择专用集群

  8. 取消选中使用外部 IP 地址的控制平面复选框。

  9. 输入 172.16.0.0/28 作为控制层面 IP 地址范围

  10. 网络设置为 custom-network1

  11. 要创建并启动该集群,请点击创建

gcloud

gcloud container clusters create "nat-test-cluster" \
    --zone "us-east4-c" \
    --username "admin" \
    --cluster-version "latest" \
    --machine-type "e2-medium" \
    --disk-type "pd-standard" \
    --disk-size "100" \
    --scopes "https://www.googleapis.com/auth/compute","https://www.googleapis.com/auth/devstorage.read_only","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/trace.append" \
    --num-nodes "3" \
    --enable-private-nodes \
    --enable-private-endpoint \
    --master-ipv4-cidr "172.16.0.0/28" \
    --enable-ip-alias \
    --network "projects/PROJECT_ID/global/networks/custom-network1" \
    --subnetwork "projects/PROJECT_ID/regions/us-east4/subnetworks/subnet-us-east-192" \
    --max-nodes-per-pool "110" \
    --enable-master-authorized-networks \
    --addons HorizontalPodAutoscaling,HttpLoadBalancing \
    --enable-autoupgrade \
    --enable-autorepair

Terraform

您可以使用 Terraform 资源创建专用集群。

resource "google_container_cluster" "primary" {
  project            = var.project_id
  name               = "nat-test-cluster"
  location           = "us-east4-c"
  initial_node_count = 3
  network            = var.network # Replace with a reference or self link to your network, in quotes
  subnetwork         = var.subnet  # Replace with a reference or self link to your subnet, in quotes
  private_cluster_config {
    master_ipv4_cidr_block  = "172.16.0.0/28"
    enable_private_endpoint = true
    enable_private_nodes    = true
  }
  ip_allocation_policy {
  }
  master_authorized_networks_config {
  }
}

第 3 步:创建一条允许 SSH 连接的防火墙规则

控制台

  1. 在 Google Cloud 控制台中,转到防火墙页面。

    转到“防火墙政策”页面

  2. 点击创建防火墙规则

  3. 输入 allow-ssh 作为名称

  4. 指定 custom-network1 作为网络

  5. 流量方向设置为入站

  6. 对匹配项执行的操作设置为允许

  7. 目标设置为网络中的所有实例

  8. 来源过滤条件设置为 IPv4 范围

  9. 来源 IP 地址范围设置为 35.235.240.0/20

  10. 协议和端口设置为指定的协议和端口

  11. 选中 tcp 复选框,然后输入端口 22

  12. 点击创建

gcloud

gcloud compute firewall-rules create allow-ssh \
    --network custom-network1 \
    --source-ranges 35.235.240.0/20 \
    --allow tcp:22

Terraform

您可以使用 Terraform 资源来创建防火墙规则。

resource "google_compute_firewall" "rules" {
  project = var.project_id
  name    = "allow-ssh"
  network = var.network
  allow {
    protocol = "tcp"
    ports    = ["22"]
  }
  source_ranges = ["35.235.240.0/20"]
}

第 4 步:为您的某个节点创建 IAP SSH 权限

在随后的步骤中,使用 IAP 连接到该节点。

控制台

  1. 在 Google Cloud 控制台中,转到 Identity-Aware Proxy 页面。

    转到 Identity-Aware Proxy 页面

  2. 选择 SSH 和 TCP 资源标签页。

  3. 选中所有隧道资源 > us-east4-c 下方列表中第一个节点旁边的复选框。其名称与 gke-nat-test-cluster-default-pool-b50db58d-075t 类似。

  4. 记下节点的名称;稍后您将用它来测试连接。

  5. 在右侧窗格中,点击添加主账号

  6. 要向用户、群组或服务账号授予资源访问权限,请在新主账号字段中指定其电子邮件地址。

    如果您只是测试此功能,则可以输入自己的电子邮件地址。

  7. 要通过 Cloud IAP 的 TCP 转发功能向主账号授予资源访问权限,请在角色下拉列表中选择 Cloud IAP > 受 IAP 保护的隧道用户

  8. 点击保存

gcloud

对于此步骤,请按照控制台说明操作。

第 5 步:登录节点并确认其无法连接到互联网

控制台

  1. 在 Google Cloud 控制台中,转到虚拟机实例页面。

    转到“虚拟机实例”页面

  2. 找到您为其创建 IAP SSH 权限的节点。在连接列中,点击 SSH 下拉箭头,然后选择在浏览器窗口中打开

    如果这是您第一次连接到实例,Google Cloud 会为您生成 SSH 密钥。

  3. 在节点提示符下,找到 kube-dns 容器的进程 ID:

    pgrep '^kube-dns$'
  4. 访问容器:

    sudo nsenter --target PROCESS_ID --net /bin/bash
  5. kube-dns,尝试连接到互联网:

    curl example.com

    您应该不会获得任何结果。否则,您可能没有将集群创建为专用集群,或者可能存在其他问题。如需排查问题,请参阅虚拟机无需 Public NAT 即可意外访问互联网

    如需结束该命令,您可能需要输入 Ctrl+C

gcloud

  1. 找到其中一个集群节点的名称:

    gcloud compute instances list

    节点名称类似于 gke-nat-test-cluster-default-pool-1a4cbd06-3m8v。记下该节点名称,并将下面命令中的所有 NODE_NAME 替换为该名称。

  2. 连接到节点:

    gcloud compute ssh NODE_NAME \
        --zone us-east4-c \
        --tunnel-through-iap
  3. 在节点提示符下,找到 kube-dns 容器的进程 ID:

    pgrep '^kube-dns$'
  4. 访问容器:

    sudo nsenter --target PROCESS_ID --net /bin/bash
  5. kube-dns,尝试连接到互联网:

    curl example.com

    您应该不会获得任何结果。如需结束该命令,您可能需要输入 Ctrl+C

第 6 步:使用 Cloud Router 创建 NAT 配置

您必须在与使用 Public NAT 的实例相同的地区中创建 Cloud Router 路由器。Public NAT 仅用于在虚拟机上放置 NAT 信息。它不是实际 NAT 网关的一部分。

此配置允许该地区中的所有实例将 Public NAT 用于所有主要和别名 IP 地址范围。此外,它还为 NAT 网关自动分配外部 IP 地址。如需了解更多选项,请参阅 Google Cloud CLI 文档。

控制台

  1. 在 Google Cloud 控制台中,转到 Cloud NAT 页面。

    转到“Cloud NAT”页面

  2. 点击开始使用创建 NAT 网关

  3. 输入 nat-config 作为网关名称

  4. VPC 网络设置为 custom-network1

  5. 地区设置为 us-east4

  6. Cloud Router 下,选择创建新路由器

    1. 输入 nat-router 作为名称
    2. 点击创建
  7. 点击创建

gcloud

  1. 创建 Cloud Router 路由器:

    gcloud compute routers create nat-router \
        --network custom-network1 \
        --region us-east4
  2. 向路由器添加配置:

    gcloud compute routers nats create nat-config \
        --router-region us-east4 \
        --router nat-router \
        --nat-all-subnet-ip-ranges \
        --auto-allocate-nat-external-ips

Terraform

您可以使用 Terraform 资源创建 Cloud Router 路由器。

resource "google_compute_router" "router" {
  project = var.project_id
  name    = "nat-router"
  network = var.network
  region  = "us-east4"
}

您可以使用 Terraform 模块创建 NAT 配置。

module "cloud-nat" {
  source                             = "terraform-google-modules/cloud-nat/google"
  version                            = "~> 5.0"
  project_id                         = var.project_id
  region                             = "us-east4"
  router                             = google_compute_router.router.name
  name                               = "nat-config"
  source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"
}

第 7 步:尝试再次连接到互联网

NAT 配置最多可能需要 3 分钟才能传播,因此请至少等待一分钟再尝试访问互联网。

如果您仍未登录到 kube-dns,请按照第 5 步中的流程重新连接。登录后,重新运行 curl 命令:

curl example.com

您会看到包含以下内容的输出:


<html>
<head>
<title>Example Domain</title>
...
...
...
</head>

<body>
<div>
    <h1>Example Domain</h1>
    <p>This domain is established to be used for illustrative examples in documents. You can use this
    domain in examples without prior coordination or asking for permission.</p>
    <p><a href="http://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>

后续步骤