Uso do Service Connect no Fargate com a AWS CLI - Amazon Elastic Container Service

Uso do Service Connect no Fargate com a AWS CLI

O tutorial a seguir mostra como criar um serviço do Amazon ECS que contenha uma tarefa do Fargate que usa o Service Connect com a AWS CLI.

O Amazon ECS é compatível com o recurso Service Connect nas Regiões da AWS listadas em Regions with Service Connect.

Pré-requisitos

Este tutorial pressupõe que os seguintes pré-requisitos foram concluídos:

Etapa 1: criar um cluster do Amazon ECS

Use as etapas a seguir para criar um cluster e um namespace do Amazon ECS.

Para criar o cluster e o namespace AWS Cloud Map do Amazon ECS
  1. Crie um cluster do Amazon ECS denominado tutorial a ser usado. O parâmetro --service-connect-defaults define o namespace padrão do cluster. Na saída do exemplo, um namespace do AWS Cloud Map com o nome service-connect não existe nessa conta nem na Região da AWS. Portanto, o namespace é criado pelo Amazon ECS. O namespace é criado no AWS Cloud Map na conta e é visível com todos os outros namespaces. Portanto, use um nome que indique a finalidade.

    aws ecs create-cluster --cluster-name tutorial --service-connect-defaults namespace=service-connect

    Saída:

    {
        "cluster": {
            "clusterArn": "arn:aws:ecs:us-west-2:123456789012:cluster/tutorial",
            "clusterName": "tutorial",
            "serviceConnectDefaults": {
                "namespace": "arn:aws:servicediscovery:us-west-2:123456789012:namespace/ns-EXAMPLE"
            },
            "status": "PROVISIONING",
            "registeredContainerInstancesCount": 0,
            "runningTasksCount": 0,
            "pendingTasksCount": 0,
            "activeServicesCount": 0,
            "statistics": [],
            "tags": [],
            "settings": [
                {
                    "name": "containerInsights",
                    "value": "disabled"
                }
            ],
            "capacityProviders": [],
            "defaultCapacityProviderStrategy": [],
            "attachments": [
                {
                    "id": "a1b2c3d4-5678-90ab-cdef-EXAMPLE11111",
                    "type": "sc",
                    "status": "ATTACHING",
                    "details": []
                }
            ],
            "attachmentsStatus": "UPDATE_IN_PROGRESS"
        }
    }
    }
  2. Verifique se o cluster foi criado:

    aws ecs describe-clusters --clusters tutorial

    Saída:

    {
        "clusters": [
            {
                "clusterArn": "arn:aws:ecs:us-west-2:123456789012:cluster/tutorial",
                "clusterName": "tutorial",
                "serviceConnectDefaults": {
                    "namespace": "arn:aws:servicediscovery:us-west-2:123456789012:namespace/ns-EXAMPLE"
                },
                "status": "ACTIVE",
                "registeredContainerInstancesCount": 0,
                "runningTasksCount": 0,
                "pendingTasksCount": 0,
                "activeServicesCount": 0,
                "statistics": [],
                "tags": [],
                "settings": [],
                "capacityProviders": [],
                "defaultCapacityProviderStrategy": []
            }
        ],
        "failures": []
    }
                    
  3. (opcional) verifique se o namespace foi criado no AWS Cloud Map. É possível usar o AWS Management Console ou a configuração normal da AWS CLI, pois ela é criada no AWS Cloud Map.

    Por exemplo, use a AWS CLI:

    aws servicediscovery --region us-west-2 get-namespace --id ns-EXAMPLE

    Saída:

    {
        "Namespace": {
            "Id": "ns-EXAMPLE",
            "Arn": "arn:aws:servicediscovery:us-west-2:123456789012:namespace/ns-EXAMPLE",
            "Name": "service-connect",
            "Type": "HTTP",
            "Properties": {
                "DnsProperties": {
                    "SOA": {}
                },
                "HttpProperties": {
                    "HttpName": "service-connect"
                }
            },
            "CreateDate": 1661749852.422,
            "CreatorRequestId": "service-connect"
        }
    }
                    

Etapa 2: criar o serviço do Amazon ECS para o servidor

