Вы когда-нибудь задумывались, каково это внутри лямбды? Хватит удивляться. Давай выясним.
С момента своего появления в 2014 году лямбда-функции AWS стали горячей темой, открывающей новые летописи в области безсерверных вычислений . Удовольствия без сохранения состояния, без платы за обслуживание и исполнение буквально меняют — если не искоренивают — самые корни парадигмы облачных вычислений. Пока в игру вступают другие игроки, такие как Google и MS Azure, AWS пока что является абсолютным победителем.
Хорошо, проповедуя в стороне, как это действительно выглядит внутри лямбда-функции?
Согласно AWS, лямбды управляются контейнерными технологиями ; если быть точным, AWS EC2 Container Service (ECS) . Следовательно, в этот момент лямбда — это просто контейнер Docker с ограниченным доступом извне. Однако код функции, который мы запускаем внутри контейнера, имеет практически неограниченный доступ к нему, за исключением привилегий root, включая файловую систему, встроенные и установленные команды и инструменты CLI, системные метаданные и статистику, журналы и многое другое. Не очень полезно для обычного лямбда-автора, но может быть и так, если вы собираетесь идти по колено в вещах уровня ОС.
Очевидно, что самый простой способ изучить все эти предложения на уровне ОС — это иметь доступ к командной оболочке CLI (оболочки). К сожалению, в настоящее время это невозможно; тем не менее, комбинируя безумно простой синтаксис, предоставляемый средой выполнения NodeJS, и тем фактом, что лямбды имеют время поддержки нескольких минут , мы можем легко написать десятистрочную лямбду, которая может эмулировать оболочку. Хотя настоящая «сессия» не может быть установлена таким образом (например, вы не можете запустить top для представления обновления в реальном времени), вы можете многократно запускать серию команд, как будто вы взаимодействуете с пользовательской консолью.
|
01
02
03
04
05
06
07
08
09
10
|
let {exec} = require('child_process');exports.handle = (event, context, callback) => { console.log(event); exec(event.cmd, (err, stdout, stderr) => { console.log(stdout); if (err) console.log(stderr); callback(undefined, {statusCode: 200}); });} |
К счастью для нас, поскольку код представляет собой простой набор из десяти строк с нулевыми внешними зависимостями, мы можем развернуть всю лямбду — включая код, конфигурации и роль выполнения — через один шаблон CloudFormation :
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
AWSTemplateFormatVersion: '2010-09-09'Resources: shell: Type: AWS::Lambda::Function Properties: FunctionName: shell Handler: index.handle Runtime: nodejs6.10 Code: ZipFile: > let {exec} = require('child_process'); exports.handle = (event, context, callback) => { console.log(event); exec(event.cmd, (err, stdout, stderr) => { console.log(stdout); if (err) console.log(stderr); callback(undefined, {statusCode: 200}); }); } Timeout: 60 Role: Fn::GetAtt: - role - Arn role: Type: AWS::IAM::Role Properties: ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: lambda.amazonaws.com |
Развернуть все это так же просто, как:
|
1
|
aws cloudformation deploy --stack-name shell --template-file /path/to/template.yaml --capabilities CAPABILITY_IAM |
или выберите и загрузите шаблон на панель мониторинга CloudFormation , если у вас нет интерфейса командной строки AWS, чтобы сделать это (см. выше).
После развертывания достаточно просто вызвать лямбду с полезной нагрузкой, содержащей желаемую команду оболочки:
|
1
|
{"cmd":"the command to be executed"} |
Если у вас есть интерфейс командной строки AWS, все это становится намного более сексуальным, когда вызывается с помощью следующего фрагмента оболочки:
|
1
2
3
4
5
6
7
8
9
|
echo -n "> "read cmdwhile [ "$cmd" != "exit" ]; do echo aws lambda invoke --function-name shell --payload "{\"cmd\":\"$cmd\"}" --log-type Tail /tmp/shell.log --query LogResult --output text | base64 -d echo echo -n "> " read cmddone |
С этим сценарием все, что вам нужно, это вызвать сценарий; вам будет выдана фальшивая «оболочка», в которой вы сможете выполнить долгожданную команду, и лямбда выполнит ее и сразу же вернет вывод обратно на консоль, вернув вас обратно в приглашение «shell»:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
> freeSTART RequestId: c143847d-12b8-11e8-bae7-1d25ba5302bd Version: $LATEST2018-02-16T01:28:56.051Z c143847d-12b8-11e8-bae7-1d25ba5302bd { cmd: 'free' }2018-02-16T01:28:56.057Z c143847d-12b8-11e8-bae7-1d25ba5302bd total used free shared buffers cachedMem: 3855608 554604 3301004 200 44864 263008-/+ buffers/cache: 246732 3608876Swap: 0 0 0END RequestId: c143847d-12b8-11e8-bae7-1d25ba5302bdREPORT RequestId: c143847d-12b8-11e8-bae7-1d25ba5302bd Duration: 6.91 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 82 MB> |
С помощью этой хитрости вы можете узнать немного больше о среде обитания и образе жизни лямбда-функции. Для начала я узнал, что среда выполнения контейнеров включает в себя экземпляры Amazon Linux с около 4 ГБ (возможно, совместно используемой) памяти Memeey и несколькими (неиспользуемыми) дисковыми хранилищами значительного размера (в дополнение к «рекомендуемым для использования» 500 МБ). смонтировать на /tmp ):
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
> dfSTART RequestId: bb0034fa-12ba-11e8-8390-cb81e1cfae92 Version: $LATEST2018-02-16T01:43:04.559Z bb0034fa-12ba-11e8-8390-cb81e1cfae92 { cmd: 'df' }2018-02-16T01:43:04.778Z bb0034fa-12ba-11e8-8390-cb81e1cfae92 Filesystem 1K-blocks Used Available Use% Mounted on/dev/xvda1 30830568 3228824 27501496 11% //dev/loop8 538424 440 526148 1% /tmp/dev/loop9 128 128 0 100% /var/taskEND RequestId: bb0034fa-12ba-11e8-8390-cb81e1cfae92REPORT RequestId: bb0034fa-12ba-11e8-8390-cb81e1cfae92 Duration: 235.44 ms Billed Duration: 300 ms Memory Size: 128 MB Max Memory Used: 22 MB> cat /etc/*-releaseSTART RequestId: 6112efb9-12bd-11e8-9d14-d5c0177bc74f Version: $LATEST2018-02-16T02:02:02.190Z 6112efb9-12bd-11e8-9d14-d5c0177bc74f { cmd: 'cat /etc/*-release' }2018-02-16T02:02:02.400Z 6112efb9-12bd-11e8-9d14-d5c0177bc74f NAME="Amazon Linux AMI"VERSION="2017.03"ID="amzn"ID_LIKE="rhel fedora"VERSION_ID="2017.03"PRETTY_NAME="Amazon Linux AMI 2017.03"ANSI_COLOR="0;33"CPE_NAME="cpe:/o:amazon:linux:2017.03:ga"HOME_URL="http://aws.amazon.com/amazon-linux-ami/"Amazon Linux AMI release 2017.03END RequestId: 6112efb9-12bd-11e8-9d14-d5c0177bc74fREPORT RequestId: 6112efb9-12bd-11e8-9d14-d5c0177bc74f Duration: 209.82 ms Billed Duration: 300 ms Memory Size: 128 MB Max Memory Used: 22 MB> |
Правда, формат вывода (который в основном является необработанным из журналов CloudWatch ) может быть значительно улучшен, в дополнение к десяткам других возможных улучшителей. Итак, давайте обсудим, под комментариями!
| Смотреть оригинальную статью здесь: Внутри Lambda Runtime: заглянуть в безсерверное логово
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |