[DOCKER] Exécuter des binaires C sur AWS Lambda

C'est une question triviale, mais j'ai essayé d'exécuter C avec le runtime personnalisé de Lambda.

Structure du répertoire

.
├── bin
│   ├── bootstrap
│   └── lambda_function
├── docker-compose.yml
├── Dockerfile
└── src
    ├── lambda_function.c
    └── Makefile

Un ensemble de codes peut être trouvé à https://github.com/tsubasaogawa/lambda-with-c.

procédure

Aperçu

  1. Écrivez la source C
  2. Compilez la source dans le même environnement d'exécution que Lambda
  3. Correction du bootstrap
  4. Télécharger vers Lambda

Détails

Ecrire la source C

Écrivez la source comme d'habitude. Cette fois, j'en ai fait un simple qui "sort le contenu d'entrée standard".

lambda_function.c


#include <stdio.h>

int main(void) {
  char buf[512];

  while(1) {
    /* Obtain from Stdin https://qiita.com/mpyw/items/aff12a6ff2c7726ed1d8 */
    if(scanf("%511[^\n]%*[^\n]", buf) != 1) {
      break;
    }
    /* Ignore linefeed */
    scanf("%*c");

    printf("%s\n", buf);
  }

  return 0;
}

Makefile


PROGRAM = lambda_function
CC = gcc
CFLAGS = -Wall
OBJS = $(PROGRAM).o

$(PROGRAM): $(OBJS)
	$(CC) $(CFLAGS) -o $(PROGRAM) $(OBJS)

$(OBJS): $(PROGRAM).c
	$(CC) -c $(PROGRAM).c

.PHONY: clean
clean:
	rm -f $(PROGRAM) $(OBJS)

.PHONY: clean_obj
clean_obj:
	rm -f $(OBJS)

Compilez la source dans le même environnement d'exécution que Lambda

Il s'exécute sur Lambda, vous devez donc le compiler dans le même environnement que Lambda. Selon Environnement d'exécution Lambda et bibliothèques disponibles, j'utilise Amazon Linux (2019/02) Maintenant que nous le savons), nous allons le compiler sur un conteneur Amazon Linux.

Dockerfile


FROM amazonlinux:2
MAINTAINER tsubasaogawa

WORKDIR /usr/local/src/lambda-with-c

RUN set -x && yum install -y gcc make

# ADD ./bootstrap .
COPY ./src/lambda_function.c .
COPY ./src/Makefile .

RUN make && make clean_obj

J'ai réussi à passer à Amazon Linux 2. docker-compose est ci-dessous.

docker-compose.yml


version: '3'
services:
  lambda-with-c-compiler:
    build: .
    volumes:
      - ./bin:/var/tmp
    command: /bin/bash -c 'cp -r /usr/local/src/lambda-with-c/lambda_function /var/tmp'

Le binaire créé par make au moment de la construction du conteneur est copié dans le répertoire monté. De plus, lorsque le conteneur est exécuté, un binaire est créé sous bin / sur l'hôte.

$ docker-compose build
$ docker-compose up -d
$ ls -l bin/lambda_function
-rwxr-xr-x 1 root root 8232 Feb 11 12:49 bin/lambda_function

Correction du bootstrap

Le runtime personnalisé exécute un fichier appelé bootstrap. C'est comme exécuter un binaire via bootstrap. Dans Tutorial, bootstrap est écrit dans un script shell. Ceci est en partie (ou presque) détourné.

bootstrap


#!/bin/sh

set -euo pipefail

# Processing
while true
do
  HEADERS="$(mktemp)"
  # Get an event
  EVENT_DATA=$(curl -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
  REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)

  # Execute the handler function from the script
  EXEC="$LAMBDA_TASK_ROOT/$(echo "$_HANDLER" | cut -d. -f1)"
  RESPONSE=$(echo "$EVENT_DATA" | $EXEC)

  # Send the response
  curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response"  -d "$RESPONSE"
done

Transférer vers Lambda

Compressez l'artefact et téléchargez-le sur Lambda. Veuillez préparer un rôle approprié à l'avance.

Transférer vers Lambda


$ cd bin
$ zip ../lambda_function.zip ./*
$ cd ..
$ ls -l lambda_function.zip 
-rw-rw-r-- 1 vagrant vagrant 3032 Feb 11 12:55 lambda_function.zip

$ aws lambda create-function --function-name lambda-with-c \
    --zip-file fileb://lambda_function.zip --handler lambda_function.handler \
    --runtime provided --role arn:aws:iam::***:role/role_name

Je vais essayer.

Courir


$ aws lambda invoke --function-name lambda-with-c \
    --invocation-type RequestResponse \
    --payload '{ "test1": "value1" }' \
    /tmp/lambda-with-c.log
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}

Résultat d'exécution


$ cat /tmp/lambda-with-c.log 
{
    "test1": "value1"
}

Cela semble bon. Maintenant que nous avons les arguments, nous pouvons les analyser librement et les utiliser.

en conclusion

Recommended Posts

Exécuter des binaires C sur AWS Lambda
Exécutez mruby / c sur PSoC 5
Java sur AWS Lambda est-il lent?
Hello World avec AWS Lambda + Java
Exécutez STS4 sur Mac
Changement de fuseau horaire AWS Lambda
Exécutez PostgreSQL sur Java
Exécuter le traitement sur Ant
Exécutez tiscamera sur Ubuntu 18.04
Publiez régulièrement des images de tweets sur Twitter avec AWS Lambda + Java
Exécutez openvpn sur Docker (Windows)
Exécutez l'applet java sur ubuntu
Mettre à jour RVM sur AWS Cloud 9
Installer docker sur AWS EC2
Exécutez Eclipse CDT sur Ubuntu
Créez AWS Lambda avec Quarkus
Essayez d'exécuter SlackBot réalisé avec Ruby x Sinatra sur AWS Lambda