EC2 Java StartInstancesRequest переходит от «ожидающего» к «остановленному» к «остановленному» - PullRequest
0 голосов
/ 20 июня 2019

У меня следующая ситуация:

  • Выделенный арендатор m4.large Экземпляр EC2 под управлением RHEL6
  • Запуск вручную с помощью консоли AWS работает нормально
  • Лямбда-функция (написанная на Java), которая пытается ее запустить, завершается сбоем, потому что состояние экземпляра переходит: остановлено -> ожидание -> остановка -> остановлено

У меня есть лямбда-функция, которая регистрирует все изменения состояния EC2 через VPC следующим образом:

'use strict';
exports.handler = (event, context, callback) => {
  console.log('LogEC2InstanceStateChange');
  console.log('Received event:', JSON.stringify(event, null, 2));
  callback(null, 'Finished');
}

И еще одна лямбда-функция, которая пытается запускать экземпляры EC2 на основе расписания, написанного на Java, которое состоит из большого количества кода, но его ядро ​​выглядит примерно так:

public void handleRequest(Object input, Context context) {
  final List<String> instancesToStart = getInstancesToStart(); //implementation not shown
  try {
    StartInstancesRequest startRequest = new StartInstancesRequest().withInstanceIds((String[]) instancesToStart.toArray());
    context.logger.log("StartInstancesRequest: " + startRequest.toString());
    StartInstancesResult res = ec2.startInstances(startRequest);
    context.logger.log("StartInstancesResult: " + res.toString());
  }
  catch(Exception e) {
    logException(e); //calls context.logger.log on the stack trace string
  }
}

Массив instancesToStart заполняется идентификаторами экземпляров, такими как i-0abcdef1234567890.

Я создаю функции Lambda и все необходимые роли IAM и т. Д. С помощью CloudFormation. Вот бит, описывающий роль / разрешения для лямбда-функции на основе Java, которая выполняет эту работу:

Resources:
  EC2SchedulerRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
  EC2SchedulerPolicy:
    DependsOn:
      - EC2SchedulerRole
    Type: 'AWS::IAM::Policy'
    Properties:
      PolicyName: ec2-scheduler-role
      Roles:
        - !Ref EC2SchedulerRole
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action:
              - 'logs:*'
            Resource:
              - 'arn:aws:logs:*:*:*'
          - Effect: Allow
            Action:
              - 'ec2:DescribeInstanceAttribute'
              - 'ec2:DescribeInstanceStatus'
              - 'ec2:DescribeInstances'
              - 'ec2:StartInstances'
              - 'ec2:StopInstances'
              - 'ec2:DeleteTags'
            Resource:
              - '*'

В конечном итоге, согласно журналам CloudWatch от первой функции (сценарий, который регистрирует изменения состояния экземпляра), мы получаем:

Received event:
{
    "version": "0",
    "id": "<guid>",
    "detail-type": "EC2 Instance State-change Notification",
    "source": "aws.ec2",
    "account": "12345678",
    "time": "2019-06-20T19:01:35Z",
    "region": "us-east-1",
    "resources": [
        "arn:aws:ec2:us-east-1:12345678:instance/i-0abcdef12345678"
    ],
    "detail": {
        "instance-id": "i-0abcdef12345678",
        "state": "pending"
    }
}

Received event:
{
    "version": "0",
    "id": "<guid>",
    "detail-type": "EC2 Instance State-change Notification",
    "source": "aws.ec2",
    "account": "12345678",
    "time": "2019-06-20T19:01:37Z",
    "region": "us-east-1",
    "resources": [
        "arn:aws:ec2:us-east-1:12345678:instance/i-0abcdef12345678"
    ],
    "detail": {
        "instance-id": "i-0abcdef12345678",
        "state": "stopping"
    }
}

Received event:
{
    "version": "0",
    "id": "<guid>",
    "detail-type": "EC2 Instance State-change Notification",
    "source": "aws.ec2",
    "account": "12345678",
    "time": "2019-06-20T19:01:37Z",
    "region": "us-east-1",
    "resources": [
        "arn:aws:ec2:us-east-1:12345678:instance/i-0abcdef12345678"
    ],
    "detail": {
        "instance-id": "i-0abcdef12345678",
        "state": "stopped"
    }
}

И согласно журналам CloudWatch от функции «worker» (функция, которая фактически пытается запустить экземпляры), мы получаем:

StartInstancesRequest: {InstanceIds: [i-0abcdef12345678],}
StartInstancesResult: {StartingInstances: [{CurrentState: {Code: 0,Name: pending},InstanceId: i-0abcdef12345678,PreviousState: {Code: 80,Name: stopped}}]}

Таким образом, с точки зрения лямбды на основе Java, которая делает эту работу, она делает все, что ей нужно, чтобы дать команду для запуска экземпляра EC2; но затем, когда экземпляр EC2 пытается фактически запуститься, он переходит от «ожидающего» к «остановке» к «остановленному». Если бы у него не было разрешения, оно бы даже не зашло так далеко, верно?

Если бы это была проблема с самим экземпляром (например, с аппаратным обеспечением), я ожидал бы, что ручной запуск его с помощью консоли AWS завершится с ошибкой . Но это не подводит. Это успешно при запуске вручную!

Так что происходит? Как мне диагностировать это дальше? Это разрешения или экземпляр испорчен?

Я на 99% уверен, что не из-за недостатка доступной емкости в АЗ, потому что всякий раз, когда я пытаюсь запустить экземпляр вручную, он всегда работает. Это не эфемерная проблема или что-то, что происходило только недавно. Это продолжается в течение нескольких месяцев, как это, где ручной запуск работает 100% времени, а запуск на основе сценариев работает 0% времени.

Ответы [ 2 ]

1 голос
/ 22 июня 2019

Может возникнуть проблема с загрузкой EBS. Как вы уже упоминали, в EC2 есть 3 тома EBS с шифрованием KMS. Вы должны предоставить разрешение KMS (kms: CreateGrant) для запуска ваших экземпляров

{
        "Sid": "GrantAccess",
        "Effect": "Allow",
        "Action": "kms:CreateGrant",
        "Resource": "arn:aws:kms:::key/1234"
}
0 голосов
/ 21 июня 2019

Попробуйте эту политику и посмотрите, работает ли она.Если это так, проблема связана с политикой:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:Start*",
        "ec2:Stop*"
      ],
      "Resource": "*"
    }
  ]
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...