Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

Beanstalk로 Go 애플리케이션 배포

AWS Elastic Beanstalk는 EC2, S3, SNS, CloudWatch, Auto Scaling, Elatic Load Balancer과 같은 다양한 AWS 서비스를 조율해서 배치 할 수 있도록 제공되는 오케스트레이션 서비스다. Beanstalk는 운영체제를 추상화 한다. 즉 운영체제를 신경 쓸 필요 없이, 미리 구축된 환경에서 애플리케이션을 실행 할 수 있다. PaaS 서비스로 Heroku가 이와 유사한 서비스가 되겠다.

Beanstalk를 이용해서 go 애플리케이션을 배포하기로 했다. go 애플리케이션을 배포하는 몇 가지 방법이 있다.
  1. 소스코드를 올린다 : Beanstalk는 Go 플랫폼을 제공한다. Beanstalk는 소스코드를 빌드해서 실행 애플리케이션을 만들고 실행한다. 이 애플리케이션은 5000번 포트에서 시작을 한다.
  2. 빌드된 실행파일을 "zip"파일로 묶어서 혹은 Procfile과 함께 올린다. Go는 one file 빌드가 가능하다. 단지 하나의 파일만 압축해서 올리면 되기 때문에, 배포가 단순해 진다.
Go 언어를 사용한다면, 그냥 2번 방법을 사용하자. 2번의 경우 eb cli를 이용하면 zip으로 묶어서 배포하는 과정들까지 자동화 한다.

Beanstalk 구성 요소

Beanstalk의 구성요소는 아래와 같다.

 Beanstalk의 구성요소

  • 애플리케이션(Application) : 애플리케이션의 종류(Tier), 실행 플랫폼(Java, Python, Go ...), 실행버전과 같은 애플리케이션의 전반적인 실행정보를 가지고 있다.
  • 환경(Environment) : 애플리케이션은 환경(Environment)를 담는 그릇이다. 실제 실행단위는 환경이다. 애플리케이션은 하나 이상의 환경을 가질 수 있는데, 보통 개발->스테이징->프러덕트 와 같이 개발&배포 프로세스에 따라서 환경을 만든다. 여기에는 인스턴스타입, 볼륨, capacity(몇 개의 인스턴스를 띄울 건지), 로드밸런서, VPC 설정, Security group 과 같은 애플리케이션의 실행에 필요한 정보들이 들어간다.

Environment Tier

Web server environment tier 애플리케이션의 구성

Nginx 웹 서버와 웹 애플리케이션 서버로 구성된다. Nginx 웹 서버는 HTTP 요청을 127.0.0.1:5000 으로 reverse proxy 하는 location 룰을 가지고 있다. 따라서 Web server environment tier 애플리케이션은 5000번에 바인드 하도록 구성하면 된다. Nginx 설정은 필요에 따라 바꿀 수도 있다.

 Web server environment tier

Worker environment tier 애플리케이션 구성

웹서버가 클라이언트의 요청을 SQS로 던지면 Worker 가 읽어서 처리하는 구성이다. 이미지 처리 애플리케이션이 이런 식으로 구성되는 경우가 많다.
  1. 이미지 원본이 웹서버로 업로드 된다.
  2. 웹서버는 이미지 원본을 S3에 저장을 한다.
  3. SQS에 이미지 원본 URL을 보낸다.
  4. Worker들 중 하나가 SQS에서 이미지 원본 URL을 읽은 다음, 이미지 작업(리사이징, 섬네일 만들기 등)을 수행한다.
 Worker environment tier

EB CLI 설치

웹 콘솔로 beanstalk를 제어 할 수 있기는 한데, 결국 제대로 다루려면 EB CLI를 이용해야 한다. EB CLI를 우선으로 작업을 하고 웹 콘솔로 확인하는 방식으로 진행하기로 했다. 사용중인 운영체제는 우분투리눅스 17.04다. 테스트를 위해서 간단한 웹 애플리케이션 프로젝트를 만들었다. 이 프로젝트의 디렉토리 구성은 아래와 같다.
--- simpleweb --+--- hello.go
                |
                +--- Makefile

