Upgrade to Pro — share decks privately, control downloads, hide ads and more …

インプレースデプロイからBlue/Greenデプロイへの変更をゴリ押しで進めた話

 インプレースデプロイからBlue/Greenデプロイへの変更をゴリ押しで進めた話

Toshiaki Furukawa

March 14, 2022
Tweet

Other Decks in Programming

Transcript

  1. インプレースデプロイからBlue/Greenデプロ
    イへの変更をゴリ押しで進めた話
    JAWS-UG朝会
    2022/3/14

    View Slide

  2. 2
    ⾃⼰紹介
    古川 敏光(ふるかわ としあき)
    名前:
    筋トレ、サーフィン、サッカー観戦
    趣味:
    2年ちょい
    (サーバレス開発、CI/CD導⼊)
    AWS歴:
    住んでる場所: 神奈川県藤沢市
    (最近引っ越しました)

    View Slide

  3. ⽬次
    1. はじめに
    2. 既存環境
    3. どうB/Gにするのか
    4. 懸念点
    5. ゴリ押しポイント
    6. まとめ

    View Slide

  4. はじめに

    View Slide

  5. 5
    はじめに
    AWS CodeBuild AWS CodeCommit AWS CodeDeploy
    弊社はAWS専業なので、CI/CD導⼊案件ではAWS Codeシリーズを使⽤するこ
    とが多いです
    今回お話する案件では、Jenkinsにより既にCI/CDが導⼊されており、 Jenkins
    からAWS Fargate上にアプリケーションをインプレースデプロイしています

    View Slide

  6. 既存環境

    View Slide

  7. 7
    構成
    複数のサービス(13個)が
    Fargate上で稼働している
    Internal ALBによる
    サービス間通信
    インフラ構成管理ツールに
    Serverless Frameworkと
    CloudFormationを使⽤
    CloudFormation Serverless Framework

    View Slide

  8. 8
    デプロイ⽅式
    ECSはローリングアップデート
    Serverless Frameworkのプラグイン
    「serverless-aws-nested-stacks」を
    使⽤し、CFnのテンプレートファイルを
    読み込む
    sls deployで⼀括デプロイ
    # serverless.yml
    Custom:
    :nested-stacks:
    location: ./
    stacks:
    - id: ${self:service}${self:provider.stackName}
    template: elb.yml
    enabled: true
    timeout: 60
    parameters:
    - VPC: vpc-**********
    - Subnet1: subnet-**********
    - Subnet2: subnet-**********

    View Slide

  9. 9
    CIツール
    EC2上にJenkins環境を構築
    Webブラウザ経由でJenkinsに
    アクセスし、GUIで操作
    GUIにて、デプロイするサ
    ービス名を選択して起動
    EC2

    View Slide

  10. どうB/Gにするのか

    View Slide

  11. 11
    前提条件
    デプロイ⽅式の変更と並⾏して、Global IPの固定化を⾏った
    前段にNLBを置くことが必須
    NLBの加重ラウンドロビン(重み付け)は不可能
    Route53によるB/Gの切り替えは不可能
    デプロイ時のサービス間ダウンタイムを無くしたい
    JenkinsやServerless Frameworkなどを使⽤し、変更を最⼩限にしたい

    View Slide

  12. 12
    ①タスクセット切り替え
    NLBの後ろにInternal ALBを配置
    デプロイする際に、サービスごとに
    Green⽤のECSタスクセットを作成
    B/Gの切り替えは、LiveListenerの
    TargetGroup変更で⾏う

    View Slide

  13. 13
    ①タスクセット切り替え

    View Slide

  14. 14
    ②ALBの追加
    NLBの後ろにALBを配置
    ALBのターゲットグループに
    Internal ALBを配置
    B/Gの切り替えはALBの加重
    ラウンドロビンで⾏う

    View Slide

  15. 15
    ③IPベースの重み付け
    NLBの後段にBlue⽤、Green
    ⽤のInternalALBを配置
    LambdaによりNLBの
    TargetGroupにIPアドレス
    を登録
    IPアドレスの登録個数で
    ラウンドロビン

    View Slide

  16. 16
    ④ ターゲットグループの直接切り替え
    NLBの後段にBlue⽤、
    Green⽤のInternalALBを
    配置
    Green⽤のデプロイをする
    際は、サービスレイヤーをS
    丸ごとServerless Deployす

    AWS CLIを使⽤して、NLB
    のターゲットグループを直
    接切り替える

    View Slide

  17. 17
    ⽐較検討
    ⼿法 実装コスト ダウンタイム 備考
    1. タスクセット切り替え ⾼ ⾼ 改修が必要
    2. ALBの追加 低 低 実現不可
    3. IPベースでの重み付け ⾼ 低
    4. ターゲットグループを直接
    切り替え
    低 ⾼ ダウンタイムがどのぐ
    らいか要検証
    実装コストを第⼀優先に考えると、4.ターゲットグループ
    を直接切り替えが望ましい
    実際に、B/G切り替えによるダウンタイムを⼿動にて検証
    したところ、10秒かかった。

    View Slide

  18. 懸念点

    View Slide

  19. 19
    懸念点
    サービス間のアクセスはどうするか

    View Slide

  20. 20
    懸念点
    ALBの後にNginxを配置し、
    URLでリバースプロキシ先
    を振り分ける
    Fatgate上にNginxを構築し、
    ECS Service Discoveryで各
    ECSコンテナに⾃動的にAレ
    コード登録を⾏う

    View Slide

  21. 21
    懸念点
    # nginx.conf
    events {
    }
    http {
    proxy_connect_timeout 60;
    proxy_send_timeout 60;
    proxy_read_timeout 60;
    server {
    location / {
    proxy_pass http://a-blue.service;
    }
    location /static/ {
    proxy_pass http://static-blue.service/;
    }
    location /a/ {
    proxy_pass http://a-blue.service:8080/;
    }
    }
    }
    Nginxでリバースプロ
    キシ設定

    View Slide

  22. ゴリ押しポイント

    View Slide

  23. 23
    ゴリ押しポイント
    既存のテンプレートを使いたい
    ので、あくまでServeless
    Frameworkを使う
    プラグイン「serverless-
    plugin-additional-stack」に変

    `deploy --stage ${STAGE} `
    で、STAGEにBlueかGreenを設
    定することで、
    additionalStacks:
    blue:
    StackName: blue-${self:service}-${self:provider.stage}-backend
    DeployParameters:
    - ParameterKey: Name
    ParameterValue: blue-${self:service}-${self:provider.stage}-backend
    - ParameterKey: Stage
    ParameterValue: ${self:provider.stage}
    Parameters: ${file(./backend.template.yml):Parameters}
    Resources: ${file(./backend.template.yml):Resources
    green:
    StackName: green-${self:service}-${self:provider.stage}-backend
    DeployParameters:
    - ParameterKey: Name
    ParameterValue: green-${self:service}-${self:provider.stage}-backend
    - ParameterKey: Stage
    ParameterValue: ${self:provider.stage}
    - ParameterKey: PrivateSubnets
    Parameters: ${file(./backend.template.yml):Parameters}
    Resources: ${file(./backend.template.yml):Resources

    View Slide

  24. 24
    ゴリ押しポイント
    Blue環境 Green環境切り替え
    Green環境テスト
    ターゲットグループ1つに対して、関連付けられるリスナールールは1つのみ
    ターゲットグループとリスナールールの関連づけを⾃ら⾏う必要がある

    View Slide

  25. 25
    切り替え⼿順
    Blue→Green
    STEP Jenkinsジョブ名 役割
    1 enable-test-listener テストリスナー(green)を作成し、有効化
    2 docker-push-nginx green環境⽤nginxのdocker imageをPUSH
    3 deploy-all-new-infra green環境⽤のリソースをデプロイ
    4 replace-live-listener 重み付け変更によりライブリスナーを切り替え
    5 remove-all-previous-infra blue環境⽤の削除
    切り戻し(Green→Blue)
    STEP Jenkinsジョブ名
    1 rollback-to-previous-version リスナーの重み付けを変更
    2 remove-all-previous-infra green環境⽤のリソースを変更

    View Slide

  26. まとめ

    View Slide

  27. 27
    まとめ
    B/Gデプロイ⼿法に正解はない。
    JenkinsとCodeシリーズを⽐較すると、Codeシリーズの⽅が実装コスト
    は⼩さく済むが、Jenkinsの⽅がより細かいジョブ設定ができる
    実装コストやダウンタイム許容時間等、
    要件に沿ってデプロイ⼿法を決める
    Jenkinsfileは最初取っ付きにくく感じるかもれしれないが、仲良くなれた
    らCI/CDの世界が広がる

    View Slide

  28. View Slide