Канарское развертывание — это методика, которая снижает риск развертывания новой версии приложения, медленно выкачивая изменения в небольшое подмножество пользователей, прежде чем отказаться от его на всей базе клиента.
КАК ЭТО РАБОТАЕТ?
Концепции синих/зеленых и канаречных развертываний находились на некоторое время и были хорошо созданы как лучшие практики для снижения риска развертывания программного обеспечения. В традиционных приложениях вы медленно и постепенно обновляете серверы в своем флоте, одновременно проверяющие приложение для здоровья. Тем не менее, есть некоторое несоответствие импеданса при сопоставлении этих концепций миру без сервеса. Вы не можете постепенно развернуть ваше программное обеспечение через флот серверов, когда нет серверов!
Ответ заключается в том, что есть пара услуг и функций, связанных с этим возможным. Давайте объясним:
Лямбда версии и псевдонимы
AWS LAMBDA позволяет публиковать несколько версий одной и той же функции. Каждая версия имеет свой собственный код и связанные зависимости, а также свои собственные настройки функций (например, распределение памяти, переменные тайм-аута и среды).
Затем вы можете обратиться к данной версии, используя псевдоним лямбда. Псевдоним — это не что иное, как имя, которое можно указать на данную версию функции лямбда.
Переключение трафика с псевдонимами лямбда
С введением перемещения перемещения псевдонима, теперь можно тривиально реализовать канарные развертывания функций лямбда. Обновление дополнительной версии веса на псевдонимах, трафика вызова направляется на новые функциональные версии на основе указанного веса. Подробные метрики Cloudwatch для псевдонима и версии могут быть проанализированы во время развертывания, или другие проверки здоровья, чтобы убедиться, что новая версия будет здоровой перед продолжением.
Перемещение трафика с Сэмом и Кодедеме
AWS CODDEDEDOND обеспечивает интуитивно понятное внедрение этой функциональности, интегрированной непосредственно в AWS SAM.
Развертывание сдвинутого трафиками могут быть объявлены в шаблоне SAM, а CodeDeyPload управляет функцией развертывания как часть обновления стека CloudFormation. CloudWatch Alarms также можно настроить, чтобы вызвать откат стека, если что-то пойдет не так.
Обновить шаблон Сэма
Откройте шаблон SAM (SAM-App/Template.yaml) в вашем проекте и добавьте следующие строки в раздел Свойства HellowOrldFunction.
AutoPublishAlias: live DeploymentPreference: Type: Canary10Percent5Minutes
Береги себя в отступы, YAML файлы!: D.
Типы предпочтений развертывания
Для этого семинара мы используем стратегию Canary10Percent5minute, что означает, что трафик смещается в два шага. В первом приросте только 10% трафика смещены на новую лямбда, а через 5 минут оставшиеся 90% смещены.
Есть и другие стратегии развертывания, которые вы можете выбрать в коде
- Canary10Percent30minutes.
- Canary10Percent5minute
- Canary10Percent10minutes.
- Canary10Percent15minutes.
- Linear10percenteveryly10minutes.
- Linear10percentevery1minute.
- Linear10percentevery2minute
- Linear10Percentevery3Minutes.
- Все сразу
Линейная стратегия означает, что трафик смещается равным приращение с равным количеством временного интервала между каждым приращением.
Проверьте шаблон Сэма
Запустите следующую команду на вашем терминале:
~ cd ~/environment/sam-app ~ sam validate
Если шаблон правильный, вы увидите template.yaml — это действительный шаблон Сэма. Если вы видите ошибку, вы, вероятно, имеете проблема вдавливания в файле yaml. Дважды проверьте и убедитесь, что он соответствует скриншоту, показанному выше.
Подтолкнуть изменения
В терминале запустите следующие команды из корневого каталога вашего проекта SAM-App.
~ git add . ~ git commit -m "Canary deployments with SAM" ~ git push
Мониторинг Canary Health
Канарские развертывания значительно более успешны, если код контролируется во время развертывания. Вы можете настроить CODDEDEDOWLED для автоматического отказа от развертывания, если указанная метрика CloudWatch нарушила порог тревоги. Общие метрики для мониторинга — это ошибки вызова лямбда или продолжительность вызова (латентность), например.
Определите тревогу CloudWatch
Добавьте следующее определение аварийного сигнала в файл Template.yaml в разделе «Ресурсы» после определения HellowOrdFunction.
CanaryErrorsAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmDescription: Lambda function canary errors ComparisonOperator: GreaterThanThreshold EvaluationPeriods: 2 MetricName: Errors Namespace: AWS/Lambda Period: 60 Statistic: Sum Threshold: 0 Dimensions: - Name: Resource Value: !Sub "${HelloWorldFunction}:live" - Name: FunctionName Value: !Ref HelloWorldFunction - Name: ExecutedVersion Value: !GetAtt HelloWorldFunction.Version.Version
А затем добавьте следующие строки в раздел «РазвертываниеPreference» определения HellowOllordFunction.
Alarms: - !Ref CanaryErrorsAlarm
Ваш шаблон.yaml должен выглядеть так:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > sam-app Sample SAM Template for sam-app Globals: Function: Timeout: 3 Resources: HelloWorldFunction: Type: AWS::Serverless::Function Properties: CodeUri: hello-world/ Handler: app.lambdaHandler Runtime: nodejs14.x AutoPublishAlias: live DeploymentPreference: Type: Canary10Percent5Minutes Alarms: - !Ref CanaryErrorsAlarm Events: HelloWorld: Type: Api Properties: Path: /hello Method: get CanaryErrorsAlarm: Type: AWS::CloudWatch::Alarm Properties: AlarmDescription: Lambda function canary errors ComparisonOperator: GreaterThanThreshold EvaluationPeriods: 2 MetricName: Errors Namespace: AWS/Lambda Period: 60 Statistic: Sum Threshold: 0 Dimensions: - Name: Resource Value: !Sub "${HelloWorldFunction}:live" - Name: FunctionName Value: !Ref HelloWorldFunction - Name: ExecutedVersion Value: !GetAtt HelloWorldFunction.Version.Version Outputs: # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function # Find out more about other implicit resources you can reference within SAM # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api HelloWorldApi: Description: "API Gateway endpoint URL for Prod stage for Hello World function" Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/" HelloWorldFunction: Description: "Hello World Lambda Function ARN" Value: !GetAtt HelloWorldFunction.Arn HelloWorldFunctionIamRole: Description: "Implicit IAM Role created for Hello World function" Value: !GetAtt HelloWorldFunctionRole.Arn
Тогда вы можете подтвердить снова:
cd ~/environment/sam-app sam validate
Если все в порядке, то нажмите еще раз:
git add . git commit -m "Added CloudWatch alarm to monitor the canary" git push
Перейдите к консоли AWS CodeDeploind и через пару минут, вы должны увидеть новое развертывание в процессе. Нажмите на развертывание, чтобы увидеть детали.
Статус развертывания показывает, что 10% трафика были смещены на новую версию (ака канарцы). Кодеде выполнит оставшийся процент до тех пор, пока не указал интервал времени, в этом случае мы указали интервал на 5 минут.
Вскоре после 5 минут оставшийся трафик должен быть перенесен на новую версию:
Откат
Мониторинг здоровья вашей канареер позволяет коде выполнить, чтобы принять решение о том, необходим ли откат или нет. Если какая-либо из сигналов тревоги CloudWatch получает статус тревоги, CoDeDeDoind развернуть развертывание автоматически.
Ввести ошибку специально
Давайте сломаем функцию лямбда нарочно так, чтобы Canaryerrorsalarm запускается во время развертывания. Обновите код лямбда в Sam-App/Hello-World/App.js, чтобы бросить ошибку на каждый вызов, как это:
let response; exports.lambdaHandler = async (event, context) => { throw new Error("This will cause a deployment rollback"); // try { // response = { // 'statusCode': 200, // 'body': JSON.stringify({ // message: 'hello my friend with canaries', // }) // } // } catch (err) { // console.log(err); // return err; // } // return response };
Обязательно обновите тест на единицу, в противном случае сборка не удастся. Ознакомьтесь с каждой строкой в Sam-App/Hello-World/Tests/Build/Test-Handler.js файл:
// 'use strict'; // const app = require('../../app.js'); // const chai = require('chai'); // const expect = chai.expect; // var event, context; // describe('Tests index', function () { // it('verifies successful response', async () => { // const result = await app.lambdaHandler(event, context) // expect(result).to.be.an('object'); // expect(result.statusCode).to.equal(200); // expect(result.body).to.be.an('string'); // let response = JSON.parse(result.body); // expect(response).to.be.an('object'); // expect(response.message).to.be.equal("hello my friend with canaries"); // }); // });
В терминале запустите следующие команды из корневого каталога вашего проекта SAM-App.
git add . git commit -m "Breaking the lambda function on purpose" git push
Опять же, подождите, пока ваш трубопровод достигнет этапа развертывания (ExecuteCheset). Это должно стать синим, когда он начинается:
Вызывать Канарейка
Хотя развертывание запущено, вам необходимо создать трафик к новой функции LAMBDA, чтобы она не удалась и запустила тревогу CloudWatch. В реальной производственной среде ваши пользователи, скорее всего, будут генерировать органический трафик к функции Canary, поэтому вам нельзя делать это.
В вашем терминале запустите следующую команду, чтобы вызвать функцию Lambda:
aws lambda invoke --function-name \ $(aws lambda list-functions | jq -r -c '.Functions[] | select( .FunctionName | contains("sam-app-HelloWorldFunction")).FunctionName'):live \ --payload '{}' response.json
Помните: во время развертывания только 10% трафика будут направлены на новую версию. Итак, продолжайте приостановить лямбда много раз. 1 из 10 вызовов должны вызвать новую сломанную лямбду, что вы хотите вызвать откат.
Вот команда, которая вызывает вашу функцию 15 раз в цикле. Не стесняйтесь бегать в своем терминале.
counter=1 while [ $counter -le 15 ] do aws lambda invoke --function-name \ $(aws lambda list-functions | jq -r -c '.Functions[] | select( .FunctionName | contains("sam-app-HelloWorldFunction")).FunctionName'):live \ --payload '{}' \ response.json sleep 1 ((counter++)) done
Перейдите к консоли AWS CODDEDELOWPLAY и перейдите в прогресс развертывания, чтобы просмотреть его детали.
Через несколько минут Кодеде выполнил, что сработал CanaryerrorSalarm, и он начнет откатывать обратно развертывание. Экран будет выглядеть что-то подобное:
Очистка
Удалить ведра S3
Опорить ведра, перейдем к консоли S3. А затем удалить их (есть 2 ведра).
Удалить CF Stacks
Теперь, когда ведра пусты, мы можем удалить стопки облака:
Удалите стеки CF в следующей последовательности и, пожалуйста, подождите, пока каждый дойдет, прежде чем перейти к следующему.
~ aws cloudformation delete-stack --stack-name sam-app ~ aws cloudformation delete-stack --stack-name sam-app-cicd ~ aws cloudformation delete-stack --stack-name aws-sam-cli-managed-default
Теперь мы можем удалить экземпляр Cloud9, который мы создали:
- Перейдите в свою среду Cloud9.
- Выберите среду (I.E. myCloud9workspace) и нажмите Удалить.
Поздравляю, вы закончили семинар. Спасибо за чтение всех частей этой серии семинаров.
Оригинал: «https://dev.to/aws-builders/deploying-ci-cd-for-nodejs-serverless-applications-workshop-part-v-4g32»