ããªãªã«ã¼ãã§ã«ã¼ããæ²ããã¨ãã«ä½ãå¾æããã¦ãã¾ãCTO室 kenzo0107 ã§ãã
ä»å㯠2018/04/02 ã«ãªãã¥ã¼ã¢ã«ããã¤ã·ã³ã¡ã® Rails à ECS ã«ã¤ãã¦ã§ãã
ã¤ã·ã³ã¡ã¨ã¯ï¼
ãã¤ã·ã³ã¡ãã¯ãå»å¸«10ä¸äººã®å£°ã§ã¤ãããã«ã¹ã±ã¢ã¡ãã£ã¢ã§ãã
å»å¸«ã¨ä¸è¬ã®æ¹ã
ãã¤ãªãããã¨ã§ãå»çæ
å ±æ ¼å·®ãåãããã¨ãç®æãã¦ãã¾ãã
MedPeerã®10ä¸äººã®å»å¸«ä¼å¡ã«ååããã ããã¢ã³ã±ã¼ãçµæããã¨ã«ç·¨éé¨ã§è¨äºãå·çããå»å¸«ç£ä¿®ã®ä¸ã§é ä¿¡ãå¤ãã®å»å¸«ã®å£°ãåæ ãããã¨ã§ãããæ£ããæ å ±ãæä¾ãã¦ãã¾ã
ãªãã¥ã¼ã¢ã«çµç·¯
ãªãã¥ã¼ã¢ã«åã¯ä»¥ä¸ã®ãããªæ§æã§ããã
- ããã³ãã« Laravel 5
- ããã¯ã« Drupal
- Docker on EC2
- ã³ã³ããã¤ã¡ã¼ã¸ã® S3 ã§ã®ãã©ã¤ãã¼ã管ç
Docker ãã¾ã åºã¦ãã¦éããªãé ãå½ç¶ãAWS ECS ããªãªã¼ã¹ããã¦ããã
ææ¢ã«æè¡çã«ãã£ã¬ã³ã¸ããçè·¡ãå¤ã
ããã¾ããã
ã§ããã å½æã®æ§æã§ã¯ä»¥ä¸ã®åé¡ãããã¾ããã
- ã¤ã¡ã¼ã¸ã®ç®¡çããããã¤ããè¾ã
- ã¹ã±ã¼ãªã³ã°ãèæ ®ããã¦ãªã
ã¾ãã
Google æ¤ç´¢çµæã®å»çãå¥åº·ã«é¢ããæ¤ç´¢çµæã®æ¹å ã追ã風ã¨ãªããã©ãã£ãã¯ã伸ã³ãã¹ã±ã¼ãªã³ã°ã¸ã®é
æ
®ãéè¦ã«ãªãã¾ããã
ä¸è¨ã®åé¡ã AWS ECSã»ECR ã®æ©æµãåãããã¨ã§è§£æ±ºãããã¨èãã¾ããã
ã¾ãã
éçºä¿é²ããã¹ããå¼ç¤¾ã§éçºã®ç¥è¦ã®ããå¤ã Rails ã¸ã®ãªãã¬ã¤ã¹ãè¡ãéã³ã¨ãªãã¾ããã
ã¾ãçµè«
â» å·¦å´ãã¦ã¼ã¶ãµã¤ããå³å´ã管çç»é¢ã«ãªãã¾ãã
- ã¤ã¡ã¼ã¸ç®¡ç㯠ECR
- ãããã¤ã¯ ecs-cli
- CloudFront > ALB > Nginx > Rails ã¨ããã«ã¼ãã£ã³ã°*1
- Tasks, EC2 ããªã¼ãã¹ã±ã¼ãªã³ã°
- RDS Aurora MySQL ã¸ãªãã¬ã¤ã¹ã Read Replica ãªã¼ãã¹ã±ã¼ãªã³ã°
ã¡ãã£ã¢ãµã¤ãã¨ãããµã¤ãç¹æ§ããããã¢ã¯ã»ã¹ãéä¸ãã¹ãã¤ã¯ãããã¨ãéã¿ã¦ CloudFront ã§ã®ãã£ãã·ã¥ãæå¹ã«ãããªã¼ãã¹ã±ã¼ãªã³ã°ã§ããã¨ããã¯ããæ§ã«ãã¾ããã
ãªãã¥ã¼ã¢ã«ç´å¾ã® 2018å¹´4æé ã麻ç¹ãæµè¡ããéã«éº»ç¹é¢é£ã®è¨äºã¸ã®ã¢ã¯ã»ã¹ãæ¥å¢ããéã¯ãæ¬å½ã«ãã®æ§æã«ãã¦ããã¦ããã£ãã¨æãã¾ããã
https://ishicome.medpeer.jp/entry/767ishicome.medpeer.jp
ç¶ã㦠ECS ã§ãµã¼ãã¹æ§æããã«å½ãã£ã¦èæ ®ãããã¨ãã¾ã¨ãã¾ããã
ECS ã¸ã®æºåã§èæ ®ãããã¨
- ã³ã³ããè¨è¨
- ãããã¤
- ãã®ã³ã°
- ãªã¼ãã¹ã±ã¼ã«
- ãããå¦ç
- æ¤è¨¼ç°å¢
ã³ã³ããè¨è¨
Nginx
Nginx ãã«ã¼ãã£ã³ã°ã«æãã ã®ã¯ä»¥ä¸ã®çç±ããã§ãã
- Rate limit ã®è¨å®ãç´°ããã³ã³ããã¼ã«ãããã£ãã*2
- AWS WAF ã§ã¯æä½ã§ã 5åéã« 2000 ãªã¯ã¨ã¹ã以ä¸ã§ã¢ã¯ã»ã¹å¶éå¯è½
- IP ç´æå®åé¿
Rails
Rails ã³ã³ããã«ã¤ãã¦ä»¥ä¸ã®ç¹ãè¨è¨èæ ®ãã¾ããã
secrets.yml
yaml_vault ã§æå·åã»å¾©å·ããããã«ãã¾ããã*3
- KMS ã®ã¨ã¤ãªã¢ã¹ãã¼ãä½æã
- ãã®ãã¼ã§ã®æã»å¾©å·æ¨©éã IAM Group ã§ç®¡çãã
ãããããã¨ã§
権éã®ä»ä¸æã«ã¯ IAM Group ã«å«ããã
権éã®å¥å¥ªæã«ã¯ IAM Group ããé¤å¤ããã
ã¨ç®¡çã楽ã«ãªãã¾ããã
Task Definition ã«ã¯åºæ¬ç§å¯æ å ±ãè¼ããªãæ§ã«ãã¾ããã*4
- å®è¡ã³ãã³ã
// secrets.yml ã®æå·å (env: production) yaml_vault encrypt \ config/secrets.yml \ -o config/encrypted_secrets.yml.production \ --cryptor=aws-kms \ --aws-region=ap-northeast-1 \ --aws-kms-key-id=<kms alias> \ --aws-profile <profile> // secrets.yml ã®å¾©å· (env: production) yaml_vault decrypt \ config/encrypted_secrets.yml.production \ -o config/secrets.yml \ --cryptor=aws-kms \ --aws-region=ap-northeast-1 \ --aws-kms-key-id=<kms alias> \ --aws-profile <profile>
Dockerfile (Rails)
RAILS_ENV ã渡ãã¦ãã«ããåç°å¢æ¯ã«å¦çåãããã¦ã¾ãã
FROM ruby:2.5-alpine RUN apk update \ && apk upgrade \ && apk add --update build-base mysql-dev nodejs tzdata git \ && rm -rf /var/cache/apk/* # TZ JST RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime ENV app /work/app WORKDIR $app COPY . $app RUN bundle install -j4 --retry 6 --without test development --no-cache \ && npm install --production --no-progress \ && mkdir -p tmp/sockets \ && mkdir -p tmp/pids ARG RAILS_ENV # docker build æã« db æ¥ç¶ãããã¨ããçºãæ¥ç¶ããªãæ§ãnulldb æå® RUN chmod +x docker/on_build.sh \ && sync \ && docker/on_build.sh CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
docker/on_build.sh
- assets:precompile, assets:sync å®è¡æã« S3 ã«ã¢ãããã¼ã, CloudFrontã§é ä¿¡ by asset_sync, fog-aws
#!/bin/sh set -e # docker build æã« db æ¥ç¶ãããã¨ããçºãæ¥ç¶ããªãæ§ãnulldb æå® DB_ADAPTER=nulldb bundle exec rake assets:precompile assets:sync RAILS_ENV=${RAILS_ENV}
ãããã¤
ecs-cli ãæ¡ç¨ãã¾ããï¼
æ¡ç¨çç±ã¯ä»¥ä¸ã®éãã§ãã
- ECS åãã® AWS ãªãã£ã·ã£ã«ã®ãã¼ã«
- æ¢åã®è¨å®ãã AWS credential å©ç¨å¯
- Task å®ç¾©ã docker-compose.yml å½¢å¼
- Fargate 対å¿å¯
Fargate Tokyo region ãå¾ ã¡é ããã§ãâª*5
ãããã¤ããã¼
master
,develop
,qa/*
ã« merge ãããªã¬ã¼ã« CircleCI ãã«ã- ãã¹ãããã¹ããã CodePipeline éå§
- CodePipeline ã§
cap (production|staging) deploy
å®è¡
CircleCI ã«ã¯ CodePipeline ã®éå§ã»æ´æ°æ¨©éã®ã¿ã® AWS Access Key ID, Secret Key ãè¨å®ãã¦ãã¾ãã
CircleCI ä¸ãããããã¤ããªãã®ï¼
ã¯ããã«æ¤è¨ããã®ã§ãã以ä¸çç±ã«ããä¸è¨æ§æãé¸æãã¾ããã
- CircleCI ã¨ãã«ããµã¼ããåãããã¨ã§ CircleCI ã¯ãã¹ãã«å°å¿µã§ããã
â ãããã¤ãçµããã¾ã§ãªã½ã¼ã¹ãææ¾ããä»ã®ãã«ããé 延ããã®ãé¿ããã
ãããã㯠CodePipeline ã§ãã¹ããå®è¡ãå
¨ã¦ãå®çµããã¦ã¿ã¦ã³ã¹ãæ¯è¼ããæ¤è¨¼ããããã¨æã£ã¦ãã¾ãã
æ¢ã«ãã£ããæãã¦ãã ãã
ãã®ã³ã°
- ã³ã³ãããã awslogs 㧠CloudWatch ã«åºå
- Lambda ã§æ¥æ¬¡ã§ CloudWatch ã®ãã°ã°ã«ã¼ãã S3 ã«ä¿å
Rails ã³ã³ããã§ã¯ç°å¢å¤æ°ã«
RAILS_LOG_TO_STDOUT: 1
ãè¨å®ãããã¨ã§
Rails ã®ãã°ãæ¨æºåºåããCloudWatch ã«æµãæ§ã«ãã¦ãã¾ãã
ã¾ããã好ã¿ã§ãã
lograge 㧠CloudWatch ä¸ã®ãã°ã®è¦èªæ§ãé«ã¾ãã¾ããã
CloudWatch ã®ã¤ãã³ããã£ã«ã¿ã¼ã§
{$.db >= 1000}
ã¨ãããã¨ã§ DB㧠1000 msec 以ä¸æéãè¦ããã¤ãã³ããæ½åºãããã¨ãã§ãã¾ãã
ãªã¼ãã¹ã±ã¼ã«
ã¹ã±ã¼ã«ã¢ã¦ãæã«èæ ®ãããã¨ã¨
- ã¾ã EC2 ã¤ã³ã¹ã¿ã³ã¹ãå¢ããã¦ããã®å¾ãTask ãå¢ãã
â Task ãä¸æ¹ã«åã£ã¦ãã¾ãçã®äºè±¡ãçºçãã¦ãã¾ãçºã§ãã
CloudWatch ã®ç£è¦è¨å®ã§ evaluation_periods ã EC2 < Task ã®æ§ã«è¨å®ãã¾ããã
ã¤ã³ã¹ã¿ã³ã¹åä½ã® CPU 使ç¨ççã®ã¡ããªã¯ã¹ã§ãªããService ã§ã®ã¡ããªã¯ã¹ã§èãããã¨
â ä¸æçãªåãã§ãªããå ¨ä½çã«è² è·ãé«ãå ´åã«ã¹ã±ã¼ã«ãããã¨ããæ§ã«ããçºã§ããRDS Aurora MySQL ã®ãªã¼ãã¹ã±ã¼ã«ã¯ Read/Write ã switch_point ã§åç §å ãåãæ¿ããæ§ã«ãã¾ããã
ãããå¦ç
ã¯ã©ã¹ã¿ãæå®ã ECS Scheduled Tasks 㧠one-off container ã§å®æå®è¡ãã¾ãã
ä»¥ä¸ Sitemap å®ææ´æ°ã¿ã¹ã¯ä¾ã§ãã
æ¤è¨¼ç°å¢ã®èªåæ§ç¯
qa/*
ã¨ãããã©ã³ãå㧠push ããã¨ãã®ãã©ã³ãã«ç´ã¥ããã¼ãã§æ¤è¨¼ç°å¢ãèªåã§æ§ç¯ããæ§ã«ãã¾ããã
ããã«ããã¨ã³ã¸ãã¢ã»ãã£ã¬ã¯ã¿ã¼ã®æ¤è¨¼åæ°ãé£èºçã«å¢ããç»é¢ãéãã¦ã³ãã¥ãã±ã¼ã·ã§ã³ãããã¨ã§èªèã®é½é½¬ãæ¸ãããã¸ã§ã¯ããããåæ»ã«é²ãæ§ã«ãªãã¾ããã
ç¾ç¶ãã¤ã³ã¹ã¿ã³ã¹ã¿ã¤ã m5.large
ã® EC2 ã¤ã³ã¹ã¿ã³ã¹ãã¹ãããã§å©ç¨ãããã¨ã§ä¾¡æ ¼ãæãã¤ã¤ 3~5 ç¨åº¦ã®æ¤è¨¼ç°å¢ãåä½ãã¦ãã¾ãã
æ§ç¯æé
- ALB ã®ç©ºãã¦ãã Listener Port åå¾
- 空ã Port ãå ã« target group ä½æ
- target group ã« branch åãã¿ã°ä»ã
- ã¤ã³ã¹ã¿ã³ã¹ç»é²
- ALB Listener ä½æ
- ECS Service ä½æ
- service åã branch åããããããã«ã©ããªã³ã°
- QA ç°å¢ã¸ deploy
ç¾ç¶ä¸è¦ã¨ãªã£ã QA 㯠cap ã§åé¤ç¨ã³ãã³ããç¨æãã¦ã¾ãã ãã©ã³ãåé¤æã«èªååé¤ãããçãæ¤è¨ä¸ã§ãã
ã¡ãªã¿ã«ãã©ã®ãã©ã³ããã©ã®ãã¼ãã使ã£ã¦ããã㯠Slack bot ãæãã¦ããã¾ãã
ã¾ã¨ã
Rails à ECS ã¸ã®ãªãã¬ã¤ã¹ã«ããèªååã§ããé¨åãå¤ãæ¬å½ã«éç¨ã楽ã«ãªã£ãã¨æãã¾ãã
ç¹ã«æ¤è¨¼ç°å¢ã®èªåæ§ç¯ã¯ä»ããã¸ã§ã¯ãã§ãæã¾ãå°å ¥ãé²ãã¦ãã¾ãã
ã¾ããFargate ã®æ¤è¨¼ãå®æ½ãã¦ããã¾ãã®ã§ããã®æã«ã¯æ¬ããã°ã«ã¾ã¨ãã¦ããããã¨æãã¾ãã
以ä¸ã§ãã
åèã«ãªãã°å¹¸ãã§ãã
æ¯éèªè ã«ãªã£ã¦ãã ãã(ï¸ ÕਠÕ)ï¸
ã¡ããã¢ã§ã¯ä¸ç·ã«åã仲éãåéãã¦ãã¾ãã ãå¿åããå¾ ã¡ãã¦ããã¾ãï¼
â åéãã¸ã·ã§ã³ã¯ãã¡ã
https://medpeer.co.jp/recruit/entry/
â éçºç°å¢ã¯ãã¡ã
https://medpeer.co.jp/recruit/workplace/development.html
ã¤ã³ãã©æ§ç¯ã»éç¨ãéçºããã»ã¹ã®æ¹åã«æºãã£ã¦ããã ãã SRE åéä¸ã§ãï¼
https://medpeer.co.jp/recruit/entry/entry09.html
Railsæªçµé¨/çµé¨å¹´æ°ã2年以å ã®ããã³ã·ã£ã«ã¨ã³ã¸ãã¢çµ¶è³åéä¸ã§ãï¼*6
Railséçºãã¦ã¿ãã人ãæ°ããæè¡ã«æ欲çãªäººããªã¼ãã¨ã³ã¸ãã¢ã«æè²ããã¦ã¿ããï¼ï¼ï¼äººãå»çã«é¢ãããµã¼ãã¹éçºãè¡ã£ã¦ã¿ãã人ããã®ä»ã¡ããã¢ã«èå³ãæã£ãæ¹ãªã©ã¯ãæ¯éãã³ã³ã¿ã¯ããåã£ã¦é ããã°ã¨æãã¾ãï¼
*1:Nginx ãæãã çç±ã¯ã³ã³ããè¨è¨ã§ï¼
*2:ææã /phpmyadmin ã®ãããªãã¹ã§ã¢ã¯ã»ã¹ãã¦ãããããªæ»æã1åéã« 200 ãªã¯ã¨ã¹ãç¨ãã¾ããã AWS WAF ã® based rule ã§ã¯é²ãã¾ããã
*3:ã¤ã·ã³ã¡ ãªãã¥ã¼ã¢ã«ç´å¾ã« Rails 5.2 credentials ãåºãçºãsecrets.yml ã§ã®ç§å¯æ å ±ç®¡çããã¦ãã¾ãã
*4:EC2 ä¸ã§ ssm ã§å¤ãåå¾ãç°å¢å¤æ°ã«è¨å®ããæ¹æ³ãããã¾ãã Fargate ã®æã©ãããã®ãæ¤è¨¼ä»åãããä¸æ¦ secrets.yml ã«å¯ããæ§ã«ãã¾ããã
*5:æ¬è¨äºå·çæã« Fargate Tokyo Region ã® 2018å¹´7æ äºå®ãã¢ãã¦ã³ã¹ãããç¥ã¿ã¤ãã³ã°ã§ããã®ã§ãå·çãæ¥ãã¾ãã
*6:ãªã¼ãã¨ã³ã¸ãã¢ãåéä¸ã§ãï¼