Впервые я был подвержен функциям Lambda на работе, когда команде необходимо было реализовать службу API, которая будет получать запросы от других услуг, разрабатывать данные, а затем отправляет эти данные в Kafka. Теперь эта услуга обрабатывает около 1 м запроса каждый месяц 🎉🎉
Я был очень смущен тем, с чего начать или как сделать это для работы в области разработки, тестирования и производственных сред. Я видел Без сервера Framework , Кнайт и Kubeless в Интернете и потребовалось много времени, чтобы решить, что выбрать, так как мы используем K8s в наших средах.
Наконец, я нашел Серверный Наиболее подходящий для использования во всех наших средах, поэтому я начал изучать, как создавать функцию без сервера, используя ее. Это довольно легко выучить, использовать и даже читать вашу конфигурацию.
Структура каталога
Лучше абстрагировать каждую функцию в отдельном каталоге с его компонентами. Вы также увидите Dockerfile
а также .docker
каталог, который используется в среде разработки. Вы также увидите, что мы используем Jenkins в нашем конвейере CI/CD. Язык программирования, который мы использовали, это Nodejs
. Мы поговорим о каждой настройке среды.
Код обработчика функции всегда внутри Handler.js
. Мы создаем столько файлов внутри lib/
по мере необходимости. Соответствующие тесты для всего этого кода находятся под тесты/
.
Serverless.yml
Позвольте мне начать с того, что поделитесь нашими «простой» serverless.yml 😅, а затем я начну комментировать его и объясню, как мы используем этот файл для всех наших сред:
service: api-service provider: name: aws runtime: nodejs12.x memorySize: 512 stage: ${opt:stage, 'dev'} logRetentionInDays: ${self:custom.logRetention.${self:provider.stage}, self:custom.logRetention.other} vpc: subnetIds: - ${self:custom.subnetIds.${self:provider.stage}, self:custom.subnetIds.other} securityGroupIds: - ${self:custom.securityGroupIds.${self:provider.stage}, self:custom.securityGroupIds.other} deploymentBucket: name: api-service
Во -первых, вам придется указать имя службы, на которое вы хотите назвать Сервис. В части провайдера вам нужно будет назвать своего облачного провайдера, которого вы собираетесь использовать. Я AWS, как показано выше, но если вы используете GCP, это будет Google
. Вы можете увидеть пример для GCP здесь . Затем время выполнения, которое будет использовать ваше приложение без сервера. Не забудьте установить версию, подобную той, которую вы используете в среде разработчика.
Одним из важных вариантов в блоке поставщика является добавление объем памяти
ценность. Значение по умолчанию составляет 1024, но иногда ваша функция не будет использовать эту большую часть памяти, поэтому хорошо сэкономить немного денег здесь. Далее Стадия
Вариант, вы можете установить его с помощью аргумента SLS во время развертывания или использовать значение для отступления, как указано выше, Dev
в нашем случае.
Далее следует устанавливать политику удержания для вашей функции ( logretentionIndys
). Некоторые люди забывают использовать эту опцию, но это хороший способ избавиться от старых журналов и сэкономить деньги от уменьшения тонн журналов, хранящихся в CloudWatch. Мы устанавливаем другое значение в тестировании, кроме производства, поскольку нам нужно, чтобы производственные журналы были дольше. Значения здесь установлены значениями в пользовательском разделе. Мы устанавливаем значение в зависимости от этапа, на которую мы развертываем. Мы используем этот подход в большинстве наших областей. Хорошо написать общий Serverless.yml
Файл, который может обрабатывать несколько этапов/сред. Так что, если вы используете Stage Prod, он получит значение от Custom.Logretention.Prod
. Это пойдет и посмотрит, если у нас есть Custom.Logretention.prod
уже определен. Если нет, это установит значение с Custom.Logretention.other
который мы используем для всех средств тестирования.
Для субсетиды
и SecurityGroupids
Варианты, вы будете использовать их, если вам нужно подключить приложение к внутреннему ресурсу в своем кластере, поэтому пропустите его, если нет. Вам придется взять подсету и группы безопасности, в которых размещаются ваши другие ресурсы.
Будьте осторожны, как только вы подключите свою функцию с VPC, функция больше не может получить доступ к Интернету, даже если вы выбираете публичную подсети с маршрутом к интернет -шлюзу для вашей функции (см. Для функций Lambda Чтобы узнать больше). Таким образом, вы не можете иметь и то, и другое: доступ к ресурсам в вашем VPC и через Интернет.
Чтобы получить доступ к вашему VPC, а также в Интернете, вам нужно раскрутить Nat Gateway. Или в некоторых случаях вы можете сойти с рук с конечной точкой VPC.
Последняя часть здесь, добавляет ваш DeploymentBucket
. Важно поместить все ваши развертывания в одно ведро. У вас будет каждый этап, функционирование и развертывание в организованных каталогах с временными метками. Если вы собираетесь пропустить это, это создаст случайное ведро для каждого развертывания.
package: include: - functions/api-service/.env.defaults - functions/api-service/app.js - functions/api-service/handler.js - functions/api-service/lib/** - functions/api-service/node_modules/**
Пакет
Опция используется для включения, а также исключить файлы и каталоги из ваших функций, а также может помочь вам в уменьшении размера вашего приложения, который будет загружаться каждое развертывание на S3.
functions: api-service: handler: functions/api-service/handler.api-service description: this function will receive data from multiple services environment: KAFKA_TOPIC: api.service KAFKA_BROKERS: ${self:custom.KAFKA_BROKERS.${self:provider.stage}, self:custom.KAFKA_BROKERS.other} events: - http: path: api-service method: post cors: origins: - https://*.example.com headers: - Content-Type - X-Amz-Date - Authorization - X-Api-Key - X-Amz-Security-Token - X-Amz-User-Agent allowCredentials: true
Самая интересная часть — определение ваших функций массива. В нашем случае мы используем только одну функцию, но вы можете добавить столько, сколько вам нужно в зависимости от трубопровода, над которым вы работаете, или вы как бы не ботаник и используете функции шага 🤓. Я рекомендую искать здесь Если вы заинтересованы в поиске с шагами функциями.
Назовите свою функцию и добавьте ее вместе с его Описание
и обработчик
Анкет Убедитесь, что вы пишете функцию правого обработчика, а не имя файла. Тогда вы можете использовать среда
Возможность экспортировать некоторые переменные среды для использования во время работы вашей функции. Вы поймете, что мы используем один и тот же подход при обработке одной и той же переменной среды с несколькими этапами, такими как в $ {Self: Custom. Kafka_brokers. $ {Self: provider.stage}, self: custom. Kafka_brokers.other}
В События
Раздел, это зависит от того, что запускает вашу функцию: API Gateway, WebSocket, Kinesis & DynamoDB, S3 и т. Д. Смотри Здесь Больше подробностей.
Мы используем шлюз API с HTTP Endpoint Rading только для просьбы POST на /api-service
Анкет Вы также можете добавить некоторые конфигурации CORS в вашу функцию, как мы видим выше.
plugins: - serverless-domain-manager - serverless-offline
Хорошая вещь, которая обеспечивает вам плагины без сервера, это плагины. Мы используем Сервер без официального линии
Для запуска нашей настройки локально в среде разработки и Без сервера-домен-менеджер
плагин для обработки конфигурации шлюза API.
custom: customDomain: domainName: ${self:custom.subDomain.${self:provider.stage}, self:custom.subDomain.other}.${self:custom.domain.${self:provider.stage}, self:custom.domain.other} certificateName: "*.${self:custom.domain.${self:provider.stage}, self:custom.domain.other}" basePath: "${self:custom.basePath.${self:provider.stage}, self:custom.basePath.other}" stage: ${self:provider.stage} createRoute53Record: true domain: prod: example-prod.com other: example.com subDomain: prod: api-service other: api-service basePath: prod: other: ${self:provider.stage} subnetIds: prod: subnet-xxxxxxx other: subnet-yyyyyyy securityGroupIds: prod: 'sg-xxxxxxx' other: 'sg-yyyyyyy' KAFKA_BROKERS: prod: kafka-prod.example.com other: kafka-${self:provider.stage}.example.com logRetention: prod: 14 other: 7
В обычай
Раздел, это как объявление переменных. Переменные позволяют динамически заменять значения конфигурации в Serverless.yml
конфигурация Мы объявляем один для продлевать
и Другое
чтобы задержать, когда сцена не продлевает. Как когда мы использовали $ {self: custom.subnetids. $ {self: provider.stage}, self: custom.subnetids.other}
Анкет
Customdomain
Переменная используется здесь для определения конфигурации шлюза API. Итак, мы настраиваем доменное имя
, Сертификат
, Базепат
Что очень полезно, если используемый вами сертификат не обрабатывает альтернативные доменные имена (CNAME). Здесь Для получения дополнительной информации и Стадия поле. Вы также можете установить
Createroute53record с
Верно Чтобы фреймворк создал для вас, Route53 Records для использования в других ваших внешних службах.
Настройка среды разработки
Для среды разработки я предпочел запустить функцию без сервера с помощью Docker, чтобы лучше справиться с зависимостями. Так вот как выглядят Dockerfile и The Entrypoint:
FROM node:12.15.0-stretch COPY ./.docker/startup.sh /etc/ RUN chmod +x /etc/startup.sh CMD /etc/startup.sh
#!/bin/bash cd /var/www/app npm install -g serverless npm install sls offline -o api-service
Вы выше вы увидите, насколько просто настройка в среде разработки. Мы просто запускаем SLS
командовать с Сервер без официального линии
плагин. Это позволит локальному шлюзу API работать на порту 3000
Внутри контейнера и запускает функцию, как только мы ее нажимаем.
Наши параметры хранятся в функции/API-Service/.env.Defaults
Анкет Мы будем обрабатывать наши параметры по -другому в других средах.
Чтобы запустить эту настройку локально, вы можете использовать только команду Docker, либо вы также можете использовать Docker-Compose.
Команда Docker:
$ docker build -t api-service . $ docker run --name api-service -d -p 80:3000 -v ${PWD}:/var/www/app api-service
докер-состав:
version: '3.7' services: # api service api: build: context: . ports: - "80:3000" volumes: - .:/var/www/app
$ docker-compose up -d
Настройка тестирования и производственной среды
К счастью, потому что мы написали очень крутой и общий Serverless.yml
файл. У нас не так много шагов в этих средах. Вам просто нужно запустить:
sls deploy -s [stage] -v
Этот шаг создаст .serverless
каталог, который будет иметь сгенерированный шаблон облачной информации, Serverless-State и zip-файл, который будет загружен в ковш S3. Мне также нравится -v
возможность увидеть каждый созданный ресурс, и каждый шаг без сервера делает 👀
Автоматизация развертывания производства
Если вы хотите шагнуть выше со своим трубопроводом и добавить некоторую автоматизацию, вы можете использовать Дженкинс Чтобы автоматизировать ваш трубопровод CI/CD или автоматически развернуть ваше приложение при объединении ваших изменений в мастер.
Примером Jenkinsfile является как ниже:
pipeline { agent { kubernetes { label 'api-service' defaultContainer 'jnlp' yaml """ apiVersion: v1 kind: Pod metadata: labels: component: ci spec: # Use service account that can deploy to all namespaces containers: - name: node image: node:12.15.0-stretch command: - cat tty: true - name: awscli image: organs/awscli command: - cat tty: true """ } } stages { stage('build') { environment { BRANCH_NAME = sh ( script: "echo ${env.GIT_BRANCH}| rev | cut -f1 -d '/' | rev | sed 's/ *//g'", returnStdout: true ).trim() } steps { container('node') { sh """ npm install """ } container('awscli') { sh """ # deploy to prod stage if branch is master if [ "${env.BRANCH_NAME}" == "master" ]; then sls deploy -s prod -v fi """ } } } } }
Закрытие
Serverless — это удивительная технология или мышление, если хотите. Это важный шаг к делегированию проблем инфраструктуры для компаний, которые гораздо лучше связаны с ними. Независимо от того, насколько хорошо вы становитесь в DevOps, вам иногда нужны эти компании, чтобы обрабатывать и управлять своими приложениями, с которыми вы не хотите беспокоиться. И главное, что здесь — строить вашу архитектуру, не тратя эпохи, налаживая ее самостоятельно и не экономя тонны денег, размещая ее.
Я буду продолжать писать о различных темах без серверов и сценариях корпусов, с которыми я столкнулся, что я также вижу это интересным и сложным.
Цените ваши комментарии и отзывы 😊
Оригинал: «https://dev.to/mohamedmahmoud97/from-zero-to-serverless-20g1»