AWS: настройка VPC peering

By | 06/12/2018
 

VPC peering – соединение между двумя VPC, позволяющее ресурсам в этих сетях обмениваться трафиком, используя приватные IP адреса из подсетей тих VPC, как если бы они были в пределах одной сети.

VPC peering может быть установлен между вашими сетями, или между сетями из другого AWS аккаунта. Кроме того – можно создать подключение между VPC в разных регионах AWS.

Документация – тут>>>.

В посте ниже выполним создание сетей и двух ЕС2 в них, а затем настроим пиринг между этими VPC.

Ограничения

Кратко об основных ограничениях при использовании VPC peering:

  • сети и подсети VPC не должны перескаться, т.е. невозможно использовать блок адресов 10.0.0.0/16 и в VPC-A и VPC-B
  • маршрутизация трафика доступна только между двумя VPC и не допускает передачи трафика в третью сеть, т.е. вы не можете создать подключение между VPC-A и VPC-B, затем между VPC-B и VPC-C, а потом передавать трафик между VPC-A и VPC-C (но вы можете создать соединения между VPC-A => VPC-B  и VPC-A => VPC-C, и таким образом передавать трафик между VPC-A => VPC-C)

Больше см. тут>>>.

IAM 

Создание VPC

Создаём первую VPC, сеть 10.0.0.0/24:

aws --profile btrm-mon ec2 create-vpc --cidr-block 10.0.0.0/24

Добавляем тег Name:

aws --profile btrm-mon  ec2 create-tags --resources vpc-76e0b11e --tags Key=Name,Value=VPC-A

Вторую сеть, с блоком адресов 10.0.1.0/24:

aws --profile btrm-mon ec2 create-vpc --cidr-block 10.0.1.0/24

Задаём ей имя:

aws --profile btrm-mon  ec2 create-tags --resources vpc-8de0b1e5 --tags Key=Name,Value=VPC-B

Подсети

Создаём подсети в каждой из сетей.

Тут полезно будет использовать ipcalc, например получить список из 3-х подсетей для 10 хостов в сети 10.0.0.0/24 можно так:

ipcalc 10.0.0.0/24 -s 10 10 -b
Address:   10.0.0.0
Netmask:   255.255.255.0 = 24
Wildcard:  0.0.0.255
=>
Network:   10.0.0.0/24
HostMin:   10.0.0.1
HostMax:   10.0.0.254
Broadcast: 10.0.0.255
Hosts/Net: 254                   Class A, Private Internet
1. Requested size: 10 hosts
Netmask:   255.255.255.240 = 28
Network:   10.0.0.0/28
HostMin:   10.0.0.1
HostMax:   10.0.0.14
Broadcast: 10.0.0.15
Hosts/Net: 14                    Class A, Private Internet
2. Requested size: 10 hosts
Netmask:   255.255.255.240 = 28
Network:   10.0.0.16/28
HostMin:   10.0.0.17
HostMax:   10.0.0.30
Broadcast: 10.0.0.31
Hosts/Net: 14                    Class A, Private Internet
Needed size:  32 addresses.
Used network: 10.0.0.0/27
Unused:
10.0.0.32/27
10.0.0.64/26
10.0.0.128/25

Но сейчас для примера нужна только одна подсеть, создаём её в VPC-A:

aws --profile btrm-mon  ec2 create-subnet --vpc-id vpc-76e0b11e --cidr-block 10.0.0.0/28

Имя:

aws --profile btrm-mon  ec2 create-tags --resources subnet-9cdd9bf4 --tags Key=Name,Value=vpc-a-subnet-1

Аналогично для VPC-B:

aws --profile btrm-mon  ec2 create-subnet --vpc-id vpc-8de0b1e5 --cidr-block 10.0.1.0/28
aws --profile btrm-mon  ec2 create-tags --resources subnet-309c7d7c --tags Key=Name,Value=vpc-b-subnet-1

VPC Internet Gateway

Добавляем два IGW – первый для VPC-A:

aws --profile btrm-mon ec2 create-internet-gateway
aws --profile btrm-mon ec2 attach-internet-gateway --internet-gateway-id igw-c2d61baa --vpc-id vpc-76e0b11e
aws --profile btrm-mon ec2 create-tags --resources igw-c2d61baa --tags Key=Name,Value=vpc-a-igw

И VPC-B:

aws --profile btrm-mon ec2 create-internet-gateway
aws --profile btrm-mon ec2 attach-internet-gateway --internet-gateway-id igw-8ced20e4 --vpc-id vpc-8de0b1e5
aws --profile btrm-mon ec2 create-tags --resources igw-8ced20e4 --tags Key=Name,Value=vpc-b-igw