awsebcli를 설치하자.
$ pip install awsebcli --upgrade --user
eb cli 프로그램은 $HOME/.local/bin 에 설치된다. $PATH에 등록해서 사용하자.
# cat .bash_profile
....
PATH=$HOME/.local/bin:$PATH

EB application create

eb init를 이용해서 EB 애플리케이션의 기본 값을 설정 할 수 있다. eb init는 현재 디렉토리에 적용이 된다. 따라서 프로젝트 디렉토리에서 실행을 하도록 하자. simpleweb 디렉토리로 이동해서 eb init를 실행했다.
# eb init
....
8) ap-southeast-2 : Asia Pacific (Sydney)
9) ap-northeast-1 : Asia Pacific (Tokyo)
10) ap-northeast-2 : Asia Pacific (Seoul)
11) sa-east-1 : South America (Sao Paulo)
12) cn-north-1 : China (Beijing)
....
(default is 3): 10

Select an application to use
1) gowiki 
2) joinc 
3) [ Create new Application ]
(default is 3): 3

Enter Application Name
(default is "simpleweb"): 

Select a platform.
......
7) Docker
8) Multi-container Docker
9) GlassFish
10) Go
......
(default is 1): 10

Select a platform version.
1) Go 1.10
2) Go 1.9
......
(default is 1): 1
대화식으로 설정 할 수 있다.
  1. 서울리전(ap-northeast-2)에 배포하기로 했다.
  2. 애플리케이션의 이름은 "simpleweb"이다.
  3. Go를 선택한다.
  4. Go 버전 1.10을 선택했다.
작업을 끝내고 나면, 작업 디렉토리에 .elasticbeanstalk/config.yml 파일이 만들어진다. 위에 설정한 내용들이 들어가 있다.
# cat .elasticbeanstalk/config.yml
branch-defaults:
  default:
    environment: null
    group_suffix: null
global:
  application_name: simpleweb
  branch: null
  default_ec2_keyname: null
  default_platform: Go 1.10
  default_region: ap-northeast-2
  include_git_submodules: true
  instance_profile: null
  platform_name: null
  platform_version: null
  profile: null
  repository: null
  sc: null
  workspace_type: Application
웹 콘솔에서 simpleweb 애플리케이션이 만들어진걸 확인 할 수 있다. 아직은 아무런 환경도 없는 상태다.

환경 설정 및 애플리케이션 배포

애플리케이션 환경을 설정해보자. eb create로 환경을 만들고 여기에 애플리케이션 버전을 배포 할 수 있다. simpleweb-dev를 만들기로 했다.
# eb create simpleweb-dev
Creating application version archive "app-180526_132901".
Uploading simpleweb/app-180526_132901.zip to S3. This may take a while.
Upload Complete.
Environment details for: simpleweb-dev
  Application name: simpleweb
  Region: ap-northeast-2
  Deployed Version: app-180526_132901
  Environment ID: e-pp8k7g3ggr
  Platform: arn:aws:elasticbeanstalk:ap-northeast-2::platform/Go 1 running on 64bit Amazon Linux/2.7.6
  Tier: WebServer-Standard-1.0
  CNAME: UNKNOWN
  Updated: 2018-05-26 04:29:06.199000+00:00
Printing Status:
INFO: createEnvironment is starting.
......
지금은 환경이 만들어졌을 뿐 아직 애플리케이션이 배포된 상태가 아니다. 애플리케이션은 eb deploy로 배포 할 수 있다.

현재 작업디렉토리에서 eb deploy 명령을 수행하면 "bin/application"을 zip으로 압축해서 환경에 배포한다. 실행프로그램의 이름은 반드시 bin 디렉토리 밑에 application 이어야 한다. 따라서 아래와 같이 코드를 빌드해야 한다.
$ go build -o bin/application simpleweb.go
이제 프로젝트의 디렉토리 구성은 아래와 같을 것이다.
--- simpleweb --+--- hello.go
                |
                +--- Makefile
                |
                +--- bin --+-- application 
                |
                +--- .elasticbeanstalk --+-- config.yml 

