透過AWS Beanstalk Docker環境佈署

2020/11/04

 

需要的檔案

因為大部分的資料都包在docker內了

所以僅需要一個docker-compose.yml及佈署EB所需的檔案即可

佈署起來非常簡潔

  • .ebextensions:同其他beanstalk設定,這裡我主要拿來設定一些AWS資源像是Auto Sacling
  • .elasticbeanstalk
    • config.yml:EB CLI專用,主要設定key pair、region等資訊
  • docker-compose.yml
  • Dockerrun.aws.json:EB的容器設定,下方會說明

 

.elasticbeanstalk/config.yml

設定EB CLI

branch-defaults:
  default:
    environment: null
    group_suffix: null
global:
  application_name: {web}
  branch: null
  default_ec2_keyname: {key-pair-name}
  default_platform: Docker
  default_region: ap-southeast-1
  include_git_submodules: true
  instance_profile: null
  platform_name: null
  platform_version: null
  profile: eb-cli
  repository: null
  sc: null
  workspace_type: Application

 

docker-compose.yml

簡單用一個vue.js的web佈署

因為image內容跟來源不是重點就隨意

version: "3.8"

services:
  vue:
    container_name: web
    image: {docker-image-source}
    restart: unless-stopped
    tty: true
    ports:
      - "80:8080"
    networks:
      - vue-app

networks:
  vue-app:
    driver: bridge

 

設定Dockerrun.aws.json的Authentication屬性

官方文件連結參考

設定這步驟比較麻煩

主要是在憑證的儲存IAM Role Policies的設定

讓EB開出來的ec2能夠執行docker pull把image拉到instance上發佈

因此如果是存取private image repository的話就需要憑證(執行docker login用)

而這個憑證則是從電腦拿出來上傳到安全的S3 bucket中(電腦中的位置為~/.docker/config.json)

然後幫aws-elasticbeanstalk-ec2-role這個IAM Role新增該bucket的s3:GetObject存取權限

EB開出來的EC2因為本上就帶有aws-elasticbeanstalk-ec2-role的角色

這樣EC2才能拉到docker image佈署

 

不過如果docker-compose.yml內設定的image來源都是公開的話

那這步驟就可以跳過

 

這邊先開好S3 Bucket(region必須同EB佈署的region)

設定好Dockerrun.aws.json的Authentication屬性

key則是上傳到S3的那個憑證檔名

{
  "AWSEBDockerrunVersion": "3",
  "Authentication": {
    "bucket": "your-bucket-name",
    "key": "docker-config.json"
  }
}

 

設定IAM aws-elasticbeanstalk-ec2-role角色

 

首先複製好存放docker login憑證的S3 Bucket ARN(AWS資源名稱)

s3-arn.png

 

前往AWS IAM的角色設定頁面

找出aws-elasticbeanstalk-ec2-role這個role

接著賦予新的policy

服務選擇S3並搜尋GetObject操作

add-new-policy.png

 

接著要限制群組資源(也就是可存取的S3 bucket)

這邊要特別注意的是的

如果是手動輸入ARN的話

結尾要用/*

不然ec2還是一樣讀不到存docker憑證的S3 bucket

導致佈署失敗

choice-arn.png

 

佈署好之後就會看到Policy JSON內

policy-json.png

 

查看結果確認有幫角色新增政策

policies.png

 

沒設定好權限的EB Deploy錯誤

如果權限沒設定好的話

執行eb create的時候

就會在佈署的時候噴錯

這時候ssh登入ec2查看/var/log/eb-engine.log

就可以看到出現EC2在跟S3要docker login憑證出現Access Denied的錯誤

看到這個就不用懷疑

去把aws-elasticbeanstalk-ec2-role設定好就對了

error.png

 

使用AWS Systems Manager來取得docker登入資訊

如果不使用上方的Dockerrun.aws.json讓ec2從S3取得docker憑證

可以使用此方式

參考連結:https://docs.aws.amazon.com/zh_tw/elasticbeanstalk/latest/dg/single-container-docker-configuration.html#docker-configuration.remote-repo

 

首先先對SSM新增參數

可以向這樣直接使用AWS CLI比較快

aws ssm put-parameter --name GITLAB_REGISTER_USERNAME --type String --value "your-gitlab-registry-access-token-username"
aws ssm put-parameter --name GITLAB_REGISTER_PASSWORD --type String --value "your-gitlab-registry-access-token-password"

 

需要賦予EB CLI IAM SSM Readonly權限

讓EB CLI佈署的時候就可以拿到SSM設定的docker帳密

接著EB的option_settings加入以下設定

左側是建立EC2設定的env變數

右側則是透過EB CLI向SSM取得的變數

option_settings:
  aws:elasticbeanstalk:application:environment:
    GITLAB_REGISTER_USERNAME: '{{resolve:ssm:GITLAB_REGISTER_USERNAME:1}}'
    GITLAB_REGISTER_PASSWORD: '{{resolve:ssm:GITLAB_REGISTER_PASSWORD:1}}'

 

設定以下兩個EB hooks(內容皆相同)

  • .platform/confighooks/prebuild
  • .platform/hooks/prebuild
#!/bin/bash
export GITLAB_REGISTER_USERNAME=`/opt/elasticbeanstalk/bin/get-config environment -k GITLAB_REGISTER_USERNAME`
export GITLAB_REGISTER_PASSWORD=`/opt/elasticbeanstalk/bin/get-config environment -k GITLAB_REGISTER_PASSWORD`
docker login registry.gitlab.com -u ${GITLAB_REGISTER_USERNAME} -p ${GITLAB_REGISTER_PASSWORD}

 

其他

 

EC2上存放專案的位置

有時候可能需要重啟docker-compose或是查看一些container資訊

這時候需要前往ec2的專案目錄

EB將會把佈署的那個目錄放到/var/app/current

 

Deploy Policy

要設定AllAtOnce以外的Policy

因為如果在同一台ec2佈署第二次(eb deploy)

會出現docker憑證被移除的狀況(目前還沒找到原因)

目前有在第一次建立的時候能正常使用docker憑證