Route table

Создаём таблицы маршрутизации для каждой подсети.

Сейчас в них будет только один маршрут – в сеть 0.0.0.0/0, т.е. Интернет, через созданные IGW.

Позже – добавим маршруты для роутинга трафика между VPC.

Создаём таблицу маршрутизации для VPC-A:

aws --profile btrm-mon ec2 create-route-table --vpc-id vpc-76e0b11e
aws --profile btrm-mon ec2 create-tags --resources rtb-7b011313 --tags Key=Name,Value=vpc-a-rtb

Добавляем в неё правило маршрутизации в 0.0.0.0/0 через IGW-A:

aws --profile btrm-mon ec2 create-route --route-table-id rtb-7b011313 --destination-cidr-block 0.0.0.0/0 --gateway-id igw-c2d61baa

Подключаем эту таблицу маршрутзации к подсети-а:

aws --profile btrm-mon ec2 associate-route-table --route-table-id rtb-7b011313 --subnet-id subnet-9cdd9bf4

Повторяем для VPC-B:

aws --profile btrm-mon ec2 create-route-table --vpc-id vpc-8de0b1e5
aws --profile btrm-mon ec2 create-tags --resources rtb-cc0715a4 --tags Key=Name,Value=vpc-b-rtb
aws --profile btrm-mon ec2 create-route --route-table-id rtb-cc0715a4 --destination-cidr-block 0.0.0.0/0 --gateway-id igw-8ced20e4
aws --profile btrm-mon ec2 associate-route-table --route-table-id rtb-cc0715a4 --subnet-id subnet-309c7d7c

Peering

Теперь создаём собственно пиринг.

VPC-A у нас будет requester VPC, т.е. инициализатором пиринга, а VPC-B – accepter VPC.

Из VPC-A мы создаём запрос на создание пиринга с VPC-B. При этом, если VPC-B находится яв другом аккаунте – требуется так же указать --peer-owner-id, т.е. ID владельца VPC, с которой мы устанавливаем пиринг. По умолчанию используется ID аккаунта пользователя, от которого выполняется запрос.

В запросе ниже:

  • vpc-8de0b1e5 – VPC-B
  • vpc-76e0b11e – VPC-A

Выполняем create-vpc-peering-connection:

aws --profile btrm-mon ec2 create-vpc-peering-connection --peer-vpc-id vpc-8de0b1e5 --vpc-id vpc-76e0b11e
{
"VpcPeeringConnection": {
"AccepterVpcInfo": {
"OwnerId": "534***385",
"VpcId": "vpc-8de0b1e5",
"Region": "us-east-2"
},
"ExpirationTime": "2018-06-18T14:24:53.000Z",
"RequesterVpcInfo": {
"CidrBlock": "10.0.0.0/24",
"CidrBlockSet": [
{
"CidrBlock": "10.0.0.0/24"
}
],
"OwnerId": "534***385",
"PeeringOptions": {
"AllowDnsResolutionFromRemoteVpc": false,
"AllowEgressFromLocalClassicLinkToRemoteVpc": false,
"AllowEgressFromLocalVpcToRemoteClassicLink": false
},
"VpcId": "vpc-76e0b11e",
"Region": "us-east-2"
},
"Status": {
"Code": "initiating-request",
"Message": "Initiating Request to 534***385"
},
"Tags": [],
"VpcPeeringConnectionId": "pcx-04fcc26d"
}
}

Проверяем:

aws --profile btrm-mon ec2 describe-vpc-peering-connections --vpc-peering-connection-ids pcx-04fcc26d --query '[VpcPeeringConnections[*].Status]'
[
[
{
"Code": "pending-acceptance",
"Message": "Pending Acceptance by 534***385"
}
]
]

Запрос на создание пиринга будет действителен одну неделю:

aws --profile btrm-mon ec2 describe-vpc-peering-connections --vpc-peering-connection-ids pcx-04fcc26d --query '[VpcPeeringConnections[*].ExpirationTime]'
[
[
"2018-06-18T14:24:53.000Z"
]
]

Принимаем запрос с помощью accept-vpc-peering-connection:

