无法通过私有 IP 从 GKE 连接到 Cloud SQL Postgres

Cha*_*uys 5 google-cloud-sql google-cloud-platform google-kubernetes-engine vpc-peering

我无法使用数据库的私有 IP 从 GKE 集群访问运行 Postgres 的 Cloud SQL 实例。我找到的所有文档都建议使用支持 VPC 的集群来完成此操作,但我仍然无法访问数据库。

具体来说,我可以从集群中的节点访问数据库,但我无法从节点上的容器内访问数据库,除非我使用主机的网络运行 docker 容器。这让我相信我对 GCP VPC 和 Kubernetes 的网络组件如何相互交互存在误解。

专有网络

我的 VPC 有一个子网和两个次要范围:

IP 范围:10.0.0.0/16
次要范围 - pod: 10.1.0.0/16
次要范围 - 服务: 10.2.0.0/16

这是使用以下 Terraform 配置创建的:

resource "google_compute_subnetwork" "cluster" {
  ip_cidr_range            = "10.0.0.0/16"
  name                     = "cluster"
  network                  = google_compute_network.vpc.self_link

  secondary_ip_range {
    ip_cidr_range = "10.1.0.0/16"
    range_name    = "pods"
  }

  secondary_ip_range {
    ip_cidr_range = "10.2.0.0/16"
    range_name    = "services"
  }
}
Run Code Online (Sandbox Code Playgroud)

数据库

我的云 SQL 数据库运行 Postgres 11 并配置为仅允许通过私有 IP 进行连接。我已与一组全局计算地址建立了对等连接,以允许从我的 VPC 访问 Cloud SQL 实例。在这种情况下,我最终得到以下值:

私有服务连接IP范围: 172.26.0.0/16
数据库私有IP: 172.26.0.3

这些资源使用以下 Terraform 配置进行供应:

resource "google_compute_global_address" "db_private_ip" {
  provider = "google-beta"

  name          = "db-private-ip"
  purpose       = "VPC_PEERING"
  address_type  = "INTERNAL"
  prefix_length = 16
  network       = google_compute_network.vpc.self_link
}

resource "google_service_networking_connection" "db_vpc_connection" {
  network                 = google_compute_network.vpc.self_link
  service                 = "servicenetworking.googleapis.com"
  reserved_peering_ranges = [google_compute_global_address.db_private_ip.name]
}


resource "google_sql_database_instance" "db" {
  depends_on = [google_service_networking_connection.db_vpc_connection]

  database_version = "POSTGRES_11"

  settings {
    availability_type = "ZONAL"
    tier              = "db-f1-micro"

    ip_configuration {
      ipv4_enabled    = false
      private_network = google_compute_network.vpc.self_link
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我的 GKE 集群配置为 VPC 原生并使用clusterVPC 子网中的次要范围。一些相关的集群信息:

Master 版本: 1.14.8-gke.17
网络: my-vpc
子网:集群
VPC-native:已启用
Pod 地址范围: 10.1.0.0/16
服务地址范围: 10.2.0.0/16

集群是使用以下 Terraform 配置创建的:

resource "google_container_cluster" "primary" {
  location           = var.gcp_region
  min_master_version = data.google_container_engine_versions.latest_patch.latest_master_version
  name               = "my-cluster"
  network            = google_compute_network.vpc.self_link
  subnetwork         = google_compute_subnetwork.cluster.self_link

  # We can't create a cluster with no node pool defined, but we want to only use
  # separately managed node pools. So we create the smallest possible default
  # node pool and immediately delete it.
  remove_default_node_pool = true
  initial_node_count       = 1

  ip_allocation_policy {
    use_ip_aliases                = true
    cluster_secondary_range_name  = "pods"
    services_secondary_range_name = "services"
  }

  master_auth {
    username = ""
    password = ""

    client_certificate_config {
      issue_client_certificate = false
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

连接尝试

我已经尝试从许多不同的上下文连接到数据库以试图找出问题所在。

独立实例

我在我的 VPC 中启动了一个新的 Ubuntu 计算 VM,并且能够使用nping和连接到数据库psql

从节点上的容器

通过kubectl attach在我的集群中的 pod 上使用或通过 SSH 连接到一个节点并运行我自己的 docker 命令,我看到所有发送到数据库的数据包都没有通过。

resource "google_compute_subnetwork" "cluster" {
  ip_cidr_range            = "10.0.0.0/16"
  name                     = "cluster"
  network                  = google_compute_network.vpc.self_link

  secondary_ip_range {
    ip_cidr_range = "10.1.0.0/16"
    range_name    = "pods"
  }

  secondary_ip_range {
    ip_cidr_range = "10.2.0.0/16"
    range_name    = "services"
  }
}
Run Code Online (Sandbox Code Playgroud)

从具有主机网络的节点上的容器

如果我重复上面的命令但使用主机的网络,我可以连接到数据库。

resource "google_compute_global_address" "db_private_ip" {
  provider = "google-beta"

  name          = "db-private-ip"
  purpose       = "VPC_PEERING"
  address_type  = "INTERNAL"
  prefix_length = 16
  network       = google_compute_network.vpc.self_link
}

resource "google_service_networking_connection" "db_vpc_connection" {
  network                 = google_compute_network.vpc.self_link
  service                 = "servicenetworking.googleapis.com"
  reserved_peering_ranges = [google_compute_global_address.db_private_ip.name]
}


resource "google_sql_database_instance" "db" {
  depends_on = [google_service_networking_connection.db_vpc_connection]

  database_version = "POSTGRES_11"

  settings {
    availability_type = "ZONAL"
    tier              = "db-f1-micro"

    ip_configuration {
      ipv4_enabled    = false
      private_network = google_compute_network.vpc.self_link
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

建议?

看到大多数关于通过私有 IP 从 GKE 连接到 Cloud SQL 实例的问题在他们将集群配置为 VPC 原生时都得到了解决,我认为我的问题出在我的网络配置中。我很感激任何建议,我很乐意提供任何其他信息。谢谢。

相关问题

使用来自 GKE 的私有 IP 连接到 Cloud SQL Postgres 时出现问题

更新 2019-12-05

将上面链接的相关问题中的命令转换为 Terraform(称之为 MVP 配置),我能够使用私有 IP 连接到 Postgres 实例,所以我现在相信问题在我的配置中更深层次。我仍然没有确定我的基础设施的哪一部分与 MVP 配置不同。

我的下一个尝试可能是增强 MVP 配置以使用单独配置的节点池而不是默认节点池,以查看这是否说明了我所看到的行为。

小智 1

通过专用连接进行通信时,Cloud SQL 实例必须遵守特定的网络要求。其中之一是您的 CloudSQL 和 GKE 实例位于同一区域和 VPC 网络。[1]

关于“我无法从节点上的容器内访问数据库”,这是否意味着您的数据库和容器位于不同的网络中?如果是这样,您无法使用 Cloud VPN 隧道、基于实例的 VPN 或云互连从另一个网络访问其私有 IP 地址上的 Cloud SQL 实例。

[1] https://cloud.google.com/sql/docs/mysql/private-ip#network_requirements


归档时间:

查看次数:

2993 次

最近记录:

4 年,11 月 前