相信很多人都知道, 要真正地掌握GCP, VPC 是1个避吾开的一关。
VPC 的全称是 Virtual Private Cloud 虚拟私有云… 但是实际上, 我们提起它, 更多的是指的是
VPC Network , 而不是VPC 本身。
VPC Network 我们可以理解为它就是1个虚拟局域网.
而 1个VPC network 中, 我们可以创建多个子网(subnet)。
例如下面的表格
vpc network | subnet | subnet ip range | vm | vm-ip |
---|---|---|---|---|
tf-vpc0 | tf-vpc0-subnet0 | 192.168.0.0/24 | tf-vpc0-subnet0-vm0 | 192.168.0.3 |
tf-vpc0 | tf-vpc0-subnet1 | 192.168.1.0/24 | tf-vpc0-subnet1-vm0 | 192.168.1.4 |
tf-vpc1 | tf-vpc1-subnet0 | 192.168.8.0/24 | tf-vpc1-subnet0-vm0 | 192.168.8.3 |
包含了2个vpc network
3个subnet, 其中 两个子网属于同1个vpc network
上面的3个vm中
其中tf-vpc0-subnet0-vm0 与 tf-vpc0-subnet1-vm0 (前两行) 默认是互通的, 虽然它们所属的子网不同, ip段也不同,但是她们属于同1个vpc-network, 也就在1个局域网中, 所以是互通的。
但是tf-vpc1-subnet0-vm0 这个vm 就默认不与其他2个vm 互通了。 去打通两个vpc network 的通信 实际上就是云工程师的日常工作。
而且, 很多gcp 其他product , 例如dataflow, gke 都依赖于vpc network. 所以去了解vpc network是一个cloud engineer的必备技能。
我们进入VPC network的页面,并点击button “CREATE VPC Network”
那么我们就进入VPC network创建的页面
我们接下里解析一些细节:
最大传输单元(MTU)是指在网络通信中可以传输的最大数据包大小。它是以字节为单位来衡量的,包括数据包的有效载荷和头部信息。
当数据包从源主机发送到目标主机时,它们会被分割成更小的片段进行传输。MTU定义了每个片段的最大大小。如果数据包的大小超过了网络路径上的任何设备或链路的MTU,那么它将被分割成更小的片段以适应MTU的限制。
在一些情况下,你可能需要调整MTU的大小。例如,当使用虚拟专用网络(VPN)时,VPN隧道的头部信息会增加数据包的大小,可能导致超过某些网络设备或链路的MTU。在这种情况下,你可能需要降低MTU的大小,以确保数据包能够成功传输。
关于收费的问题,通常来说,调整MTU的大小不会直接导致额外的费用。然而,如果你需要使用特定的网络服务或功能来支持更大的MTU,可能会涉及到额外的费用。例如,某些云服务提供商可能会为支持更大的MTU大小而收取额外的费用。因此,在调整MTU大小之前,建议你查看相关的服务提供商文档或与他们联系,以了解是否会有额外的费用或限制。
我们保持默认值 1460 就好
这个选项是用来指定在VPC网络中分配内部IPv6地址时使用的ULA地址范围。你可以在创建VPC网络时设置这个选项,以定义你希望在VPC网络中使用的特定IPv6地址范围。
在创建VPC网络时,你可以选择启用IPv6,并指定一个ULA地址范围。这样,GCP会为你的VPC网络分配一个内部IPv6地址范围,以供你在网络中分配给内部资源。
除非你有ipv6的使用需求, 否则保持disabled就好
在创建VPC页面, 我们应该要同时创建1个subnet
当然你可以选择Automatic, 这样GCP 会自动分配1个subnet,到这个VPC上.
如果把 VPC 当左1个大的内网, 那么subnet就是这个内网的一些子网, 而子网最重要的就是ip地址范围。 当我们点击Add Subnet button就可见到下面的创建子网页面
这个很重要, 每个子网必须属于1个region, 而后面的resource 例如VM自能选择相同区域的子网。
举个例子, 假如我选择在HK创建1个VM, 那么这个VM必须选择1个HK region的子网。
上面的例子我选择了eurepo-west2 , 那么代表这个子网是属于伦敦的.
这个就是子网的重点, 意思就是ipv4 地址的范围
上面我写到是 192.168.1.0/24
意思就是这个子网
从192.168.0.1 开始, 从192.168.0.255 结束, 简单来讲就是可以分配 254个虚拟机到这个子网.
而192.168.0.1 必须用于gateway , 192.168.0.255 用于广播, 这两个ip是不能被分配给其他resources的
具体子网掩码的换算可以参考
https://www.sojson.com/convert/subnetmask.html
用于控制子网中的实例是否可以通过内部IP地址访问Google服务,而无需通过公共Internet连接。
当你启用"Private Google Access"选项时,子网中的实例可以使用内部IP地址直接访问Google服务,例如Google Cloud Storage、Google BigQuery等,而无需通过公共Internet连接。这提供了一种更安全和高效的方式来访问Google服务,特别是在需要保护数据隐私或限制公共Internet访问的情况下。
需要注意的是,启用"Private Google Access"选项只适用于子网内的实例,对于子网之外的实例仍然需要通过公共Internet连接来访问Google服务。
简单来讲也可以让子网下的resource可以通过GCP内网而不是公网去连接 GCP的其他产品(BQ, bucket等), 走内网的好处是
1,更快
2,更安全
3,公网流量更低, 更便宜
所以一般选择ON
当我们在一个已创建的vpc network上创建subnet时, 我们还会见到1个option 选项 Purpose
有4个options
官方文档是这么说的:
REGIONAL_MANAGED_PROXY is a user-created subnetwork that is reserved for regional Envoy-based load balancers
简单来讲它是for load balancer的, 亲自测试过 我们不能在这种子网内create vm
官方文档是这么说的:
PRIVATE_SERVICE_CONNECT reserves the subnet for hosting a Private Service Connect published service
而private service connect 是gcp 上另1个product
https://console.cloud.google.com/net-services/psc/list/consumers?project=jason-hsbc
也测试过, 不能在这种子网内create vm
官方文档是这么说的:
它还是beta状态, 相信是为了NAT gateway的subnet,
也测试过, 不能在这种子网内create vm
所以我们在子网内create vm的话, 只能选择这种purpose 为None的类型。
但是注意: 当我们选择None purpose时, 实际上create出来的子网, purpose 这一项是Private
例如:
gateman@MoreFine-S500:~/tmp$ gcloud compute networks subnets describe tf-vpc0-subnet0 --region=europe-west2
creationTimestamp: '2023-12-09T09:52:28.296-08:00'
enableFlowLogs: false
fingerprint: VaJIplQwbMw=
gatewayAddress: 192.168.0.1
id: '1442678474200913843'
ipCidrRange: 192.168.0.0/24
kind: compute#subnetwork
logConfig:
enable: false
name: tf-vpc0-subnet0
network: https://www.googleapis.com/compute/v1/projects/jason-hsbc/global/networks/tf-vpc0
privateIpGoogleAccess: false
privateIpv6GoogleAccess: DISABLE_GOOGLE_ACCESS
purpose: PRIVATE
region: https://www.googleapis.com/compute/v1/projects/jason-hsbc/regions/europe-west2
role: ACTIVE
selfLink: https://www.googleapis.com/compute/v1/projects/jason-hsbc/regions/europe-west2/subnetworks/tf-vpc0-subnet0
stackType: IPV4_ONLY
所以我们在编写terraform 脚本时, purpose要set 成Private 而不是None, 否则每次terraform plan它都会尝试去create 这个子网!
这个很重要, 每个子网必须属于1个region, 而后面的resource 例如VM自能选择相同区域的子网。
举个例子, 假如我选择在HK创建1个VM, 那么这个VM必须选择1个HK region的子网。
上面的例子我选择了eurepo-west2 , 那么代表这个子网是属于伦敦的.
这个就是子网的重点, 意思就是ipv4 地址的范围
上面我写到是 192.168.1.0/24
意思就是这个子网
从192.168.0.1 开始, 从192.168.0.255 结束, 简单来讲就是可以分配 254个虚拟机到这个子网.
而192.168.0.1 必须用于gateway , 192.168.0.255 用于广播, 这两个ip是不能被分配给其他resources的
具体子网掩码的换算可以参考
https://www.sojson.com/convert/subnetmask.html
用于控制子网中的实例是否可以通过内部IP地址访问Google服务,而无需通过公共Internet连接。
当你启用"Private Google Access"选项时,子网中的实例可以使用内部IP地址直接访问Google服务,例如Google Cloud Storage、Google BigQuery等,而无需通过公共Internet连接。这提供了一种更安全和高效的方式来访问Google服务,特别是在需要保护数据隐私或限制公共Internet访问的情况下。
需要注意的是,启用"Private Google Access"选项只适用于子网内的实例,对于子网之外的实例仍然需要通过公共Internet连接来访问Google服务。
简单来讲也可以让子网下的resource可以通过GCP内网而不是公网去连接 GCP的其他产品(BQ, bucket等), 走内网的好处是
1,更快
2,更安全
3,公网流量更低, 更便宜
所以一般选择ON
其实你不知道怎么配置的话,保持默认就好
Firewall 这里配置是 公网和这个VPN network的出入口规则
allow-custom 表示 允许用户自定义防火墙规则, 不要动它
allow-icmp 也不要动它, 否则会影响一些网络工具的使用,例如没有它, 里面vm就不能互相ping通!
allow-rdp 3389 这里 表示允许rdp 3389协议的接入, rdp协议就是远程桌面的协议, 适用于both windows 和linux, 如果你确定你这个子网下的所有VM都不需要远程桌面接入, 可以禁掉它
allow-ssh 22 , 这里就是允许外部主机ssh登录VPC network的主机啦, 务必打开
至于下面的 deny all ingress 就是默认是禁止所有外部主机访问的, 但是因为上面allow-ssh 的优先级别更高, 所以22端口还是开通的。 假如 之后我们要开启web服务, 则需要把80和443端口打开, 就是新镇1个规则, 但是优先级必须在deny all ingress 之前
allow-all-egress 就是表明vm内的resource是无限制访问外网的, 如果需要禁止访问外网, 则需要把这个规则改掉
如果你的网络环境是多区域的,并且你希望在每个区域内具有更细粒度的控制,那么选择 Regional dynamic routing mode 可能更合适。这样,你可以针对每个区域设置特定的路由策略,并根据需要进行定制。这种方式可以提供更灵活的网络配置和管理。
另一方面,如果你的网络环境是全局性的,并且你希望在整个项目中使用统一的路由策略,那么选择 Global dynamic routing mode 可能更合适。这样,你可以使用单个路由策略来管理整个项目中的所有区域,简化了配置和管理的复杂性。
需要考虑的因素还包括网络规模、复杂性和管理成本。如果你的网络规模较小且相对简单,那么选择 Regional dynamic routing mode 可能更加适合。如果你的网络规模较大且跨多个区域,那么选择 Global dynamic routing mode 可能更具优势。
我建议选择regional就好
例子:
# tf-vpc0
# ============================================================================================================================
# create a vpc
resource "google_compute_network" "tf-vpc0" {
project = var.project_id
name = "tf-vpc0"
auto_create_subnetworks = false
}
# create a subnet
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_subnetwork
resource "google_compute_subnetwork" "tf-vpc0-subnet0" {
name = "tf-vpc0-subnet0"
ip_cidr_range = "192.168.0.0/24" # 192.168.0.1 ~ 192.168.0.255
region = var.region_id
# only PRIVATE could allow vm creation, the PRIVATE item is displayed as "None" in GCP console subnet creation page
# but we cannot set purpose to "None", if we did , the subnet will still created as purpose = PRIVATE , and next terraform plan/apply will try to recreate the subnet!
# as it detect changes for "PRIVATE" -> "NONE"
# gcloud compute networks subnets describe tf-vpc0-subnet0 --region=europe-west2
purpose = "PRIVATE"
role = "ACTIVE"
private_ip_google_access = "true" # to eanble the vm to access gcp products via internal network but not internet, faster and less cost!
network = google_compute_network.tf-vpc0.name
}
# create a subnet
resource "google_compute_subnetwork" "tf-vpc0-subnet1" {
name = "tf-vpc0-subnet1"
ip_cidr_range = "192.168.1.0/24" # 192.168.0.1 ~ 192.168.0.255
region = var.region_id
purpose = "PRIVATE"
role = "ACTIVE"
private_ip_google_access = "true"
network = google_compute_network.tf-vpc0.name
}
# Create firewall rules
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_firewall
resource "google_compute_firewall" "tf-vpc0-firewall" {
name = "tf-vpc0-firewall"
network = google_compute_network.tf-vpc0.name
allow {
protocol = "icmp" # to enable ping
}
allow {
protocol = "tcp"
ports = ["8080", "80", "443", "22"]
}
source_ranges = ["0.0.0.0/0"] # allow any external part access
# target_tags - (Optional) A list of instance tags indicating sets of instances located in the network that may make network connections as specified in allowed[].
# If no targetTags are specified, the firewall rule applies to all instances on the specified network.
# target_tags = [google_compute_subnetwork.tf-subnet.name]
}
## Create Cloud Router
resource "google_compute_router" "tf-vpc0-nat-router" {
project = var.project_id
name = "tf-vpc0-nat-router"
network = google_compute_network.tf-vpc0.name
region = var.region_id
}
## Create Nat Gateway
resource "google_compute_router_nat" "tf-vpc0-cloud-nat" {
name = "tf-vpc0-cloud-nat"
router = google_compute_router.tf-vpc0-nat-router.name
region = var.region_id
nat_ip_allocate_option = "AUTO_ONLY"
source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"
log_config {
enable = true
filter = "ERRORS_ONLY"
}
}
# tf-vpc1
## ======================================================================================================================================================
# create a vpc
resource "google_compute_network" "tf-vpc1" {
project = var.project_id
name = "tf-vpc1"
auto_create_subnetworks = false
}
# create a subnet
resource "google_compute_subnetwork" "tf-vpc1-subnet0" {
name = "tf-vpc1-subnet0"
ip_cidr_range = "192.168.8.0/24"
region = var.region_id
purpose = "PRIVATE"
role = "ACTIVE"
#
private_ip_google_access = "true"
network = google_compute_network.tf-vpc1.name
}
# Create firewall rules
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_firewall
resource "google_compute_firewall" "tf-vpc1-firewall" {
name = "tf-vpc1-firewall"
network = google_compute_network.tf-vpc1.name
allow {
protocol = "icmp" # to enable ping
}
allow {
protocol = "tcp"
ports = ["8080", "80", "443", "22"]
}
source_ranges = ["0.0.0.0/0"] # allow any external part access
# target_tags - (Optional) A list of instance tags indicating sets of instances located in the network that may make network connections as specified in allowed[].
# If no targetTags are specified, the firewall rule applies to all instances on the specified network.
# target_tags = [google_compute_subnetwork.tf-subnet.name]
}
### Create Cloud Router
#
#resource "google_compute_router" "tf-vpc1-nat-router" {
# project = var.project_id
# name = "tf-vpc1-nat-router"
# network = google_compute_network.tf-vpc1.name
# region = var.region_id
#}
#
### Create Nat Gateway
#
#resource "google_compute_router_nat" "tf-vpc1-cloud-nat" {
# name = "tf-vpc1-cloud-nat"
# router = google_compute_router.tf-vpc1-nat-router.name
# region = var.region_id
# nat_ip_allocate_option = "AUTO_ONLY"
# source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"
#
# log_config {
# enable = true
# filter = "ERRORS_ONLY"
# }
#}
# ==========================================================================================================================================
# output
# ==========================================================================================================================================
output "tf_vpc0_name" {
value = google_compute_network.tf-vpc0.name
}
output "tf_vpc0_subnet0_name" {
value = google_compute_subnetwork.tf-vpc0-subnet0.name
}
output "tf_vpc0_subnet1_name" {
value = google_compute_subnetwork.tf-vpc0-subnet1.name
}
output "tf_vpc1_name" {
value = google_compute_network.tf-vpc1.name
}
output "tf_vpc1_subnet0_name" {
value = google_compute_subnetwork.tf-vpc1-subnet0.name
}