Learn Chef Rally 學習筆記 part8 —基礎 Test Kitchen 工作流程
本文記錄 Learn Chef Rally 以下章節的學習歷程:
- Track — Infrastructure Automation > Get started with Test Kitchen > Get started with Test Kitchen with CentOS on Amazon Web Services
- Track — Infrastructure Automation > Get started with Test Kitchen > Set up your workstation
- Track — Infrastructure Automation > Get started with Test Kitchen > Apply a cookbook locally
[Get started with Test Kitchen with CentOS on Amazon Web Services]
本 module 一開始也要選擇環境,我選的是 CentOS 7 -> Amazon Web Services。
到目前我們學到的 Chef 開發流程如下:
- 寫 Chef 程式碼
- 上傳至 Chef server
- 在 node 上跑
chef-client
指令 - 連線進 node 看新的設定是否生效
- 重複以上流程
在 學習筆記 part 7 中,我們上傳了一個有問題的 recipe 導致 web server 啟動失敗,我們必須想辦法在這組設定在上 production 環境之前先發現問題,而不是跑了 chef-client
失敗了才去修正。
一般會想到也常被使用的方法就是再 build 一個測試環境先跑過再上 production,但這邊要介紹的是 Test Kitchen,可以用來快速實驗新的變更有沒有問題。
用 Test Kitchen 的做法差別在於它會建立一個臨時的測試環境來測試我們的程式碼,就不用每次都上傳到 Chef server 之後還要再跑 chef-client
才能知道結果;這個臨時的環境可以是 workstation 上的 virtual machine 或雲端機器或 container instance。
就以我自己初學到現在的使用經驗,每做一個小修改就要上傳到 Chef server 再跑 chef-cient
這整個流程其實還蠻沒效率的。而 Test Kitchen 就是為了解決這個問題,讓我們可以在本機端先跑過測試再上 Chef server。這個流程以下會稱為 local development。
使用 local development 的話整個開發流程就會變成:
- 更新 Chef 程式碼
- 在 local 端跑測試確認變更是否正確
- 將程式碼上傳至 Chef server
- 在 node 上執行
chef-client
- 重複以上流程
使用 Test Kitchen 另一個好處就是不管你的 work station 是什麼環境都沒關係。
[Set up your workstation]
Test Kitchen 可以整合 EC2 的 AMI、instance type (t2.micro, t2.small 之類的)、security groups,感覺考慮的很周到。
要設定之前必須先準備好以下的項目:
- AWS credentials file (用來登入機器的 .pem)
- Region and availability zone (例 us-east-1b)
- VPC subnet ID
- Security group ID
- CentOS 7 AMI ID (我是用新加坡的 ami-7d2eab1e)
- AWS key pair file (須有開機器的權限)
這些項目如果平常有在用 EC2 的話應該都不陌生,就不多解釋了。
如果你用的是 Linux 或 macOS,可以在 ~/.aws/credentials
設定好 key pair 以節省麻煩:
[default]
aws_access_key_id = ACCESS_KEY
aws_secret_access_key = SECRET_KEY
如果你有在用 aws-cli 的話這部分應該就已經是設定好的狀態了。
[Apply a cookbook locally]
整個 kitchen 的測試流程如下:
- kitchen create — Test Kitchen 在虛擬環境中開一台機器
- kitchen converge — Test Kitchen 套用 cookbook 到虛擬環境
- kitchen login — Test Kitchen 建立 SSH 連線到虛擬環境
- verify — 我們要在這個步驟人工驗證設定是否正確
- kitchen destroy — Test Kitchen 把虛擬環境關掉
這邊特別說明,在這個 module 裡我們只會學到人工確認結果 (上述的 verify 步驟),但在典型的實作上會寫自動測試,在之後的 module 裡會學到。
從 GitHub 取得 learn_chef_httpd cookbook
先新增好資料夾 ~/learn-chef/cookbooks
並進入,然後下指令:
$ git clone https://github.com/learn-chef/learn_chef_httpd.git
Cloning into 'learn_chef_httpd'...
remote: Counting objects: 97, done.
remote: Total 97 (delta 0), reused 0 (delta 0), pack-reused 97
Unpacking objects: 100% (97/97), done.
新增 kitchen 設定檔
如果是用 chef generate cookbook
生成的 cookbook 目錄,會內含一個 .kitchen.yaml
的檔案。剛剛 clone 下來的 repository 底下就有這個檔案。
進入 learn_chef_httpd
目錄,開啟檔案 .kitchen.yml
,並修改成以下內容:
---
driver:
name: ec2
aws_ssh_key_id: learn-chef
region: us-east-1
availability_zone: b
subnet_id: subnet-3f22bd15
instance_type: t2.micro
image_id: ami-46c1b650
security_group_ids: ["sg-0e08cf75"]
retryable_tries: 120
provisioner:
name: chef_zero
verifier:
name: inspec
transport:
ssh_key: /root/.ssh/learn-chef.pem
platforms:
- name: centos-7.3
suites:
- name: default
run_list:
- recipe[learn_chef_httpd::default]
verifier:
inspec_tests:
- test/smoke/default
attributes:
然後把上面粗體的部分換成你自己的設定。
這裡我有個小疑問,就是 availability_zone
不知道可不可以設定多個?簡單辜狗了一下沒有找到答案,先不管。
上面這個 .kitchen.yml
的說明如下:
- driver:常用的 drivers 在此。
- provistioner:這裡用的
chef_zero
讓我們的 local 環境偽裝成 Chef server 環境。 - transport:指定連線到 instance 的方法
- verifier:指定用哪個 application 來跑自動測試。這部分以後才會學到。
- platforms:指明是什麼作業系統。
- suites:指定要用套用哪些設定到虛擬環境裡。
比較詳細的說明可參考 https://docs.chef.io/config_yml_kitchen.html。
產生測試實例
先用 kitchen list
看看到目前為止 kitchen 裡有什麼東西:
$ kitchen list
Instance Driver Provisioner Verifier Transport Last Action Last Error
default-centos-73 Ec2 ChefZero Inspec Ssh <Not Created> <None>
接下來用 kitchen create
產生測試實例:
$ kitchen create
-----> Starting Kitchen (v1.16.0)
-----> Creating <default-centos-73>...
Detected platform: centos version 7 on x86_64. Instance Type: t2.micro. Default username: cento
s (default).
If you are not using an account that qualifies under the AWS
free-tier, you may be charged to run these suites. The charge
should be minimal, but neither Test Kitchen nor its maintainers
are responsible for your incurred costs.Instance <i-0c08c42b8616f52eb> requested.
Polling AWS for existence, attempt 0...
Attempting to tag the instance, 0 retries
EC2 instance <i-0c08c42b8616f52eb> created.
Waited 0/600s for instance <i-0c08c42b8616f52eb> volumes to be ready.
Waited 0/600s for instance <i-0c08c42b8616f52eb> to become ready.
Waited 5/600s for instance <i-0c08c42b8616f52eb> to become ready.
Waited 10/600s for instance <i-0c08c42b8616f52eb> to become ready.
Waited 15/600s for instance <i-0c08c42b8616f52eb> to become ready.
Waited 20/600s for instance <i-0c08c42b8616f52eb> to become ready.
EC2 instance <i-0c08c42b8616f52eb> ready.
Waiting for SSH service on ec2-54-169-127-55.ap-southeast-1.compute.amazonaws.com:22, retrying in 3 seconds
Waiting for SSH service on ec2-54-169-127-55.ap-southeast-1.compute.amazonaws.com:22, retrying in 3 seconds
Waiting for SSH service on ec2-54-169-127-55.ap-southeast-1.compute.amazonaws.com:22, retrying in 3 seconds
[SSH] Established
Finished creating <default-centos-73> (1m16.46s).
-----> Kitchen is finished. (1m24.67s)
打開 EC2 console 看一下,真的自動開了一台 id 是 i-0c08c42b8616f52eb 的機器!
再次用 kitchen list
看一下:
$ kitchen list
Instance Driver Provisioner Verifier Transport Last Action Last Error
default-centos-73 Ec2 ChefZero Inspec Ssh Created <None>
套用 cookbook
執行 kitchen converge
:
$ kitchen converge
-----> Starting Kitchen (v1.16.0)
-----> Converging <default-centos-73>...
(...略)
Running handlers:
Running handlers complete
Chef Client finished, 4/4 resources updated in 15 seconds
Finished converging <default-centos-73> (0m49.56s).
-----> Kitchen is finished. (0m52.10s)
我們可以用 echo $?
指令來確認這中間是否有錯誤產生,如果有的話,就會回傳不是 0
的數字,你就必須把錯誤修掉。
$ echo $?
0
我這次回傳的是 0
,所以沒有問題。用 kitchen list
看一下狀態:
$ kitchen list
Instance Driver Provisioner Verifier Transport Last Action Last Error
default-centos-73 Ec2 ChefZero Inspec Ssh Converged <None>
可以看到 Last Action
已經變成 Converged
。
另外,第一次執行 kitchen converge
會跑比較久,第二次之後因為相關的套件都已經安裝好,就會變比較快了。
檢驗設定是否正確
前面有說過,實作上我們應該要寫自動測試來檢驗結果,但現在會先用人工驗證,這邊要做的是登入測試的 instance 然後 curl localhost
看有沒有回傳 “hello world” 即可。
登入的話只要用 kitchen login
指令即可,因為登入資訊在前面的步驟都已經設定好了。
$ kitchen login
Last login: Wed Sep 27 11:30:38 2017 from 122-116-172-114.hinet-ip.hinet.net$ curl localhost
<html>
<body>
<h1>hello world</h1>
</body>
</html>
確認沒有問題。
但這樣方式還是有點遜,我們可以用類似 knife ssh
的方式連線到測試環境去下命令,這個指令叫 kitchen exec
:
$ kitchen exec -c 'curl localhost'
-----> Execute command on default-centos-73.
<html>
<body>
<h1>hello world</h1>
</body>
</html>
kitchen exec
的文件在這裡,可以找到 -c
這個選項就是你想下的指令內容。
關閉測試環境
確認完結果之後就可以把測試環境摧毀掉了,指令也很簡單,用 kitchen destroy
:
$ kitchen destroy
-----> Starting Kitchen (v1.16.0)
-----> Destroying <default-centos-73>...
EC2 instance <i-0c08c42b8616f52eb> destroyed.
Finished destroying <default-centos-73> (0m0.61s).
-----> Kitchen is finished. (0m3.16s)
進 EC2 console 看一下,instance 已被 terminated。
再看一下 kitchen list
:
$ kitchen list
Instance Driver Provisioner Verifier Transport Last Action Last Error
default-centos-73 Ec2 ChefZero Inspec Ssh <Not Created> <None>
Last Action
又變回 <Not Created>
了。
測驗
Test Kitchen:
- Lets you run your cookbooks in temporary environments.
- Manages the virtual machines you use for temporary environments.
- Makes it easier to work with the hypervisor that manages the virtual machines.
Which of these commands generates the .kitchen.yml file?
kitchen cat .kitchen.yml
file '/.kitchen.yml'
chef generate cookbook
Which of these commands directs Test Kitchen to add a temporary environment?
kitchen make
kitchen create
kitchen build
The kitchen converge
command:
- Runs chef-client on the instance.
- Runs automated tests on the instance.
- Downloads the latest version of the provisioner.
Which command gets rid of unwanted instances?
kitchen delete
kitchen clean
kitchen destroy
答案是 1, 3, 2, 1, 3。