Chef 實戰 part6 — 用 Chef 指令在 EC2 開機器

Luyo
verybuy-dev
Published in
9 min readSep 29, 2017

在前幾篇實戰中,我已經用 chef 把 Elasticsearch cluster 的雛型做出來了,接下的問題是要怎麼 scale up。

Autoscaling?

最初的想法是用 EC2 的 Autoscaling 來做,但仔細想了一下,scale up 比較沒問題,但如果要 scale down 的話,因為有效的 shards 減少了,整個 cluster 就必須重新分配 shards。

Google 到這篇問答,解答的人就說了 “Auto scaling doesn’t make a lot of sense with ElasticSearch.”,雖然還是有方法,但看起來的確不太適合這麼做。

那麼就還是先考慮手動 scale up 吧,也許過程中會找到比較合理的解法。

Knife EC2?

不過雖然是手動 scale up,要進到 EC2 console 跑開機器流程也是挺不 make sense 的。再 Google 了一下又找到這個問答,發現有個 knife ec2 server create 的指令,馬上再搜尋這個指令,就找到了 chef/knife-ec2 這個 git repository,馬上來試用看看吧。

安裝 chef/knife-ec2

我用的是 Chef DK,安裝指令為:

$ chef gem install knife-ec2

設定 IAM credential

要在 EC2 開機器,就必須有具開機器權限的 IAM 帳號及 credential,然告訴 knife 你的 credential 是什麼。

寫死在檔案裡

我們可以直接把 credential 寫進 .chef/knife.rb 裡,如:

knife[:aws_access_key_id] = "Your AWS Access Key ID"
knife[:aws_secret_access_key] = "Your AWS Secret Access Key"

但這樣寫死在檔案裡是最不得已的做法,因為一般來說這些程式碼是要做版本控制的,你把自己的 credential 寫死進去了不就給人家看光光,每個人都可以用你這組 key pair 開機器。

使用環境變數

好一點的做法是存到環境變數裡:

$ export AWS_ACCESS_KEY_ID="Your AWS Access Key ID"
$ export AWS_SECRET_ACCESS_KEY="Your AWS Secret Access Key"

然後在 knife.rb 裡加入:

knife[:aws_access_key_id] = ENV['AWS_ACCESS_KEY_ID']
knife[:aws_secret_access_key] = ENV['AWS_SECRET_ACCESS_KEY']

這樣大家就可以自己設定自己的 credential 到環境變數裡給 knife 去抓。

使用 AWS Credential File

除了上述使用環境變數的方法外,也可以使用 AWS 的設定檔。我個人是比較傾向用這個方法,因為它跟 AWS CLI 做整合,可以不用另外記一套規則。

雖然沒有一定要安裝 AWS CLI 也可以照範例自己生設定檔,但我覺得這樣就有點失去這個方法意義,還不如用環境變數算了。

所以就先來安裝 AWS CLI,文件在此,在 MacOS 或 Linux 環境基本上就是用這個指令:

$ pip install awscli --upgrade --user

若你用的是 pip3 就用:

$ pip3 install awscli --upgrade --user

安裝好之後就可以用 aws configure 做初始設定:

$ aws configure
AWS Access Key ID [None]: (Your AWS Access Key ID)
AWS Secret Access Key [None]: (Your AWS Secret Access Key)
Default region name [None]: (預設的 region 名稱,如 ap-southeast-1)
Default output format [None]: (預設的 output format,如 json)

做好以上設定之後,在你的家目錄底下就會產生 .aws 目錄以及兩個設定檔:

$ tree .aws/
.aws/
├── config
└── credentials

再來就是告訴 knife 我們的設定檔放在哪裡了。

我們一樣可以寫死在 knife.rb 裡,如:

knife[:aws_credential_file] = File.join(ENV['HOME'], "/.aws/credentials")
knife[:aws_config_file] = File.join(ENV['HOME'], "/.aws/config")

但我目前還不想寫死在檔案裡,想先用帶參數的方式測試看看 knife ec2 server create 是否能正常運作。

先來查一下有沒有我想要的參數可以用:

$ knife ec2 server create --help

可以發現參數支援的蠻完整的,想得到的幾乎都有,那就來試試看吧:

$ knife ec2 server create -r 'role[es]' -I (你要用的 AMI ID) -f t2.micro --ssh-key (你的 ssh key id) --ssh-user (登入身分) --identity-file (你的 pem 檔路徑) --aws-credential-file ~/.aws/credentials --aws-config-file ~/.aws/config --security-group-id (你的 security group id)
Instance ID: i-057a0992752cdafaf
Flavor: t2.micro
Image: ami-7d2eab1e
Region: ap-southeast-1
Availability Zone: ap-southeast-1b
Security Group Ids: sg-xxxxxxxx
Tags: Name: i-057a0992752cdafaf
SSH Key: development
Waiting for EC2 to create the instance.....
Public DNS Name: ec2-54-251-142-118.ap-southeast-1.compute.amazonaws.com
Public IP Address: 54.251.142.118
Private DNS Name: ip-172-31-9-219.ap-southeast-1.compute.internal
Private IP Address: 172.31.9.219
Waiting for sshd access to become available
SSH Target Address: ec2-54-251-142-118.ap-southeast-1.compute.amazonaws.com(dns_name)
done
SSH Target Address: ec2-54-251-142-118.ap-southeast-1.compute.amazonaws.com()
Creating new client for i-057a0992752cdafaf
Creating new node for i-057a0992752cdafaf
Connecting to ec2-54-251-142-118.ap-southeast-1.compute.amazonaws.com
ec2-54-251-142-118.ap-southeast-1.compute.amazonaws.com -----> Installing Chef Omnibus (-v 13)
ec2-54-251-142-118.ap-southeast-1.compute.amazonaws.com downloading https://omnitruck-direct.chef.io/chef/install.sh
(...略)

這樣機器就順利開起來,也自動執行 knife bootstrap 的動作了!

確認 node 狀態

接下來用 knife node list 看看 node 是否有被加進來:

$ knife node list
es-dev-1
es-dev-2
i-057a0992752cdafaf

可以看到剛剛被開起來的機器就出現在列表中了,而 node name 是 instance ID。如果你想要自訂 node name 的話,就在前面的 knife ec2 server create 指令中加入 --node-name 選項即可。

關掉機器

在開發期間蠻有可能會遇到設定不對要把機器關掉的情況,就可以用 knife ec2 server delete 的指令。這個指令預設不會將 Chef server 跟 node 之間的關聯移除掉,如果要移除的話可以加上 --purge 的選項:

$ knife ec2 server delete (instance ID) --aws-credential-file ~/.aws/credentials --aws-config-file ~/.aws/config --purge
Instance ID: i-04eb64a8ab0ca6a4e
Instance Name: es-1
Flavor: t2.micro
Image: ami-7d2eab1e
Region: ap-southeast-1
Availability Zone: ap-southeast-1b
Security Groups: es-production
SSH Key: development
Root Device Type: ebs
Public DNS Name: ec2-13-229-98-196.ap-southeast-1.compute.amazonaws.com
Public IP Address: 13.229.98.196
Private DNS Name: ip-172-31-5-28.ap-southeast-1.compute.internal
Private IP Address: 172.31.5.28
\n
Do you really want to delete this server? (Y/N) Y

這樣機器就會被 terminate 掉了。

--

--