我最近开始使用Terraform,作为VPC配置的一部分,我在netnum
函数中理解cidrsubnet()
时遇到了一些困难。
我调查了Terraform documentation,它说:
netnum
(第三个参数)是一个整数,可以表示为不超过newbits
二进制数字的二进制整数,用于填充添加到前缀的其他位 - 仍然有一些难以理解它。
例如:
cidrsubnet("100.121.0.0/20", 8,64) --> 100.121.4.0/28
cidrsubnet("10.1.2.0/24", 4, 15) --> 10.1.2.240/28
如果您能解释netnum
参数,请欣赏。
非常感谢,
的
使用cidrsubnet
需要熟悉一些网络寻址概念。
最重要的想法是IP地址(无论是IPv4还是IPv6)基本上是由二进制数字构成的,即使我们通常将其表示为四个十进制八位字节(对于IPv4)或一系列16位十六进制数字(对于IPv6) 。
以上面的cidrsubnet("10.1.2.0/24", 4, 15)
为例,该函数将首先将给定的IP地址字符串转换为等效的二进制表示:
10 . 1 . 2 . 0
00001010 00000001 00000010 | 00000000
network | host
前缀字符串末尾的/24
指定地址的前24位(或前三个八位字节)标识网络,而其余位(32 - 24 = 8位,在此情况下)标识网络。
CLI工具ipcalc
可用于将CIDR前缀可视化为二进制数。我们可以通过向ipcalc
提供相同的前缀字符串来确认上述转换:
$ ipcalc 10.1.2.0/24
Address: 10.1.2.0 00001010.00000001.00000010. 00000000
Netmask: 255.255.255.0 = 24 11111111.11111111.11111111. 00000000
Wildcard: 0.0.0.255 00000000.00000000.00000000. 11111111
=>
Network: 10.1.2.0/24 00001010.00000001.00000010. 00000000
HostMin: 10.1.2.1 00001010.00000001.00000010. 00000001
HostMax: 10.1.2.254 00001010.00000001.00000010. 11111110
Broadcast: 10.1.2.255 00001010.00000001.00000010. 11111111
Hosts/Net: 254 Class A, Private Internet
这为我们提供了一些额外的信息,但也确认了(使用略有不同的表示法)从十进制到二进制的转换,并显示了该网络中可能的主机地址范围。
虽然cidrhost
允许计算单个主机IP地址,但另一方面cidrsubnet
在给定网络前缀内创建新的网络前缀。换句话说,它创建了一个子网。
当我们调用cidrsubnet
时,我们还传递了两个额外的参数:newbits
和netnum
。 newbits
决定结果前缀的位数多长;在我们的示例中,我们指定了4
,这意味着生成的子网的前缀长度为24 + 4 = 28位。我们可以想象这些位分解如下:
10 . 1 . 2 . ? 0
00001010 00000001 00000010 | XXXX | 0000
parent network | netnum | host
最初为“主机号”的8位中的4位现在被重新用作子网号。网络前缀不再落在精确的八位字节边界上,因此实际上我们现在将IP地址中的最后一个十进制数分成两部分,其中一半用来表示子网号,另一半用来表示主机号。
然后,netnum
参数决定将哪个数值编码为这四个新子网位。在我们当前的例子中,我们传递了15
,它以二进制形式表示为1111
,允许我们在上面填写XXXX
段:
10 . 1 . 2 . 15 0
00001010 00000001 00000010 | 1111 | 0000
parent network | netnum | host
要将其转换回正常的十进制表示法,我们需要重新组合最终八位字节的两个部分。将11110000
从二进制转换为十进制给出240,然后可以将我们的新前缀长度28组合以产生结果10.1.2.240/28
。我们可以再次将此前缀字符串传递给ipcalc
以使其可视化:
$ ipcalc 10.1.2.240/28
Address: 10.1.2.240 00001010.00000001.00000010.1111 0000
Netmask: 255.255.255.240 = 28 11111111.11111111.11111111.1111 0000
Wildcard: 0.0.0.15 00000000.00000000.00000000.0000 1111
=>
Network: 10.1.2.240/28 00001010.00000001.00000010.1111 0000
HostMin: 10.1.2.241 00001010.00000001.00000010.1111 0001
HostMax: 10.1.2.254 00001010.00000001.00000010.1111 1110
Broadcast: 10.1.2.255 00001010.00000001.00000010.1111 1111
Hosts/Net: 14 Class A, Private Internet
新子网有四个可用于主机编号的位,这意味着一旦我们减去网络自己的地址和广播地址,就有14个主机地址可用于分配。因此,您可以使用cidrhost
函数通过提供1到14之间的值来计算这些主机地址:
> cidrhost("10.1.2.240/28", 1)
10.1.2.241
> cidrhost("10.1.2.240/28", 14)
10.1.2.254
有关CIDR表示法和子网划分的更多信息,请参阅Classless Inter-domain Routing。
(我在cidrsubnet
中将上面的内容添加到Terraform的PR #20828文档中;它应该在下一个Terraform版本发布后反映在主要的Terraform文档中。)