Укажите имя хоста для экземпляров реестра схем, работающих в ECS.

Я создаю избыточный реестр схем, размещенный в Amazon, для нашего кластера MSK Kafka, используя кластер ECS.

SchemaRegistry TaskDefinition необходимо определить имя хоста, которое уникально для каждой задачи при ее запуске.

SchemaRegistryTaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      Family: !Ref SchemaRegistryTaskName
      RequiresCompatibilities: [ EC2 ]
      NetworkMode: bridge
      Cpu: !Ref CPUReservation
      Memory: !Ref MemoryReservation
      Volumes: []
      ContainerDefinitions:
        - Name: !Ref SchemaRegistryTaskName
          Image: !Ref SchemaRegistryTaskImage
          Essential: true
          PortMappings:
            - ContainerPort: !Ref SchemaRegistryPort
              HostPort: 0 # Randomly assigned port from the ephemeral port range.
          Environment:
            - Name: AWS_DEFAULT_REGION
              Value: !Ref AWS::Region
            - Name: SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS
              Value: !Ref MskBrokerUrls
            - Name: SCHEMA_REGISTRY_HOST_NAME
              Value: $HOSTNAME
          LogConfiguration:
            LogDriver: awslogs
            Options:
              awslogs-group: !Ref 'CloudwatchLogsGroup'
              awslogs-region: !Ref 'AWS::Region'

NB: Использование $Hostname работает при запуске контейнера докеров непосредственно в экземпляре EC2 через cli, потому что оболочка заменяет полностью определенное имя хоста, которое является уникальным; но я в тупике, пытаясь понять, как заставить эту работу работать в ECS и CloudFormation.

4 ответа

Решение

В итоге я пошел с кастомом Command а также EntryPoint на TaskDefinition ContainerDefinitions; используя конечную точку метаданных, предложенную @Apolozeus:

EntryPoint: ["/bin/bash"]
Command: ["-c","(export SCHEMA_REGISTRY_HOST_NAME=$(wget -qO- 169.254.169.254/latest/meta-data/local-ipv4);/etc/confluent/docker/run)"]

Это обеспечивает переменную среды для SCHEMA_REGISTRY_HOST_NAME существует в контейнере и правильно отображается на ipv4 экземпляра EC2, на котором работает контейнер.

Для меня это предпочтительнее, потому что мы не контролируем запускаемый контейнер Docker (он общедоступен), и я не хочу заключать его в контейнер Docker, который мы должны поддерживать.

Что я сделал, так это иметь entrypoint скрипт в образе Docker, который будет искать из метаданных ECS и предоставлять значения как среду SCHEMA_REGISTRY_HOST_NAME. Ниже приведен образец сценария.

#!/bin/sh

#########
# Detect whether this is running in an ECS cluster
#########
curl --max-time 1 -s --fail -o /dev/null http://169.254.169.254/
if [[ 0 -eq $? ]]; then
    echo "AWS environment was detected - looking up HOST IP from metadata"
    SCHEMA_REGISTRY_HOST_NAME=$(curl http://169.254.169.254/latest/meta-data/local-ipv4 -s)
    export SCHEMA_REGISTRY_HOST_NAME
else
    echo "Not running in AWS environment. Will not set SCHEMA_REGISTRY_HOST_NAME"
fi

Вы также можете посмотреть на это один о том, как сделать локальное тестирование / развитие, а также.

В дополнение к ответу Syntax для поддержки реестра схем в конфигурации кластера (работает более 1 экземпляра) вам необходимо правильно настроить прослушиватели для использования правильного порта. Чтобы избежать жесткого кодирования портов, можно запросить службу метаданных ECS и вплести ее в конфигурацию реестра схемы следующим образом:

      EntryPoint: ["/bin/bash"]
Command: ["-c","(
   export SCHEMA_REGISTRY_HOST_NAME=$(curl 169.254.169.254/latest/meta-data/local-ipv4);
   curl $ECS_CONTAINER_METADATA_URI_V4 > ecs.json;
   export HOST_PORT=$(python -c \"import json; f = open('ecs.json').read(); data = json.loads(f); print(data['Ports'][0]['HostPort'])\");
   export SCHEMA_REGISTRY_LISTENERS=\"http://0.0.0.0:$HOST_PORT,http://0.0.0.0:8081\";
   /etc/confluent/docker/run)"]

Дополнительная конфигурация прослушивателя необходима, так как $HOST_PORT — это фактический порт, который будет объявлен другим экземплярам реестра схемы для пересылки операций записи на мастер.

Если вы используете принятый ответ, ваши реплики не смогут этого сделать, поскольку по умолчанию они попытаются отправить трафик на 8081, который, скорее всего, не будет портом, который будет доступен ECS.

Это работало для агента ECS 1.50 и образа Docker 5.5.3 реестра Confluent Schema Registry.

Вот решение для работы на ECS Fargate, основанное на одном из приведенных выше ответов. Это зависит от наличия jqпоэтому вам может потребоваться установить это. Он также жестко привязан к первой сети, что может не соответствовать вашему варианту использования.

      
#########
# Detect whether this is running in an ECS cluster
#########
curl --max-time 1 -s --fail -o /dev/null ${ECS_CONTAINER_METADATA_URI_V4}

if [[ 0 -eq $? ]]; then
    echo "AWS environment was detected - looking up HOST IP from metadata"
    curl ${ECS_CONTAINER_METADATA_URI_V4} > meta.json
    SCHEMA_REGISTRY_HOST_NAME=$(jq '.Networks[0].IPv4Addresses[0]' meta.json -r) 
    export SCHEMA_REGISTRY_HOST_NAME
else
    echo "Not running in AWS environment. Will not set SCHEMA_REGISTRY_HOST_NAME"
fi
Другие вопросы по тегам