当我用下面的terrform 构建1个GCE Vm后
resource "google_compute_instance" "k8s-master" {
name = "k8s-master"
project = var.project_id
zone = var.zone_id
allow_stopping_for_update = true
machine_type = "n2d-highmem-2" # 2cpu 16GB
boot_disk {
initialize_params {
image = "debian-cloud/debian-11"
size = 20
}
}
network_interface {
network = var.vpc
subnetwork = var.subnet
}
service_account {
email = "[email protected]"
scopes = ["https://www.googleapis.com/auth/cloud-platform"]
}
# https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#provisioning_model
# to reduce cost
scheduling {
automatic_restart = false # Scheduling must have preemptible be false when AutomaticRestart is true.
provisioning_model = "SPOT"
preemptible = true
}
}
发现创建后的VM 并没有外网访问权限, 原因是没有分配外部ip, 导致一些操作(例如安装某些软件)不方便
暴力解决方法就是分配1个外部ip, 但是外部ip是收费资源, 而且当vm很多的时候, 申请大量外部ip十分浪费。
而且不符合微服务的构建思想。
在微服务里, 通常只有load balancer or api gateway 才可以被外网访问。
使用 Google Cloud Nat
这个就是本文想解决的问题
Nat 的全程是 Network address tranformation , 网络地址转换…
通常是1台具有双网卡 (双 ip)地址的机器, 1个公网ip, 1个内网ip
功能是让局域网的各个内网主机可以通过这个Nat gatway , 去访问公网。
但是公网是不能通过这个Nat gateway去访问指定内网主机的。
是的, 我们的家用路由器实际上应该是1个Nat 网关, 而不是一台狭义的路由, 只不过名字叫路由器而已
所以google的cloud Nat 就是的功能就是让没有公网ip的内网主机可以访问公网。
而CloudNat 是绑定在某个VPC 上的, 但是可以for all the subnet
Cloud Nat 配置相当简单
首先需要1个Cloud Routes , 注意这个Cloud Routes 和 VPC Routes 并不是用1个东西
然后创建1个Cloud Nat, 模式选择 Auto only, source_subnetwork_ip_ranges_to_nat 设成 ALL_SUBNETWORKS_ALL_IP_RANGES
具体terraform代码:
## Create Cloud Router
resource "google_compute_router" "tf-router" {
project = var.project_id
name = "tf-nat-router"
network = google_compute_network.tf-vpc.name
region = var.region_id
}
## Create Nat Gateway
resource "google_compute_router_nat" "tf-cloud-nat" {
name = "tf-cloud-nat"
router = google_compute_router.tf-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"
}
}
一旦创建后, 这个VPC的内网主机就可以访问外网了