WebLog

LBを作ったときにdualstackを設定することで、ipv4とipv6に同時に対応できる

2023/07/21 22:38

はじめに

先日、route53 を眺めていたら、「dualstack」から始まるレコードがあった。

結論から言うと、「dualstack」とは ipv4 と ipv6 に同時に対応できる機能 のことらしい。

エイリアスレコードとは?

dualstack について説明する前に、エイリアスレコード について説明する。

エイリアスレコードは、route53 固有の機能で、ある AWS リソースに対してトラフィックをルーティングする機能のこと。

具体的には、AWS リソースを作ると、その AWS リソース固有の DNS 名が勝手に作られる。(例えば、hogehoge.ap-northeast-1.amazon.com)

主な使い方としては、A レコードの向き先に ip アドレスではなく、この DNS 名を指定する感じで使う。 その意味では、CNAME レコードっぽい。

  • 普通の A レコード
    • hogehoge.example.com -> x.x.x.x(ipv4 アドレス)
  • エイリアスレコードの機能を用いた A レコード
    • hogehoge.example.com -> hogehoge.ap-northeast-1.amazon.com(向き先に指定したい AWS リソースの DNS 名)
エイリアスレコードと非エイリアスレコードの選択 - Amazon Route 53エイリアスレコードと非エイリアスレコードの選択 - Amazon Route 53
エイリアスレコードと非エイリアスレコードの選択 - Amazon Route 53エイリアスレコードと非エイリアスレコードの選択 - Amazon Route 53

エイリアスレコードと非エイリアスレコードの選択 - Amazon Route 53エイリアスレコードと非エイリアスレコードの選択 - Amazon Route 53

Amazon Route 53 でエイリアスレコードを作成するかどうかを選択します。

なぜエイリアスレコードが必要なのか?

A レコードや AAAA レコードの向き先は ip アドレスだが、AWS リソースは ip アドレスが可変の場合が多い。(多分冗長性とかのため)

エイリアスレコードを使った A レコードだったら、AWS リソースの ip が変わっても、DNS 名が自動的に新しい ip アドレスを向いてくれるのでレコードを変更したりしなくていい。

エイリアスレコードを使用して AWS リソースにトラフィックをルーティングしている場合、Route 53 はリソースでの変更を自動的に認識します。例えば、エイリアスレコード example.com が lb1-1234.us-east-2.elb.amazonaws.com の ELB ロードバランサーを指し示しているとします。ロードバランサーの IP アドレスが変更された場合、Route 53 が自動的に開始され、新しい IP アドレスを使用して DNS クエリに応答します。(エイリアスレコードと非エイリアスレコードの選択)

dualstack とは?

以上を踏まえて、dualstack とは ipv4 アドレスと ipv6 アドレスの両方が引ける DNS 名のこと(もしくは、その機能のこと?)

つまり、エイリアスレコードの機能を用いて、A レコードの向き先にもできるし、AAAA レコードの向き先にもできる DNS 名のこと。

デフォルトだとこの DNS 名は「dualstack」から始まる。

実験してみる

基本がわかったところで、terraform で実際に作ってみようと思う。

ELB を作るだけじゃーんって思ったけど、vpc の ipv6 対応とかあんまりしたことなくて微妙に面倒だった。

terraform で作る

ざっとできたものが以下。

alb/main.tf
1locals {
2 az = ["ap-northeast-1a", "ap-northeast-1c"]
3}
4
5resource "aws_vpc" "main" {
6 cidr_block = "10.0.0.0/16"
7 assign_generated_ipv6_cidr_block = true
8
9 tags = {
10 Name = "dualstack-test-lb"
11 }
12}
13
14resource "aws_subnet" "public" {
15 count = 2
16 vpc_id = aws_vpc.main.id
17 cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)
18 ipv6_cidr_block = cidrsubnet(aws_vpc.main.ipv6_cidr_block, 8, count.index)
19 availability_zone = local.az[count.index]
20
21 tags = {
22 Name = "dualstack-test-lb-public${count.index}}"
23 }
24}
25
26resource "aws_internet_gateway" "main" {
27 vpc_id = aws_vpc.main.id
28
29 tags = {
30 Name = "dualstack-test-lb-igw"
31 }
32}
33
34resource "aws_route_table" "public" {
35 vpc_id = aws_vpc.main.id
36
37 route {
38 cidr_block = "0.0.0.0/0"
39 gateway_id = aws_internet_gateway.main.id
40 }
41}
42
43resource "aws_route_table_association" "public" {
44 count = 2
45 subnet_id = aws_subnet.public[count.index].id
46 route_table_id = aws_route_table.public.id
47}
48
49resource "aws_security_group" "lb_sg" {
50 name = "dualstack-test-lb-sg"
51 description = "Used in the terraform"
52 vpc_id = aws_vpc.main.id
53
54 ingress {
55 from_port = 80
56 to_port = 80
57 protocol = "tcp"
58 cidr_blocks = ["0.0.0.0/0"]
59 }
60
61 egress {
62 from_port = 0
63 to_port = 0
64 protocol = "-1"
65 cidr_blocks = ["0.0.0.0/0"]
66 }
67}
68
69resource "aws_lb" "main" {
70 name = "dualstack-test-lb"
71 internal = false
72 load_balancer_type = "application"
73 security_groups = [ aws_security_group.lb_sg.id ]
74 subnets = aws_subnet.public.*.id
75 ip_address_type = "ipv4" # dualstack or ipv4
76 enable_deletion_protection = false
77
78 tags = {
79 Name = "dualstack-test-lb"
80 }
81}
82
83resource "aws_lb_listener" "http" {
84 load_balancer_arn = aws_lb.main.arn
85 port = 80
86 protocol = "HTTP"
87
88 default_action {
89 type = "fixed-response"
90
91 fixed_response {
92 content_type = "text/plain"
93 message_body = "Hello, World"
94 status_code = "200"
95 }
96 }
97}
98

dig コマンドで実験

terraform で AWS リソースができたら、ELB の DNS 名をとってきて、dig コマンドで実験してみた。

ちなみに、dig コマンドは+short というオプションをつけることで、IP アドレスだけ出力できる。

Aレコード
1dig (dns名) +short # ipv4を引く

ipv6 アドレスを dig コマンドで引くには以下のような感じ

AAAAレコード
1# -t = type : DNSレコードの種類
2# @8.8.8.8 : DNSサーバーによってはipv6対応していないかもしれないのでGoogle Public DNS(8.8.8.8)をDNSサーバーに指定して問い合わせ
3dig -t AAAA @8.8.8.8 (dns名) +short # ipv6を引く

最新の投稿