Kubernetes 耗尽单个子网上的 IP

Posted

技术标签:

【中文标题】Kubernetes 耗尽单个子网上的 IP【英文标题】:Kubernetes exhausting IPs on a single subnet 【发布时间】:2022-01-22 02:46:16 【问题描述】:

我当前的 eks 集群与 4 个子网相关联,其中 4 个子网耗尽了单个子网的 IP 分配,这意味着没有 IP 可以分配给 pod。所有可用子网都有一个 /24 的 CIDR 块。谁能帮助我了解分配的工作原理以及它只考虑某个子网组而不在所有子网上进行分布式分配的可能原因是什么?

提前致谢。

【问题讨论】:

【参考方案1】:

您是否在多个子网上有工作人员?如果不这样做,那么只有单个子网中的节点才会添加 pod。

EKS 的一个好的做法是为每个子网的工作人员创建一个 ASG,这样可以确保只要该区域启动并运行,您就始终在该子网中拥有节点。

此外,这将解决具有持久卷的节点在错误的子网上重生并且无法连接到卷的问题。

这就是我通过 terraform 构建子网的方式。

module "vpc" 
  source = "terraform-aws-modules/vpc/aws"

  name                 = local.cluster_name
  cidr                 = module.subnet_addrs.base_cidr_block
  azs                  = data.aws_availability_zones.available.names
  private_subnets      = local.private_subnets
  public_subnets       = [module.subnet_addrs.network_cidr_blocks.pub1, module.subnet_addrs.network_cidr_blocks.pub2, module.subnet_addrs.network_cidr_blocks.pub3]
  enable_nat_gateway   = true
  single_nat_gateway   = true
  enable_dns_hostnames = true
  reuse_nat_ips        = true # <= Skip creation of EIPs for the NAT Gateways
  external_nat_ip_ids  = aws_eip.nat.*.id

  public_subnet_tags = 
    "kubernetes.io/cluster/$local.cluster_name" = "shared"
    "kubernetes.io/role/elb"                      = "1"
  

  private_subnet_tags = 
    "kubernetes.io/cluster/$local.cluster_name" = "shared"
    "kubernetes.io/role/internal-elb"             = "1"
  
  tags = local.tags


module "eks" 
  source = "terraform-aws-modules/eks/aws"

  cluster_name    = local.cluster_name
  cluster_version = var.cluster_version
  subnets         = module.vpc.private_subnets
  vpc_id          = module.vpc.vpc_id
  enable_irsa     = true
  map_roles       = concat(var.map_roles, local.map_roles)
  map_users       = var.map_users
  cluster_encryption_config = [
    
      provider_key_arn = aws_kms_key.eks.arn
      resources        = ["secrets"]
    
  ]
  cluster_endpoint_public_access_cidrs = var.cluster_endpoint_public_access_cidrs
  tags                                 = local.tags
  worker_groups                        = var.worker_groups

  worker_groups_launch_template = [
    
      name                 = "bottlerocket-nodes"
      ami_id               = local.bottlerocket_ami
      instance_type        = "t3a.small"
      asg_desired_capacity = 1

      # This section overrides default userdata template to pass bottlerocket
      # specific user data
      userdata_template_file = "$path.module/userdata.toml"
      # we are using this section to pass additional arguments for
      # userdata template rendering
      userdata_template_extra_args = 
        enable_admin_container   = false
        enable_control_container = true
        aws_region               = var.aws_region
      
      # example of k8s/kubelet configuration via additional_userdata
      additional_userdata = <<EOT
[settings.kubernetes.node-labels]
ingress = "allowed"
EOT
    
  ]
  node_groups_defaults = 
    ami_type = "AL2_x86_64"
  

  node_groups = local.node_groups

【讨论】:

是的,我的工人在多个子网上。 你的 pod 是否在多个节点上? 是的,Pod 也在多个节点上进行了调度。问题在于它使用单个私有子网进行分配,而不是分布式方式

以上是关于Kubernetes 耗尽单个子网上的 IP的主要内容,如果未能解决你的问题,请参考以下文章

Kubernetes AWS EKS 负载均衡器未配置

在AWS上配置基本的VPC

Kubernetes pod 应用程序与不在容器上的 Mysql 数据库的连接

无分类编址 CIDR (构成超网)

用bash实现一个kubernets CNI

谷歌云防火墙是不是默认阻止子网间流量?