Terraform AWS EKS-无法将EFS卷挂载到Fargate Pod

如何解决Terraform AWS EKS-无法将EFS卷挂载到Fargate Pod

我已经为此连续工作了将近5天,无法使它正常工作。根据AWS文档,我应该*能够将EFS卷安装到已部署到kubernetes(EKS)中的Fargate节点的Pod中。

我正在通过Terraform 100%进行所有操作。在这一点上,我迷路了,而我所阅读的可怕文档几乎使我的眼睛流血。任何人都可以给我的有关使它正常工作的指导都将是惊人的!

这是我到目前为止所做的:

  1. 设置EKS CSI驱动程序,存储类和角色绑定(不确定我为什么需要这些角色绑定tbh)
resource "kubernetes_csi_driver" "efs" {
  metadata {
    name = "efs.csi.aws.com"
  }

  spec {
    attach_required        = false
    volume_lifecycle_modes = [
      "Persistent"
    ]
  }
}

resource "kubernetes_storage_class" "efs" {
  metadata {
    name = "efs-sc"
  }
  storage_provisioner = kubernetes_csi_driver.efs.metadata[0].name
  reclaim_policy      = "Retain"
}

resource "kubernetes_cluster_role_binding" "efs_pre" {
  metadata {
    name = "efs_role_pre"
  }
  role_ref {
    api_group = "rbac.authorization.k8s.io"
    kind      = "ClusterRole"
    name      = "cluster-admin"
  }
  subject {
    kind      = "ServiceAccount"
    name      = "default"
    namespace = "pre"
  }
}

resource "kubernetes_cluster_role_binding" "efs_live" {
  metadata {
    name = "efs_role_live"
  }
  role_ref {
    api_group = "rbac.authorization.k8s.io"
    kind      = "ClusterRole"
    name      = "cluster-admin"
  }
  subject {
    kind      = "ServiceAccount"
    name      = "default"
    namespace = "live"
  }
}
  1. 使用策略和安全组设置EFS卷
module "vpc" {
  source    = "../../read_only_data/vpc"
  stackname = var.vpc_stackname
}
resource "aws_efs_file_system" "efs_data" {
    creation_token = "xva-${var.environment}-pv-efsdata-${var.side}"

    # encrypted   = true
    # kms_key_id  = ""

    performance_mode = "generalPurpose" #maxIO
    throughput_mode  = "bursting"
    
    lifecycle_policy {
        transition_to_ia = "AFTER_30_DAYS"
    }
}

data "aws_efs_file_system" "efs_data" {
  file_system_id = aws_efs_file_system.efs_data.id
}

resource "aws_efs_access_point" "efs_data" {
  file_system_id = aws_efs_file_system.efs_data.id
}

/* Policy that does the following:
- Prevent root access by default
- Enforce read-only access by default
- Enforce in-transit encryption for all clients
*/
resource "aws_efs_file_system_policy" "efs_data" {
  file_system_id = aws_efs_file_system.efs_data.id

  policy = jsonencode({
    "Version": "2012-10-17","Statement": [
        {
            "Effect": "Allow","Principal": {
                "AWS": "*"
            },"Action": "elasticfilesystem:ClientMount","Resource": aws_efs_file_system.efs_data.arn
        },{
            "Effect": "Deny","Action": "*","Resource": aws_efs_file_system.efs_data.arn,"Condition": {
                "Bool": {
                    "aws:SecureTransport": "false"
                }
            }
        }
    ]
  })
}

# Security Groups for this volume
resource "aws_security_group" "allow_eks_cluster" {
  name        = "xva-${var.environment}-efsdata-${var.side}"
  description = "This will allow the cluster ${data.terraform_remote_state.cluster.outputs.eks_cluster_name} to access this volume and use it."
  vpc_id      = module.vpc.vpc_id

  ingress {
    description = "NFS For EKS Cluster ${data.terraform_remote_state.cluster.outputs.eks_cluster_name}"
    from_port   = 2049
    to_port     = 2049
    protocol    = "tcp"
    security_groups = [
      data.terraform_remote_state.cluster.outputs.eks_cluster_sg_id
    ]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "allow_tls"
  }
}

# Mount to the subnets that will be using this efs volume
# Also attach sg's to restrict access to this volume
resource "aws_efs_mount_target" "efs_data-app01" {
  file_system_id = aws_efs_file_system.efs_data.id
  subnet_id      = module.vpc.private_app_subnet_01

  security_groups = [
    aws_security_group.allow_eks_cluster.id
  ]
}

resource "aws_efs_mount_target" "efs_data-app02" {
  file_system_id = aws_efs_file_system.efs_data.id
  subnet_id      = module.vpc.private_app_subnet_02

  security_groups = [
    aws_security_group.allow_eks_cluster.id
  ]
}
  1. 创建一个持久化卷,引用kubernetes中的EFS卷
