구글 클라우드에서 점차 중심 복사식 네트워크 토폴로지 실현
만약 당신이 당신의 업무를 위해 잘못된 토폴로지 구조를 실현했다면, 당신은 앞으로 제로 업무 가치 때문에 많은 돈을 쓸 것이다.
간단한 용례부터 시작합시다.고객은 단순함을 유지하고 싶어 한다(또는 Poc에서 투자 수익을 얻기를 원한다)😨) 모든 워크로드와 환경에 대해 공유 VPC를 생성합니다.공유 VPC는 클라우드 VPN을 사용하여 로컬 환경에 연결됩니다.네트워크 아키텍처는 다음과 같습니다.
각 환경마다 서브넷이 하나씩 있습니다.30개의 관건적인 마이크로 서비스가 생산 과정에서 실행되고 있는데, 예를 들어 Elasticsearch 같은 상태가 있는 응용 프로그램을 제외하고는 클라우드 SQL 데이터베이스에 저장된 민감한 데이터에 의존한다.
고객은 보안상의 이유로 이제 프로덕션 워크로드를 별도의 독점 네트워크에서 분리하기를 원합니다.마이그레이션을 수행하기 위해 외부 서비스 공급업체를 요청했습니다.다운타임을 허용하지 않습니다.
서비스 공급업체는 현재의 네트워크 아키텍처를 분석하고 다음 마이그레이션 계획을 제시합니다.
기업에는 가치가 없고 최종 사용자에게는 가치가 없다.고객이 마이그레이션을 연기할 수 있습니다.
나는 인터넷 토폴로지가 더욱 복잡한 고객을 만났다. 그는 개발 환경을 유럽 서브넷에 놓고 생산 환경을 런던 서브넷에 두었다.GDPR의 한계로 인해, 그는 작업 부하를 런던에서 유럽 서브넷으로 옮기기를 희망한다.이것은 그들의 업무에 아무런 가치가 없기 때문에, 이전을 시작하는 데 필요한 예산은 불합리하다.그러나 어떤 대가를 치르든지 간에 그는 앞으로도 이렇게 해야 한다.
따라서 구글 클라우드에서 구현할 수 있는 가장 좋은 네트워크 토폴로지는 다음과 같습니다.
무엇이 중심 방사능 네트워크 토폴로지입니까?
The spoke-hub distribution paradigm is a form of transport topology optimization in which traffic planners organize routes as a series of "spokes" that connect outlying points to a central "hub". Wikipedia [2]
성망[3]
구름이 많거나 혼합 클라우드 구조에서 방사식 전유 네트워크는 중심 전유 네트워크를 통해 외부 환경과 통신한다.관련 루트는 센터 전용 네트워크에서 지점 전용 네트워크로 내보냅니다.[4]
본고에서 우리는 구글 클라우드에서 다음과 같은 구조를 실현할 것이다.VPC 피어 및 환경 기반의 세분화된 중심 복사 아키텍처:
The spoke-hub distribution paradigm is a form of transport topology optimization in which traffic planners organize routes as a series of "spokes" that connect outlying points to a central "hub". Wikipedia [2]
Terraform을 사용하여 인프라를 구축하고 Gitlab CI를 사용하여 배포합니다.창설 센터부터 시작합시다.
중추 네트워크 프로젝트
새 프로젝트 만들기mycompany-network-hub
:
gcloud projects create mycompany-network-hub
gcloud compute networks delete default
다음 파일을 만듭니다.
gcloud projects create mycompany-network-hub
gcloud compute networks delete default
data "google_project" "hub" {
project_id = "mycompany-network-hub"
}
repo mycompany 네트워크 센터/계획/전용 네트워크.tfresource "google_compute_network" "hub" {
name = "hub"
auto_create_subnetworks = false
project = data.google_project.hub.project_id
}
resource "google_compute_subnetwork" "hub-subnet" {
name = "hub-subnet"
ip_cidr_range = var.hub_subnet_ip_range
region = var.region
network = google_compute_network.hub.id
project = data.google_project.hub.project_id
}
repo mycompany 네트워크 센터/계획/vpn.tfresource "google_compute_vpn_tunnel" "tunnel" {
name = "tunnel"
peer_ip = var.on_premise_peer_ip
shared_secret = data.google_secret_manager_secret_version.vpn-shared-secret.secret_data
project = data.google_project.hub.project_id
ike_version = 2
remote_traffic_selector = [var.on_premise_network_ip_range]
local_traffic_selector = [var.hub_subnet_ip_range]
target_vpn_gateway = google_compute_vpn_gateway.target_gateway.id
region = var.region
depends_on = [
google_compute_forwarding_rule.fr_esp,
google_compute_forwarding_rule.fr_udp500,
google_compute_forwarding_rule.fr_udp4500,
]
}
resource "google_compute_vpn_gateway" "target_gateway" {
name = "vpn"
network = google_compute_network.hub.id
project = data.google_project.hub.project_id
region = var.region
}
resource "google_compute_forwarding_rule" "fr_esp" {
name = "fr-esp"
ip_protocol = "ESP"
ip_address = data.google_compute_address.vpn-static-ip.address
target = google_compute_vpn_gateway.target_gateway.id
project = data.google_project.hub.project_id
region = var.region
}
resource "google_compute_forwarding_rule" "fr_udp500" {
name = "fr-udp500"
ip_protocol = "UDP"
port_range = "500"
ip_address = data.google_compute_address.vpn-static-ip.address
target = google_compute_vpn_gateway.target_gateway.id
project = data.google_project.hub.project_id
region = var.region
}
resource "google_compute_forwarding_rule" "fr_udp4500" {
name = "fr-udp4500"
ip_protocol = "UDP"
port_range = "4500"
ip_address = data.google_compute_address.vpn-static-ip.address
target = google_compute_vpn_gateway.target_gateway.id
project = data.google_project.hub.project_id
region = var.region
}
resource "google_compute_route" "route" {
name = "route"
network = google_compute_network.hub.name
project = data.google_project.hub.project_id
dest_range = var.on_premise_network_ip_range
priority = 1000
next_hop_vpn_tunnel = google_compute_vpn_tunnel.tunnel.id
}
data "google_secret_manager_secret_version" "vpn-shared-secret" {
project = data.google_project.hub.project_id
secret = "vpn-shared-secret"
}
data "google_compute_address" "vpn-static-ip" {
project = data.google_project.hub.project_id
name = "vpn-static-ip"
region = var.region
}
Note: Classic VPN is deprecating certain functionality on October 31, 2021. For more information, see the Classic VPN partial deprecation page.
repo mycompany 네트워크 센터/계획/방화벽.tf
resource "google_compute_firewall" "allow-ingress-traffic-from-vpn" {
name = "allow-ingress-traffic-to-vpn"
network = google_compute_network.hub.name
project = data.google_project.hub.project_id
allow {
protocol = "tcp"
}
source_ranges = [var.on_premise_network_ip_range]
priority = 1000
direction = "INGRESS"
}
resource "google_compute_firewall" "allow-egress-traffic-to-vpn" {
name = "allow-egress-traffic-to-vpn"
network = google_compute_network.hub.name
project = data.google_project.hub.project_id
allow {
protocol = "tcp"
}
destination_ranges = [var.on_premise_network_ip_range]
priority = 1000
direction = "EGRESS"
}
resource "google_compute_firewall" "deny-ingress-traffic-from-internet" {
name = "deny-all-ingress-traffic"
network = google_compute_network.hub.name
project = data.google_project.hub.project_id
deny {
protocol = "all"
}
source_ranges = ["0.0.0.0/0"]
priority = 2000
direction = "INGRESS"
}
resource "google_compute_firewall" "deny-egress-traffic-to-internet" {
name = "deny-all-egress-traffic"
network = google_compute_network.hub.name
project = data.google_project.hub.project_id
deny {
protocol = "all"
}
destination_ranges = ["0.0.0.0/0"]
priority = 2000
direction = "EGRESS"
}
repo mycompany 네트워크 센터/계획/백엔드.tfterraform {
backend "gcs" {
}
}
mycompany 네트워크 센터/계획/공급자 환매.tfterraform {
required_version = ">= 0.12"
required_providers {
google = "~> 3.0"
}
}
repo mycompany 네트워크 센터/계획/변수.tfvariable "hub_subnet_ip_range" {
type = string
}
variable "region" {
type = string
default = "europe-west1"
}
variable "on_premise_network_ip_range" {
type = string
}
variable "on_premise_peer_ip" {
type = string
}
repo mycompany 네트워크 센터/계획/지형.tfvarshub_subnet_ip_range = "<HUB_SUBNET_IP_RANGE>"
on_premise_peer_ip = "<ON_PREMISE_PEER_IP>"
on_premise_network_ip_range = "<ON_PREMISE_NETWORK_IP_RANGE>"
복사망 프로젝트
각 브랜치에 대한 새 항목을 만들려면 다음과 같이 하십시오.
gcloud projects create mycompany-network-spoke-nonprod
gcloud compute networks delete default
gcloud projects create mycompany-network-spoke-prod
gcloud compute networks delete default
다음 파일을 만듭니다.
gcloud projects create mycompany-network-spoke-nonprod
gcloud compute networks delete default
gcloud projects create mycompany-network-spoke-prod
gcloud compute networks delete default
data "google_project" "spoke" {
project_id = "mycompany-network-spoke-${var.env}"
}
data "google_project" "hub" {
project_id = "mycompany-network-hub"
}
resource "google_compute_shared_vpc_host_project" "host" {
project = data.google_project.spoke.project_id
}
mycompany 네트워크 스포일러/계획/전유 네트워크 재구매.tfresource "google_compute_network" "spoke" {
name = "spoke"
auto_create_subnetworks = false
project = data.google_project.spoke.project_id
}
resource "google_compute_subnetwork" "spoke-subnet" {
name = "spoke-subnet"
ip_cidr_range = var.spoke_subnet_ip_range
region = var.region
network = google_compute_network.spoke.id
project = data.google_project.spoke.project_id
secondary_ip_range = [
{
range_name = "pods"
ip_cidr_range = var.spoke_subnet_pods_ip_range
},
{
range_name = "services"
ip_cidr_range = var.spoke_subnet_services_ip_range
}
]
}
resource "google_compute_network_peering" "spoke-to-hub" {
name = "spoke-to-hub"
network = google_compute_network.spoke.id
peer_network = data.google_compute_network.hub.self_link
export_custom_routes = true
import_custom_routes = true
}
# Could be moved to network hub tf
resource "google_compute_network_peering" "hub-to-spoke" {
name = "hub-to-spoke"
network = data.google_compute_network.hub.self_link
peer_network = google_compute_network.spoke.id
export_custom_routes = true
import_custom_routes = true
}
data "google_compute_network" "hub" {
name = "hub"
project = data.google_project.hub.project_id
}
mycompany 네트워크 스포일러/계획/nat 회수.tf
resource "google_compute_router" "router" {
name = "router"
region = google_compute_subnetwork.spoke-subnet.region
network = google_compute_network.spoke.id
project = data.google_project.spoke.project_id
bgp {
asn = 64514
}
}
resource "google_compute_router_nat" "nat" {
name = "nat"
router = google_compute_router.router.name
region = google_compute_router.router.region
project = data.google_project.spoke.project_id
nat_ip_allocate_option = "MANUAL_ONLY"
nat_ips = [data.google_compute_address.nat-static-ip1.self_link, data.google_compute_address.nat-static-ip2.self_link]
source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES"
}
data "google_compute_address" "nat-static-ip1" {
project = data.google_project.spoke.project_id
name = "nat-static-ip1"
region = var.region
}
data "google_compute_address" "nat-static-ip2" {
project = data.google_project.spoke.project_id
name = "nat-static-ip2"
region = var.region
}
mycompany 네트워크 스포일러/계획/백엔드를 환매합니다.tfterraform {
backend "gcs" {
}
}
mycompany 네트워크 스포일러/계획/공급자 환매.tfterraform {
required_version = ">= 0.12"
required_providers {
google = "~> 3.0"
}
}
mycompany 네트워크 스포일러/계획/변수를 환매합니다.tfvariable "region" {
type = string
default = "europe-west1"
}
variable "spoke_subnet_ip_range" {
type = string
}
variable "spoke_subnet_pods_ip_range" {
type = string
}
variable "spoke_subnet_services_ip_range" {
type = string
}
variable "env" {
type = string
}
mycompany 네트워크 스포일러/환경/비봉상/지형 환매.tfvarsenv = "<ENV>"
spoke_subnet_ip_range = "<SPOKE_SUBNET_IP_RANGE>"
spoke_subnet_pods_ip_range = "<SPOKE_SUBNET_PODS_IP_RANGE>"
spoke_subnet_services_ip_range = "<SPOKE_SUBNET_SERVICES_IP_RANGE>"
mycompany 네트워크 스포일러/envs/prod/terraform을 다시 구입합니다.tfvarsenv = "<ENV>"
spoke_subnet_ip_range = "<SPOKE_SUBNET_IP_RANGE>"
spoke_subnet_ip_pods_range = "<SPOKE_SUBNET_PODS_RANGE>"
spoke_subnet_ip_services_range = "<SPOKE_SUBNET_SERVICES_RANGE>"
배치하다
Gitlab CI에서 파이프라인을 실행하기 전에 먼저 네트워크 허브 프로젝트에서 다음 리소스를 만들어야 합니다.
gcloud config set project mycompany-network-hub
gcloud compute addresses create vpn-static-ip --region europe-west1
gcloud services enable secretmanager.googleapis.com
gcloud beta secrets create vpn-shared-secret --locations europe-west1 --replication-policy user-managed
echo -n "<shared_key_here>" | gcloud beta secrets versions add vpn-shared-secret --data-file=-
Note: Static IP used to establish a static VPN connection should always be created manually
. If you ever need to recreate (or have unintentionally destroyed) your VPN tunnel, the on-premise environment won't need to recreate the tunnel.
각 항목에 대해 다음을 수행합니다.
gcloud config set project mycompany-network-spoke-<env>
gcloud compute addresses create nat-static-ip1 --region europe-west1
gcloud compute addresses create nat-static-ip2 --region europe-west1
Note: Static IP addresses used to create a NAT Gateway should always be created manually
. If you ever need to recreate (or have unintentionally destroyed) the NAT Gateway, the tools and servers that whitelist those IP addresses won't need to update their source IP addresses.
우리는 우리의 지형 상태를 저장하기 위해 물통이 하나 더 필요하다.
## enable apis
gcloud config set project mycompany-secops
gcloud services enable cloudresourcemanager.googleapis.com
gcloud services enable storage.googleapis.com
## create gcs bucket
export REGION_DEFAULT=europe-west1
export BUCKET_NAME=bucket-mycompany-terraform-backend
gsutil mb -c standard -l $REGION_DEFAULT gs://$BUCKET_NAME
gsutil versioning set on gs://$BUCKET_NAME
Note: I recommend customers to centralize the terraform bucket in a specific project.
이제 우리는 파이프를 만들 수 있다.Gitlab 실행에 필요한 권한은 다음과 같습니다.
gcloud config set project mycompany-network-hub
gcloud compute addresses create vpn-static-ip --region europe-west1
gcloud services enable secretmanager.googleapis.com
gcloud beta secrets create vpn-shared-secret --locations europe-west1 --replication-policy user-managed
echo -n "<shared_key_here>" | gcloud beta secrets versions add vpn-shared-secret --data-file=-
Note: Static IP used to establish a static VPN connection should always be created manually
. If you ever need to recreate (or have unintentionally destroyed) your VPN tunnel, the on-premise environment won't need to recreate the tunnel.
gcloud config set project mycompany-network-spoke-<env>
gcloud compute addresses create nat-static-ip1 --region europe-west1
gcloud compute addresses create nat-static-ip2 --region europe-west1
Note: Static IP addresses used to create a NAT Gateway should always be created manually
. If you ever need to recreate (or have unintentionally destroyed) the NAT Gateway, the tools and servers that whitelist those IP addresses won't need to update their source IP addresses.
## enable apis
gcloud config set project mycompany-secops
gcloud services enable cloudresourcemanager.googleapis.com
gcloud services enable storage.googleapis.com
## create gcs bucket
export REGION_DEFAULT=europe-west1
export BUCKET_NAME=bucket-mycompany-terraform-backend
gsutil mb -c standard -l $REGION_DEFAULT gs://$BUCKET_NAME
gsutil versioning set on gs://$BUCKET_NAME
Note: I recommend customers to centralize the terraform bucket in a specific project.
roles/compute.networkAdmin
네트워크 폴더 수준.roles/compute.xpnAdmin
Spoke 폴더 수준에서 사용할 수 있습니다.roles/storage.objectAdmin
mycompany-secops
프로젝트에 관하여.Note: To assign permissions to a Gitlab runner, please check out my latest article on .
다음 단계를 완료합니다
terraform.tfvars
.HUB_SUBNET_IP_RANGE=
ON_PREMISE_PEER_IP=
ON_PREMISE_NETWORK_IP_RANGE=
sed -i "s,<HUB_SUBNET_IP_RANGE>,${HUB_SUBNET_IP_RANGE},g;s,<ON_PREMISE_PEER_IP>,${ON_PREMISE_PEER_IP},g;s,<ON_
PREMISE_NETWORK_IP_RANGE>,${ON_PREMISE_NETWORK_IP_RANGE},g" plan/terraform.tfvars
repo mycompany network hub/.gitlab ci.아마르stages:
- init
- deploy
# Install Terraform
.install:
before_script:
- apt-get update
- apt-get install -y zip unzip
- curl -sS "https://releases.hashicorp.com/terraform/0.14.7/terraform_0.14.7_linux_amd64.zip" > terraform.zip
- unzip terraform.zip -d /usr/bin
init terraform:
extends: .install
stage: init
image:
name: google/cloud-sdk
script:
- cd plan
- gcloud config set project mycompany-network-hub
- terraform init -backend-config="bucket=bucket-mycompany-terraform-backend" -backend-config="prefix=network/hub/terraform/state"
artifacts:
paths:
- plan/.terraform
only:
- master
tags:
- k8s-network-runner
deploy terraform:
extends: .install
stage: deploy
image:
name: google/cloud-sdk
script:
- cd plan
- gcloud config set project mycompany-network-hub
- terraform apply -auto-approve
only:
- master
tags:
- k8s-network-runner
다음 단계를 완료합니다terraform.tfvars
.ENV=
SPOKE_SUBNET_IP_RANGE=
SPOKE_SUBNET_PODS_IP_RANGE=
SPOKE_SUBNET_SERVICES_IP_RANGE=
sed -i "s,<ENV>,${ENV},g;s,<SPOKE_SUBNET_IP_RANGE>,${SPOKE_SUBNET_IP_RANGE},g;s,<SPOKE_SUBNET_PODS_IP_RANGE>,${SPOKE_SUBNET_PODS_IP_RANGE},g;s,<SPOKE_SUBNET_SERVICES_IP_RANGE>,${SPOKE_SUBNET_SERVICES_IP_RANGE},g" envs/$ENV/terraform.tfvars
mycompany 네트워크 스포일러 재구매.gitlab ci.아마르stages:
- init
- deploy
init terraform:
stage: init
image:
name: google/cloud-sdk
script:
- cd envs/$ENV
- gcloud config set project mycompany-network-spoke-$ENV
- terraform init -backend-config="bucket=bucket-mycompany-terraform-backend" -backend-config="prefix=network/spoke/$ENV/terraform/state" ../../plan/
artifacts:
paths:
- envs/$ENV/.terraform
only:
- master
tags:
- k8s-network-runner
deploy terraform:
stage: deploy
image:
name: google/cloud-sdk
script:
- cd envs/$ENV
- gcloud config set project mycompany-network-spoke-$ENV
- terraform apply -auto-approve ../../plan/
only:
- master
tags:
- k8s-network-runner
휠과 스포크 사이에 연결을 설정하면 서비스 항목을 주 항목에 추가할 수 있습니다.gcloud config set project mycompany-business-$ENV
gcloud beta compute shared-vpc associated-projects add mycompany-business-$ENV --host-project mycompany-network-spoke-$ENV
PROJECT_NUMBER=$(gcloud projects list --filter="$(gcloud config get-value project)" --format="value(PROJECT_NUMBER)")
gcloud projects add-iam-policy-binding mycompany-network-spoke-$ENV --member "serviceAccount:$PROJECT_NUMBER@cloudservices.gserviceaccount.com" --role "roles/compute.networkUser"
gcloud projects add-iam-policy-binding mycompany-network-spoke-$ENV --member "serviceAccount:service-$PROJECT_NUMBER@compute-system.iam.gserviceaccount.com" --role "roles/compute.networkUser"
서비스 프로젝트에서 실행되는 모든 계산 자원은 자동으로 로컬 작업 부하에 접근할 것이며, 반대로도 마찬가지다.한층 더
연결 보안을 강화하기 위해 다음과 같은 몇 가지를 구현할 수 있습니다organization policy constraints.
compute.restrictVpnPeerIPs
compute.restrictDedicatedInterconnectUsage
compute.restrictPartnerInterconnectUsage
compute.restrictVpcPeering
compute.restrictCloudNATUsage
compute.restrictXpnProjectLienRemoval
compute.restrictSharedVpcHostProjects
compute.restrictSharedVpcSubnetworks
compute.skipDefaultNetworkCreation
compute.vmExternalIpAccess
만약 당신의 비즈니스 프로젝트에 개인 GKE 집단이 있다면, POD에서 내부 네트워크를 접할 수 없습니다.POD에서 온 모든 데이터를 강제로 위장해야 합니다[5].
로컬 프로젝트와 업무 프로젝트 사이에서 DNS를 해석해야 한다면 중심 복사 모델과 유사한 DNS 토폴로지를 실현할 수 있다.
이것은 아마도 새로운 댓글의 주제일 것이다😄.
결론
본고에서 우리는 Terraform과 Gitlab CI를 사용하여 구글 클라우드에서 중심 복사 네트워크 토폴로지를 실현했다.
이런 토폴로지 구조는 대부분의 용례의 확장 가능한 네트워크 체계 구조를 확보했다.
질문이나 피드백이 있으면 언제든지 댓글을 달아주세요.
그렇지 않으면 또래와 나누는 것을 주저하지 마라😊
읽어주셔서 감사합니다!
문서
[1] https://cloud.google.com/solutions/hybrid-and-multi-cloud-network-topologies
[2] https://en.wikipedia.org/wiki/Spoke%E2%80%93hub_distribution_paradigm
[3] https://en.wikipedia.org/wiki/Star_network
[4] https://cloud.google.com/solutions/deploying-nat-gateways-in-a-hub-and-spoke-architecture-using-vpc-network-peering-and-routing
[5] https://cloud.google.com/kubernetes-engine/docs/how-to/ip-masquerade-agent
Reference
이 문제에 관하여(구글 클라우드에서 점차 중심 복사식 네트워크 토폴로지 실현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/stack-labs/implementing-step-by-step-the-hub-and-spoke-network-topology-in-google-cloud-57n4
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
[1] https://cloud.google.com/solutions/hybrid-and-multi-cloud-network-topologies
[2] https://en.wikipedia.org/wiki/Spoke%E2%80%93hub_distribution_paradigm
[3] https://en.wikipedia.org/wiki/Star_network
[4] https://cloud.google.com/solutions/deploying-nat-gateways-in-a-hub-and-spoke-architecture-using-vpc-network-peering-and-routing
[5] https://cloud.google.com/kubernetes-engine/docs/how-to/ip-masquerade-agent
Reference
이 문제에 관하여(구글 클라우드에서 점차 중심 복사식 네트워크 토폴로지 실현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/stack-labs/implementing-step-by-step-the-hub-and-spoke-network-topology-in-google-cloud-57n4텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)