### 管理 Amazon 的 EC2 實例
> The most amazing achievement of the computer software industry is its continuing cancellation of the steady and staggering gains made by the computer hardware industry.
>
> — Henry Petroski
如果你覺得你的電腦近年來變得比較慢,這可能是正確的。 對于大多數應用程序而言,你已不必將所有的計算能力(computing power) 全部擠進你辦公桌下的一個米色盒子里。 為了解決這個問題,計算能力已經成為一種可以在網上購買的商品。
亞馬遜不只是賣書了:他們也賣首飾、摩托車、葉鼓風機,以及對我們當前目的有用的計算能力。 你可以用信用卡簽約使用 **Amazon Web Services**,并根據你的需要創建眾多的服務器實例, 每個服務器基于小時計費。如果你只是想試水,可以運行一個免費最長一年的微型實例。 如果你正在尋找將你的一部分基礎設施遷移到公共云的方案,這是一個不錯的實驗方式。
本處方將向你展示一個使用 Puppet 創建并自動供應一個 **EC2** 實例的簡單方法。 盡管還可以使用更強大的方式實現,包括使用 MCollective,但作為教學目的, 我們將只做最低限度的必要的工作:讓一個實例運行起來并應用 Puppet 配置清單。 一旦你獲得了基本思路,你就可以以此作為基礎加入你自己的改良和改進。
#### 準備工作
你需要一個 **Amazon Web Services**(**AWS**)賬號。如果還沒有,請到 [http://aws-portal.amazon.com/gp/aws/developer/subscription/index.html?productCode=AmazonEC2](http://aws-portal.amazon.com/gp/aws/developer/subscription/index.html?productCode=AmazonEC2) 注冊。
你需要 AWS 訪問的 key ID,這個秘密訪問 Key 對應于你的 AWS 賬號。你可以在這個頁面找到它: [http://aws-portal.amazon.com/gp/aws/developer/account/index.html?action=access-key](http://aws-portal.amazon.com/gp/aws/developer/account/index.html?action=access-key) 。
你還需要訪問 EC2 實例的 SSH 密鑰對。為此,你需要如下步驟:
1. 在 [https://console.aws.amazon.com/ec2/home](https://console.aws.amazon.com/ec2/home) 登錄 AWS 管理控制臺。
2. 選擇 **Amazon EC2 標簽**,在導航部分的標題 **Network & Security** 上單擊 **Key Pairs**。
3. 單擊 **Create key pair**,當提示出現后下載 keypair 文件。將此文件保存到一個安全的地方, 并使用如下命令為它設置模式為 0600 的權限:
```
# chmod 600 bitfield.pem
```
#### 操作步驟
1. 創建 fog 模塊:
```
# mkdir /etc/puppet/modules/fog
# mkdir /etc/puppet/modules/fog/manifests
# mkdir /etc/puppet/modules/fog/files
```
2. 使用如下內容創建 /etc/puppet/modules/fog/manifests/init.pp 文件:
```
class fog {
package { "fog":
ensure => installed,
provider => gem,
}
file { "/usr/local/etc/fog_credentials":
source => "puppet:///modules/fog/fog_credentials",
}
file { "/usr/local/bin/boot-ec2":
source => "puppet:///modules/fog/boot-ec2.rb",
mode => "755",
}
file { "/usr/local/bin/bootstrap-ec2":
source => "puppet:///modules/fog/bootstrap-ec2.sh",
mode => "755",
}
}
```
3. 使用如下內容創建 /etc/puppet/modules/fog/files/boot-ec2.rb 文件 (修改 :private_key_path 參數指向你自己的 AWS 私鑰文件):
```
#!/usr/bin/ruby
require 'rubygems'
require 'fog'
HOSTNAME = 'devbox'
@server = ''
Fog.credentials_path = '/usr/local/etc/fog_credentials'
def command( cmdline )
puts "Running command: #{cmdline}"
res = @server.ssh( "sudo #{cmdline}" )[0]
puts res.stdout
puts res.stderr
end
def create()
puts "Bootstrapping instance..."
connection = Fog::Compute.new( { :provider => 'AWS' } )
@server = connection.servers.bootstrap( :key_name =>
'bitfield',
:private_key_path =>
'~/bitfield.pem',
:username => 'ubuntu')
@server.wait_for { ready? }
@server.reload
puts "Instance name: #{@server.dns_name}"
puts "Setting hostname..."
@server.ssh( "sudo hostname #{HOSTNAME}" )
end
def copy_bootstrap_files()
puts "Copying bootstrap files..."
@server.scp( "puppet.tar.gz", "/tmp" )
@server.scp( "/usr/local/bin/bootstrap-ec2", "/tmp" )
end
def bootstrap()
puts "Bootstrapping..."
command( "sudo sh /tmp/bootstrap-ec2" )
end
create()
copy_bootstrap_files()
bootstrap()
```
4. 使用如下內容創建 /etc/puppet/modules/fog/files/bootstrap-ec2.sh 文件:
```
#!/bin/bash
apt-get update
apt-get -y install puppet
apt-get -y install git-core
cd /root
tar xzf /tmp/puppet.tar.gz
puppet --modulepath=/root/puppet/modules \
/root/puppet/manifests/site.pp
```
5. 使用如下內容創建 /etc/puppet/modules/fog/files/fog_credentials 文件 (使用你自己的 AWS 憑證替換相應的值):
```
:default:
:aws_access_key_id: AKIAI5RGMC3QRPO3AJWR
:aws_secret_access_key: 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
```
6. 添加如下的節點聲明,此節點將會應用 EC2 實例:
```
node devbox {
file { "/etc/motd":
content => "Puppet power!\n",
}
}
```
7. 添加如下代碼到一個節點:
```
include fog
```
8. 運行 Puppet:
```
# puppet agent --test
info: Retrieving plugin
info: Caching catalog for cookbook.bitfieldconsulting.com
info: Applying configuration version '1313160844'
notice: /Stage[main]/Fog/Package[fog]/ensure: ensure changed
'purged' to 'present'
notice: /Stage[main]/Fog/File[/usr/local/bin/bootstrap-ec2]/
ensure: defined content as '{md5}5bc2ffb3b5aa94b33b17d419625ecbab'
notice: /Stage[main]/Fog/File[/usr/local/bin/boot-ec2]/ensure:
defined content as '{md5}dadc835c6e52c89cb928d60db7677713'
notice: /Stage[main]/Fog/File[/usr/local/etc/fog_credentials]/
ensure: defined content as '{md5}3b140aedac170bbfcc2837077e03bb93'
notice: Finished catalog run in 1.67 seconds
```
9. 在你的工作目錄中,為分發 EC2 實例創建一個 Puppet 的 tar 包。 最簡單的方法是對你現有的 Puppet 倉庫(對于 git 的裸倉庫需要先檢出)執行 tar 命令:
```
# cd /etc
# tar czf /tmp/puppet.tar.gz --exclude .git puppet
# cd -
# mv /tmp/puppet.tar.gz .
```
10. 運行 boot-ec2 腳本:
```
# boot-ec2
Bootstrapping instance...
Instance name: ec2-107-20-59-174.compute-1.amazonaws.com
Setting hostname...
Copying bootstrap files...
Bootstrapping...
Running command: sudo sh /tmp/bootstrap.sh
sudo: unable to resolve host devbox
sudo: unable to resolve host devbox
...
notice: //Node[devbox]/File[/etc/motd]/content: defined content as
'unknown checksum'
```
11. 登錄到該實例檢查你的配置清單已被正確應用:
```
# ssh -i bitfield.pem ubuntu@ec2-107-20-59-174.compute-1.amazonaws.com
Puppet power!
ubuntu@devbox:~$
```
12. 你已經得到了一個由 Puppet 管理控制的云服務器! 如果想要創建十個實例,運行此腳本十次即可。 不要忘記使用完畢之后,要在 AWS 管理控制臺關閉這些實例(按使用時間付費的哦!)。
#### 工作原理
**Fog** 是一個用于管理云資源的 Ruby 庫,包括 EC2 和其他一些供應商(如 Rackspace)。 盡管你可以使用 Amazon 自己提供的 ec2-tools 腳本啟動和管理 EC2 實例, 但使用 Fog 可以輕而易舉地將你的實例遷移到另一個供應商, 而且還不需要你為運行 ec2-tools 而安裝 Java 以及其他依賴的軟件。 對于創建 EC2 基礎設施的這兩種方法來說,我可以自信的說我更喜歡用 Fog, 盡管事實上它幾乎沒有文檔(而 Amazon 卻有很多)。
在 boot-ec2 腳本中,我們用自己的憑證使用 Fog 創建了一個新的 EC2 實例, 并為其傳輸了一份 Puppet 配置清單的拷貝。 然后我們復制 bootstrap-ec2 腳本,它用于安裝 Puppet 以及應用程序的配置清單。
對于本例而言,配置清單相當簡單:
```
file { "/etc/motd":
content => "Puppet power!\n",
}
```
你可以輕松地修改它,比如,與你的生產應用服務器同名。 這對于快速部署位于物理負載平衡器之后的大量應用程序服務器來說是一個好方法, 例如,處理突然飆升的需求。另外,你也可以使用 EC2 實例作為測試服務器或臨時服務器 (這完全取決于你自己的需求)。
#### 更多用法
除了你的信用卡強加給你的限制之外,此處的腳本沒有對你能部署的 EC2 實例數量做任何限制。 所以你可以嘗試修改此處所示的腳本,啟用一個由命令行參數設置的實例數量。
你或許想要創建不同類型的實例,例如:Web 服務器、人工隊列服務器(queue worker servers)等。 你可以修改啟動腳本,攜帶一個參數指定要啟動的實例類型。
此處顯示的腳本有一個重要的限制,就是它以 tar 包形式提供了一個包含你的 Puppet 配置清單快照的實例。 顯然,當你在 Puppetmaster 上修改你的 Puppet 配置清單后,EC2 實例不受影響,即更改不會被應用到 EC2 實例。 基于簡單的目的,本處方中的例子僅僅使用 Puppet 構建了初始的服務器,它沒有運行 Puppet 守護進程也沒與 Puppetmaster 服務器聯系。
這對于短生存期或僅為指定目的而運行的 EC2 實例往往還是不錯的。 如果你需要運行長生存期的服務器,或者需要通過 Puppet 更新 EC2 實例服務器, 就應該修改腳本使實例能與你的 Puppetmaster 服務器取得聯系。 要解決的是證書簽名問題,例如你可以對證書進行預簽名并伴隨 bootstrap 腳本一同部署到 EC2 實例。 另外一種方法是,在腳本中通過 SSH 或 MCollective 登錄 Puppetmaster 服務器并對實例的證書請求進行簽名。 這兩種證書簽名的機制或簡單或復雜,隨你選擇。
你可能還想使用其他的云服務提供商,例如 Rackspace 或 Linode。 為此,你需要對腳本做輕微地修改。 請參考 Fog 文檔獲取相關的詳細信息,網址為 [http://fog.io](http://fog.io) 。
> 
> 你也可以使用 Puppet 新的云供應商擴展(Cloud Provisioner extension)來管理 EC2 實例; 要獲取相關的詳細信息請參考 Puppet Labs 的 [http://docs.puppetlabs.com/guides/cloud_pack_getting_started.html](http://docs.puppetlabs.com/guides/cloud_pack_getting_started.html) 頁面。
#### 參見本書
* 本章的 [使用 Vagrant 管理虛擬機](#ch08sec07) 一節
- Puppet 2.7 Cookbook 中文版
- 中文翻譯版
- 譯者序
- 項目緣起
- 翻譯方法
- 社區鏈接
- 社區建議
- 貢獻者
- 原書版權頁
- 關于作者
- 前言
- 本書內容
- 閱讀前提
- 適用讀者
- 格式約定
- 讀者反饋
- 客戶支持
- 下載案例代碼
- 勘誤表
- Puppet 基礎設施
- 使用版本控制
- 使用提交鉤子
- 使用 Rake 部署變更
- 配置 Puppet 的文件服務器
- 從 cron 運行 Puppet
- 使用自動簽名
- 預簽名證書
- 從 Puppet 的 filebucket 檢索文件
- 使用 Passenger 擴展 Puppet 的部署規模
- 創建去中心化的分布式 Puppet 架構
- 監控、報告和排錯
- 生成報告
- 通過 Email 發送包含特定標簽的日志信息
- 創建圖形化報告
- 自動生成 HTML 文檔
- 繪制依賴關系圖
- 測試你的 Puppet 配置清單
- 執行模擬運行
- 檢測編譯錯誤
- 理解 Puppet 的錯誤信息
- 顯示命令的輸出結果
- 輸出調試信息
- 檢查配置設置
- 使用標簽
- 使用運行階段
- 使用不同的環境
- Puppet 語言及其寫作風格
- 使用 Puppet 社區規范
- 使用模塊
- 使用標準的命名規范
- 使用嵌入式 Ruby 代碼
- 使用純 Ruby 代碼書寫配置清單
- 遍歷多個項目
- 書寫強大的條件語句
- 在 if 語句中使用正則表達式
- 使用選擇器和 case 語句
- 檢測字符串中是否包含指定的值
- 使用正則表達式替換
- 書寫更優質的配置清單
- 使用資源的數組
- 使用 define 資源
- 指定資源的依賴關系
- 使用節點繼承
- 使用類的繼承和重載
- 給類傳遞參數
- 書寫可重用的跨平臺配置清單
- 獲得系統的環境信息
- 導入動態信息
- 從 CSV 文件導入數據
- 給 Shell 命令傳遞參數
- 使用文件和軟件包
- 為配置文件添加配置行
- 使用 Augeas 自動修改配置文件
- 使用配置片段構建配置文件
- 使用 ERB 模板
- 在模板中遍歷數組
- 從第三方倉庫安裝軟件包
- 配置 APT 軟件倉庫
- 配置 GEM 倉庫
- 從源碼包自動構建軟件
- 比較軟件包的版本
- 用戶和虛擬資源
- 使用虛擬資源
- 使用虛擬資源管理用戶
- 管理用戶基于密鑰的 SSH 訪問
- 管理用戶的自定義文件
- 有效地分發 cron 任務
- 當文件更新時運行命令
- 使用主機資源
- 為文件資源指定多個源
- 使用文件資源遞歸地分發整個目錄樹
- 清理過期的舊文件
- 使用日程表資源
- 資源的審計
- 臨時禁用資源
- 管理時區
- 應用程序
- 管理 Apache 服務
- 創建 Apache 虛擬主機
- 創建 Nginx 虛擬主機
- 創建 MySQL 數據庫及用戶
- 管理 Drupal 站點
- 管理 Rails 應用程序
- 服務器和云基礎設施
- 部署 Nagios 監控服務器
- 使用 Heartbeat 構建高可用服務
- 管理 NFS 服務和文件共享
- 使用 HAProxy 為多個 web 服務器實現負載均衡
- 使用 iptables 管理防火墻
- 管理 Amazon 的 EC2 實例
- 使用 Vagrant 管理虛擬機
- 外部工具和 Puppet 生態環境
- 創建 Facter 的自定義 fact
- 在運行 Puppet 之前和之后執行命令
- 從 Shell 會話生成 Puppet 配置清單
- 從運行的系統上生成 Puppet 配置清單
- 使用 Puppet Dashboard
- 使用 Foreman
- 使用 MCollective
- 使用公共模塊
- 使用外部節點分類器
- 創建自定義的資源類型
- 創建自定義的提供者