aws --profile btrm-mon ec2 accept-vpc-peering-connection --vpc-peering-connection-id pcx-04fcc26d
{
"VpcPeeringConnection": {
"AccepterVpcInfo": {
"CidrBlock": "10.0.1.0/24",
"CidrBlockSet": [
{
"CidrBlock": "10.0.1.0/24"
}
],
"OwnerId": "534***385",
"PeeringOptions": {
"AllowDnsResolutionFromRemoteVpc": false,
"AllowEgressFromLocalClassicLinkToRemoteVpc": false,
"AllowEgressFromLocalVpcToRemoteClassicLink": false
},
"VpcId": "vpc-8de0b1e5",
"Region": "us-east-2"
},
"RequesterVpcInfo": {
"CidrBlock": "10.0.0.0/24",
"CidrBlockSet": [
{
"CidrBlock": "10.0.0.0/24"
}
],
"OwnerId": "534***385",
"PeeringOptions": {
"AllowDnsResolutionFromRemoteVpc": false,
"AllowEgressFromLocalClassicLinkToRemoteVpc": false,
"AllowEgressFromLocalVpcToRemoteClassicLink": false
},
"VpcId": "vpc-76e0b11e",
"Region": "us-east-2"
},
"Status": {
"Code": "provisioning",
"Message": "Provisioning"
},
"Tags": [],
"VpcPeeringConnectionId": "pcx-04fcc26d"
}
}

Проверяем в панели управления:

Таблица маршрутизации

Но сейчас роутинг между сетями ещё не работает.

Попробуем пропинговать интанс в сети Б (10.0.1.0/24) с интанса в сети А (10.0.0.0/24) – не забываем разрешить ICMP в группах безопасности:

ssh ubuntu@18.216.161.214 -i setevoy-testing-ohio.pem 'ip a s eth0 | grep -w inet; ping -c 1 10.0.1.5'
inet 10.0.0.10/28 brd 10.0.0.15 scope global eth0
PING 10.0.1.5 (10.0.1.5) 56(84) bytes of data.
--- 10.0.1.5 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

Что бы работал роутинг трафика между этими сетями – необходимо обновить таблицы маршрутизации для подсетей.

Сейчас у нас есть их две:

  1. rtb-7b011313 с именем vpc-a-rtb, подключенная к подсети subnet-9cdd9bf4 с именем vpc-a-subnet-1, 10.0.0.0/28
  2. rtb-cc0715a4 с именем vpc-b-rtb, подключенная к подсети subnet-309c7d7c с именем vpc-b-subnet-1, 10.0.1.0/28

В обеих таблицах по одному правилу – 0.0.0.0/0 через igw-ID (ещё есть правило для маршрутизации трафика внутри сети через local, но мы тут его не рассматриваем).

Теперь надо добавить ещё по одному правилу:

  1. для таблицы vpc-a-rtb – правило роутинга в сеть vpc-b-subnet-1, 10.0.1.0/28 через пиринг “VpcPeeringConnectionId”: “pcx-04fcc26d”
  2. для таблицы vpc-b-rtb – правило роутинга в сеть vpc-a-subnet-1, 10.0.0.0/28 через пиринг “VpcPeeringConnectionId”: “pcx-04fcc26d”

Документация – тут>>>.

Обновляем таблицу vpc-a-rtb:

aws --profile btrm-mon ec2 create-route --route-table-id rtb-7b011313 --destination-cidr-block 10.0.1.0/28 --vpc-peering-connection-id pcx-04fcc26d
{
"Return": true
}

И таблица подсети-Б:

aws --profile btrm-mon ec2 create-route --route-table-id rtb-cc0715a4 --destination-cidr-block 10.0.0.0/28 --vpc-peering-connection-id pcx-04fcc26d
{
"Return": true
}

Проверяем пинг из сети-А в сеть-Б:

ssh ubuntu@18.216.161.214 -i setevoy-testing-ohio.pem 'ip a s eth0 | grep -w inet; ping -c 1 10.0.1.5'
inet 10.0.0.10/28 brd 10.0.0.15 scope global eth0
PING 10.0.1.5 (10.0.1.5) 56(84) bytes of data.
64 bytes from 10.0.1.5: icmp_seq=1 ttl=64 time=1.28 ms
--- 10.0.1.5 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.286/1.286/1.286/0.000 ms

И из сети-Б в сеть-А:

ssh ubuntu@18.219.85.219 -i setevoy-testing-ohio.pem 'ip a s eth0 | grep -w inet; ping -c 1 10.0.0.10'
inet 10.0.1.5/28 brd 10.0.1.15 scope global eth0
PING 10.0.0.10 (10.0.0.10) 56(84) bytes of data.
64 bytes from 10.0.0.10: icmp_seq=1 ttl=64 time=1.19 ms
--- 10.0.0.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.195/1.195/1.195/0.000 ms

Готово.