이제 simpleweb-dev 환경에 배포해 보자.
$ eb deploy simpleweb-dev
Creating application version archive "app-180526_023557".
Uploading simpleweb/app-180526_023557.zip to S3. This may take a while.
Upload Complete.
INFO: Environment update is starting.                               
INFO: Deploying new version to instance(s).                         
WARN: Process termination taking longer than 10 seconds.            
INFO: New application version was deployed to running EC2 instances.
INFO: Environment update completed successfully.                    
웹 콘솔에서 확인해 보자.

simpleweb-dev 환경의 simpleweb 애플리케이션이 실행 중인 걸 확인 할 수 있다. 환경을 클릭하면, 애플리케이션을 모니터링 하고 관리 할 수 있는 페이지로 넘어간다.

윗 부분에 애플리케이션 URL 이 있다. curl로 테스트해보자.
$ curl simpleweb-dev.xxxxxx.ap-northeast-2.elasticbeanstalk.com/hello -i
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Sat, 26 May 2018 04:39:45 GMT
Server: nginx/1.12.1
Content-Length: 11
Connection: keep-alive

Hello World

eb config 명령을 이용해서 애플리케이션 환경의 설정 정보를 읽거나 수정 할 수 있다. simpleweb-dev 환경의 설정 내용을 가져와보자.
$ eb config
ApplicationName: simpleweb
DateUpdated: 2018-05-26 04:29:05+00:00
EnvironmentName: simpleweb-dev
PlatformArn: arn:aws:elasticbeanstalk:ap-northeast-2::platform/Go 1 running on 64bit
  Amazon Linux/2.7.6
settings:
  AWSEBAutoScalingScaleDownPolicy.aws:autoscaling:trigger:
    LowerBreachScaleIncrement: '-1'
  AWSEBAutoScalingScaleUpPolicy.aws:autoscaling:trigger:
    UpperBreachScaleIncrement: '1'
  AWSEBCloudwatchAlarmHigh.aws:autoscaling:trigger:
    UpperThreshold: '6000000'
  AWSEBCloudwatchAlarmLow.aws:autoscaling:trigger:
    BreachDuration: '5'
    EvaluationPeriods: '1'
    LowerThreshold: '2000000'
    MeasureName: NetworkOut
    Period: '5'
    Statistic: Average
    Unit: Bytes
  aws:autoscaling:asg:
......

추가 설정

simpleweb을 올리긴 했으나 아직 갈길이 남아 있다. eb config로 네트워크 설정을 보자.
  aws:ec2:vpc:
    AssociatePublicIpAddress: null
    ELBScheme: public
    ELBSubnets: null
    Subnets: null
    VPCId: null
VPC가 아닌 classic EC2 타입으로 실행됐다. 이 애플리케이션은 ElasticCache, RDS등과 함께 사용할 계획이므로 VPC에 넣어야 겠다.

Beanstalk 고급 설정은 .ebextensions을 사용하여 이루어진다. .ebextensions 디렉토리를 만들고 YAML(혹은 JSON) 포맷의 설정파일을 만들어서 Beanstalk의 설정을 변경 할 수 있다.
# cat .ebextensions/vpc.config
option_settings:
    aws:ec2:vpc:
        VPCID: vpc-cc6yyyyy
        AssociatePublicIpAddress: 'false'
        ELBScheme: public
        ELBSubnets: subnet-6cyyyyy, subnet-4cxxxxxx
        Subnets: subnet-6cyyyyy, subnet-4cfxxxxx  
  • VPCID : 애플리케이션을 배포할 VPCID
  • AssociatePublicIpAddress : Public IP를 붙일지
  • ELBScheme : Public 혹은 Private ELB
  • ELBSubnets : ELB를 생성할 서브넷, 인터넷에서 연결 할 수 있어야 하니 퍼블릭서브넷에 붙여야 할 것이다.
  • Subnets : EB EC2가 위치할 서브넷
