AWS CDK Python-子网选择和ISubnet对象



背景

我正试图使用AWS CDK在Python中创建一个带有Cluster对象的EKS Cluster。

我有一个Stack,它构造了诸如VPCs和Subnets之类的网络对象。该Stack定义了三个";"类型";子网数:

  1. 控制子网组-包含EKS ENI
  2. 工作子网组-包含工作节点组
  3. 公共子网组-使用公共路由表,并负责ALB等

定义该信息的代码如下。这是来自我的网络堆栈:

# Define the number of subnets to create in a for loop later on. This will be a shared value between the worker, control, and public subnets. 
subnet_count = range(1,3)
# Create empty lists for each of our subnet types. These will hold our SubnetConfigurations that are passed to VPC creation
self.public_subnets = []
self.worker_subnets = []
self.control_subnets = []

# Loop through our defined range above, creating the appropriate control, worker, and public subnets, aligning to CIDRs above
for x in subnet_count:
x = str(x)
self.control_subnets.append(ec2.SubnetConfiguration(
name = 'Control-0{}'.format(x),
cidr_mask=28,
subnet_type = ec2.SubnetType.PRIVATE_WITH_NAT,
reserved = False
))
self.worker_subnets.append(ec2.SubnetConfiguration(
name = 'Worker-0{}'.format(x),
cidr_mask=24,
subnet_type = ec2.SubnetType.PRIVATE_WITH_NAT,
reserved = False
))
self.public_subnets.append(ec2.SubnetConfiguration(
name = 'Public-0{}'.format(x),
cidr_mask=27,
map_public_ip_on_launch=True,
subnet_type = ec2.SubnetType.PUBLIC,
reserved = False
))

然后我创建了一个VPC,用于EKS,通过打开这些SubnetConfiguration列表:

self.kubernetes_vpc = ec2.Vpc(self, 
"Kubernetes", 
cidr=my_cidr,
default_instance_tenancy=ec2.DefaultInstanceTenancy.DEFAULT,
enable_dns_hostnames=True,
enable_dns_support=True,
flow_logs=None,
gateway_endpoints=None,
max_azs=2,
nat_gateway_provider=ec2.NatProvider.gateway(),
nat_gateways=1, # this is 1 PER AZ
subnet_configuration=[*self.public_subnets,*self.control_subnets,*self.worker_subnets],
vpc_name="Kubernetes",
vpn_connections=None
)

我将此堆栈传递给EKS集群堆栈,称为my_network_stack

所以我现在要做的是,使用ec2.SubnetSelectionsubnet_group_name参数,特别调用在另一个堆栈中创建的控制子网的名称,并将这些名称移交给EKS堆栈中Clustervpc_subnets参数。

self.control_subnets = []
for subnet_config in my_network_stack.control_subnets:
self.selected_subnets = my_network_stack.kubernetes_vpc.select_subnets(subnet_group_name=subnet_config.name).subnets

my_network_stack.control_subnets是先前在网络堆栈中定义的self.control_subnets

这应该会给我一个基于控制子网组名称正确选择的ISubnet对象列表,我在这里设置了一个简单的测试:

for item in self.selected_subnets:
logging.debug(type(item))

返回

DEBUG:root:<class 'aws_cdk.aws_ec2.PrivateSubnet'>
DEBUG:root:<class 'aws_cdk.aws_ec2.PrivateSubnet'>

这些是ISubnet对象,对吗?

方法1

我的第一次尝试是为特定列表提供一个解包器,该列表应该是一组ISubnet对象(截断的集群参数(:

self.Cluster = eks.Cluster(
vpc_subnets = [
ec2.SubnetSelection(subnets=[*self.selected_subnets])
]

这给了我一个错误:

jsii.errors.JSIIError: Expected object reference, got "latest"

不完全确定我做错了什么。我已经尝试了一些传递正确的ISubnet对象列表的变体,即使我特别调用数组索引:

vpc_subnets = [
ec2.SubnetSelection(subnets=[self.selected_subnets[0], self.selected_subnets[1]])
]

但是发生了相同的错误。

方法2

使用实际的SubnetSelection函数获取ISubnet对象列表:

vpc_subnets = [
ec2.SubnetSelection(subnets= 
[my_network_stack.kubernetes_vpc.select_subnets(subnet_group_name=self.control_subnet_names[0]).subnets, my_network_stack.kubernetes_vpc.select_subnets(subnet_group_name=self.control_subnet_names[1])])
]

这给了我一个错误:

jsii.errors.JSIIError: Expected object reference, got [{"$jsii.byref":"aws-cdk-lib.aws_ec2.PrivateSubnet@10011"},{"$jsii.byref":"aws-cdk-lib.aws_ec2.PrivateSubnet@10012"}]

这看起来可能是带有实际ISubnet对象的字典引用列表,在这种情况下,不确定它比引用实际对象的方法1好多少。

pip freeze:的输出

$ pip freeze
attrs==21.4.0
aws-cdk-lib==2.8.0
cattrs==1.10.0
constructs==10.0.37
jsii==1.52.1
publication==0.0.3
python-dateutil==2.8.2
six==1.16.0
typing-extensions==4.0.1

更新:解决方案

正如回答者所指出的,这个错误expected object, got 'latest'与集群创建语句中的ALB版本有关,而不是与传入的子网有关。这一直是问题所在。我在下面包含了那个(坏的(代码:

self.cluster = eks.Cluster(
self,
"InfrastructureCluster",
default_capacity_type=eks.DefaultCapacityType.NODEGROUP,
alb_controller=eks.AlbControllerOptions(version='latest'),
endpoint_access=eks.EndpointAccess.PUBLIC_AND_PRIVATE,
version=eks.KubernetesVersion.V1_21,
cluster_name="InfrastructureCluster",
security_group=my_network_stack.controlplane_security_group,
vpc=my_network_stack.kubernetes_vpc,
vpc_subnets=
[
ec2.SubnetSelection(subnets=self.selected_subnets)
],
)

此外,这并不能解决子网中传递的问题,但我最终能够让这些代码发挥作用。这里的关键是select_subnets(subnet_group_name=subnet_config返回一个ISubnet对象列表,因此您必须将其分离为多个对象,然后将其解压缩到集群的vpc_subnets:中

for subnet_config in my_network_stack.control_subnets:
for item in my_network_stack.kubernetes_vpc.select_subnets(subnet_group_name=subnet_config.name).subnets:
self.selected_subnets.append(item)

# Later, during cluster creation:
vpc_subnets=
[
ec2.SubnetSelection(subnets=[*self.selected_subnets])
]

我只能让以上内容发挥作用,传入列表对象(SubnetSelection(subnets=[](需要列表(的组合会导致语法错误。

以下工作正常,不是问题的原因:

self.Cluster = eks.Cluster(
vpc_subnets = [SubnetSelection(subnets=selected_subnets)]

问题的原因是您在聊天中提供的Cluster初始化中的以下行:

alb_controller=eks.AlbControllerOptions(version="latest")

AlbControllerOptionsversion参数需要AlbControllerVersion的实例,而不是字符串。

正确的代码是:

alb_controller=eks.AlbControllerOptions(version=eks.AlbControllerVersion.V2_3_1),

相关内容

  • 没有找到相关文章

最新更新