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

Автор: | 12/06/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:

[simterm]

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

[/simterm]

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

[simterm]

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

[/simterm]

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

[simterm]

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

[/simterm]

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

[simterm]

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

[/simterm]

Подсети

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

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

[simterm]

$ 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

[/simterm]

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

[simterm]

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

[/simterm]

Имя:

[simterm]

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

[/simterm]

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

[simterm]

$ 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

[/simterm]

VPC Internet Gateway

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

[simterm]

$ 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

[/simterm]

И VPC-B:

[simterm]

$ 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

[/simterm]

Route table

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

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

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

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

[simterm]

$ 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

[/simterm]

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

[simterm]

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

[/simterm]

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

[simterm]

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

[/simterm]

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

[simterm]

$ 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

[/simterm]

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:

[simterm]

$ 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"
    }
}

[/simterm]

Проверяем:

[simterm]

$ 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"
        }
    ]
]

[/simterm]

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

[simterm]

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

[/simterm]

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

[simterm]

$ 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"
    }
}

[/simterm]

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

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

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

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

[simterm]

$ ssh [email protected] -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

[/simterm]

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

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

  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:

[simterm]

$ 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
}

[/simterm]

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

[simterm]

$ 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
}

[/simterm]

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

[simterm]

$ ssh [email protected] -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

[/simterm]

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

[simterm]

$ ssh [email protected] -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

[/simterm]

Готово.