O recurso Service Connect é destinado à interconexão de várias aplicações no Amazon ECS. Pelo menos uma dessas aplicações precisa fornecer um serviço Web ao qual se conectar. Nessa etapa, você criará:

  • A definição de tarefa que usa a imagem oficial do contêiner NGINX não modificada e inclui a configuração do Service Connect.

  • A definição de serviço do Amazon ECS que configura o Service Connect para fornecer proxy de descoberta de serviços e de malha de serviços para o tráfego desse serviço. A configuração reutiliza o namespace padrão da configuração do cluster para reduzir a quantidade de configuração de serviço feita para cada serviço.

  • O serviço do Amazon ECS. Ele executa uma tarefa usando a definição de tarefa e insere um contêiner adicional para o proxy do Service Connect. O proxy recebe a porta proveniente do mapeamento da porta do contêiner na definição de tarefa. Em uma aplicação cliente executada no Amazon ECS, o proxy na tarefa do cliente recebe as conexões de saída para o nome da porta de definição de tarefa, o nome da descoberta do serviço ou o nome do alias do cliente de serviço e o número da porta do alias do cliente.

Para criar o serviço Web com o Amazon ECS Service Connect
  1. Registre uma definição de tarefa compatível com o Fargate e use o modo de rede awsvpc. Siga estas etapas:

    1. Crie um arquivo denominado service-connect-nginx.json com o conteúdo da seguinte definição de tarefa.

      Essa definição de tarefa configura o Service Connect adicionando os parâmetros name e appProtocol ao mapeamento de portas. O nome da porta torna essa porta mais identificável na configuração do serviço quando várias portas são usadas. O nome da porta também é usado por padrão como o nome detectável para uso por outras aplicações no namespace.

      A definição da tarefa contém o perfil do IAM da tarefa, pois o serviço tem o ECS Exec ativado.

      Importante

      Essa definição de tarefa usa a logConfiguration para enviar a saída do nginx de stdout e stderr para o Amazon CloudWatch Logs. Esse perfil de execução de tarefas não tem as permissões extras necessárias para a criação do grupo de logs do CloudWatch Logs. Crie o grupo de logs no CloudWatch Logs usando o AWS Management Console ou a AWS CLI. Se você não quiser enviar os logs do nginx para o CloudWatch Logs, poderá remover a logConfiguration.

      Substitua o id da Conta da AWS no perfil de execução pelo seu id de Conta da AWS.

      { "family": "service-connect-nginx", "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole", "taskRoleArn": "arn:aws:iam::123456789012:role/ecsTaskRole", "networkMode": "awsvpc", "containerDefinitions": [ { "name": "webserver", "image": "public.ecr.aws/docker/library/nginx:latest", "cpu": 100, "portMappings": [ { "name": "nginx", "containerPort": 80, "protocol": "tcp", "appProtocol": "http" } ], "essential": true, "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "/ecs/service-connect-nginx", "awslogs-region": "region", "awslogs-stream-prefix": "nginx" } } } ], "cpu": "256", "memory": "512" }
    2. Registre a definição de tarefa usando o arquivo service-connect-nginx.json:

      aws ecs register-task-definition --cli-input-json file://service-connect-nginx.json
  2. Crie um serviço do ECS seguindo estas etapas:

    1. Crie um arquivo denominado service-connect-nginx-service.json com o conteúdo do serviço do Amazon ECS que você está criando. Este exemplo usa a definição de tarefa criada na etapa anterior. Uma awsvpcConfiguration é necessária, pois o exemplo de definição de tarefa usa o modo de rede awsvpc.

      Ao criar o serviço do ECS, especifique o tipo de inicialização do Fargate e a versão LATEST da plataforma que oferece suporte ao Service Connect. Os securityGroups e as subnets devem pertencer a uma VPC que tenha os requisitos para usar o Amazon ECS. É possível obter os IDs de grupos de segurança e sub-redes no console da Amazon VPC.

      Esse serviço configura o Service Connect adicionando o parâmetro serviceConnectConfiguration. O namespace não é necessário porque o cluster tem um namespace padrão configurado. As aplicações cliente em execução no ECS no namespace se conectam a esse serviço usando o portName e a porta no clientAliases. Por exemplo, esse serviço pode ser acessado usando http://nginx:80/, pois o nginx fornece uma página de boas-vindas no / do local raiz. Aplicações externas que não estão sendo executadas no Amazon ECS ou não estão no mesmo namespace podem acessar essa aplicação por meio do proxy do Service Connect usando o endereço IP da tarefa e o número da porta da definição de tarefa. Na configuração do tls, adicione o arn do certificado para awsPcaAuthorityArn, kmsKey e roleArn do perfil do IAM.

      Esse serviço usa uma logConfiguration para enviar a saída do proxy de conexão do serviço de stdout e stderr para o Amazon CloudWatch Logs. Esse perfil de execução de tarefas não tem as permissões extras necessárias para a criação do grupo de logs do CloudWatch Logs. Crie o grupo de logs no CloudWatch Logs usando o AWS Management Console ou a AWS CLI. Recomendamos que você crie esse grupo de logs e armazene os logs de proxy no CloudWatch Logs. Se você não quiser enviar os logs do proxy para o CloudWatch Logs, poderá remover a logConfiguration.

      { "cluster": "tutorial", "deploymentConfiguration": { "maximumPercent": 200, "minimumHealthyPercent": 0 }, "deploymentController": { "type": "ECS" }, "desiredCount": 1, "enableECSManagedTags": true, "enableExecuteCommand": true, "launchType": "FARGATE", "networkConfiguration": { "awsvpcConfiguration": { "assignPublicIp": "ENABLED", "securityGroups": [ "sg-EXAMPLE" ], "subnets": [ "subnet-EXAMPLE", "subnet-EXAMPLE", "subnet-EXAMPLE" ] } }, "platformVersion": "LATEST", "propagateTags": "SERVICE", "serviceName": "service-connect-nginx-service", "serviceConnectConfiguration": { "enabled": true, "services": [ { "portName": "nginx", "clientAliases": [ { "port": 80 } ], "tls": { "issuerCertificateAuthority": { "awsPcaAuthorityArn": "certificateArn" }, "kmsKey": "kmsKey", "roleArn": "iamRoleArn" } } ], "logConfiguration": { "logDriver": "awslogs", "options": { "awslogs-group": "/ecs/service-connect-proxy", "awslogs-region": "region", "awslogs-stream-prefix": "service-connect-proxy" } } }, "taskDefinition": "service-connect-nginx" }
    2. Crie um serviço do ECS usando o arquivo service-connect-nginx-service.json:

      aws ecs create-service --cluster tutorial --cli-input-json file://service-connect-nginx-service.json

      Saída:

      {
          "service": {
              "serviceArn": "arn:aws:ecs:us-west-2:123456789012:service/tutorial/service-connect-nginx-service",
              "serviceName": "service-connect-nginx-service",
              "clusterArn": "arn:aws:ecs:us-west-2:123456789012:cluster/tutorial",
              "loadBalancers": [],
              "serviceRegistries": [],
              "status": "ACTIVE",
              "desiredCount": 1,
              "runningCount": 0,
              "pendingCount": 0,
              "launchType": "FARGATE",
              "platformVersion": "LATEST",
              "platformFamily": "Linux",
              "taskDefinition": "arn:aws:ecs:us-west-2:123456789012:task-definition/service-connect-nginx:1",
              "deploymentConfiguration": {
                  "deploymentCircuitBreaker": {
                      "enable": false,
                      "rollback": false
                  },
                  "maximumPercent": 200,
                  "minimumHealthyPercent": 0
              },
              "deployments": [
                  {
                      "id": "ecs-svc/3763308422771520962",
                      "status": "PRIMARY",
                      "taskDefinition": "arn:aws:ecs:us-west-2:123456789012:task-definition/service-connect-nginx:1",
                      "desiredCount": 1,
                      "pendingCount": 0,
                      "runningCount": 0,
                      "failedTasks": 0,
                      "createdAt": 1661210032.602,
                      "updatedAt": 1661210032.602,
                      "launchType": "FARGATE",
                      "platformVersion": "1.4.0",
                      "platformFamily": "Linux",
                      "networkConfiguration": {
                          "awsvpcConfiguration": {
                              "assignPublicIp": "ENABLED",
                              "securityGroups": [
                                  "sg-EXAMPLE"
                              ],
                              "subnets": [
                                  "subnet-EXAMPLEf",
                                  "subnet-EXAMPLE",
                                  "subnet-EXAMPLE"
                              ]
                          }
                      },
                      "rolloutState": "IN_PROGRESS",
                      "rolloutStateReason": "ECS deployment ecs-svc/3763308422771520962 in progress.",
                      "failedLaunchTaskCount": 0,
                      "replacedTaskCount": 0,
                      "serviceConnectConfiguration": {
                          "enabled": true,
                          "namespace": "service-connect",
                          "services": [
                              {
                                  "portName": "nginx",
                                  "clientAliases": [
                                      {
                                          "port": 80
                                      }
                                  ]
                              }
                          ],
                          "logConfiguration": {
                              "logDriver": "awslogs",
                              "options": {
                                  "awslogs-group": "/ecs/service-connect-proxy",
                                  "awslogs-region": "us-west-2",
                                  "awslogs-stream-prefix": "service-connect-proxy"
                              },
                              "secretOptions": []
                          }
                      },
                      "serviceConnectResources": [
                          {
                              "discoveryName": "nginx",
                              "discoveryArn": "arn:aws:servicediscovery:us-west-2:123456789012:service/srv-EXAMPLE"
                          }
                      ]
                  }
              ],
              "roleArn": "arn:aws:iam::123456789012:role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS",
              "version": 0,
              "events": [],
              "createdAt": 1661210032.602,
              "placementConstraints": [],
              "placementStrategy": [],
              "networkConfiguration": {
                  "awsvpcConfiguration": {
                      "assignPublicIp": "ENABLED",
                      "securityGroups": [
                          "sg-EXAMPLE"
                      ],
                      "subnets": [
                          "subnet-EXAMPLE",
                          "subnet-EXAMPLE",
                          "subnet-EXAMPLE"
                      ]
                  }
              },
              "schedulingStrategy": "REPLICA",
              "enableECSManagedTags": true,
              "propagateTags": "SERVICE",
              "enableExecuteCommand": true
          }
      }
                              

      A serviceConnectConfiguration que você forneceu aparece na primeira implantação da saída. À medida que você faz alterações no serviço do ECS de maneiras que precisam fazer alterações nas tarefas, uma nova implantação é criada pelo Amazon ECS.

Etapa 3: verificar se você pode se conectar

Para verificar se o Service Connect está configurado e funcionando, siga estas etapas para se conectar ao serviço Web em uma aplicação externa. Em seguida, veja as métricas adicionais no CloudWatch que são criadas pelo proxy do Service Connect.

Para se conectar ao serviço Web em uma aplicação externa
  • Conecte-se ao endereço IP da tarefa e à porta do contêiner usando o endereço IP da tarefa

    Use a AWS CLI para obter o ID da tarefa, usando o aws ecs list-tasks --cluster tutorial.

    Se suas sub-redes e seu grupo de segurança permitirem tráfego da Internet pública na porta da definição da tarefa, será possível se conectar ao IP público no seu computador. No entanto, o IP público não está disponível em “describe-tasks”. Portanto, as etapas envolvem acessar o AWS Management Console ou a AWS CLI do Amazon EC2 para obter os detalhes da interface de rede elástica.

    Nesse exemplo, uma instância do Amazon EC2 na mesma VPC usa o IP privado da tarefa. A aplicação é nginx, mas o cabeçalho server: envoy mostra que o proxy do Service Connect é usado. O proxy do Service Connect recebe a porta do contêiner vindo da definição de tarefa.

    $ curl -v 10.0.19.50:80/
    *   Trying 10.0.19.50:80...
    * Connected to 10.0.19.50 (10.0.19.50) port 80 (#0)
    > GET / HTTP/1.1
    > Host: 10.0.19.50
    > User-Agent: curl/7.79.1
    > Accept: */*
    >
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    < server: envoy
    < date: Tue, 23 Aug 2022 03:53:06 GMT
    < content-type: text/html
    < content-length: 612
    < last-modified: Tue, 16 Apr 2019 13:08:19 GMT
    < etag: "5cb5d3c3-264"
    < accept-ranges: bytes
    < x-envoy-upstream-service-time: 0
    <
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html> 
                    
Para visualizar as métricas do Service Connect

O proxy do Service Connect cria métricas de aplicações (conexão HTTP, HTTP2, gRPC ou TCP) nas métricas do CloudWatch. Quando usar o console do CloudWatch, veja as dimensões das métricas adicionais de DiscoveryName, (DiscoveryName, ServiceName, ClusterName), TargetDiscoveryName e (TargetDiscoveryName, ServiceName, ClusterName) no namespace do ECS. Para obter mais informações sobre essas métricas e dimensões, consulte Visualizar métricas disponíveis no Guia do usuário do Amazon CloudWatch Logs.