使用 AWS Elastic Beanstalk 與 Docker deploy 環境

使用 AWS Elastic Beanstalk 也用了一段時間了,是時候寫一篇技術文留個紀錄。

Elastic Beanstalk 是 aws 提供的一個高階服務,它可以讓你用比較簡單的方式部署 Load Balancer 架構, 收費都是以你用的基礎服務為主,不會另外再多收費。

Docker 則是一個跨平台的虛擬化技術,指令下起來很像 git。我的需求是希望可以將事先打包好的網頁程式可以在 staging 、production 還有 testing 環境無痛執行,所以選擇了 Docker。

下面的內容比較偏實作,建議讀者至少要有 EC2、Docker 與 git 的相關使用經驗會比較容易上手。

安裝 EB CLI

在 macOS 上安裝 EB CLI 的細節可以參考這篇

因為我的電腦原本就有 python 相關的環境了, 所以我就直接下

pip install --upgrade --user awsebcli

執行 which eb確認 eb command 裝在哪個路徑, eb --help 看看說明訊息有沒有跑出來 ?

建立 deploy eb 專用的資料夾

mkdir eb-sample-app
  • 我個人的習慣是會加一個 prefix eb 用來區分它是 Elastic Beanstalk 專用的,避免跟其他 git repo 搞混

建立 Application

在資料夾內執行 eb init 設定 AWS region、application name、platform 等資訊,原則上可以參考這篇設定

不過需要注意的是:

  • 如果你是第一次執行 eb init, 它會問你的 AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY 如果不知道的話可以去 AWS console 的 IAM service 建立一組使用者 key 與 secret,以後你執行 eb command 的權限就是根據這個使用者的權限決定的,成功之後你的 ~/.aws/config 檔案應該要有你設定的東西,以後要更換 key 可以來這裡直接改。
  • eb ec2 的 instance ssh 建立的 keypair 如果搞丟了,以後可以透過 eb ssh --init 重新設定回來,環境會重跑就是了 (喂 !)

eb init 做完之後, 你的資料夾內應該要有 .elasticbeanstalk/config.yml 這個檔案。aws Elastic Beanstalk 的 console 應該可以看到空的 application 頁面

這時可以在資料夾內建立一個名為 Dockerrun.aws.json 的檔案,內容如下:

{
"AWSEBDockerrunVersion": "1",
"Authentication": {
"Bucket": "YOUR_S3_BUCKET_NAME",
"Key": "eb-sample-app-docker-auth.json"
},
"Image": {
"Name": "{DOCKER_USER}/{IMAGE_NAME}:{TAG}",
"Update": "true"
},
"Ports": [
{
"ContainerPort": "8080"
}
],
"Logging": "/var/log/eb-sample-app"
}
  • Bucket 的 value 要換成你放 docker hub 登入用的認證檔案的 S3 bucket 名稱
  • Key 則是 docker hub 登入用的認證檔案名稱,這邊用 eb-sample-app-docker-auth.json 做範例
  • Image 是 Docker Image 的名稱, 格式跟你在 docker cli 操作的差不多。例如: {DOCKER_USER}/{IMAGE_NAME}:{TAG}
  • ContainerPort 就是你 Docker Container expose 出去的 public port
  • Logging 則是你的 Elastic Beanstalk EC2 instance 裡面放 log 的位置。例如之後如果你需要將 production log 導到 slack channel 看,就可以從這裡下手。AWS Elastic Beanstalk Console 頁面也有提供下載 log 跟看 log 的地方,不過個人覺得沒有那麼方便直覺就是了。

建立檔案eb-sample-app-docker-auth.json 內容如下

{
"https://index.docker.io/v1/": {
"auth": "xxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
  • auth 的 value 可以去 ~/.docker/config.json 看,只要你之前有做過 docker login ,你應該會有這東西
  • 格式一定要照上面 eb-sample-app-docker-auth.json 的寫,千萬不要傻傻的直接把 ~/.docker/config.json 拷貝過去,這樣 deploy 會失敗。( 我之前就中招過 ! )

設定 EC2 的環境變數

對,就是那個 export xx=xx 如果你有需要代資訊給你的程式

在資料夾內建立一個 .ebextensions 的資料夾

mkdir .ebextensions

然後在 .ebextensions 建立一個檔案 .config 內容如下

option_settings:
- option_name: SESSION_REDIS_HOST
value: ec2-xxx-xxx-xxx-xxx.ap-southeast-1.compute.amazonaws.com
- option_name: SESSION_REDIS_PORT
value: 6379
- option_name: SESSION_REDIS_PASSWORD
value: xxxx

這樣你 deploy 出去的 EC2 instance 就可以吃到 SESSION_REDIS_HOST SESSION_REDIS_PORT SESSION_REDIS_PASSWORD 等變數

建立 Environment

執行 eb create 建立 environment,這時如果你已經不小心 CTRL+C cancel 掉 cli 的訊息顯示,你也可以登入 aws console 的 elasticbeanstalk 頁面觀看環境的狀態, 如果 healh check 檢查環境有問題會亮成紅色

  • 一個 Application 設定可以產生多個 Environments, 例如上圖我就有 eb-sample-app-dev 與 eb-sample-app-dev2 兩個 Environments
  • 每個 Environment 都是一個 load balancer 掛多個 EC2 instances
  • 如果你之後有需要設定 ssl certificate,注意 load balancer type 要選 classic 之後在 Elastic Beanstalk 的網頁才會有 配置 -> 網路套餐 -> 負載平衡的頁面可以選,憑證你可以透過 AWS Certificate Manager 產生,也可以透過 aws iam upload-server-certificate自行上傳

執行 eb list 可以列出這個 Application 底下的 Environment 清單

f

名稱前面的星號 *可以看到你目前 focus 在那個 environment 上, 此時在下 eb status 可以看到 environment 個別狀態

eb use 後面接 environment 名稱可以切換 focus 的 environment

eb deploy 則是可以重新部署一次你的程式碼, 我推 code 的習慣會先更改 Dockerrun.aws.json 的 docker tag, git commit 後再做 eb deploy

如果你之前有設定 ssh keypair,你 deploy 之後如果需要 debug,可以直接執行 eb ssh 連到個別 EC2 instance 去看狀況

eb logs 可以把 EC2 instance 的 log 顯示出來

eb terminate 可以幹掉目前 focus 的環境,它會讓你輸入環境名稱 double check 是不是要幹掉它, 如果你有手動把 Elastic Beanstalk 的 security group 關聯過其他資源,環境有可能不會 terminate 成功喔 !

這樣是不是很簡單呢 ?

Like what you read? Give kmsheng a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.