data "terraform_remote_state" "csi" {
  backend = "s3"
  config = {
    bucket  = "xva-${var.account_type}-terraform-${var.region_code}"
    key     = "${var.environment}/efs/driver/terraform.tfstate"
    region  = var.region
    profile = var.profile
  }
}
resource "kubernetes_persistent_volume" "efs_data" {
  metadata {
    name = "pv-efsdata"

    labels = {
        app = "example"
    }
  }

  spec {
    access_modes = ["ReadOnlyMany"]

    capacity = {
      storage = "25Gi"
    }

    volume_mode                      = "Filesystem"
    persistent_volume_reclaim_policy = "Retain"
    storage_class_name               = data.terraform_remote_state.csi.outputs.storage_name

    persistent_volume_source {
      csi {
        driver        = data.terraform_remote_state.csi.outputs.csi_name
        volume_handle = aws_efs_file_system.efs_data.id
        read_only    = true
      }
    }
  }
}
  1. 然后创建一个部署以与挂载EFS卷的Pod进行冲突
data "terraform_remote_state" "efs_data_volume" {
  backend = "s3"
  config = {
    bucket  = "xva-${var.account_type}-terraform-${var.region_code}"
    key     = "${var.environment}/efs/volume/terraform.tfstate"
    region  = var.region
    profile = var.profile
  }
}
resource "kubernetes_persistent_volume_claim" "efs_data" {
  metadata {
    name      = "pv-efsdata-claim-${var.side}"
    namespace = var.side
  }

  spec {
    access_modes       = ["ReadOnlyMany"]
    storage_class_name =  data.terraform_remote_state.csi.outputs.storage_name
    resources {
      requests = {
        storage = "25Gi"
      }
    }
    volume_name = data.terraform_remote_state.efs_data_volume.outputs.volume_name
  }
}

resource "kubernetes_deployment" "example" {
  timeouts {
    create = "3m"
    update = "4m"
    delete = "2m"
  }

  metadata {
    name      = "deployment-example"
    namespace = var.side

    labels = {
      app      = "example"
      platform = "fargate"
      subnet   = "app"
    }
  }

  spec {
    replicas = 1

    selector {
      match_labels = {
        app = "example"
      }
    }

    template {
      metadata {
        labels = {
          app      = "example"
          platform = "fargate"
          subnet   = "app"
        }
      }

      spec {
        volume {
          name = "efs-data-volume"
          
          persistent_volume_claim {
            claim_name = kubernetes_persistent_volume_claim.efs_data.metadata[0].name
            read_only  = true
          }
        }

        container {
          image = "${var.nexus_docker_endpoint}/example:${var.docker_tag}"
          name  = "example"

          env {
            name  = "environment"
            value = var.environment
          }
          env {
            name = "dockertag"
            value = var.docker_tag
          }

          volume_mount {
            name = "efs-data-volume"
            read_only = true
            mount_path = "/appconf/"
          }

          # liveness_probe {
          #   http_get {
          #     path = "/health"
          #     port = 443
          #   }

          #   initial_delay_seconds = 3
          #   period_seconds        = 3
          # }

          port {
            container_port = 443
          }
        }
      }
    }
  }
}

它可以看到以kuberenetes表示的持久性卷,我可以看到它已经声明了,哎呀,我什至可以看到它试图将其挂载到pod日志中。但是,在描述广告连播时,我不可避免地总是看到以下错误:

Volumes:
  efs-data-volume:
    Type:        PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:   pv-efsdata-claim-pre
    ReadOnly:    true
...
...
Events:
  Type     Reason       Age                  From                                                       Message
  ----     ------       ----                 ----                                                       -------
  Warning  FailedMount  11m (x629 over 23h)  kubelet,<redacted-fargate-endpoint>  Unable to attach or mount volumes: unmounted volumes=[efs-data-volume],unattached volumes=[efs-data-volume]: timed out waiting for the condition
  Warning  FailedMount  47s (x714 over 23h)  kubelet,<redacted-fargate-endpoint>  MountVolume.SetUp failed for volume "pv-efsdata" : kubernetes.io/csi: mounter.SetupAt failed: rpc error: code = InvalidArgument desc = Volume capability not supported

解决方法

我终于做到了。我已经成功将EFS卷安装到Fargate Pod(近6天后)!我可以从这个封闭的github问题中获得所需的指导:https://github.com/aws/containers-roadmap/issues/826

最终导致我正在使用此模块构建我的eks集群:https://registry.terraform.io/modules/cloudposse/eks-cluster/aws/0.29.0?tab=outputs

如果使用输出“ security_group_id”,则输出“其他安全组”。以我的经验,这绝对对aws毫无好处。不知道为什么当您无能为力时它甚至存在。我需要使用的安全组是“群集安全组”。因此,我在EFS卷安全组安装点和BAM的端口2049入口规则上添加了“群集安全组”的ID!我已将EFS卷成功安装到已部署的Pod。

另一个重要的更改是我将持久性卷类型更改为ReadWriteMany,因为fargate显然不支持ReadOnlyMany。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-