ЁЯПв рдзрдбрд╛ 04 тАФ рдкреНрд░рддреНрдпреЗрдХ AZ рд▓рд╛ рдПрдХ рдлрд╛рдЯрдХ
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 8 рдкреИрдХреА рдзрдбрд╛ 04 ┬╖ рдорд╛рдЧреЗ: lesson-03-gateway-vs-instance ┬╖ рдкреБрдвреЗ: lesson-05-elastic-ips
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ03, рдЖрдгрд┐ рдЯрд┐рдХрд╛рдК рд░рдЪрдирд╛: рдкреНрд░рддреНрдпреЗрдХ Availability Zone рдордзреНрдпреЗ рдПрдХ NAT gateway,
рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ AZ рдЪреА private route table рддреНрдпрд╛рдЪ AZ рдордзреАрд▓ NAT рдХрдбреЗ рдирд┐рд░реНрджреЗрд╢ рдХрд░рддреЗ.
nat/demo.py рдордзреАрд▓ peraz() рджреЛрдиреНрд╣реА рд░рдЪрдирд╛рдВрдордзреНрдпреЗ рдПрдХ AZ рдмрдВрдж рдкрд╛рдбреВрди рдкрд╛рд╣рддреЗ.
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рд╢рд╛рд│реЗрдЪреНрдпрд╛ рддреАрди рдЗрдорд╛рд░рддреА рдЖрд╣реЗрдд ЁЯПвЁЯПвЁЯПв: A, B рдЖрдгрд┐ C. рдкреНрд░рддреНрдпреЗрдХреАрдЪреА рд╕реНрд╡рддрдГрдЪреА рд╡реАрдЬ рдЖрд╣реЗ.
рдЖрд░рд╛рдЦрдбрд╛ 1: рдлрдХреНрдд рдЗрдорд╛рд░рдд A рд▓рд╛ рдлрд╛рдЯрдХ рдЖрд╣реЗ. B рдЖрдгрд┐ C рдордзреАрд▓ рд╡рд┐рджреНрдпрд╛рд░реНрдерд┐рдиреА рдореИрджрд╛рди рдУрд▓рд╛рдВрдбреВрди A рдЪреНрдпрд╛ рдлрд╛рдЯрдХрд╛рдХрдбреЗ рдЬрд╛рддрд╛рдд. рдордЧ A рдЪреА рд╡реАрдЬ рдЬрд╛рддреЗ. рдкреНрд░рддреНрдпреЗрдХ рдЗрдорд╛рд░рддреАрддреАрд▓ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рджреНрдпрд╛рд░реНрдерд┐рдиреА рдЖрдд рдЕрдбрдХрддреЗ тАФ рдЖрдгрд┐ рдореИрджрд╛рди рдУрд▓рд╛рдВрдбрдгреНрдпрд╛рдЪреНрдпрд╛ рд▓рд╛рдВрдмрдЪреНрдпрд╛ рдЪрд╛рд▓реАрдд рд░реЛрдЬ рд╡реЗрд│рд╣реА рдЬрд╛рдд рд╣реЛрддрд╛.
рдЖрд░рд╛рдЦрдбрд╛ 2: рдкреНрд░рддреНрдпреЗрдХ рдЗрдорд╛рд░рддреАрд▓рд╛ рд╕реНрд╡рддрдГрдЪреЗ рдлрд╛рдЯрдХ рдЖрдгрд┐ рд╕реНрд╡рддрдГрдЪрд╛ рд░рдЦрд╡рд╛рд▓рджрд╛рд░ рдЖрд╣реЗ. A рдЪреА рд╡реАрдЬ рдЬрд╛рддреЗ. A рдордзреАрд▓ рд╡рд┐рджреНрдпрд╛рд░реНрдерд┐рдиреА рдЕрдбрдХрддрд╛рдд (рддреНрдпрд╛рдВрдЪреА рдЗрдорд╛рд░рдд рддрд╢реАрд╣реА рдЕрдВрдзрд╛рд░рд╛рдд рдЖрд╣реЗ). B рдЖрдгрд┐ C рдордзреАрд▓ рд╡рд┐рджреНрдпрд╛рд░реНрдерд┐рдиреА рдиреЗрд╣рдореАрдкреНрд░рдорд╛рдгреЗ рдЖрдкрд╛рдкрд▓реНрдпрд╛ рдлрд╛рдЯрдХрд╛рдВрддреВрди рдмрд╛рд╣реЗрд░ рдЬрд╛рддрд╛рдд.
AWS рдпрд╛ рдЗрдорд╛рд░рддреАрдВрдирд╛ Availability Zones рдореНрд╣рдгрддреЗ. рдореИрджрд╛рди рдУрд▓рд╛рдВрдбреВрди рдЬрд╛рдгреЗ рдореНрд╣рдгрдЬреЗ cross-AZ traffic, рдЖрдгрд┐ рддреНрдпрд╛рдЪреА рдХрд┐рдВрдордд рдореЛрдЬрд╛рд╡реА рд▓рд╛рдЧрддреЗ.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart TB
subgraph A["ЁЯПв AZ a ЁЯТе"]
pa["private-a"] --> na["nat-a"]
end
subgraph B["ЁЯПв AZ b"]
pb["private-b"] --> nb["nat-b"]
end
subgraph C["ЁЯПв AZ c"]
pc["private-c"] --> nc["nat-c"]
end
na -.->|"1 down with its AZ"| x["ЁЯЪл"]
nb -->|"2 still out"| net["ЁЯМР internet"]
nc -->|"2 still out"| net
ЁЯЧ║я╕П рдХрд╛рдврд▓реЗрд▓реА рдЖрдХреГрддреА + рдПрдХ lab: https://school-edh.pages.dev/nat/lesson-diagrams.html#l04
тЭУ рдХрд╛рдп
- NAT gateway рдПрдХрд╛рдЪ AZ рдордзреНрдпреЗ рд░рд╛рд╣рддреЛ тАФ рддреЛ рдПрдХрд╛ subnet рдордзреНрдпреЗ рддрдпрд╛рд░ рд╣реЛрддреЛ, рдЖрдгрд┐ subnet рдПрдХрд╛рдЪ AZ рдордзреНрдпреЗ рдЕрд╕рддреЗ. AWS рддреНрдпрд╛рд▓рд╛ рдлрдХреНрдд рддреНрдпрд╛ AZ рдЪреНрдпрд╛ рдЖрдд redundant рдмрдирд╡рддреЗ.
- рдкреНрд░рддреНрдпреЗрдХ AZ рд▓рд╛ рдПрдХ тАФ рддреБрдореНрд╣реА рд╡рд╛рдкрд░рдд рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ AZ рдЪреНрдпрд╛ public subnet рдордзреНрдпреЗ NAT gateway рддрдпрд╛рд░ рдХрд░рд╛.
- рдкреНрд░рддреНрдпреЗрдХ AZ рдЪреА route table тАФ рдкреНрд░рддреНрдпреЗрдХ AZ рдЪреНрдпрд╛ private subnets рдирд╛ рддреНрдпрд╛рдВрдЪреА рд╕реНрд╡рддрдГрдЪреА route table рджреНрдпрд╛:
private-a: 0.0.0.0/0 тЖТ nat-a,private-b: 0.0.0.0/0 тЖТ nat-b,private-c: 0.0.0.0/0 тЖТ nat-c. рдПрдХрдЪ shared private route table рд╣реЗ рдХрд░реВ рд╢рдХрдд рдирд╛рд╣реА тАФ рддреА рдлрдХреНрдд рдПрдХрд╛рдЪ NAT рдЪреЗ рдирд╛рд╡ рд▓рд┐рд╣реВ рд╢рдХрддреЗ. - Blast radius тАФ рдкреНрд░рддреНрдпреЗрдХ AZ рд▓рд╛ рдПрдХ NAT рдЕрд╕реЗрд▓ рддрд░ AZ рдмрдВрдж рдкрдбрд▓реНрдпрд╛рдЪрд╛ рдкрд░рд┐рдгрд╛рдо рдлрдХреНрдд рддреНрдпрд╛рдЪ AZ рд╡рд░ рд╣реЛрддреЛ, рдЬреНрдпрд╛рдЪреЗ рд╕реНрд╡рддрдГрдЪреЗ servers рддрд╕реЗрд╣реА рдЧреЗрд▓реЗрд▓реЗ рдЕрд╕рддрд╛рдд. рдПрдХрдЪ shared NAT рдЕрд╕реЗрд▓ рддрд░ рддреНрдпрд╛рдЪрд╛ AZ рдмрдВрдж рдкрдбрд▓рд╛ рдХреА рдкреНрд░рддреНрдпреЗрдХ AZ рддреБрдЯрддреЛ.
- Cross-AZ data тАФ рдПрдХрдЪ shared NAT рдЕрд╕реЗрд▓ рддрд░ рдЗрддрд░ AZs рдордзреАрд▓ рдкреНрд░рддреНрдпреЗрдХ byte AZs рдУрд▓рд╛рдВрдбрддреЛ рдЖрдгрд┐ NAT рдЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ per-GB fee рдЪреНрдпрд╛ рд╡рд░ cross-AZ data transfer charge рднрд░рддреЛ.
- рджреЗрд╡рд╛рдгрдШреЗрд╡рд╛рдг тАФ рддреАрди NATs рдореНрд╣рдгрдЬреЗ рддреАрди рддрд╛рд╕рд╛рдЪреЗ charges. Dev рдЖрдгрд┐ test рд╕рд╛рдареА рдПрдХрдЪ shared NAT рд╣реА рдиреЗрд╣рдореАрдЪреА, рд╕реНрд╡реАрдХрд╛рд░рд╛рд░реНрд╣ рдмрдЪрдд рдЖрд╣реЗ.
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг AZs рдЦрд░реЛрдЦрд░ рдмрдВрдж рдкрдбрддрд╛рдд тАФ рд╡реАрдЬ, cooling, network тАФ рдЖрдгрд┐ multi-AZ apps рдЕрд╢рд╛рдЪ рдмрд╛рдВрдзрд▓реНрдпрд╛ рдЬрд╛рддрд╛рдд рдХреА рдПрдЦрд╛рджрд╛ AZ рдЧреЗрд▓рд╛ рддрд░реА рдЪрд╛рд▓реЗрд▓. рдПрдХрдЪ shared NAT, multi-AZ рд░рдЪрдирд╛ рдЬреЛ single point of failure рдХрд╛рдврдгреНрдпрд╛рд╕рд╛рдареА рд╣реЛрддреА, рддреЛрдЪ рдЧреБрдкрдЪреВрдк рдкрд░рдд рдЖрдгрддреЛ: AZ b рдЖрдгрд┐ c рдордзреАрд▓ app servers рдЯрд┐рдХрддрд╛рдд, рдкрдг рддреЗ payment API рдкрд░реНрдпрдВрдд рдкреЛрд╣реЛрдЪреВ рд╢рдХрдд рдирд╛рд╣реАрдд.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
nat/gateway.py рдордзреАрд▓ route_for() "рд╣реЗ private subnet рдХреЛрдгрддрд╛ NAT рд╡рд╛рдкрд░рддреЗ?" рдпрд╛рдЪреЗ
рдЙрддреНрддрд░ рджреЗрддреЗ тАФ рдкреНрд░рддреНрдпреЗрдХ AZ рд▓рд╛ рдПрдХ рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рд░рдЪрдиреЗрдд nat_by_az[az], рдХрд┐рдВрд╡рд╛ рддреБрдореНрд╣реА рджрд┐рд▓рд╛ рддрд░ shared.
reachable() рд╕рд╛рдВрдЧрддреЗ рдХреА рддреЛ NAT up рдЖрд╣реЗ рдХрд╛. nat/demo.py рдордзреАрд▓ peraz()
nat-a рдмрдВрдж рдХрд░рддреЗ рдЖрдгрд┐ рджреЛрдиреНрд╣реА рд░рдЪрдирд╛рдВрдордзреНрдпреЗ рддрд┐рдиреНрд╣реА AZs рддрдкрд╛рд╕рддреЗ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 nat/demo.py peraz
python3 - <<'EOF'
import sys; sys.path.insert(0, "nat"); from gateway import NatGateway, route_for, reachable, monthly_cost
gws = {n: NatGateway(n, [ip], az) for n, ip, az in (("nat-a", "13.232.10.20", "a"), ("nat-b", "13.232.10.21", "b"), ("nat-c", "13.232.10.22", "c"))}
by_az = {"a": "nat-a", "b": "nat-b", "c": "nat-c"}
print("routes per AZ:", [route_for(az, by_az) for az in "abc"], "┬╖ shared:", [route_for(az, by_az, "nat-a") for az in "abc"])
gws["nat-b"].up = False
print("nat-b down, one per AZ :", [az for az in "abc" if reachable(az, by_az, gws)])
print("nat-b down, shared nat-a:", [az for az in "abc" if reachable(az, by_az, gws, "nat-a")])
print("hours only: 3 NATs", monthly_cost(3, 0), "┬╖ 1 NAT", monthly_cost(1, 0))
EOF
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
peraz рд╣реЗ ЁЯТе AZ a goes down (nat-a with it) рдЫрд╛рдкрддреЗ, рдордЧ
private-b: one-per-AZ тЖТ тЬЕ ┬╖ one shared nat-a тЖТ ЁЯЪл cut off (рдЖрдгрд┐
private-c рд╕рд╛рдареАрд╣реА рддрд╕реЗрдЪ). рддреБрдордЪрд╛ snippet рд╣реЗ рдЫрд╛рдкрддреЛ:
routes per AZ: ['nat-a', 'nat-b', 'nat-c'] ┬╖ shared: ['nat-a', 'nat-a', 'nat-a']
nat-b down, one per AZ : ['a', 'c']
nat-b down, shared nat-a: ['a', 'b', 'c']
hours only: 3 NATs 98.55 ┬╖ 1 NAT 32.85
рддрд┐рд╕рд░реА рдУрд│ рдиреАрдЯ рд╡рд╛рдЪрд╛. AZ b рдмрдВрдж рдкрдбрддреЛ рддреЗрд╡реНрд╣рд╛ shared рд░рдЪрдирд╛ рдареАрдХ рджрд┐рд╕рддреЗ тАФ рдлрд╛рдЯрдХ AZ a рдордзреНрдпреЗ рдЖрд╣реЗ. Shared рд░рдЪрдирд╛ рд░реЛрдЬ рдмрд┐рдШрдбрд▓реЗрд▓реА рдирд╕рддреЗ; рддреА рддреНрдпрд╛рдЪ рджрд┐рд╡рд╢реА рдмрд┐рдШрдбрддреЗ рдЬреНрдпрд╛ рджрд┐рд╡рд╢реА рдмрдВрдж рдкрдбрдгрд╛рд░рд╛ AZ рдлрд╛рдЯрдХ рдЕрд╕рд▓реЗрд▓рд╛рдЪ рдЕрд╕рддреЛ. рдХреЛрдгрддрд╛ AZ рдмрдВрдж рдкрдбреЗрд▓ рд╣реЗ рддреБрдореНрд╣реА рдирд┐рд╡рдбреВ рд╢рдХрдд рдирд╛рд╣реА. рд╢реЗрд╡рдЯрдЪреА рдУрд│ рдореНрд╣рдгрдЬреЗ рд╕реБрд░рдХреНрд╖рд┐рддрддреЗрдЪреА рдХрд┐рдВрдордд: рдПрдХрд╛ рдРрд╡рдЬреА рддреАрди рддрд╛рд╕рд╛рдЪреЗ рдореАрдЯрд░ (рдЙрджрд╛рд╣рд░рдг рдХрд┐рдорддреА, рдХреЛрдгрддреНрдпрд╛рд╣реА GB рдЖрдзреА).
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
рдкреНрд░рддреНрдпреЗрдХ AZ рд▓рд╛ рдПрдХ NAT рдЕрд╕реЗрд▓ рддрд░ AZ рдЪрд╛ рдмрд┐рдШрд╛рдб рддреНрдпрд╛ AZ рдЪреНрдпрд╛ рдЖрддрдЪ рд░рд╛рд╣рддреЛ; рдПрдХрдЪ shared NAT рдЕрд╕реЗрд▓ рддрд░ рддреЗ рдирд╢рд┐рдмрд╛рд╡рд░ рдЕрд╡рд▓рдВрдмреВрди рдЕрд╕рддреЗ тАФ рдЖрдгрд┐ рд╕реБрд░рдХреНрд╖рд┐рдд рд░рдЪрдиреЗрд╕рд╛рдареА рджреЛрди рдЬрд╛рд╕реНрддреАрдЪреЗ рддрд╛рд╕рд╛рдЪреЗ charges рд▓рд╛рдЧрддрд╛рдд.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- tutorial рдордзреВрди copy рдХреЗрд▓реЗрд▓реА, рд╕рдЧрд│реНрдпрд╛ AZs рд╕рд╛рдареА рдПрдХрдЪ private route table тАФ рддреА рдлрдХреНрдд рдПрдХрд╛рдЪ NAT рдХрдбреЗ рдирд┐рд░реНрджреЗрд╢ рдХрд░реВ рд╢рдХрддреЗ
- рддреАрди NAT gateways рддрдпрд╛рд░ рдХреЗрд▓реЗ, рдкрдг copy-paste рдореБрд│реЗ рдкреНрд░рддреНрдпреЗрдХ route table
nat-aрдХрдбреЗрдЪ рдирд┐рд░реНрджреЗрд╢ рдХрд░рддреЗ - AZ a рдордзреАрд▓ NAT gateway "рддрд╛рддреНрдкреБрд░рддрд╛" AZ b рд▓рд╛ рд╕реЗрд╡рд╛ рджреЗрддреЛ тАФ рдЖрдгрд┐ рдорд╛рдЧреЛрдорд╛рдЧ рдпреЗрдгрд╛рд░реЗ cross-AZ bill
- рдирдВрддрд░ рдЬреЛрдбрд▓реЗрд▓реНрдпрд╛ рдирд╡реНрдпрд╛ AZ рд▓рд╛ рд╕реБрджреНрдзрд╛ рд╕реНрд╡рддрдГрдЪрд╛ NAT рдЖрдгрд┐ route table рд▓рд╛рдЧрддреЗ рд╣реЗ рд╡рд┐рд╕рд░рдгреЗ
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд
рдЦрд▒реНрдпрд╛ account рд╡рд░ тАФ рдкреНрд░рддреНрдпреЗрдХ AZ рд╕рд╛рдареА рдПрдХ NAT gateway рдЖрдгрд┐ рдПрдХ private route рдпрд╛рд╕рд╛рдареА Terraform:
locals { azs = ["a", "b", "c"] }
resource "aws_eip" "nat" {
for_each = toset(local.azs)
domain = "vpc"
}
resource "aws_nat_gateway" "this" {
for_each = toset(local.azs)
allocation_id = aws_eip.nat[each.key].id
subnet_id = aws_subnet.public[each.key].id
tags = { Name = "nat-${each.key}" }
}
resource "aws_route" "private_default" {
for_each = toset(local.azs)
route_table_id = aws_route_table.private[each.key].id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.this[each.key].id
}
рдкреНрд░рддреНрдпреЗрдХ private route table рддреНрдпрд╛рдЪреНрдпрд╛рдЪ AZ рдордзреАрд▓ NAT рдХрдбреЗ рдирд┐рд░реНрджреЗрд╢ рдХрд░рддреЗ рд╣реЗ рддрдкрд╛рд╕рд╛:
aws ec2 describe-route-tables --filters Name=vpc-id,Values=vpc-0abc --query 'RouteTables[].[RouteTableId,Associations[0].SubnetId,Routes[?DestinationCidrBlock==`0.0.0.0/0`].NatGatewayId|[0]]' --output table
aws ec2 describe-nat-gateways --filter Name=vpc-id,Values=vpc-0abc --query 'NatGateways[].[NatGatewayId,SubnetId]' --output table
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: "рдПрдХ AZ рдЧреЗрд▓рд╛ рддрд░ рдХрд╛рдп рд╣реЛрддреЗ?" рд╣рд╛ рдкреНрд░рддреНрдпреЗрдХ architecture review рдордзреАрд▓ рдкрд╣рд┐рд▓рд╛ рдкреНрд░рд╢реНрди рдЕрд╕рддреЛ. Egress рд╕рд╛рдареА рдмрд░реЛрдмрд░ рдЙрддреНрддрд░ рдЖрд╣реЗ "рдкреНрд░рддреНрдпреЗрдХ AZ рдЪрд╛ рд╕реНрд╡рддрдГрдЪрд╛ NAT рдЖрд╣реЗ; рдЖрдкрдг рддреЛ AZ рдЧрдорд╛рд╡рддреЛ, рдмрд╛рдХреА рдХрд╛рд╣реА рдирд╛рд╣реА".
тПня╕П рдкреБрдвреЗ
рдмрд╛рд╣реЗрд░ рдЬрд╛рдгрд╛рд░реА рдкреНрд░рддреНрдпреЗрдХ рдлреЗрд░реА рдлрд╛рдЯрдХрд╛рдЪрд╛ рдкрддреНрддрд╛ рдШреЗрдКрди рдмрд╛рд╣реЗрд░ рдкрдбрддреЗ. Partners рддреНрдпрд╛ рдкрддреНрддреНрдпрд╛рд╡рд░ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдареЗрд╡реВ рд╢рдХрддрд╛рдд тАФ рдкрдг рддреНрдпрд╛рдВрдиреА рдлрдХреНрдд рддреНрдпрд╛рд╡рд░рдЪ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдареЗрд╡рд╛рд╡рд╛ рдХрд╛? Elastic IPs рдЖрдгрд┐ allow-listing.
git checkout lesson-05-elastic-ips