애플리케이션을 다시 배포하고 네트워크 살정을 확인했다.
......
  aws:autoscaling:updatepolicy:rollingupdate:
    MaxBatchSize: '1'
    MinInstancesInService: '1'
    PauseTime: null
    RollingUpdateEnabled: 'true'
    RollingUpdateType: Health
    Timeout: PT30M
  aws:ec2:vpc:
    AssociatePublicIpAddress: 'true'
    ELBScheme: public
    ELBSubnets: subnet-6ccc4d20, subnet-4cf0a324
    Subnets: subnet-6ccc4d20,subnet-4cf0a324
    VPCId: vpc-cc693ca4
......

스케일링

eb health로 애플리케이션 상태를 확인 할 수 있다.
 simpleweb-dev    Ok  2018-05-26 17:10:48WebServer     Go 1 running on 64bit Amazon Linux/2.7.6  total      ok    warning  degraded  severe    info   pending  unknown 
                                                                                                    1        1        0        0        0        0        0        0    
  instance-id           status     cause                                                                                               health  
    Overall             Ok                
  i-0edxxxxxxxf3a7543   Ok                
   
  instance-id           r/sec    %2xx   %3xx   %4xx   %5xx      p99      p90      p75     p50     p10                                requests  
    Overall             0.0         -      -      -      -         -        -       -       -       -
  i-0edxxxxxxxf3a7543   0.0         -      -      -      -         -        -       -       -       -
   
  instance-id           type       az   running     load 1  load 5      user %  nice %  system %  idle %   iowait %                       cpu  
  i-0edxxxxxxxf3a7543   t2.micro   2a   22 mins        0.0     0.0         0.0     0.0       0.0   100.0        0.0
   
  instance-id           status     id   version             ago                                                                   deployments  
  i-0edxxxxxxxf3a7543   Deployed   1    app-180526_164706   21 mins  
하나의 인스턴스가 떠 있는 걸 확인 할 수 있다. 2개로 스케일링해보자. eb scale로 스케일을 조절 할 수 있다.
$ eb scale 2
INFO: Environment update is starting.                               
INFO: Updating environment simpleweb-dev's configuration settings.  
INFO: Successfully deployed new configuration to environment.       
다시 확인
 simpleweb-dev    Ok  2018-05-26 17:10:48WebServer     Go 1 running on 64bit Amazon Linux/2.7.6  total      ok    warning  degraded  severe    info   pending  unknown 
                                                                                                    2        2        0        0        0        0        0        0    

  instance-id           status     cause                                                                                               health  
    Overall             Ok                
  i-06xxxxxxxxaabd5fa   Ok                
  i-0exxxxxxxf3a7543    Ok                
   
  instance-id           r/sec    %2xx   %3xx   %4xx   %5xx      p99      p90      p75     p50     p10                                requests  
    Overall             0.0         -      -      -      -         -        -       -       -       -
  i-06xxxxxxxxaabd5fa   0.0         -      -      -      -         -        -       -       -       -
  i-0exxxxxxxf3a7543    0.0         -      -      -      -         -        -       -       -       -
   
  instance-id           type       az   running     load 1  load 5      user %  nice %  system %  idle %   iowait %                       cpu  
  i-06xxxxxxxxaabd5fa   t2.micro   2c   31 mins        0.0     0.0         0.0     0.0       0.0   100.0        0.0
  i-0exxxxxxxf3a7543    t2.micro   2a   56 mins        0.0     0.0         0.0     0.0       0.0   100.0        0.0
   
  instance-id           status     id   version             ago                                                                   deployments  
  i-06xxxxxxxxaabd5fa   Deployed   1    app-180526_164706   31 mins  
  i-0exxxxxxxf3a7543    Deployed   1    app-180526_164706   54 mins  

애플리케이션 환경 삭제

쓰지 않는 애플리케이션 환경 삭제
$ eb terminate
The environment "simpleweb-dev" and all associated instances will be terminated.
To confirm, type the environment name: simpleweb-dev
INFO: terminateEnvironment is starting.

더 봐야 할 것들