在 AWS ECS Fargate 中,任务内无法进行容器间连接

Posted

技术标签:

【中文标题】在 AWS ECS Fargate 中,任务内无法进行容器间连接【英文标题】:In AWS ECS Fargate, inter-container connect is not possible within a task 【发布时间】:2021-11-29 21:18:58 【问题描述】:

假设和我想要实现的目标

我想在 ECS Fargate 上运行一个简单的 LAMP 应用程序。

我遇到的问题和错误消息

我无法从 php (Laravel) 容器访问 Mariadb 容器。

(与 ECS Exec 上的 php artisan migrate 相同的错误)

在这篇文章中,似乎可以在同一个任务中与 localhost 通信,但我无法访问它。

Linking Container in AWS Fargate error

SQLSTATE[HY000] [2002] 没有这样的文件或目录(SQL: ...

基础设施定义。

Laravel 和 MariaDB 容器都由 ECR 使用内置的 Dockerfile 管理。

*目前有很多东西需要调整,但我的目标是先让它工作,所以有些是多余的。

Laravel-Dockerfile

FROM php:7.4.24-apache

#install all the system dependencies and enable PHP modules 
RUN apt-get update \
  && apt-get install -y zlib1g-dev \
  && apt-get install -y zip unzip \
  && apt-get -y install libzip-dev libonig-dev \
  && docker-php-ext-install pdo_mysql mysqli zip \
  && docker-php-ext-enable mysqli \
  && a2enmod rewrite

ENV TZ=Asia/Tokyo

RUN apt-get update && apt-get install -y \
  busybox-static \
  && apt-get clean

#install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer
ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME /composer
ENV PATH $PATH:/composer/vendor/bin

#set our application folder as an environment variable
ENV APP_HOME /var/www/html

#change uid and gid of apache to docker user uid/gid
RUN usermod -u 1000 www-data && groupmod -g 1000 www-data

COPY ./php/vhost.conf /etc/apache2/conf-enabled/vhost.conf

# enable apache module rewrite
RUN a2enmod rewrite

#copy source files and run composer
COPY . $APP_HOME

RUN mkdir bootstrap/sessions
#RUN mkdir storage/framework/sessions && \
#    mkdir storage/framework/views && \
#    mkdir storage/framework/cache

# install all PHP dependencies
RUN composer install --no-dev --no-interaction

#change ownership of our applications
RUN chown -R www-data:www-data $APP_HOME
#    chmod -R 0777 bootstrap && \
 #   chmod -R 0777 storage
RUN mv .env.production .env

EXPOSE 80

MariaDB-Dockerfile

FROM mariadb:10.4

ENV MYSQL_USER=dbuser \
    MYSQL_PASSWORD=**** \
    MYSQL_DATABASE=simplememo \
    MYSQL_ROOT_PASSWORD=****

COPY ./init.sql /docker-entrypoint-initdb.d

EXPOSE 3306

任务定义(ECS)


  "ipcMode": null,
  "executionRoleArn": "arn:aws:iam::995962138333:role/ecsTaskExecusionRole",
  "containerDefinitions": [
    
      "dnsSearchDomains": null,
      "environmentFiles": null,
      "logConfiguration": 
        "logDriver": "awslogs",
        "secretOptions": null,
        "options": 
          "awslogs-group": "/ecs/fargate-laravel",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "ecs"
        
      ,
      "entryPoint": null,
      "portMappings": [
        
          "hostPort": 80,
          "protocol": "tcp",
          "containerPort": 80
        
      ],
      "command": null,
      "linuxParameters": null,
      "cpu": 0,
      "environment": [
        
          "name": "DB_DATABASE",
          "value": "simplememo"
        ,
        
          "name": "DB_HOST",
          "value": "localhost"
        ,
        
          "name": "DB_PASSWORD",
          "value": "simplememodbuse"
        ,
        
          "name": "DB_USER",
          "value": "dbuser"
        
      ],
      "resourceRequirements": null,
      "ulimits": null,
      "dnsServers": null,
      "mountPoints": [],
      "workingDirectory": null,
      "secrets": null,
      "dockerSecurityOptions": null,
      "memory": null,
      "memoryReservation": 127,
      "volumesFrom": [],
      "stopTimeout": null,
      "image": "995962138333.dkr.ecr.ap-northeast-1.amazonaws.com/laravelecs:latest",
      "startTimeout": null,
      "firelensConfiguration": null,
      "dependsOn": null,
      "disableNetworking": null,
      "interactive": null,
      "healthCheck": null,
      "essential": true,
      "links": null,
      "hostname": null,
      "extraHosts": null,
      "pseudoTerminal": null,
      "user": null,
      "readonlyRootFilesystem": null,
      "dockerLabels": null,
      "systemControls": null,
      "privileged": null,
      "name": "laravel"
    ,
    
      "dnsSearchDomains": null,
      "environmentFiles": null,
      "logConfiguration": 
        "logDriver": "awslogs",
        "secretOptions": null,
        "options": 
          "awslogs-group": "/ecs/fargate-laravel",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "ecs"
        
      ,
      "entryPoint": null,
      "portMappings": [
        
          "hostPort": 3306,
          "protocol": "tcp",
          "containerPort": 3306
        
      ],
      "command": null,
      "linuxParameters": null,
      "cpu": 0,
      "environment": [],
      "resourceRequirements": null,
      "ulimits": null,
      "dnsServers": null,
      "mountPoints": [],
      "workingDirectory": null,
      "secrets": null,
      "dockerSecurityOptions": null,
      "memory": null,
      "memoryReservation": 128,
      "volumesFrom": [],
      "stopTimeout": null,
      "image": "995962138333.dkr.ecr.ap-northeast-1.amazonaws.com/mariadb:latest",
      "startTimeout": null,
      "firelensConfiguration": null,
      "dependsOn": null,
      "disableNetworking": null,
      "interactive": null,
      "healthCheck": null,
      "essential": true,
      "links": null,
      "hostname": null,
      "extraHosts": null,
      "pseudoTerminal": null,
      "user": null,
      "readonlyRootFilesystem": null,
      "dockerLabels": null,
      "systemControls": null,
      "privileged": null,
      "name": "mariadb"
    
  ],
  "placementConstraints": [],
  "memory": "512",
  "taskRoleArn": "arn:aws:iam::995962138333:role/ecsTaskExecusionRole",
  "compatibilities": [
    "EC2",
    "FARGATE"
  ],
  "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:995962138333:task-definition/fargate-laravel:4",
  "family": "fargate-laravel",
  "requiresAttributes": [
    
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
    ,
    
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "ecs.capability.execution-role-awslogs"
    ,
    
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "com.amazonaws.ecs.capability.ecr-auth"
    ,
    
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
    ,
    
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "com.amazonaws.ecs.capability.docker-remote-api.1.21"
    ,
    
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "com.amazonaws.ecs.capability.task-iam-role"
    ,
    
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "ecs.capability.execution-role-ecr-pull"
    ,
    
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
    ,
    
      "targetId": null,
      "targetType": null,
      "value": null,
      "name": "ecs.capability.task-eni"
    
  ],
  "pidMode": null,
  "requiresCompatibilities": [
    "FARGATE"
  ],
  "networkMode": "awsvpc",
  "cpu": "256",
  "revision": 4,
  "status": "ACTIVE",
  "inferenceAccelerators": null,
  "proxyConfiguration": null,
  "volumes": []

我尝试了什么

将数据库连接的主机名更改为 127.0.0.1。 MariaDB 的 Dockerfile 中的 EXPOSE 3306。 执行 MariaDB 容器(Fargate)并检查数据库 → simplememo 数据库是否存在。

附加信息(固件/工具版本等)

ECS 集群:基于 Fargate Fargate 平台版本:1.4.0 PHP: 7.4 拉拉维尔:8.4 MariaDB:10.4

感谢您阅读到最后。

如果您有任何提示或提示,我将不胜感激。

注意:我能够确认 MariaDB 能够监听。

从 Laravel 容器中,我发现它正在监听 localhost:3306。

另外,DB_HOST=0.0.0.0 也不起作用。 我会很感激任何建议,即使它们是微不足道的。

Amazon ECS Exec

【问题讨论】:

"SQLSTATE[HY000] [2002] 没有这样的文件或目录 (SQL" - 剩下的是什么?它是哪个文件? 当我访问 Laravel 容器时会发生这种情况。 SQLSTATE[HY000] [2002] No such file or directory (SQL: select memos. * from memos where user_id is null and deleted_at is null order by updated_at desc) 或者,您可以访问带有 Amazon ECS Exec 和 php artisan migrate 的 Laravel 容器也会这样做。 这表示当你直接访问任务的IP地址时。 【参考方案1】:

您看到的问题很可能与 AWS 无关。

错误消息表明客户端正在尝试通过localhost 连接到服务器。在 MySQL 的世界中,这意味着通过 UNIX 套接字进行连接。由于其他任务在同一个封闭网络中运行但不共享文件系统,因此找不到套接字文件,您需要通过将主机名从localhost更改为127.0.0.1来告诉客户端通过网络连接。

【讨论】:

问题出在应用程序端。这是应用程序方面的问题。 Laravel 框架缓存还在,即使我更改了附件,缓存仍然在监听,所以它是一个 localhost 连接。谢谢你的提示。

以上是关于在 AWS ECS Fargate 中,任务内无法进行容器间连接的主要内容,如果未能解决你的问题,请参考以下文章

AWS ECS Fargate 和端口映射

AWS ECS Fargate 未创建任务 AmazonECSTaskExecutionRole 错误

AWS ECS Fargate 任务的静态出站 IP

AWS ECS Fargate 模式 - 自动扩展

AWS ECS Fargate ALB 错误(请求超时)

指定 aws ECS/Fargate 容器依赖项无法部署