tag:blogger.com,1999:blog-44282573811490338652024-03-14T10:20:15.806+08:00小信豬的原始部落曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.comBlogger284125tag:blogger.com,1999:blog-4428257381149033865.post-66610034019176235422014-11-23T10:33:00.001+08:002015-04-12T16:12:45.588+08:00還是決定要搬家了......恩......接觸了 Markdown 的語法之後<br />
<br />
覺得使用 markdown 寫 blog 輕鬆太多了......<br />
<br />
不用處理一堆雜事....<br />
<br />
花了一些時間把 GitHub Pages + Jekyll 整合好!<br />
<br />
所以就決定把 blog 遷到 <a href="https://godleon.github.io/">https://godleon.github.io</a> 囉!曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com1tag:blogger.com,1999:blog-4428257381149033865.post-49872630061722602372014-10-14T14:07:00.001+08:002018-12-17T14:48:25.144+08:00OpenStack Swift 簡介<html>
<head>
<title>OpenStack Swift 簡介</title>
<link href="https://stackedit.io/res-min/themes/base.css" rel="stylesheet"></link>
<script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML" type="text/javascript"></script>
</head>
<body><div class="container">
<h1 id="目錄">
目錄</h1>
<div class="toc">
<ul>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#%E7%9B%AE%E9%8C%84">目錄</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#1openstack-swift-%E6%98%AF%E4%BB%80%E9%BA%BC">1、OpenStack Swift 是什麼?</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#2swift-request">2、Swift Request</a><ul>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#21-account">2.1 Account</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#22-container">2.2 Container</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#23-object">2.3 Object</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#24-object-url-%E7%B5%84%E6%88%90">2.4 Object URL 組成</a></li>
</ul>
</li>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#3swift-processes">3、Swift Processes</a><ul>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#31-proxy-layer">3.1 Proxy Layer</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#32-account-layer">3.2 Account Layer</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#33-container-layer">3.3 Container Layer</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#34-object-layer">3.4 Object Layer</a></li>
</ul>
</li>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#4swift-consistency-services">4、Swift Consistency Services</a><ul>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#41-auditor">4.1 Auditor</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#42-replicator">4.2 Replicator</a></li>
</ul>
</li>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#5swift-cluster-%E5%88%86%E7%BE%A4%E6%A6%82%E5%BF%B5">5、Swift Cluster 分群概念</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#6swift-%E8%B3%87%E6%96%99%E5%AD%98%E5%8F%96%E8%A8%AD%E8%A8%88">6、Swift 資料存取設計</a><ul>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#61-partition">6.1 Partition</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#62-ring">6.2 Ring</a></li>
</ul>
</li>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#7switch-%E5%AE%8C%E6%95%B4%E6%9E%B6%E6%A7%8B">7、Switch 完整架構</a></li>
<li><a href="https://www.blogger.com/blogger.g?blogID=4428257381149033865#8%E5%8F%83%E8%80%83%E8%B3%87%E6%96%99">8、參考資料</a></li>
</ul>
</div>
<br />
<h1 id="1openstack-swift-是什麼">
1、OpenStack Swift 是什麼?</h1>
以下截至 <a href="https://swiftstack.com/openstack-swift/">StackSwift</a> 的定義:<br />
<blockquote>
OpenStack Swift is a multi-tenant, highly scalable and durable object storage system that was designed to store large amounts of unstructured data at low cost via a RESTful HTTP API.<br />
</blockquote>
從上述簡單的定義,無法完全表達 Swift 的強大,因此以下列出 Swift 的特色:<br />
<ul>
<li>open source & 免費。</li>
<li>目前有許多大型的 object storage 雲端服務使用 Swift (例如:Rackspace、Cloud Files、HP Cloud … etc)。</li>
<li>Swift 可以單獨提供 storage 服務,也可以與其他的雲端環境進行整合。</li>
<li>只要是標準的 x86 架構的硬體,搭配標準的 Linux 系統,就可以運行 Swift。</li>
<li>Swift 跟 Amazon S3 相同,提供最終一致性(eventual consistency),因此也提供了強大的水平擴展能力。</li>
<li>所有儲存在 Swift 的物件、檔案都有一個 URL。</li>
<li>提供標準的 RESTful HTTP API,因此非常合適作為經由 web-based 存取資料的用戶端、裝置、應用程式。</li>
<li>儲存於 Swift 的物件可以擁有可擴展性的 metadata,可用來有效率的進行索引 & 搜尋。</li>
<li>所有儲存在 Swift 的物件都會有多個複本存在於其他的 Zone or Region。</li>
<li>Swift 透過增加額外的節點就可以很簡單的進行擴展。</li>
<li>當增加或更換硬體時,不需要將原本的資料移動到其他的節點內。</li>
<li>在 Swift 運行中,可隨時增加 or 移除節點。</li>
<li>設計在低成本的前提下,可儲存超大量非結構性資料(檔案、圖片、影像 … 等等)。</li>
</ul>
<h1 id="2swift-request">
2、Swift Request</h1>
Swift 有個重要特性:<br />
<blockquote>
<strong>所有儲存在 Swift 的物件、檔案都有一個 URL,並可透過 HTTP RESTful API 存取</strong><br />
</blockquote>
接著來看看實際上 object 是如何存放在 Swift 中的,用下圖來說明:<br />
<img alt="object storage localtion in Swift" src="https://swiftstack.com/static/global/images/swift_architecture_aco.jpg" title="" /><br />
上圖一共有三個部分,分別是:<br />
<h2 id="21-account">
2.1 Account</h2>
Account storage 在整個 Swift storage 中是一個獨一無二的名稱,但 <strong>Account storage 在概念上並不屬於特定使用者的帳號 or 認證資訊,而是屬於儲存區域(storage area)的概念</strong>。<br />
在 Account storage 中,包含了與 Account 相關的 metadata 之外,就是儲存包含在此 Account 內的 Container 資訊。<br />
<h2 id="22-container">
2.2 Container</h2>
Container storage 則是屬於使用者自行定義的儲存區域,除了包含一些與 Container 本身相關的 metadata 之外,裡面主要就是 object 存放的地方。<br />
<h2 id="23-object">
2.3 Object</h2>
Object storage 存放的資料除了檔案本身之外,還包含了與檔案相關的 metadata。<br />
<h2 id="24-object-url-組成">
2.4 Object URL 組成</h2>
有了 Account / Container / Object 三種概念後,就可以進一步來了解每個 object 的 URL 組成,每個 object 都會有一個專屬的 URL 可供存取,結構如下:<br />
<blockquote>
<a href="https://swift.example.com/v1/">https://swift.example.com/v1/</a><strong>account</strong>/<strong>container</strong>/<strong>object</strong><br />
</blockquote>
其中 URL 結構包含兩個主要部分:<br />
<ul>
<li>Cluster 位置:也就是 <strong><a href="https://swift.example.com/v1/">https://swift.example.com/v1/</a></strong></li>
<li>object 位置:/<strong>account</strong>/<strong>container</strong>/<strong>object</strong></li>
</ul>
<h1 id="3swift-processes">
3、Swift Processes</h1>
只要有運行 Swift process 或是 service 的機器,稱為 “node”。<br />
運行 Proxy server process 的機器稱為 Proxy Node。<br />
運行 Account / Container / Object process 的機器稱為 Storage Node。(當然也另外包含了處理資料一致性的 consistent service)<br />
以下可以用一張簡單的圖說明 proxy node & storage node 在處理資料時的關係:<br />
<img alt="Swift Proxy Node & Storage Node" src="https://swiftstack.com/static/global/images/swift_architecture_requests.jpg" title="" /><br />
<h2 id="31-proxy-layer">
3.1 Proxy Layer</h2>
Proxy server process 是 Swift 中直接與外部的 client 連線的部分,用來處理來自外部的 HTTP request & response。<br />
在整個架構中建議至少使用兩個 proxy node,以避免 single point failure 的狀況發生。<br />
當 proxy server 收到 client request 後,會決定某個 storage node 來處理,收到 storage node 處理完的通知後會再回應給 client。<br />
<h2 id="32-account-layer">
3.2 Account Layer</h2>
Account server process 用來處理與 Account 相關的 metadata & Account 內所包含的 Container 資訊,而這些資訊是存放再 Account server process 所在機器內的 SQLite 資料庫中。<br />
<h2 id="33-container-layer">
3.3 Container Layer</h2>
Container server process 用來處理 Container metadata & 包含在內的 object 資訊需求,這些資料同樣也是存在 Container server process 所在機器內的 SQLite 的資料庫中。<br />
<h2 id="34-object-layer">
3.4 Object Layer</h2>
Object server process 負責實際檔案的儲存,檔案是以二進位的方式儲存於磁碟中。<br />
除了二進位資料外,還包含了很重要的時間戳記(timestamp)資訊,時間戳記資訊可以讓 Swift 同時儲存多種不同版本的檔案,<br />
而 object 的 metadata 則是以副檔名 xattrs 的方式,與 object 儲存在一起,Swift 會負責將這些資料複製到多個不同節點上。<br />
<h1 id="4swift-consistency-services">
4、Swift Consistency Services</h1>
為了確保每個 storage node 之間的資料一致,Swift 提供了兩個重要的 Service,分別是 <strong>Auditor</strong> & <strong>Replicator</strong>。<br />
<h2 id="41-auditor">
4.1 Auditor</h2>
Auditor service 運作在每一個 storage node 中,持續掃描磁碟確認沒有任何錯誤的發生,若是有錯誤發生,Auditor service 就會將有問題的 object 移到隔離區。<br />
<blockquote>
每一個 process(Account / Container / Object) 都有專屬的 Auditor 進行資料檢查之用。<br />
</blockquote>
<img alt="Audit Service" src="https://swiftstack.com/static/global/images/swift_architecture_quarantine.jpg" title="" /> <br />
<h2 id="42-replicator">
4.2 Replicator</h2>
同樣的 Account / Container / Object process 也都有相對應的 replicator,功能主要用來確保本地端的資料與 Cluster 中其他 storage node 的資料是一致的。<br />
比較需要注意的是,replicator service 只會將新的資料送到其他的 storage node,而不會從其他的 storage node 抓取新資料回來更新本地端資料。<br />
而 replicator service 是透過 checksum 的方式來達到各 storage node 資料的一致:<br />
<img alt="Replicator Service" src="https://swiftstack.com/static/global/images/swift_architecture_replicator.jpg" title="" /><br />
<h1 id="5swift-cluster-分群概念">
5、Swift Cluster 分群概念</h1>
Swift 是由一堆 proxy node & storage node 所組成,為了容易區分,因此有 <strong>Region</strong> & <strong>Zone</strong> 兩種邏輯上的分群概念。<br />
以下直接用一張圖來說明 Region & Zone 的樣子:<br />
<img alt="Swift Cluster Architecture" src="https://swiftstack.com/static/global/images/swift_architecture_regions.jpg" title="" /><br />
Zone 是由多個 storage node 所組成,一般常用來作為資料中心內部同機櫃的分類之用,或是用來將特別用途的 node 歸類之用。<br />
Region 則是由多個 Zone 組成,一般常用來區分不同區域的資料中心。<br />
<blockquote>
Region & Zone 是可以隨使用者自行定義的,上述只是範例而已。<br />
</blockquote>
<h1 id="6swift-資料存取設計">
6、Swift 資料存取設計</h1>
<h2 id="61-partition">
6.1 Partition</h2>
Swift 為了有效的跨 storage node 來存放資料,並可以達到快速存取的目的,在資料存放的模型有經過特別設計,以下用一張簡單的圖來說明:<br />
<img alt="Swift Partition" src="https://swiftstack.com/static/global/images/swift_architecture_partition.jpg" title="" /><br />
從上圖可以看到有三種元素,分別是:<br />
<ol>
<li>Storage Node</li>
<li>Disk</li>
<li>Partition</li>
</ol>
每個 Storage node 可能會有好幾個 Disk。<br />
而 Partition 在這邊並不是傳統磁碟分割的概念來看,而是應該把它當作是 Disk 的一個目錄的概念來看,所以一個 Disk 會有很多個 Partition。<br />
Partition 是 Swift process 處理的最小單位,也是資料實際存放的地方,而 consistency process 則是以 partition 為單位在檢查資料的一致性,資料在不同的硬碟(or 設備)間移動也是以 partition 為單位。<br />
透過以 paritition 為單位來處理的方式,Swift 可以減少 process & 網路的負擔。<br />
<h2 id="62-ring">
6.2 Ring</h2>
Ring 在 Swift 架構中是個相當重要的部分,它是一個映射(mapping)檔案,由一致性的 hash 演算法所產生,種類有三種,分別是 Account Ring / Container Ring / Object Ring。<br />
透過 Ring 就可以知道每一個 object 實際對應到的 Account & Container & 實際存放的位置(partition),如下圖:<br />
<img alt="Swift Ring" src="https://swiftstack.com/static/global/images/swift_architecture_ring_map.jpg" title="" /><br />
Ring 存在於 Swift Storage Cluster 中的每一個 node 中,透過 Ring,可以確保每個 object 在 Swift Storage Cluster 中有多個複本存在於不同的 storage 內,也可以確保後續可以進行快速的存取。<br />
透過維持一致性的 Ring,Swift Storage Cluster 不僅避免了單點錯誤的狀況發生,提升存取的速度,也大大的增加水平擴展的能力。<br />
<h1 id="7switch-完整架構">
7、Switch 完整架構</h1>
最後來個 Swift Storage Cluster 的完整架構概觀:<br />
<img alt="OpenStack Swift Architecture" src="https://developers.seagate.com/download/attachments/1769521/SwiftStack%20Current%20Architecture.jpg?version=1&modificationDate=1381516991000&api=v2" title="" /><br />
<ul>
<li>Proxy Server 是直接接受來自 client 請求的部分。</li>
<li>Proxy Server 收到 client 請求後,會透過 Ring 快速地進行 object 的存取 or 將資料同步到不同的 Object Server(storage node) 上。</li>
<li>不同的 Object Server 可能會根據不同的規劃(地理區域、服務對象、功能性….等),區分成不同的 Zone(or Region) 作為管理之用。</li>
</ul>
<h1 id="8參考資料">
8、參考資料</h1>
<ul>
<li><a href="https://swiftstack.com/openstack-swift/">OpenStack Swift | SwiftStack</a></li>
<li><a href="https://swiftstack.com/uploads/factsheets_pdf/openstack_swift_technology_brief.pdf">OpenStack Swift Tech Brief | SwiftStack</a></li>
<li><a href="https://swiftstack.com/openstack-swift/architecture/">OpenStack Swift Architecture | SwiftStack</a></li>
<li><a href="http://zmanda-taiwan.blogspot.tw/2012/05/openstack-swift.html">Zmanda - OpenStack Swift 雲端存儲架構說明(一)</a></li>
<li><a href="http://hugo.openstack.com.tw/2014/03/openstack-swift-ep0.html">Hugo Pot: OpenStack Swift (ep0) - 進化的儲存系統與需求</a></li>
<li><a href="http://jimwayne.blogspot.tw/2014/06/openstack-swift.html">黑毛到白毛的攻城獅之路: OpenStack Swift 的儲存結構最佳化</a></li>
<li><a href="http://itman2266.blogspot.tw/2014/04/hadoopopenstack-swift-ceph.html">蕃薯的筆記本: 從Hadoop到OpenStack Swift 再到Ceph</a></li>
<li><a href="http://fanli7.net/a/bianchengyuyan/PHP/20120622/174582.html">深入雲存儲系統Swift核心組件:Ring實現原理剖析_人人IT網-StackDoc</a></li>
<li><a href="http://fanli7.net/a/bianchengyuyan/Python/20120628/177804.html">深入雲存儲系統Swift核心組件:Ring數據結構及構建、重平衡操作_人人IT網-StackDoc</a></li>
<li><a href="http://zh.wikipedia.org/wiki/%E5%A4%9A%E7%A7%9F%E6%88%B6%E6%8A%80%E8%A1%93">多租戶技術 - 維基百科,自由的百科全書</a></li>
</ul>
</div>
</body>
</html>曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-90275289932843411972014-10-11T15:16:00.001+08:002014-10-11T15:21:28.533+08:00Ceph 簡介<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ceph 簡介</title>
<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body><div class="container"><h1 id="目錄">目錄</h1>
<p><div class="toc"><div class="toc">
<ul>
<li><a href="#目錄">目錄</a></li>
<li><a href="#1前言">1、前言</a></li>
<li><a href="#2ceph-功能">2、Ceph 功能</a></li>
<li><a href="#3與-openstack-整合狀況">3、與 OpenStack 整合狀況</a></li>
<li><a href="#4ceph-基礎元素">4、Ceph 基礎元素</a><ul>
<li><a href="#41-crush">4.1 CRUSH</a><ul>
<li><a href="#411-crush-algorithm">4.1.1 CRUSH Algorithm</a></li>
<li><a href="#412-crush-map">4.1.2 CRUSH Map</a></li>
</ul>
</li>
<li><a href="#42-placement-group">4.2 Placement Group</a></li>
<li><a href="#43-object-storage-daemon-osd">4.3 Object Storage Daemon (OSD)</a></li>
<li><a href="#44-monitor">4.4 Monitor</a></li>
<li><a href="#45-metadata-server-mds">4.5 Metadata Server (MDS)</a></li>
</ul>
</li>
<li><a href="#5ceph-storage-cluster-架構">5、Ceph Storage Cluster 架構</a><ul>
<li><a href="#51-ceph-node-類型">5.1 Ceph Node 類型</a><ul>
<li><a href="#511-ceph-osd-daemons">5.1.1 Ceph OSD Daemons</a></li>
<li><a href="#512-monitor">5.1.2 Monitor</a></li>
<li><a href="#513-mds">5.1.3 MDS</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#52-完整架構">5.2 完整架構</a></li>
<li><a href="#521-object-storage">5.2.1 Object Storage</a></li>
<li><a href="#522-block-storage">5.2.2 Block Storage</a></li>
<li><a href="#523-file-system">5.2.3 File System</a></li>
<li><a href="#6參考資料">6、參考資料</a></li>
</ul>
</div>
</div>
</p>
<h1 id="1前言">1、前言</h1>
<p>什麼是 Ceph? </p>
<p>它是以 RADOS (Reliable Autonomic Distributed Object Store) 為主要設計方式的分散式儲存平台,因此在水平擴展的能力極為強大。</p>
<p>以下截錄一段在 <a href="http://www.inktank.com/what-is-ceph/">inktank</a> 網站上的說明:</p>
<blockquote>
<p>Ceph is an open-source, massively scalable, software-defined storage system which provides object, block and file system storage in a single platform. It runs on commodity hardware—saving you costs, giving you flexibility—and because it’s in the Linux kernel, it’s easy to consume.</p>
</blockquote>
<p>從以上的內容可以看出,Ceph 是個<strong>軟體定義的儲存系統</strong>有以下幾個特點:</p>
<ol>
<li>在同一平台下可同時提供 Object Storgae & Block Storage & File System 等三種不同的服務。</li>
<li>強大的擴展能力。</li>
<li>不受限於任何硬體規格,<strong>no vendor lock-in</strong> !</li>
</ol>
<p>一個平台可以同時提供三種服務,簡直是健達出奇蛋一樣,三種願望一次滿足。XD</p>
<h1 id="2ceph-功能">2、Ceph 功能</h1>
<p>Ceph 在三種不同的功能(object / block / file system)中,分別提供了以下特性:</p>
<table>
<thead>
<tr>
<th>CEPH OBJECT STORE</th>
<th>CEPH BLOCK DEVICE</th>
<th>CEPH FILESYSTEM</th>
</tr>
</thead>
<tbody><tr>
<td>RESTful Interface</td>
<td>Thin-provisioned</td>
<td>POSIX-compliant semantics</td>
</tr>
<tr>
<td>S3- and Swift-compliant APIs</td>
<td>Images up to 16 exabytes</td>
<td>Separates metadata from data</td>
</tr>
<tr>
<td>S3-style subdomains</td>
<td>Configurable striping</td>
<td>Dynamic rebalancing</td>
</tr>
<tr>
<td>Unified S3/Swift namespace</td>
<td>In-memory caching</td>
<td>Subdirectory snapshots</td>
</tr>
<tr>
<td>User management</td>
<td>Snapshots</td>
<td>Configurable striping</td>
</tr>
<tr>
<td>Usage tracking</td>
<td>Copy-on-write cloning</td>
<td>Kernel driver support</td>
</tr>
<tr>
<td>Striped objects</td>
<td>Kernel driver support</td>
<td>FUSE support</td>
</tr>
<tr>
<td>Cloud solution integration</td>
<td>KVM/libvirt support</td>
<td>NFS/CIFS deployable</td>
</tr>
<tr>
<td>Multi-site deployment</td>
<td>Back-end for cloud solutions</td>
<td>Use with Hadoop (replace HDFS)</td>
</tr>
<tr>
<td>Disaster recovery</td>
<td>Incremental backup</td>
<td></td>
</tr>
</tbody></table>
<h1 id="3與-openstack-整合狀況">3、與 OpenStack 整合狀況</h1>
<p>從 <strong>Folsom</strong> 版本開始,Ceph 就已經正式整合進 OpenStack 了。</p>
<p><img src="http://www.inktank.com/wp-content/uploads/2013/03/Diagram_v3.0_CEEPHOPENTSTACK11-1024x455.png" alt="Ceph for OpenStack" title=""></p>
<p>Ceph 提供了 Block Device service 給 Cinder & Glance & Nova 使用,還包含了其他強大的特性,例如:High Availability、Fault Tolerant … 等等。</p>
<p>此外 Ceph 也完全相容 Swift API,因此可以取代 Swift 提供 Object Storage service 之用;當然認證部分當然也整合了 Keystone。</p>
<p>由於以上原因,Ceph 可說是提供了一個完整的 storage solution 可用來整合進 OpenStack 中。</p>
<h1 id="4ceph-基礎元素">4、Ceph 基礎元素</h1>
<p>在開始研究 Ceph 之前,有些基礎的元素是需要先了解的,以下逐一介紹:</p>
<h2 id="41-crush">4.1 CRUSH</h2>
<p>CRUSH 在整個資料分散上扮演著重要角色,從「<a href="http://www.ssrc.ucsc.edu/Papers/weil-sc06.pdf">CRUSH: Controlled, Scalable, Decentralized Placement of Replicated Data</a>」一文中可以看出 CRUSH 的功能:</p>
<blockquote>
<p>CRUSH, a scalable pseudo-random data distribution function designed for distributed object-based storage system that efficiently maps data objects to storage devices without relying on a central directory.</p>
<p>CRUSH is designed to facilitate the addition and removal of storage while minimizing unnecessary data movement.</p>
<p>The algorithm accommodates a wide variety of data replication and reliability mechanisms and distributes data in terms of user-defined policies that enforce separation of replicas across failure domains.</p>
</blockquote>
<p>從上面的說明可以看出,CRUSH 提供了以下功能:</p>
<ol>
<li>將資料有效率的存放在不同的儲存裝置中。</li>
<li>即使移除整個 cluster 中的儲存裝置,也不會影響到資料正常的存取。</li>
<li>不需要有任何主要的管理裝置(or 節點)來做為控管之用。</li>
<li>可依照使用者所定義的規則來處理資料分散的方式。</li>
</ol>
<p>CRUSH 包含了兩個部分,分別是 Algorithm & Map。</p>
<h3 id="411-crush-algorithm">4.1.1 CRUSH Algorithm</h3>
<p>CRUSH Algorithm 的用途在於可透過資料儲存位置的計算,決定如何存取資料;也因為是透過演算法計算的方式,可以有效避免 single point of failure 的問題發生。</p>
<h3 id="412-crush-map">4.1.2 CRUSH Map</h3>
<p>CRUSH Map 是一群資訊的集合,包含了:</p>
<ol>
<li>OSD(Object Storage Daemon) 集合的資訊</li>
<li>由多個 device 所匯集而成的實體位置資訊</li>
<li>多個用來指定 Ceph 應該如何在 ceph cluster pool 進行資料複製的規則</li>
</ol>
<p>透過以上資訊,CRUSH 可以將資料分散存放在不同的實體位置,並避免單點錯誤造成資料無法存取的狀況發生。</p>
<h2 id="42-placement-group">4.2 Placement Group</h2>
<p>首先用下圖來說明 object / Placement Group / OSD 之間的關係:</p>
<p><img src="http://ceph.com/docs/v0.78/_images/ditaa-c7fd5a4042a21364a7bef1c09e6b019deb4e4feb.png" alt="Placement Group" title=""></p>
<p>當使用者把資料(object)存到 cluster 中時,每個 object 都會對應到一個 placement group(PG),而每一個 PG 都會對應到一組 OSD,其中第一個 OSD 為 primary,其他則是 replica。</p>
<blockquote>
<p>多個 PG 也可以對應到同一個 OSD,因此 PG & OSD 其實是種多對多的關係。</p>
</blockquote>
<p>而 OSD 在幹嘛? 就是把資料存入到不同的實體位置囉!</p>
<h2 id="43-object-storage-daemon-osd">4.3 Object Storage Daemon (OSD)</h2>
<p>Ceph OSD(Object Storage Daemon) Daemon 的主要工作就是透過網路,進行實際資料(object)的存取,但 OSD 完整個功能主要有以下幾項:</p>
<ol>
<li>資料儲存</li>
<li>資料複製</li>
<li>資料回復</li>
<li>資料回填(backfilling, 通常發生於新 OSD 加入時)</li>
<li>Rebalance (發生於新 OSD 加入 CRUSH map 時)</li>
<li>以 heartbeat 的方式取得其他 OSD 的狀態,並將資訊提供 Ceph Monitor </li>
</ol>
<h2 id="44-monitor">4.4 Monitor</h2>
<p>為了有效的在分散式的環境下存取檔案,每一個 Ceph Monitor daemon 維護著很多份與 cluster 相關的映射資料(map),包含:</p>
<ol>
<li>Monitor map</li>
<li>OSD map</li>
<li>Placement Group (PG) map</li>
<li>CRUSH map</li>
<li>MDS map (若使用 Ceph File System,還會有這組映射資料)</li>
</ol>
<p>主要是用來監控 Ceph Storage Cluster 上的即時狀態,確保 Ceph 可以運作無誤。</p>
<h2 id="45-metadata-server-mds">4.5 Metadata Server (MDS)</h2>
<p>負責管理 Ceph File System 上的 metadata,且讓使用者可以把 Ceph File System 當作一般的檔案系統操作。</p>
<blockquote>
<p>Ceph Object Storage & Ceph Block Device 不會使用到 MDS。</p>
</blockquote>
<h1 id="5ceph-storage-cluster-架構">5、Ceph Storage Cluster 架構</h1>
<h2 id="51-ceph-node-類型">5.1 Ceph Node 類型</h2>
<p>組成 Ceph Storage Cluster 的元素稱為 Ceph node,而 Ceph node 共有以下類型:</p>
<h3 id="511-ceph-osd-daemons">5.1.1 Ceph OSD Daemons</h3>
<p>實際與 client 溝通進行資料存取的即為 OSD daemon。</p>
<p>每個 object 被儲存到多個 PG(placement group) 中,每個 PG 再被存放到多個 OSD 中。</p>
<p>為了達到 Active + Clean 的狀態,確認每份資料都有兩份的儲存,每個 Ceph Storage Cluster 中至少都必須要有兩個 Ceph OSD。</p>
<h3 id="512-monitor">5.1.2 Monitor</h3>
<p>在每一個 Ceph Storage Cluster 中,都有多個 Monitor 存在,每個 Monitor 都維護著上述的五種映射資訊(monitor map / OSD map / PG map / CRUSH map / MDS map),以及 monitor / OSD / PG …等狀態的歷史資訊。</p>
<h3 id="513-mds">5.1.3 MDS</h3>
<p>作為處理 Ceph File System 的 metadata 之用,若僅使用 Block or Object storage,就不會用到這部分功能。</p>
<h1 id="52-完整架構">5.2 完整架構</h1>
<p>首先用下圖來表示完整的 Ceph 架構:</p>
<p><img src="http://ceph.com/docs/master/_images/stack.png" alt="Ceph Architecture" title=""></p>
<p>其中最底層的 RADOS 是由 OSD & Monitor & MDS 三種所組成:</p>
<p><img src="http://ceph.com/docs/master/_images/ditaa-fbe8ee62a8a21a317df92d84a62447c4ecd11e34.png" alt="enter image description here" title=""></p>
<p>以上則是提供不同的 middleware( radosgw / rbd / cephfs),呼叫 librados 進行資料存取,來提供不同的 service(Object / Block / File System)。</p>
<h1 id="521-object-storage">5.2.1 Object Storage</h1>
<p>Ceph Object Storage 的架構如下:</p>
<p><img src="http://ceph.com/docs/master/_images/ditaa-50d12451eb76c5c72c4574b08f0320b39a42e5f1.png" alt="Ceph Object Storage" title=""></p>
<p>其中底層由 OSD & Monitor 來組成,透過 librados 來控制協調;上層則提供了 <strong>RADOSGW</strong> 來達成與 OpenStack Swift & Amazon S3 APIs 的一致性。</p>
<h1 id="522-block-storage">5.2.2 Block Storage</h1>
<p>Ceph Block Storage 的架構如下:</p>
<p><img src="http://ceph.com/docs/master/_images/ditaa-dc9f80d771b55f2daa5cbbfdb2dd0d3e6dfc17c0.png" alt="Ceph Block Storage" title=""></p>
<p>Ceph Block device 提供了 thin-provison / 可調整大小 / 分散儲存 / 快照 / 一致性 … 等功能。</p>
<p>Ceph block storage 除了可以被 Linux kernel 直接使用外,也可以被 KVM / Qemu 使用,也可以透過 LIBRBD 與其他雲端系統(例如:OpenStack、CloudStack)整合。</p>
<h1 id="523-file-system">5.2.3 File System</h1>
<p>Ceph File System 的架構如下:</p>
<p><img src="http://ceph.com/docs/master/_images/ditaa-1cae553f9d207d72257429d572673632afbd108c.png" alt="Ceph File System" title=""></p>
<p>底層的部分同樣是由 RADOS(OSDs + Monitors + MDSs) 提供,在上一層同樣與 librados 溝通,最上層則是有不同的 library 將其轉換成標準的 POSIX 檔案系統供使用。</p>
<h1 id="6參考資料">6、參考資料</h1>
<ul>
<li><p><a href="http://www.storageforum.tw/2013/08/blog-post_15.html">storageforum.tw: [技術|產業] 解析軟體定義儲存</a></p></li>
<li><p><a href="http://www.inktank.com/openstack-storage-solutions/">(Ceph for OpenStack) - Inktank</a></p></li>
<li><p><a href="http://ceph.com/docs/master/start/intro/">Intro to Ceph — Ceph Documentation</a></p></li>
<li><p><a href="http://siliconangle.com/blog/2014/07/29/ceph-and-swift-friends-not-enemies/">Ceph and Swift: Friends, not enemies | SiliconANGLE</a></p></li>
<li><p><a href="http://ceph.com/">Home Ceph</a></p></li>
<li><p><a href="http://www.inktank.com/what-is-ceph/">What is Ceph? – - Inktank</a></p></li>
<li><p><a href="http://yizhaolingyan.net/?p=11">“Ceph淺析”系列之一——前言| 一棹凌煙且行且悟</a></p></li>
<li><p><a href="http://yizhaolingyan.net/?p=19">“Ceph淺析”系列之二——Ceph概況| 一棹凌煙且行且悟</a></p></li>
<li><p><a href="http://ceph.com/docs/master/architecture/">Architecture — Ceph Documentation</a></p></li>
<li><p><a href="http://www.ssrc.ucsc.edu/Papers/weil-sc06.pdf">CRUSH: Controlled, Scalable, Decentralized Placement of Replicated Data</a></p></li>
</ul></div></body>
</html>曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com2tag:blogger.com,1999:blog-4428257381149033865.post-90904726378453755422014-10-08T05:50:00.001+08:002014-10-08T05:50:50.226+08:00安裝 OpenStack @ Ubuntu 14.04 (8) - 安裝 Block Storage Service (Cinder)<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>安裝 OpenStack @ Ubuntu 14.04 (8) - 安裝 Block Storage Service (Cinder)</title>
<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body><div class="container"><h1 id="目錄">目錄</h1>
<p><div class="toc"><div class="toc">
<ul>
<li><a href="#目錄">目錄</a></li>
<li><a href="#1安裝環境說明">1、安裝環境說明</a></li>
<li><a href="#2block-storage-servicecinder-概觀">2、Block Storage Service(Cinder) 概觀 </a></li>
<li><a href="#3cinder-服務元件架構">3、Cinder 服務元件架構</a><ul>
<li><a href="#31-cinder-api">3.1 cinder-api</a></li>
<li><a href="#32-cinder-scheduler">3.2 cinder-scheduler</a></li>
<li><a href="#33-cinder-volume">3.3 cinder-volume</a></li>
<li><a href="#34-message-queue">3.4 message queue</a></li>
</ul>
</li>
<li><a href="#4安裝-設定-block-storage-service-controller">4、安裝 & 設定 Block Storage Service Controller</a><ul>
<li><a href="#41-安裝服務套件">4.1 安裝服務套件</a></li>
<li><a href="#42-設定資料庫">4.2 設定資料庫</a></li>
<li><a href="#43-設定-message-queue">4.3 設定 message queue</a></li>
<li><a href="#44-設定-identity-service-認證">4.4 設定 Identity Service 認證</a></li>
<li><a href="#45-向-identity-service-註冊-cinder-服務-api-服務端點">4.5 向 Identity Service 註冊 Cinder 服務 & API 服務端點</a></li>
<li><a href="#46-啟動服務">4.6 啟動服務</a></li>
</ul>
</li>
<li><a href="#5安裝-設定-block-storage-service-node">5、安裝 &設定 Block Storage Service node</a><ul>
<li><a href="#51-block-storage-node-環境說明">5.1 Block Storage Node 環境說明</a></li>
<li><a href="#52-建立-lvm-磁區">5.2 建立 LVM 磁區</a></li>
<li><a href="#53-建立-lvm-physical-volumes-logical-volumes">5.3 建立 LVM Physical Volumes & Logical Volumes</a></li>
<li><a href="#54-安裝-設定-block-storage-service">5.4 安裝 & 設定 Block Storage service</a><ul>
<li><a href="#541-安裝套件">5.4.1 安裝套件</a></li>
<li><a href="#542-設定檔調整">5.4.2 設定檔調整</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#6驗證安裝是否成功">6、驗證安裝是否成功</a></li>
<li><a href="#7-障礙排除">7. 障礙排除</a></li>
<li><a href="#8參考資料">8、參考資料</a></li>
</ul>
</div>
</div>
</p>
<h1 id="1安裝環境說明">1、安裝環境說明</h1>
<ul>
<li><p>OS:Ubuntu 14.04 LTS</p></li>
<li><p>Controller</p>
<ul><li>IP:<strong>10.0.0.11</strong> / 24</li>
<li>Gateway:10.0.0.1</li></ul></li>
<li><p>Network <br>
</p><ul><li>Management IP:<strong>10.0.0.21</strong> / 24 (<strong>eth0</strong>)</li>
<li>Gateway:10.0.0.1</li>
<li>Instance Tunnel IP:10.0.1.21 / 24 (<strong>eth1</strong>)</li>
<li>External Interface (<strong>eth2</strong>) <br>
<ul><li>IP:不指定 IP </li>
<li>設定方式如下:(修改 <strong>/etc/network/interfaces</strong>) <br></li></ul></li></ul><p></p>
<blockquote>
<p>auto eth2 <br>
iface eth2 inet manual <br>
up ip link set dev <span>$</span>IFACE up <br>
down ip link set dev <span>$</span>IFACE down</p></blockquote></li></ul>
<li><p>Compute 1</p>
<ul><li>Management IP:<strong>10.0.0.31</strong> / 24</li>
<li>Gateway:10.0.0.1</li>
<li>Instance Tunnel IP:10.0.1.31</li></ul></li>
<li><p>Block Storage 1</p>
<ul><li>Management IP:<strong>10.0.0.41</strong> / 24</li>
<li>Gateway:10.0.0.1</li>
<li>Instance Tunnel IP:10.0.1.41</li></ul></li>
<p>修改每個 node 的 /etc/hosts 檔案,並加入以下內容:</p>
<blockquote>
<p>10.0.0.11 controller <br>
10.0.0.21 network <br>
10.0.0.31 compute1 <br>
10.0.0.41 block1</p>
</blockquote>
<ul>
<li>使用者身分:root</li>
</ul>
<h1 id="2block-storage-servicecinder-概觀">2、Block Storage Service(Cinder) 概觀 </h1>
<p>OpenStack Block Storage(Cinder) 的工作包含 volume、volume 快照、volume 類型的管理,主要用來提供給 VM 區塊等級(Block Level)的永久性儲存空間,提供快照、資料回復…等功能,還可以整合其他商業化的企業儲存平台,例如 NetApp、Nexenta … 等。</p>
<h1 id="3cinder-服務元件架構">3、Cinder 服務元件架構</h1>
<p>在安裝之前,可以先用以下這張圖來了解一下 Cinder 是由那些 component 組合而成的(截錄自<a href="https://tw.pycon.org/2013/site_media/media/proposal_files/cinder_2013.pdf">工研院-OpenStack Cinder Tutorial</a> 一文):</p>
<p><img src="https://lh3.googleusercontent.com/-1O0C3CEdZA8/VDI21yfyTRI/AAAAAAAAJr0/bp9lRkWeeVo/w944-h690-no/Cinder_interaction.png" alt="Cinder Interaction" title=""></p>
<p>從上圖可看出,Cinder 共包含了以下重要的部分:</p>
<h2 id="31-cinder-api">3.1 cinder-api</h2>
<p>用來接受來自外部對於 volume 空間的請求後,透過 message queue 將請求轉給 cinder-scheduler 後再轉給 cinder-volume 進行後續處理。</p>
<h2 id="32-cinder-scheduler">3.2 cinder-scheduler</h2>
<p>類似 nova-schedular 的角色,接收到來自 message queue 的命令後,會從多個(如果有)提供 block storage 服務的 node 挑選出一個最合適來建立 volume。</p>
<h2 id="33-cinder-volume">3.3 cinder-volume</h2>
<p>cinder-volume 的工作大概有幾項:</p>
<ol>
<li>接收來自 cinder-scheduler 的命令,建立新的 volume。</li>
<li>接收來自 message queue 的訊息,進行 volume 空間的讀寫。</li>
<li>透過不同的 driver,還可以使用多種不同的 storage provider 所提供的設備。</li>
</ol>
<h2 id="34-message-queue">3.4 message queue</h2>
<p>負責將訊息派送給各個 Block Storage service。</p>
<h1 id="4安裝-設定-block-storage-service-controller">4、安裝 & 設定 Block Storage Service Controller</h1>
<p>了解 Block Storage 各個不同服務之後,接下來要來進行各個服務的安裝,首先這邊要先安裝的是 <strong>cinder-api</strong> & <strong>cinder-scheduler</strong>。</p>
<blockquote>
<p>由於這兩個服務並不牽涉到真正磁碟空間的存取 or 外部儲存設備的控制,因此這邊選擇在 <font color="red"><strong>controller node</strong></font> 上進行安裝。</p>
</blockquote>
<h2 id="41-安裝服務套件">4.1 安裝服務套件</h2>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># apt-get install cinder-api cinder-scheduler</span></code></pre>
<h2 id="42-設定資料庫">4.2 設定資料庫</h2>
<p>首先建立資料庫 & 設定權限:</p>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 登入 MySQL</span>
controller<span class="hljs-comment"># mysql -u root -p</span>
Enter password:
<span class="hljs-comment"># 建立 cinder 資料庫</span>
mysql> create database cinder;
Query OK, <span class="hljs-number">1</span> row affected (<span class="hljs-number">0.02</span> sec)
<span class="hljs-comment"># 設定使用者權限</span>
mysql> grant all privileges on cinder.* to <span class="hljs-string">'cinder'</span>@<span class="hljs-string">'localhost'</span> identified by <span class="hljs-string">'YOUR_CINDER_DB_PASSWORD'</span>;
Query OK, <span class="hljs-number">0</span> rows affected (<span class="hljs-number">0.01</span> sec)
mysql> grant all privileges on cinder.* to <span class="hljs-string">'cinder'</span>@<span class="hljs-string">'%'</span> identified by <span class="hljs-string">'YOUR_CINDER_DB_PASSWORD'</span>;
Query OK, <span class="hljs-number">0</span> rows affected (<span class="hljs-number">0.00</span> sec)</code></pre>
<p>接著修改 Cinder 設定檔 <strong>/etc/cinder/cinder.conf</strong>,加入以下內容:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[database]</span>
<span class="hljs-setting">connection = <span class="hljs-value">mysql://cinder:YOUR_CINDER_DB_PASSWORD@controller/cinder</span></span></code></pre>
<p>最後建立 Cinder 資料庫中的相關 table:</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># sh -c "cinder-manage db sync" cinder</span></code></pre>
<h2 id="43-設定-message-queue">4.3 設定 message queue</h2>
<p>此處要設定 Cinder 使用之前所安裝好的 RabbitMQ message broker 作為 message queue 之用。</p>
<p>修改設定檔 <strong>/etc/cinder/cinder.conf</strong>,加入以下內容:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[DEFAULT]</span>
<span class="hljs-setting">rpc_backend = <span class="hljs-value">rabbit</span></span>
<span class="hljs-setting">rabbit_host = <span class="hljs-value">controller</span></span>
<span class="hljs-setting">rabbit_userid = <span class="hljs-value">guest</span></span>
<span class="hljs-setting">rabbit_password = <span class="hljs-value">YOUR_RABBITMQ_PASSWORD</span></span></code></pre>
<h2 id="44-設定-identity-service-認證">4.4 設定 Identity Service 認證</h2>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment">#建立 Cinder service 用的 user</span>
controller<span class="hljs-comment"># keystone user-create --name=cinder --pass=YOUR_CINDER_PASSWORD --email=admin@example.com</span>
+----------+----------------------------------+
| Property | Value |
+----------+----------------------------------+
| email | admin@example.com |
| enabled | True |
| id | f31b2ebaf1be446490769637c6987b5b |
| name | cinder |
| username | cinder |
+----------+----------------------------------+
<span class="hljs-comment">#將 user / service Tenant / admin Role 連結</span>
controller<span class="hljs-comment"># keystone user-role-add --user=cinder --tenant=service --role=admin</span></code></pre>
<h2 id="45-向-identity-service-註冊-cinder-服務-api-服務端點">4.5 向 Identity Service 註冊 Cinder 服務 & API 服務端點</h2>
<p>首先要修改設定檔 <strong>/etc/cinder/cinder.conf</strong>,加入設定內容如下:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[keystone_authtoken]</span>
<span class="hljs-setting">auth_uri = <span class="hljs-value">http://controller:<span class="hljs-number">5000</span></span></span>
<span class="hljs-setting">auth_host = <span class="hljs-value">controller</span></span>
<span class="hljs-setting">auth_port = <span class="hljs-value"><span class="hljs-number">35357</span></span></span>
<span class="hljs-setting">auth_protocol = <span class="hljs-value">http</span></span>
<span class="hljs-setting">admin_tenant_name = <span class="hljs-value">service</span></span>
<span class="hljs-setting">admin_user = <span class="hljs-value">cinder</span></span>
<span class="hljs-setting">admin_password = <span class="hljs-value">CINDER_PASS</span></span></code></pre>
<p>向 Identity Service(Keystone) 註冊 Service & API endpoint (version1):</p>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment">#註冊 Cinder service (version 1)</span>
controller<span class="hljs-comment"># keystone service-create --name=cinder --type=volume --description="OpenStack Block Storage"</span>
+-------------+----------------------------------+
| Property | Value |
+-------------+----------------------------------+
| description | OpenStack Block Storage |
| enabled | True |
| id | <span class="hljs-number">0</span>b1d7ff1bb3f4136be58e32bc73e89bc |
| name | cinder |
| <span class="hljs-built_in">type</span> | volume |
+-------------+----------------------------------+
<span class="hljs-comment">#註冊 Cinder API endpoint (version 1)</span>
controller<span class="hljs-comment"># keystone endpoint-create --service-id=$(keystone service-list | awk '/ volume / {print $2}') --publicurl=http://controller:8776/v1/%\(tenant_id\)s --adminurl=http://controller:8776/v1/%\(tenant_id\)s</span>
+------------+-----------------------------------------+
| Property | Value |
+------------+-----------------------------------------+
| adminurl | http://controller:<span class="hljs-number">8776</span>/v1/%(tenant_id)s |
| id | <span class="hljs-number">5</span>a58ee0f46ca4721aaa28be98520dec3 |
| publicurl | http://controller:<span class="hljs-number">8776</span>/v1/%(tenant_id)s |
| region | regionOne |
| service_id | <span class="hljs-number">0</span>b1d7ff1bb3f4136be58e32bc73e89bc |
+------------+-----------------------------------------+</code></pre>
<p>接著向 Identity Service(Keystone) 註冊 Service & API endpoint (version2):</p>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment">#註冊 Cinder service (version 2)</span>
controller<span class="hljs-comment"># keystone service-create --name=cinderv2 --type=volumev2 --description="OpenStack Block Storage v2"</span>
+-------------+----------------------------------+
| Property | Value |
+-------------+----------------------------------+
| description | OpenStack Block Storage v2 |
| enabled | True |
| id | <span class="hljs-number">6</span>e20dad30957436fb142c20d1848ce91 |
| name | cinderv2 |
| <span class="hljs-built_in">type</span> | volumev2 |
+-------------+----------------------------------+
<span class="hljs-comment">#註冊 Cinder API endpoint (version 2)</span>
controller<span class="hljs-comment"># keystone endpoint-create --service-id=$(keystone service-list | awk '/ volumev2 / {print $2}') --publicurl=http://controller:8776/v2/%\(tenant_id\)s --internalurl=http://controller:8776/v2/%\(tenant_id\)s --adminurl=http://controller:8776/v2/%\(tenant_id\)s</span>
+-------------+-----------------------------------------+
| Property | Value |
+-------------+-----------------------------------------+
| adminurl | http://controller:<span class="hljs-number">8776</span>/v2/%(tenant_id)s |
| id | <span class="hljs-number">39</span>d9a5060449490fbd1016cbcd1f4904 |
| internalurl | http://controller:<span class="hljs-number">8776</span>/v2/%(tenant_id)s |
| publicurl | http://controller:<span class="hljs-number">8776</span>/v2/%(tenant_id)s |
| region | regionOne |
| service_id | <span class="hljs-number">6</span>e20dad30957436fb142c20d1848ce91 |
+-------------+-----------------------------------------+</code></pre>
<h2 id="46-啟動服務">4.6 啟動服務</h2>
<p>最後啟動 controller 上的 <strong>cinder-scheduler</strong> & <strong>cinder-api</strong> 服務:</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># service cinder-scheduler restart</span>
controller<span class="hljs-comment"># service cinder-api restart</span></code></pre>
<h1 id="5安裝-設定-block-storage-service-node">5、安裝 &設定 Block Storage Service node</h1>
<h2 id="51-block-storage-node-環境說明">5.1 Block Storage Node 環境說明</h2>
<p>controller 安裝完畢後,接著要安裝實際提供磁碟存取空間的 service 到擁有磁碟空間的 storage node 上。</p>
<p>這邊準備了另外一台電腦(<font color="red"><strong>block1</strong></font>),除了以下是目前磁碟的狀況:</p>
<pre class="prettyprint"><code class="language-bash hljs ">block1<span class="hljs-comment"># # fdisk -l</span></code></pre>
<blockquote>
<p>Disk <strong>/dev/sda</strong>: 8589 MB, 8589934592 bytes <br>
….. <br>
Device Boot Start End Blocks Id System <br>
/dev/sda1 * 2048 14680063 7339008 83 Linux <br>
/dev/sda2 14682110 16775167 1046529 5 Extended <br>
/dev/sda5 14682112 16775167 1046528 82 Linux swap / Solaris</p>
<p>Disk <strong>/dev/sdb</strong>: 17.2 GB, 17179869184 bytes <br>
….. <br>
Disk /dev/sdb doesn’t contain a valid partition table</p>
<p>Disk <strong>/dev/sdc</strong>: 17.2 GB, 17179869184 bytes <br>
….. <br>
Disk /dev/sdc doesn’t contain a valid partition table</p>
</blockquote>
<p>這邊將會以兩個空白的磁碟作 LVM 來提供磁碟空間的服務。</p>
<blockquote>
<p><strong>網路設定在前面的安裝環境說明有提供。</strong></p>
</blockquote>
<h2 id="52-建立-lvm-磁區">5.2 建立 LVM 磁區</h2>
<p>首先安裝 LVM 所需套件:</p>
<pre class="prettyprint"><code class="language-bash hljs ">block1<span class="hljs-comment"># apt-get install lvm2</span></code></pre>
<h2 id="53-建立-lvm-physical-volumes-logical-volumes">5.3 建立 LVM Physical Volumes & Logical Volumes</h2>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment">#建立 physical volume</span>
block1<span class="hljs-comment"># pvcreate /dev/sdb</span>
Physical volume <span class="hljs-string">"/dev/sdb"</span> successfully created
<span class="hljs-comment">#建立 physical volume</span>
block1<span class="hljs-comment"># pvcreate /dev/sdc</span>
Physical volume <span class="hljs-string">"/dev/sdc"</span> successfully created
<span class="hljs-comment">#建立 logical volume</span>
block1<span class="hljs-comment"># vgcreate cinder-volumes /dev/sdb /dev/sdc</span>
Volume group <span class="hljs-string">"cinder-volumes"</span> successfully created</code></pre>
<p>修改設定檔 <strong>/etc/lvm/lvm.conf</strong>,確認 filter 設定有包含上述的 /dev/sdb & /dev/sdc:</p>
<pre class="prettyprint"><code class=" hljs vala"><span class="hljs-preprocessor">#預設是允許所有 device</span>
filter = [ <span class="hljs-string">"a/.*/"</span> ]</code></pre>
<p>最後確認 PV & LV 的狀態:</p>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment">#physical volume 狀態</span>
block1<span class="hljs-comment"># # pvdisplay</span>
--- Physical volume ---
PV Name /dev/sdb
VG Name cinder-volumes
PV Size <span class="hljs-number">16.00</span> GiB / not usable <span class="hljs-number">4.00</span> MiB
Allocatable yes
PE Size <span class="hljs-number">4.00</span> MiB
Total PE <span class="hljs-number">4095</span>
Free PE <span class="hljs-number">4095</span>
Allocated PE <span class="hljs-number">0</span>
PV UUID peJ31b-ef8x-<span class="hljs-number">2</span>x60-<span class="hljs-number">3</span>uZS-ovGA<span class="hljs-operator">-d</span>TLb-<span class="hljs-number">1</span>WfpBL
--- Physical volume ---
PV Name /dev/sdc
VG Name cinder-volumes
PV Size <span class="hljs-number">16.00</span> GiB / not usable <span class="hljs-number">4.00</span> MiB
Allocatable yes
PE Size <span class="hljs-number">4.00</span> MiB
Total PE <span class="hljs-number">4095</span>
Free PE <span class="hljs-number">4095</span>
Allocated PE <span class="hljs-number">0</span>
PV UUID <span class="hljs-number">191</span>rYU-Tfdp-<span class="hljs-number">7</span>Sop-x76M-o1cn-F4Mp-S7QhoF
<span class="hljs-comment">#logical volume 狀態</span>
block1<span class="hljs-comment"># vgdisplay</span>
--- Volume group ---
VG Name cinder-volumes
System ID
Format lvm2
Metadata Areas <span class="hljs-number">2</span>
Metadata Sequence No <span class="hljs-number">1</span>
VG Access <span class="hljs-built_in">read</span>/write
VG Status resizable
MAX LV <span class="hljs-number">0</span>
Cur LV <span class="hljs-number">0</span>
Open LV <span class="hljs-number">0</span>
Max PV <span class="hljs-number">0</span>
Cur PV <span class="hljs-number">2</span>
Act PV <span class="hljs-number">2</span>
VG Size <span class="hljs-number">31.99</span> GiB
PE Size <span class="hljs-number">4.00</span> MiB
Total PE <span class="hljs-number">8190</span>
Alloc PE / Size <span class="hljs-number">0</span> / <span class="hljs-number">0</span>
Free PE / Size <span class="hljs-number">8190</span> / <span class="hljs-number">31.99</span> GiB
VG UUID ii5kLD-<span class="hljs-number">8</span>K94-wqZw-W1CN-nqSq-tLkW-<span class="hljs-number">0</span>l74oZ</code></pre>
<p>若想更了解 LVM,可參考「<a href="http://blog.nuface.tw/?p=1267">紐菲斯的部落格 » 好用的Linux LVM 管理</a>」一文。</p>
<h2 id="54-安裝-設定-block-storage-service">5.4 安裝 & 設定 Block Storage service</h2>
<h3 id="541-安裝套件">5.4.1 安裝套件</h3>
<p>除了 <strong>cinder-volume</strong> 要裝之外,<strong>python-mysqldb</strong> 也別忘記裝了,否則 cinder-volume service 無法與 controller 的 MySQL service 互動</p>
<pre class="prettyprint"><code class="language-bash hljs ">block1<span class="hljs-comment"># apt-get install cinder-volume python-mysqldb</span></code></pre>
<h3 id="542-設定檔調整">5.4.2 設定檔調整</h3>
<p>修改設定檔 <strong>/etc/cinder/cinder.conf</strong>,要加入的設定包含四個部分,分別是:</p>
<ol>
<li>Identity Service(Keystone)、</li>
<li>Message Broker (RabbitMQ)</li>
<li>Database</li>
<li>Image Service (Glance)</li>
</ol>
<p>加入的設定內容如下:</p>
<pre class="prettyprint"><code class=" hljs makefile"><span class="hljs-comment">#Identity Service (Keystone)</span>
[keystone_authtoken]
<span class="hljs-constant">auth_uri</span> = http://controller:5000
<span class="hljs-constant">auth_host</span> = controller
<span class="hljs-constant">auth_port</span> = 35357
<span class="hljs-constant">auth_protocol</span> = http
<span class="hljs-constant">admin_tenant_name</span> = service
<span class="hljs-constant">admin_user</span> = cinder
<span class="hljs-constant">admin_password</span> = CINDER_PASSWORD
<span class="hljs-comment">#Message Broker (RabbitMQ)</span>
[DEFAULT]
<span class="hljs-constant">rpc_backend</span> = rabbit
<span class="hljs-constant">rabbit_host</span> = controller
<span class="hljs-constant">rabbit_port</span> = 5672
<span class="hljs-constant">rabbit_userid</span> = guest
<span class="hljs-constant">rabbit_password</span> = YOUR_RABBITMQ_PASS
<span class="hljs-comment">#Database</span>
[database]
<span class="hljs-constant">connection</span> = mysql://cinder:YOUR_CINDER_DBPASSWORD@controller/cinder
<span class="hljs-comment">#Image Service(Glance)</span>
[DEFAULT]
<span class="hljs-constant">glance_host</span> = controller</code></pre>
<p>最後啟動相關服務即可:</p>
<pre class="prettyprint"><code class="language-bash hljs ">block1<span class="hljs-comment"># service cinder-volume restart</span>
block1<span class="hljs-comment"># service tgt restart</span></code></pre>
<h1 id="6驗證安裝是否成功">6、驗證安裝是否成功</h1>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># source ~/OpenStack/demo-openrc.sh</span>
controller<span class="hljs-comment"># cinder create --display-name myVolume 1</span>
+---------------------+--------------------------------------+
| Property | Value |
+---------------------+--------------------------------------+
| attachments | [] |
| availability_zone | nova |
| bootable | <span class="hljs-literal">false</span> |
| created_at | <span class="hljs-number">2014</span>-<span class="hljs-number">10</span>-<span class="hljs-number">07</span>T21:<span class="hljs-number">19</span>:<span class="hljs-number">50.061350</span> |
| display_description | None |
| display_name | myVolume |
| encrypted | False |
| id | d92f805d-<span class="hljs-number">7</span>bdb-<span class="hljs-number">4280</span>-<span class="hljs-number">80</span>c1-ba562de405cc |
| metadata | {} |
| size | <span class="hljs-number">1</span> |
| snapshot_id | None |
| <span class="hljs-built_in">source</span>_volid | None |
| status | creating |
| volume_<span class="hljs-built_in">type</span> | None |
+---------------------+--------------------------------------+
<span class="hljs-comment">#顯示剛剛建立的 volume 資訊,若是看到 available 就表示成功囉!</span>
controller<span class="hljs-comment"># cinder list</span>
+--------------------------------------+-----------+--------------+------+-------------+----------+-------------+
| ID | Status | Display Name | Size | Volume Type | Bootable | Attached to |
+--------------------------------------+-----------+--------------+------+-------------+----------+-------------+
| d92f805d-<span class="hljs-number">7</span>bdb-<span class="hljs-number">4280</span>-<span class="hljs-number">80</span>c1-ba562de405cc | available | myVolume | <span class="hljs-number">1</span> | None | <span class="hljs-literal">false</span> | |
+--------------------------------------+-----------+--------------+------+-------------+----------+-------------+</code></pre>
<p>登入 Horizon 之後同樣也可以看的到: <br>
<img src="https://lh4.googleusercontent.com/gXAKf0MEE6J4NQ7SA2SZ2oVXRSQv54--OKtsGwyzL3I=w1028-h504-no" alt="Project - Volumes" title=""></p>
<h1 id="7-障礙排除">7. 障礙排除</h1>
<p>一開始按照官網文件設定好時,建立好的 volume 的狀態都是 error,於是檢查了一下位於 <font color="red"><strong>controller</strong></font> 上的 log 資訊 (<strong>/var/log/cinder/cinder-scheduler.log</strong>),出現以下訊息:</p>
<blockquote>
<p>2014-10-07 21:51:51.378 16282 INFO oslo.messaging._drivers.impl_rabbit [req-a51641a5-f260-4540-86f1-88afe19d796f - - - - -] Reconnecting to AMQP server on localhost:5672 <br>
2014-10-07 21:51:51.379 16282 INFO oslo.messaging._drivers.impl_rabbit [req-a51641a5-f260-4540-86f1-88afe19d796f - - - - -] Delaying reconnect for 1.0 seconds… <br>
2014-10-07 21:51:55.393 16282 ERROR oslo.messaging._drivers.impl_rabbit [req-a51641a5-f260-4540-86f1-88afe19d796f - - - - -] AMQP server on localhost:5672 is unreachable: Socket closed. Trying again in 30 seconds. <br>
2014-10-07 21:52:25.420 16282 INFO oslo.messaging._drivers.impl_rabbit [req-a51641a5-f260-4540-86f1-88afe19d796f - - - - -] Reconnecting to AMQP server on localhost:5672 <br>
2014-10-07 21:52:25.420 16282 INFO oslo.messaging._drivers.impl_rabbit [req-a51641a5-f260-4540-86f1-88afe19d796f - - - - -] Delaying reconnect for 1.0 seconds… <br>
2014-10-07 21:52:29.440 16282 ERROR oslo.messaging._drivers.impl_rabbit [req-a51641a5-f260-4540-86f1-88afe19d796f - - - - -] AMQP server on localhost:5672 is unreachable: Socket closed. Trying again in 30 seconds. <br>
2014-10-07 21:52:41.508 16282 INFO cinder.openstack.common.service [-] Caught SIGTERM, exiting <br>
2014-10-07 21:52:42.284 8458 AUDIT cinder.service [-] Starting cinder-scheduler node (version 2014.1.2) <br>
2014-10-07 21:52:42.299 8458 INFO oslo.messaging._drivers.impl_rabbit [req-8e0f3895-d447-4f27-a3b4-f5789f02b9f8 - - - - -] Connected to AMQP server on controller:5672 <br>
2014-10-07 21:52:43.055 8458 INFO oslo.messaging._drivers.impl_rabbit [-] Connected to AMQP server on controller:5672 <br>
2014-10-07 21:52:58.305 8458 WARNING cinder.context [-] Arguments dropped when creating context: {‘user’: u’bc1ae50e167f45edb064e582702c5792’, ‘tenant’: u’7539436331ca4f9783bf93163e2a2e0f’, ‘user_identity’: u’bc1ae50e167f45edb064e582702c5792 7539436331ca4f9783bf93163e2a2e0f - - -‘} <br>
2014-10-07 21:52:58.399 8458 ERROR cinder.scheduler.flows.create_volume [req-6c3a8fac-3f20-46d5-bd59-a7689bca561f bc1ae50e167f45edb064e582702c5792 7539436331ca4f9783bf93163e2a2e0f - - -] <strong>Failed to schedule_create_volume: No valid host was found.</strong></p>
</blockquote>
<p>從上述資訊可知,cinder-scheduler 服務找不到提供 cinder-volume service 的 node,因此朝向 <strong>block1 主機沒有正確的加入 OpenStack 環境中</strong>的方向來尋找問題。</p>
<p>於是到 <font color="red"><strong>block1</strong></font> 主機上檢查 Log (<strong>/var/log/cinder/cinder-volume.log </strong>),出現以下錯誤訊息:</p>
<pre class="prettyprint"><code class=" hljs css">2014<span class="hljs-tag">-10-08</span> 05<span class="hljs-pseudo">:15</span><span class="hljs-pseudo">:04</span><span class="hljs-class">.936</span> 6422 <span class="hljs-tag">ERROR</span> <span class="hljs-tag">cinder</span><span class="hljs-class">.openstack</span><span class="hljs-class">.common</span><span class="hljs-class">.threadgroup</span> <span class="hljs-attr_selector">[-]</span> <span class="hljs-tag">No</span> <span class="hljs-tag">module</span> <span class="hljs-tag">named</span> <span class="hljs-tag">MySQLdb</span>
2014<span class="hljs-tag">-10-08</span> 05<span class="hljs-pseudo">:15</span><span class="hljs-pseudo">:06</span><span class="hljs-class">.388</span> 6432 <span class="hljs-tag">ERROR</span> <span class="hljs-tag">cinder</span><span class="hljs-class">.openstack</span><span class="hljs-class">.common</span><span class="hljs-class">.threadgroup</span> <span class="hljs-attr_selector">[-]</span> <span class="hljs-tag">No</span> <span class="hljs-tag">module</span> <span class="hljs-tag">named</span> <span class="hljs-tag">MySQLdb</span>
2014<span class="hljs-tag">-10-08</span> 05<span class="hljs-pseudo">:15</span><span class="hljs-pseudo">:06</span><span class="hljs-class">.842</span> 6442 <span class="hljs-tag">ERROR</span> <span class="hljs-tag">cinder</span><span class="hljs-class">.openstack</span><span class="hljs-class">.common</span><span class="hljs-class">.threadgroup</span> <span class="hljs-attr_selector">[-]</span> <span class="hljs-tag">No</span> <span class="hljs-tag">module</span> <span class="hljs-tag">named</span> <span class="hljs-tag">MySQLdb</span>
2014<span class="hljs-tag">-10-08</span> 05<span class="hljs-pseudo">:15</span><span class="hljs-pseudo">:08</span><span class="hljs-class">.290</span> 6452 <span class="hljs-tag">ERROR</span> <span class="hljs-tag">cinder</span><span class="hljs-class">.openstack</span><span class="hljs-class">.common</span><span class="hljs-class">.threadgroup</span> <span class="hljs-attr_selector">[-]</span> <span class="hljs-tag">No</span> <span class="hljs-tag">module</span> <span class="hljs-tag">named</span> <span class="hljs-tag">MySQLdb</span>
2014<span class="hljs-tag">-10-08</span> 05<span class="hljs-pseudo">:15</span><span class="hljs-pseudo">:08</span><span class="hljs-class">.734</span> 6462 <span class="hljs-tag">ERROR</span> <span class="hljs-tag">cinder</span><span class="hljs-class">.openstack</span><span class="hljs-class">.common</span><span class="hljs-class">.threadgroup</span> <span class="hljs-attr_selector">[-]</span> <span class="hljs-tag">No</span> <span class="hljs-tag">module</span> <span class="hljs-tag">named</span> <span class="hljs-tag">MySQLdb</span>
2014<span class="hljs-tag">-10-08</span> 05<span class="hljs-pseudo">:15</span><span class="hljs-pseudo">:10</span><span class="hljs-class">.183</span> 6472 <span class="hljs-tag">ERROR</span> <span class="hljs-tag">cinder</span><span class="hljs-class">.openstack</span><span class="hljs-class">.common</span><span class="hljs-class">.threadgroup</span> <span class="hljs-attr_selector">[-]</span> <span class="hljs-tag">No</span> <span class="hljs-tag">module</span> <span class="hljs-tag">named</span> <span class="hljs-tag">MySQLdb</span></code></pre>
<p>看起來是少裝了 python 與 MySQL 相關的 package,找了一下網路資料,原來要補裝 <font color="blue"><strong>python-mysqldb</strong></font>,所以只要在 <font color="red"><strong>block1</strong></font> 主機上補裝這個套件,再重新啟動 cinder-volume 服務即可。</p>
<blockquote>
<p>前面的安裝過程中已經補上,如果按照前面操作下來,應該是不會遇到跟我相同的錯誤。</p>
</blockquote>
<h1 id="8參考資料">8、參考資料</h1>
<ul>
<li><p><a href="http://docs.openstack.org/icehouse/install-guide/install/apt/content/ch_cinder.html">Chapter 9. Add the Block Storage service - OpenStack Installation Guide for Ubuntu 12.04/14.04 (LTS) - icehouse</a></p></li>
<li><p><a href="https://tw.pycon.org/2013/site_media/media/proposal_files/cinder_2013.pdf">OpenStack Cinder Tutorial(工業技術研究院 康佳峰)</a></p></li>
<li><p><a href="http://blog.nuface.tw/?p=1267">紐菲斯的部落格 » 好用的Linux LVM 管理</a></p></li>
</ul></div></body>
</html>曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-18435877003030585332014-10-05T11:02:00.001+08:002014-10-05T11:02:19.491+08:00安裝 OpenStack @ Ubuntu 14.04 (7) - 安裝 Dashboard (Horizon)<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>安裝 OpenStack @ Ubuntu 14.04 (7) - 安裝 Dashboard (Horizon)</title>
<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body><div class="container"><h1 id="目錄">目錄</h1>
<p><div class="toc"><div class="toc">
<ul>
<li><a href="#目錄">目錄</a></li>
<li><a href="#1安裝環境說明">1、安裝環境說明</a></li>
<li><a href="#2前言">2、前言</a></li>
<li><a href="#3安裝需求">3、安裝需求</a></li>
<li><a href="#4安裝-dashboard-horizon">4、安裝 Dashboard (Horizon)</a><ul>
<li><a href="#41-安裝相關套件">4.1 安裝相關套件</a></li>
<li><a href="#42-檢查-horizone-設定">4.2 檢查 Horizone 設定</a></li>
<li><a href="#43-設定可存取-horizon-的清單">4.3 設定可存取 Horizon 的清單</a></li>
<li><a href="#44-啟動相關服務">4.4 啟動相關服務</a></li>
</ul>
</li>
<li><a href="#5登入-horizon">5、登入 Horizon</a><ul>
<li><a href="#51-登入畫面">5.1 登入畫面</a></li>
<li><a href="#52-系統畫面">5.2 系統畫面:</a></li>
</ul>
</li>
<li><a href="#6參考資料">6、參考資料</a></li>
</ul>
</div>
</div>
</p>
<h1 id="1安裝環境說明">1、安裝環境說明</h1>
<ul>
<li><p>OS:Ubuntu 14.04 LTS</p></li>
<li><p>Controller</p>
<ul><li>IP:<strong>10.0.0.11</strong> / 24</li>
<li>Gateway:10.0.0.1</li></ul></li>
<li><p>Network <br>
</p><ul><li>Management IP:<strong>10.0.0.21</strong> / 24 (<strong>eth0</strong>)</li>
<li>Gateway:10.0.0.1</li>
<li>Instance Tunnel IP:10.0.1.21 / 24 (<strong>eth1</strong>)</li>
<li>External Interface (<strong>eth2</strong>) <br>
<ul><li>IP:不指定 IP </li>
<li>設定方式如下:(修改 <strong>/etc/network/interfaces</strong>) <br></li></ul></li></ul><p></p>
<blockquote>
<p>auto eth2 <br>
iface eth2 inet manual <br>
up ip link set dev <span>$</span>IFACE up <br>
down ip link set dev <span>$</span>IFACE down</p></blockquote></li></ul>
<li><p>Compute 1</p>
<ul><li>Management IP:<strong>10.0.0.31</strong> / 24</li>
<li>Gateway:10.0.0.1</li>
<li>Instance Tunnel IP:10.0.1.31</li></ul></li>
<p>修改每個 node 的 /etc/hosts 檔案,並加入以下內容:</p>
<blockquote>
<p>10.0.0.11 controller <br>
10.0.0.21 network <br>
10.0.0.31 compute1</p>
</blockquote>
<ul>
<li>使用者身分:root</li>
</ul>
<h1 id="2前言">2、前言</h1>
<p>首先來看一下官網對 Horizon(Dashboard) 的定義:</p>
<blockquote>
<p>OpenStack Dashboard (Horizon) provides administrators and users a graphical interface to access, provision and automate cloud-based resources. The design allows for third party products and services, such as billing, monitoring and additional management tools. Service providers and other commercial vendors can customize the dashboard with their own brand.</p>
<p>The dashboard is just one way to interact with OpenStack resources. Developers can automate access or build tools to manage their resources using the native OpenStack API or the EC2 compatibility API.</p>
</blockquote>
<p>簡單來說,Horizon 就是提供使用者可以透過圖形介面(網頁)簡單的管理雲端資源,加入 third-party 的特殊管理功能,還可以自由客製化成任何想要的樣子。</p>
<p>當然透過 Horizon 操作只是其中一個管理 & 使用 OpenStack 資源的方式,也可以透過直接下指令,甚至可以自行開發程式來呼叫相關 API 達成所需功能。</p>
<p>畢竟,OpenStack 上所有的 service 都是以 REST API-based 來提供服務的。</p>
<h1 id="3安裝需求">3、安裝需求</h1>
<p>安裝 Horizon 之前,有幾項需求必須達成:</p>
<ol>
<li>Compute Service(Nova) & Identity Service(Keystone) 必須安裝完成。 (若有按照之前的介紹安裝,此時應該會有 Nova & Keystone)</li>
<li>必須使用擁有 sudo 權限的使用者來執行 Horizon。 (我們預設使用 root,所以沒問題)</li>
<li>Python 版本為 2.6 or 2.7 且必須支援 Dajango。(我們這邊使用 Ubuntu 14.04,所以也沒問題)</li>
</ol>
<p>官網安裝文件要求 Horizon 必須安裝到可以連到 Keystone 的地方,<font color="blue"><strong>因此文中的示範會將 Horizon 安裝到 controller 上</strong></font>。</p>
<blockquote>
<p>目前 Keystone 服務也正是安裝在 controller 上。</p>
</blockquote>
<h1 id="4安裝-dashboard-horizon">4、安裝 Dashboard (Horizon)</h1>
<p>安裝 Horizon 包含了五個步驟:</p>
<ol>
<li>安裝相關套件</li>
<li>檢查 Horizone 設定</li>
<li>設定可存取 Horizon 的清單</li>
<li>啟動相關服務</li>
</ol>
<h2 id="41-安裝相關套件">4.1 安裝相關套件</h2>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment">#安裝相關套件</span>
controller<span class="hljs-comment"># apt-get -y install apache2 memcached libapache2-mod-wsgi openstack-dashboard</span>
<span class="hljs-comment">#移除會造成特殊問題的 theme 套件</span>
controller<span class="hljs-comment"># apt-get remove --purge openstack-dashboard-ubuntu-theme</span></code></pre>
<h2 id="42-檢查-horizone-設定">4.2 檢查 Horizone 設定</h2>
<ol>
<li><p>確認 <strong>/etc/openstack-dashboard/local_settings.py</strong> 中的 <font color="blue"><strong>CACHES[‘default’][‘LOCATION’]</strong></font>,是否與 <strong>/etc/memcached.conf</strong> 中的設定是否一致。</p></li>
<li><p>修改 <strong>/etc/openstack-dashboard/local_settings.py</strong>,設定如下:</p></li>
</ol>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment">#指定安裝 Identity Service(Keystone) 的 hostname 給 OPENSTACK_HOST 參數</span>
OPENSTACK_HOST = <span class="hljs-string">"controller"</span></code></pre>
<h2 id="43-設定可存取-horizon-的清單">4.3 設定可存取 Horizon 的清單</h2>
<p>檢查 <strong>/etc/openstack-dashboard/local_settings.py</strong> 中的 <font color="blue"><strong>ALLOWED_HOSTS</strong></font>,確認你所要用來連到 Horizone 的機器有包含在內。</p>
<blockquote>
<p>預設為 ALLOWED_HOSTS = “*”,表示所有機器都可以連到 Horizon。</p>
</blockquote>
<h2 id="44-啟動相關服務">4.4 啟動相關服務</h2>
<p>若以上設定檔有任何修改,則重啟以下服務:</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># service apache2 restart</span>
controller<span class="hljs-comment"># service memcached restart</span></code></pre>
<h1 id="5登入-horizon">5、登入 Horizon</h1>
<h2 id="51-登入畫面">5.1 登入畫面</h2>
<p>若按照之前的設定到這邊,可選擇 <strong>admin</strong> 或是 <strong>demo</strong> 登入。</p>
<p><img src="https://lh5.googleusercontent.com/22k1xplzzrw0QT7u_L3SgBcSYIgPj-N3F3rXztTsoLk=w519-h635-no" alt="OpenStack 登入畫面" title=""></p>
<h2 id="52-系統畫面">5.2 系統畫面:</h2>
<p>管理員 >> 系統面板 >> 概觀 <br>
<img src="https://lh6.googleusercontent.com/63jhtq3MwEafZZ9aZxT9oRtKI6jdmD12rOTFg0mnlN4=w906-h736-no" alt="Horizon >>管理員 >> 系統面板 >> 概觀" title=""></p>
<p>管理員 >> 系統面板 >> 虛擬機器管理程式 <br>
<img src="https://lh4.googleusercontent.com/-JLdEPP6gYLU/VDCuNHsrcfI/AAAAAAAAJqs/M3YhqhKT6nM/w906-h736-no/Horizon_2.png" alt="Horizon >> 管理員 >> 系統面板 >> 虛擬機器管理程式" title=""></p>
<p>管理員 >> 系統面板 >> 主機聚合 <br>
<img src="https://lh5.googleusercontent.com/-oYAoRr0Od8Y/VDCuNYjZuiI/AAAAAAAAJqM/gIBEYXIRSc4/w906-h736-no/Horizon_3.png" alt="Horizon >> 管理員 >> 系統面板 >> 主機聚合" title=""></p>
<p>管理員 >> 系統面板 >> 執行實例 <br>
<img src="https://lh3.googleusercontent.com/-Jhx8F3We8TM/VDCuN6uX4ZI/AAAAAAAAJrE/9hQAhWSo6nM/w1078-h430-no/Horizon_4.png" alt="Horizon >> 管理員 >> 系統面板 >> 執行實例" title=""></p>
<p>管理員 >> 系統面板 >> 虛擬硬體樣板 <br>
<img src="https://lh3.googleusercontent.com/-73sPjwNffQw/VDCuOCXWfjI/AAAAAAAAJqc/kfsueLzeFB8/w1078-h681-no/Horizon_5.png" alt="Horizon >> 管理員 >> 系統面板 >> 虛擬硬體樣板" title=""></p>
<p>管理員 >> 系統面板 >> 映像檔 <br>
<img src="https://lh5.googleusercontent.com/-TlX6DdDVeVo/VDCuOWZephI/AAAAAAAAJqk/kuWS4QlLlbs/w1078-h695-no/Horizon_6.png" alt="Horizon >> 管理員 >> 系統面板 >> 映像檔" title=""></p>
<p>管理員 >> 系統面板 >> 網路 <br>
<img src="https://lh5.googleusercontent.com/-clhyk3pI-ec/VDCuO5JKLII/AAAAAAAAJqw/sIc2juw-w10/w1078-h695-no/Horizon_7.png" alt="Horizon >> 管理員 >> 系統面板 >> 網路" title=""></p>
<p>管理員 >> 系統面板 >> 路由器 <br>
<img src="https://lh3.googleusercontent.com/--PLG9lEq7EM/VDCuPIDbeVI/AAAAAAAAJq4/AcLYbXf-s9c/w1078-h695-no/Horizon_8.png" alt="Horizon >> 管理員 >> 系統面板 >> 路由器" title=""></p>
<p>管理員 >> 系統面板 >> 系統資訊(伺服機) <br>
<img src="https://lh5.googleusercontent.com/-mR4-JiIGFmg/VDCuPv81VaI/AAAAAAAAJrA/XBUb-GgG2_M/w1078-h695-no/Horizon_9.png" alt="Horizon >> 管理員 >> 系統面板 >> 系統資訊" title=""></p>
<p>管理員 >> 系統面板 >> 系統資訊(運算伺服機) <br>
<img src="https://lh6.googleusercontent.com/-0y0-pPWLhes/VDCuMJ--AEI/AAAAAAAAJp0/QyyBzG1KBWs/w1078-h695-no/Horizon_10.png" alt="Horizon >> 管理員 >> 系統面板 >> 系統資訊" title=""></p>
<p>管理員 >> 系統面板 >> 系統資訊(網路代理) <br>
<img src="https://lh5.googleusercontent.com/-k5MSnzHiCvc/VDCuMBP9MpI/AAAAAAAAJp4/1-iWGfJkxIY/w1078-h695-no/Horizon_11.png" alt="Horizon >> 管理員 >> 系統面板 >> 系統資訊" title=""></p>
<p>管理員 >> 身分面板 >> 虛擬私人網路連線 <br>
<img src="https://lh3.googleusercontent.com/-K8sERwxx4Aw/VDCuMI59xSI/AAAAAAAAJqE/BhYaBXAIIIU/w1078-h479-no/Horizon_12.png" alt="Horizon >> 管理員 >> 身分面板 >> 虛擬私人網路連線" title=""></p>
<p>管理員 >> 身分面板 >> 使用者 <br>
<img src="https://lh3.googleusercontent.com/-i2PBJGjE5bA/VDCuMwqVZHI/AAAAAAAAJqY/sRV3TP4Tmhw/w995-h660-no/Horizon_13.png" alt="Horizon >> 管理員 >> 身分面板 >> 使用者" title=""></p>
<h1 id="6參考資料">6、參考資料</h1>
<ul>
<li><a href="http://docs.openstack.org/icehouse/install-guide/install/apt/content/ch_horizon.html">Chapter 8. Add the dashboard - OpenStack Installation Guide for Ubuntu 12.04/14.04 (LTS) - icehouse</a></li>
</ul></div></body>
</html>曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-79927669707678542572014-10-05T07:04:00.001+08:002014-10-05T09:31:37.603+08:00OpenStack 障礙排除 - VM 無法正常啟動 (No valid host was found)<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>OpenStack 障礙排除 - VM 無法正常啟動 (No valid host was found)</title>
<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body><div class="container"><h1 id="目錄">目錄</h1>
<p><div class="toc"><div class="toc">
<ul>
<li><a href="#目錄">目錄</a></li>
<li><a href="#1障礙說明">1、障礙說明</a></li>
<li><a href="#2檢查過程">2、檢查過程</a><ul>
<li><a href="#21-檢查-controller-node">2.1 檢查 Controller node</a><ul>
<li><a href="#211-查詢-nova-錯誤訊息">2.1.1 查詢 nova 錯誤訊息:</a></li>
<li><a href="#212-查詢-etcnovanova-apilog">2.1.2 查詢 /etc/nova/nova-api.log</a></li>
<li><a href="#213-查詢-nova-db">2.1.3 查詢 Nova DB</a></li>
</ul>
</li>
<li><a href="#22-檢查-compute-node">2.2 檢查 Compute node</a><ul>
<li><a href="#221-查詢-etcnovanova-computelog">2.2.1 查詢 /etc/nova/nova-compute.log</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#3解決方式">3、解決方式</a></li>
<li><a href="#4參考資料">4、參考資料</a></li>
</ul>
</div>
</div>
</p>
<h1 id="1障礙說明">1、障礙說明</h1>
<p>昨天按照著官方網站的安裝手冊將 Neutron 安裝好之後,準備要來啟動第一個在 OpenStack 上的 VM,結果下完 nova boot xxxxxxx 的指令之後,我檢查了一下 VM 狀態,發現 status ERROR:</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># nova list</span>
+--------------------------------------+----------------+--------+------------+-------------+----------+
| ID | Name | Status | Task State | Power State | Networks |
+--------------------------------------+----------------+--------+------------+-------------+----------+
| b7eb4c0f-ef39-<span class="hljs-number">4034</span>-b4a9-<span class="hljs-number">1</span>d9f7f90b553 | demo-instance1 | ERROR | - | NOSTATE | |
+--------------------------------------+----------------+--------+------------+-------------+----------+</code></pre>
<h1 id="2檢查過程">2、檢查過程</h1>
<h2 id="21-檢查-controller-node">2.1 檢查 Controller node</h2>
<h3 id="211-查詢-nova-錯誤訊息">2.1.1 查詢 nova 錯誤訊息:</h3>
<pre class="prettyprint"><code class="language-bash hljs "> nova show demo-instance1
+--------------------------------------+------------------------------------------------------------------------------------------------------------------------+
| Property | Value |
+--------------------------------------+------------------------------------------------------------------------------------------------------------------------+
| OS-DCF:diskConfig | MANUAL |
| OS-EXT-AZ:availability_zone | nova |
| OS-EXT-STS:power_state | <span class="hljs-number">0</span> |
| OS-EXT-STS:task_state | - |
| OS-EXT-STS:vm_state | error |
| OS-SRV-USG:launched_at | - |
| OS-SRV-USG:terminated_at | - |
| accessIPv4 | |
| accessIPv6 | |
| config_drive | |
| created | <span class="hljs-number">2014</span>-<span class="hljs-number">10</span>-<span class="hljs-number">04</span>T13:<span class="hljs-number">56</span>:<span class="hljs-number">37</span>Z |
| fault | {<span class="hljs-string">"message"</span>: <span class="hljs-string">"No valid host was found."</span>, <span class="hljs-string">"code"</span>: <span class="hljs-number">500</span>, <span class="hljs-string">"created"</span>: <span class="hljs-string">"2014-10-03T09:50:40Z"</span>} |
| flavor | m1.tiny (<span class="hljs-number">1</span>) |
| hostId | |
| id | b7eb4c0f-ef39-<span class="hljs-number">4034</span>-b4a9-<span class="hljs-number">1</span>d9f7f90b553 |
| image | cirros-<span class="hljs-number">0.3</span>.<span class="hljs-number">3</span>-x86_64 (<span class="hljs-number">77</span>c0d5f8-<span class="hljs-number">1</span>bcc-<span class="hljs-number">4937</span>-<span class="hljs-number">932</span>c-<span class="hljs-number">72</span>f4b0eccbc3) |
| key_name | demo-key |
| metadata | {} |
| name | demo-instance1 |
| os-extended-volumes:volumes_attached | [] |
| status | ERROR |
| tenant_id | <span class="hljs-number">7539436331</span>ca4f9783bf93163e2a2e0f |
| updated | <span class="hljs-number">2014</span>-<span class="hljs-number">10</span>-<span class="hljs-number">04</span>T22:<span class="hljs-number">44</span>:<span class="hljs-number">43</span>Z |
| user_id | bc1ae50e167f45edb064e582702c5792 |
+--------------------------------------+------------------------------------------------------------------------------------------------------------------------+</code></pre>
<h3 id="212-查詢-etcnovanova-apilog">2.1.2 查詢 /etc/nova/nova-api.log</h3>
<p>出現以下訊息:</p>
<blockquote>
<p>2014-10-04 13:56:38.074 1347 INFO nova.osapi_compute.wsgi.server [req-18fd79ad-0a01-48a0-b8f0-29fac56a5c09 bc1ae50e167f45edb064e582702c5792 7539436331ca4f9783bf93163e2a2e0f] 10.0.0.11 “GET /v2/7539436331ca4f9783bf93163e2a2e0f/images/77c0d5f8-1bcc-4937-932c-72f4b0eccbc3 HTTP/1.1” status: 200 len: 894 time: 0.4527042 <br>
2014-10-04 13:56:38.092 1347 INFO <strong>nova.api.openstack.wsgi [req-d508d2a8-4a70-46d6-b11e-e21da95224be bc1ae50e167f45edb064e582702c5792 7539436331ca4f9783bf93163e2a2e0f] HTTP exception thrown: The resource could not be found</strong>. <br>
2014-10-04 13:56:38.094 1347 INFO <strong>nova.osapi_compute.wsgi.server [req-d508d2a8-4a70-46d6-b11e-e21da95224be bc1ae50e167f45edb064e582702c5792 7539436331ca4f9783bf93163e2a2e0f] 10.0.0.11 “GET /v2/7539436331ca4f9783bf93163e2a2e0f/flavors/m1.tiny HTTP/1.1” status: 404</strong> len: 272 time: 0.0192289 <br>
2014-10-04 13:56:38.106 1347 INFO nova.osapi_compute.wsgi.server [req-9b6159e7-67ff-454e-a711-46c626354c7d bc1ae50e167f45edb064e582702c5792 7539436331ca4f9783bf93163e2a2e0f] 10.0.0.11 “GET /v2/7539436331ca4f9783bf93163e2a2e0f/flavors HTTP/1.1” status: 200 len: 1383 time: 0.0111101 <br>
2014-10-04 13:56:38.117 1347 INFO nova.osapi_compute.wsgi.server [req-a84e3545-5d20-456f-abad-5e8d5f7bc634 bc1ae50e167f45edb064e582702c5792 7539436331ca4f9783bf93163e2a2e0f] 10.0.0.11 “GET /v2/7539436331ca4f9783bf93163e2a2e0f/flavors HTTP/1.1” status: 200 len: 1383 time: 0.0103061 <br>
2014-10-04 13:56:38.130 1347 INFO nova.osapi_compute.wsgi.server [req-f5888737-0e2a-4c43-bffa-7f61479f3844 bc1ae50e167f45edb064e582702c5792 7539436331ca4f9783bf93163e2a2e0f] 10.0.0.11 “GET /v2/7539436331ca4f9783bf93163e2a2e0f/flavors/1 HTTP/1.1” status: 200 len: 591 time: 0.0125630</p>
</blockquote>
<h3 id="213-查詢-nova-db">2.1.3 查詢 Nova DB</h3>
<p>在 nova.instance_faults 裡面找到 error detail 為以下內容:</p>
<blockquote>
<p>File “/usr/lib/python2.7/dist-packages/nova/scheduler/filter_scheduler.py”, line 108, in schedule_run_instance <br>
raise exception.NoValidHost(reason=”“)</p>
</blockquote>
<p>可以研判是 nova schedular 找不到合適的 compute node 作為 host。</p>
<h2 id="22-檢查-compute-node">2.2 檢查 Compute node</h2>
<h3 id="221-查詢-etcnovanova-computelog">2.2.1 查詢 /etc/nova/nova-compute.log</h3>
<p>出現以下訊息:</p>
<blockquote>
<p>2014-10-04 13:56:11.489 18675 INFO oslo.messaging._drivers.impl_rabbit [-] Reconnecting to AMQP server on controller:5672 <br>
2014-10-04 13:56:11.489 18675 INFO oslo.messaging._drivers.impl_rabbit [-] Delaying reconnect for 1.0 seconds… <br>
2014-10-04 13:56:15.501 18675 ERROR oslo.messaging._drivers.impl_rabbit [-] <strong>AMQP server on controller:5672 is unreachable</strong>: Socket closed. Trying again in 5 seconds. <br>
2014-10-04 13:56:20.504 18675 INFO oslo.messaging._drivers.impl_rabbit [-] Reconnecting to AMQP server on controller:5672 <br>
2014-10-04 13:56:20.505 18675 INFO oslo.messaging._drivers.impl_rabbit [-] Delaying reconnect for 1.0 seconds… <br>
2014-10-04 13:56:24.520 18675 ERROR oslo.messaging._drivers.impl_rabbit [-] AMQP server on controller:5672 is unreachable: Socket closed. Trying again in 7 seconds. <br>
2014-10-04 13:56:31.525 18675 INFO oslo.messaging._drivers.impl_rabbit [-] Reconnecting to AMQP server on controller:5672 <br>
2014-10-04 13:56:31.525 18675 INFO oslo.messaging._drivers.impl_rabbit [-] Delaying reconnect for 1.0 seconds… <br>
2014-10-04 13:56:35.536 18675 ERROR oslo.messaging._drivers.impl_rabbit [-] AMQP server on controller:5672 is unreachable: Socket closed. Trying again in 9 seconds. <br>
……. (以下省略)</p>
</blockquote>
<p>從上面可以看出 compute node 無法與 RabbitMQ service 進行通訊。</p>
<p>另外從官網上找到一張圖,說明 Nova 在啟動 VM instance 的完整流程: <br>
<img src="http://docs.openstack.org/training-guides/content/figures/11/figures/image02.png" alt="Nova VM Provisioning" title=""></p>
<p><font color="red"><strong>問題就是出在 4~8 這一段,computer node 無法與 (queue)RabbitMQ service 進行通訊,因此無法向 nova-api 通知有可用的 compute node,因此 nova schedular 就找不到合適的 compute node 可用,也因此無法派送佈署的訊息給 queue。</strong></font></p>
<p>因為目前環境中只有一台 compute node 的情況下,Nova Scheduler 會找不到可以佈署 VM instance 的 compute node,因此會產生 Error。</p>
<h1 id="3解決方式">3、解決方式</h1>
<p>確認了 compute node 無法與 RabbitMQ 通訊後,首先檢查 <strong>/etc/nova/nova.conf</strong> 內的 RabbitMQ 帳號密碼設定是否正確。</p>
<p>結果發現原來密碼設定錯誤,難怪 compute node 一直無法與 RabbitMQ 通訊,修正後重新啟動 nova-compute 服務就可以正常佈署 VM 了!</p>
<h1 id="4參考資料">4、參考資料</h1>
<ul>
<li><p><a href="http://docs.openstack.org/training-guides/content/module001-ch010-vm-provisioning-indepth.html">Chapter 10. VM Provisioning Indepth - OpenStack Training Guides</a></p></li>
<li><p><a href="https://ask.openstack.org/en/question/9035/failed-to-scheduler_run_instance-no-valid-host-was-found/">Failed to scheduler_run_instance: No valid host was found [closed] - Ask OpenStack: Q&A Site for OpenStack Users and Developers</a></p></li>
<li><p><a href="https://ask.openstack.org/en/question/9486/no-valid-host-was-found/">No valid host was found - Ask OpenStack: Q&A Site for OpenStack Users and Developers</a></p></li>
<li><p><a href="https://ask.openstack.org/en/question/31488/failed-to-launch-instance-test-please-try-again-later-error-no-valid-host-was-found/">Failed to launch instance “test”: Please try again later [Error: No valid host was found. ]. [closed] - Ask OpenStack: Q&A Site for OpenStack Users and Developers</a></p></li>
</ul></div></body>
</html>曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-54836428285868501652014-10-04T12:42:00.001+08:002014-10-06T05:59:26.365+08:00安裝 OpenStack @ Ubuntu 14.04 (6) - 佈署第一個 VM<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>安裝 OpenStack @ Ubuntu 14.04 (6) - 佈署第一個 VM</title>
<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body><div class="container"><h1 id="目錄">目錄</h1>
<p><div class="toc"><div class="toc">
<ul>
<li><a href="#目錄">目錄</a></li>
<li><a href="#1安裝環境說明">1、安裝環境說明</a></li>
<li><a href="#2前言">2、前言</a></li>
<li><a href="#3產生金鑰對keypair">3、產生金鑰對(keypair)</a></li>
<li><a href="#4佈署-啟動第一台-vm">4、佈署 & 啟動第一台 VM</a><ul>
<li><a href="#41-flavor">4.1 flavor</a></li>
<li><a href="#42-映像檔">4.2 映像檔</a></li>
<li><a href="#43-網路">4.3 網路</a></li>
<li><a href="#44-security-group">4.4 Security Group</a></li>
<li><a href="#45-啟動-vm-instance">4.5 啟動 VM instance</a></li>
<li><a href="#46-確認-vm-狀態">4.6 確認 VM 狀態</a></li>
</ul>
</li>
<li><a href="#5存取-vm-instance-並測試">5、存取 VM instance 並測試</a></li>
<li><a href="#6問題排除">6、問題排除</a><ul>
<li><a href="#61-無法解析-domain-name">6.1 無法解析 domain name</a></li>
</ul>
</li>
<li><a href="#7參考資料">7、參考資料</a></li>
</ul>
</div>
</div>
</p>
<h1 id="1安裝環境說明">1、安裝環境說明</h1>
<ul>
<li><p>OS:Ubuntu 14.04 LTS</p></li>
<li><p>Controller</p>
<ul><li>IP:<strong>10.0.0.11</strong> / 24</li>
<li>Gateway:10.0.0.1</li></ul></li>
<li><p>Network <br>
</p><ul><li>Management IP:<strong>10.0.0.21</strong> / 24 (<strong>eth0</strong>)</li>
<li>Gateway:10.0.0.1</li>
<li>Instance Tunnel IP:10.0.1.21 / 24 (<strong>eth1</strong>)</li>
<li>External Interface (<strong>eth2</strong>) <br>
<ul><li>IP:不指定 IP </li>
<li>設定方式如下:(修改 <strong>/etc/network/interfaces</strong>) <br></li></ul></li></ul><p></p>
<blockquote>
<p>auto eth2 <br>
iface eth2 inet manual <br>
up ip link set dev <span>$</span>IFACE up <br>
down ip link set dev <span>$</span>IFACE down</p></blockquote></li></ul>
<li><p>Compute 1</p>
<ul><li>Management IP:<strong>10.0.0.31</strong> / 24</li>
<li>Gateway:10.0.0.1</li>
<li>Instance Tunnel IP:10.0.1.31</li></ul></li>
<p>修改每個 node 的 /etc/hosts 檔案,並加入以下內容:</p>
<blockquote>
<p>10.0.0.11 controller <br>
10.0.0.21 network <br>
10.0.0.31 compute1</p>
</blockquote>
<ul>
<li>使用者身分:root</li>
</ul>
<h1 id="2前言">2、前言</h1>
<p>截至目前為止,一共安裝了 OpenStack 的服務包含以下:</p>
<ol>
<li>Identity Service (<strong>Keystone</strong>)</li>
<li>Image Service (<strong>Glance</strong>)</li>
<li>Compute Service (<strong>Nova</strong>)</li>
<li>Networking Service (<strong>Neutron</strong>)</li>
</ol>
<p>若要啟動一個 VM instance,其實最少只要以上服務即可,接著以下來試著啟動一個 VM instance。</p>
<h1 id="3產生金鑰對keypair">3、產生金鑰對(keypair)</h1>
<p>大部分雲端系統支援公開金鑰認證(public key authentication)而並非簡單的帳號密碼認證,因此在啟動 VM instance 之前,我們要透過 <strong>ssh-keygen</strong> 工具來產生金鑰並加入 OpenStack 環境中使用。</p>
<blockquote>
<p>以下命令在 controller node 上執行</p>
</blockquote>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 以 demo 的身分執行</span>
controller<span class="hljs-comment"># source ~/OpenStack/demo-openrc.sh</span>
<span class="hljs-comment"># 產生金鑰對</span>
controller<span class="hljs-comment"># ssh-keygen</span>
<span class="hljs-comment"># 將產生的金鑰(公開)加入 OpenStack 環境中,並設定名稱為 demo-key</span>
controller<span class="hljs-comment"># nova keypair-add --pub-key /root/.ssh/id_rsa.pub demo-key</span>
<span class="hljs-comment"># 驗證公開金鑰是否已經匯入 OpenStack 環境中</span>
controller<span class="hljs-comment"># nova keypair-list</span>
+----------+-------------------------------------------------+
| Name | Fingerprint |
+----------+-------------------------------------------------+
| demo-key | <span class="hljs-number">61</span>:fe:<span class="hljs-number">66</span>:<span class="hljs-number">8</span>b:ee:dc:<span class="hljs-number">05</span>:c9:<span class="hljs-number">3</span>f:b0:<span class="hljs-number">7</span>f:c4:<span class="hljs-number">92</span>:<span class="hljs-number">34</span>:df:a6 |
+----------+-------------------------------------------------+</code></pre>
<h1 id="4佈署-啟動第一台-vm">4、佈署 & 啟動第一台 VM</h1>
<p>在開始佈署 VM instance 之前,有幾個部分是必須先確定的,包含 flavor(<strong>VM 的類型</strong>)、映像檔、網路、security group、公開金鑰、instance name …. 等等。</p>
<h2 id="41-flavor">4.1 flavor</h2>
<p>flavor 表示一群 VM 資源定義的集合,而定義中包含 VM 所使用的 vCPU 數量、記憶體大小、儲存空間 … 等資訊,以下列出目前預先定義好的 flavor 資訊:</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># nova flavor-list</span>
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| ID | Name | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| <span class="hljs-number">1</span> | m1.tiny | <span class="hljs-number">512</span> | <span class="hljs-number">1</span> | <span class="hljs-number">0</span> | | <span class="hljs-number">1</span> | <span class="hljs-number">1.0</span> | True |
| <span class="hljs-number">2</span> | m1.small | <span class="hljs-number">2048</span> | <span class="hljs-number">20</span> | <span class="hljs-number">0</span> | | <span class="hljs-number">1</span> | <span class="hljs-number">1.0</span> | True |
| <span class="hljs-number">3</span> | m1.medium | <span class="hljs-number">4096</span> | <span class="hljs-number">40</span> | <span class="hljs-number">0</span> | | <span class="hljs-number">2</span> | <span class="hljs-number">1.0</span> | True |
| <span class="hljs-number">4</span> | m1.large | <span class="hljs-number">8192</span> | <span class="hljs-number">80</span> | <span class="hljs-number">0</span> | | <span class="hljs-number">4</span> | <span class="hljs-number">1.0</span> | True |
| <span class="hljs-number">5</span> | m1.xlarge | <span class="hljs-number">16384</span> | <span class="hljs-number">160</span> | <span class="hljs-number">0</span> | | <span class="hljs-number">8</span> | <span class="hljs-number">1.0</span> | True |
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+</code></pre>
<p>從上表可以看到,flavor 的類型從 m1.tiny 到 m1.xlarge 都有,使用者可以根據需求決定要啟動的 VM instance 屬於哪種 flavor。</p>
<blockquote>
<p>以下範例我們將會以 <strong>m1.tiny</strong> 作示範。</p>
</blockquote>
<h2 id="42-映像檔">4.2 映像檔</h2>
<p>以下列出目前可用的映像檔:</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># nova image-list</span>
+--------------------------------------+---------------------+--------+--------+
| ID | Name | Status | Server |
+--------------------------------------+---------------------+--------+--------+
| <span class="hljs-number">0985</span>b2f3-<span class="hljs-number">058</span>e-<span class="hljs-number">4</span>ab9-<span class="hljs-number">84</span>e3-<span class="hljs-number">65</span>c51f849408 | cirros-<span class="hljs-number">0.3</span>.<span class="hljs-number">3</span>-x86_64 | ACTIVE | |
| <span class="hljs-number">77</span>c0d5f8-<span class="hljs-number">1</span>bcc-<span class="hljs-number">4937</span>-<span class="hljs-number">932</span>c-<span class="hljs-number">72</span>f4b0eccbc3 | cirros-<span class="hljs-number">0.3</span>.<span class="hljs-number">3</span>-x86_64 | ACTIVE | |
+--------------------------------------+---------------------+--------+--------+</code></pre>
<blockquote>
<p>以下範例我們將會以 ID 為 <strong>77c0d5f8-1bcc-4937-932c-72f4b0eccbc3</strong> 的映像檔作示範。</p>
</blockquote>
<h2 id="43-網路">4.3 網路</h2>
<p>以下列出可用的網路區段:</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># neutron net-list</span>
+--------------------------------------+----------+------------------------------------------------------+
| id | name | subnets |
+--------------------------------------+----------+------------------------------------------------------+
| <span class="hljs-number">629</span>c575d-<span class="hljs-number">5</span>d2e-<span class="hljs-number">4258</span>-bb96<span class="hljs-operator">-d</span>2def517aa04 | ext-net | <span class="hljs-number">4</span>af846a3-<span class="hljs-number">3</span>e14-<span class="hljs-number">450</span>d-b620-<span class="hljs-number">134</span>cb1479e0d <span class="hljs-number">192.168</span>.<span class="hljs-number">20.0</span>/<span class="hljs-number">24</span> |
| <span class="hljs-number">65</span>c99acc-<span class="hljs-number">6438</span>-<span class="hljs-number">493</span>e-bbde-b3c0def3f575 | demo-net | eb46a51b-c1b0-<span class="hljs-number">4</span>df9-<span class="hljs-number">9046</span><span class="hljs-operator">-a</span>19612fa532f <span class="hljs-number">192.168</span>.<span class="hljs-number">3.0</span>/<span class="hljs-number">24</span> |
+--------------------------------------+----------+------------------------------------------------------+</code></pre>
<blockquote>
<p>以下範例我們將會使用 <strong>demo-net(192.168.3.0/24)</strong> 作示範。</p>
</blockquote>
<h2 id="44-security-group">4.4 Security Group</h2>
<p>以下列出目前所有的 security group:</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># nova secgroup-list</span>
+--------------------------------------+---------+-------------+
| Id | Name | Description |
+--------------------------------------+---------+-------------+
| <span class="hljs-number">909</span>f974a-<span class="hljs-number">771</span>d-<span class="hljs-number">4087</span>-ae83-b6ed3aa88e56 | default | default |
+--------------------------------------+---------+-------------+</code></pre>
<p>因為我們先前沒有設定 security group,因此這邊只有 default 一項,而 default 這個群組的設定會阻擋所有來自遠端對 VM instance 的存取。</p>
<h2 id="45-啟動-vm-instance">4.5 啟動 VM instance</h2>
<p>所有必要條件都確認後,透過以下指令啟動 VM instance:</p>
<pre class="prettyprint"><code class="language-bash hljs ">nova boot --flavor m1.tiny --image <span class="hljs-number">77</span>c0d5f8-<span class="hljs-number">1</span>bcc-<span class="hljs-number">4937</span>-<span class="hljs-number">932</span>c-<span class="hljs-number">72</span>f4b0eccbc3 --nic net-id=<span class="hljs-number">65</span>c99acc-<span class="hljs-number">6438</span>-<span class="hljs-number">493</span>e-bbde-b3c0def3f575 --security-group default --key-name demo-key demo-instance1
+--------------------------------------+------------------------------------------------------------+
| Property | Value |
+--------------------------------------+------------------------------------------------------------+
| OS-DCF:diskConfig | MANUAL |
| OS-EXT-AZ:availability_zone | nova |
| OS-EXT-STS:power_state | <span class="hljs-number">0</span> |
| OS-EXT-STS:task_state | scheduling |
| OS-EXT-STS:vm_state | building |
| OS-SRV-USG:launched_at | - |
| OS-SRV-USG:terminated_at | - |
| accessIPv4 | |
| accessIPv6 | |
| adminPass | gzkYV2K7nsHc |
| config_drive | |
| created | <span class="hljs-number">2014</span>-<span class="hljs-number">10</span>-<span class="hljs-number">04</span>T04:<span class="hljs-number">21</span>:<span class="hljs-number">56</span>Z |
| flavor | m1.tiny (<span class="hljs-number">1</span>) |
| hostId | |
| id | <span class="hljs-number">29706374</span>-fa90-<span class="hljs-number">4082</span>-b51b-ca6a6cdf2a5e |
| image | cirros-<span class="hljs-number">0.3</span>.<span class="hljs-number">3</span>-x86_64 (<span class="hljs-number">77</span>c0d5f8-<span class="hljs-number">1</span>bcc-<span class="hljs-number">4937</span>-<span class="hljs-number">932</span>c-<span class="hljs-number">72</span>f4b0eccbc3) |
| key_name | demo-key |
| metadata | {} |
| name | demo-instance1 |
| os-extended-volumes:volumes_attached | [] |
| progress | <span class="hljs-number">0</span> |
| security_groups | default |
| status | BUILD |
| tenant_id | <span class="hljs-number">7539436331</span>ca4f9783bf93163e2a2e0f |
| updated | <span class="hljs-number">2014</span>-<span class="hljs-number">10</span>-<span class="hljs-number">04</span>T04:<span class="hljs-number">21</span>:<span class="hljs-number">56</span>Z |
| user_id | bc1ae50e167f45edb064e582702c5792 |
+--------------------------------------+------------------------------------------------------------+</code></pre>
<h2 id="46-確認-vm-狀態">4.6 確認 VM 狀態</h2>
<p>上述指令完成後,Nova Scheduler 會尋找合適的 compute node 將 VM instance 啟動,可以透過以下指令檢查一下目前 VM instance 的狀態:</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># nova list</span>
+--------------------------------------+----------------+--------+------------+-------------+----------------------+
| ID | Name | Status | Task State | Power State | Networks |
+--------------------------------------+----------------+--------+------------+-------------+----------------------+
| <span class="hljs-number">29706374</span>-fa90-<span class="hljs-number">4082</span>-b51b-ca6a6cdf2a5e | demo-instance1 | ACTIVE | - | Running | demo-net=<span class="hljs-number">192.168</span>.<span class="hljs-number">3.3</span> |
+--------------------------------------+----------------+--------+------------+-------------+----------------------+</code></pre>
<p>從上面可以看到 VM instance 的 ID、Network、Status、IP …. 等資訊。</p>
<h1 id="5存取-vm-instance-並測試">5、存取 VM instance 並測試</h1>
<p>因為我們在之前有設定 noVNC,可透過 browser 連線到目前運行中的 VM instance,可透過以下指令取得 noVNC 的連線網址:</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># nova get-vnc-console demo-instance1 novnc</span>
+-------+---------------------------------------------------------------------------------+
| Type | Url |
+-------+---------------------------------------------------------------------------------+
| novnc | http://controller:<span class="hljs-number">6080</span>/vnc_auto.html?token=<span class="hljs-number">9395</span>dcbd-b9e8-<span class="hljs-number">457</span>b-b6fe-c7e07a268ba9 |
+-------+---------------------------------------------------------------------------------+</code></pre>
<p>有了以上的網址後,就可以透過 browser 以 noVNC 的方式連線到 VM instance 內。</p>
<h1 id="6問題排除">6、問題排除</h1>
<h2 id="61-無法解析-domain-name">6.1 無法解析 domain name</h2>
<p>透過 noVNC 連線到剛佈署好的 VM 後,可以連到 internet,但 DNS 忘了設定…..導致於 domain name 無法解析,因此我們在 controller node 加入以下設定來解決:</p>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 顯示目前的 subnet</span>
controller<span class="hljs-comment"># neutron subnet-list</span>
+--------------------------------------+-------------+-----------------+----------------------------------------------------+
| id | name | cidr | allocation_pools |
+--------------------------------------+-------------+-----------------+----------------------------------------------------+
| <span class="hljs-number">4</span>af846a3-<span class="hljs-number">3</span>e14-<span class="hljs-number">450</span>d-b620-<span class="hljs-number">134</span>cb1479e0d | ext-subnet | <span class="hljs-number">192.168</span>.<span class="hljs-number">20.0</span>/<span class="hljs-number">24</span> | {<span class="hljs-string">"start"</span>: <span class="hljs-string">"192.168.20.11"</span>, <span class="hljs-string">"end"</span>: <span class="hljs-string">"192.168.20.30"</span>} |
| eb46a51b-c1b0-<span class="hljs-number">4</span>df9-<span class="hljs-number">9046</span><span class="hljs-operator">-a</span>19612fa532f | demo-subnet | <span class="hljs-number">192.168</span>.<span class="hljs-number">3.0</span>/<span class="hljs-number">24</span> | {<span class="hljs-string">"start"</span>: <span class="hljs-string">"192.168.3.1"</span>, <span class="hljs-string">"end"</span>: <span class="hljs-string">"192.168.3.253"</span>} |
+--------------------------------------+-------------+-----------------+----------------------------------------------------+
<span class="hljs-comment"># 為 subnet 補上 domain name server 資訊</span>
controller<span class="hljs-comment"># neutron subnet-update demo-subnet --dns_nameservers list=true 8.8.8.8 8.8.4.4</span></code></pre>
<p>如此一來,之後產生的 VM 就可以解析 domain name 囉!</p>
<h1 id="7參考資料">7、參考資料</h1>
<ul>
<li><a href="http://docs.openstack.org/icehouse/install-guide/install/apt/content/launch-instance.html">Chapter 14. Launch an instance - OpenStack Installation Guide for Ubuntu 12.04/14.04 (LTS) - icehouse</a></li>
</ul></div></body>
</html>曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-67124890895083224632014-10-03T15:47:00.001+08:002014-10-06T06:06:09.076+08:00安裝 OpenStack @ Ubuntu 14.04 (5) - 安裝 Networking Service (Neutron)<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>安裝 OpenStack @ Ubuntu 14.04 (5) - 安裝 Networking Service (Neutron)</title>
<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body><div class="container"><h1 id="目錄">目錄</h1>
<p><div class="toc"><div class="toc">
<ul>
<li><a href="#目錄">目錄</a></li>
<li><a href="#1安裝環境說明">1、安裝環境說明</a></li>
<li><a href="#2network-service-neutron-概觀">2、Network Service (Neutron) 概觀</a></li>
<li><a href="#3設定-controller-node">3、設定 Controller Node</a><ul>
<li><ul>
<li><a href="#31-建立所需資料庫-設定權限">3.1 建立所需資料庫 & 設定權限</a></li>
<li><a href="#32-向-identity-service-keystone-註冊-network-service">3.2 向 Identity Service (Keystone) 註冊 Network Service</a></li>
<li><a href="#33-安裝相關套件">3.3 安裝相關套件</a></li>
<li><a href="#34-設定-networking-service-各元件">3.4 設定 Networking Service 各元件</a><ul>
<li><a href="#341-資料庫">3.4.1 資料庫</a></li>
<li><a href="#342-認證機制">3.4.2 認證機制</a></li>
<li><a href="#343-message-broker">3.4.3 Message Broker</a></li>
<li><a href="#344-topology-change-notifier">3.4.4 Topology Change Notifier</a></li>
<li><a href="#345-modular-layer-2-plug-in">3.4.5 Modular Layer 2 Plug-in</a></li>
</ul>
</li>
<li><a href="#35-設定-modular-layer-2-ml2-plug-in">3.5 設定 Modular Layer 2 (ML2) plug-in</a></li>
<li><a href="#36-修改-compute-相關設定">3.6 修改 Compute 相關設定</a></li>
<li><a href="#37-啟動服務">3.7 啟動服務</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#4設定-network-node">4、設定 Network Node</a><ul>
<li><ul>
<li><a href="#41-調整-kernel-網路設定">4.1 調整 kernel 網路設定</a></li>
<li><a href="#42-安裝-networking-service-相關套件">4.2 安裝 Networking Service 相關套件</a></li>
<li><a href="#43-networking-一般元件設定">4.3 Networking 一般元件設定</a><ul>
<li><a href="#431-認證機制">4.3.1 認證機制</a></li>
<li><a href="#432-message-broker">4.3.2 Message Broker</a></li>
<li><a href="#433-modular-layer-2-plug-in">4.3.3 Modular Layer 2 Plug-in</a></li>
</ul>
</li>
<li><a href="#44-設定-layer-3-agent">4.4 設定 Layer 3 agent</a></li>
<li><a href="#45-設定-dhcp-agent">4.5 設定 DHCP agent</a></li>
<li><a href="#46-設定-metadata-agent">4.6 設定 metadata agent</a><ul>
<li><a href="#461-以下兩個步驟回到-controller-node-進行設定">4.6.1 以下兩個步驟回到 controller node 進行設定</a></li>
</ul>
</li>
<li><a href="#47-設定-modular-layer-2-ml2-plug-in">4.7 設定 Modular Layer 2 (ML2) plug-in</a></li>
<li><a href="#48-設定-open-vswitchovs-service">4.8 設定 Open vSwitch(OVS) Service</a><ul>
<li><a href="#481-啟動-networking-service">4.8.1 啟動 Networking Service</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="#5設定-compute-node">5、設定 Compute Node</a><ul>
<li><ul>
<li><a href="#51-調整-kernel-網路設定">5.1 調整 kernel 網路設定</a></li>
<li><a href="#52-安裝-networking-相關套件">5.2 安裝 Networking 相關套件</a></li>
<li><a href="#53-networking-一般元件設定">5.3 Networking 一般元件設定</a><ul>
<li><a href="#531-認證機制">5.3.1 認證機制</a></li>
<li><a href="#532-message-broker">5.3.2 Message Broker</a></li>
<li><a href="#533-modular-layer-2-plug-in">5.3.3 Modular Layer 2 Plug-in</a></li>
</ul>
</li>
<li><a href="#54-設定-modular-layer-2-ml2-plug-in">5.4 設定 Modular Layer 2 (ML2) plug-in</a></li>
<li><a href="#55-設定-open-vswitchovs-service">5.5 設定 Open vSwitch(OVS) Service</a></li>
<li><a href="#56-指定-compute-使用-neutron">5.6 指定 Compute 使用 Neutron</a></li>
<li><a href="#57-重新啟動相關服務">5.7 重新啟動相關服務</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#6初始化網路">6、初始化網路</a><ul>
<li><ul>
<li><a href="#61-external-network">6.1 External network</a><ul>
<li><a href="#611-建立外部虛擬網路-ext-net">6.1.1 建立外部虛擬網路 (ext-net)</a></li>
<li><a href="#612-為外部虛擬網路ext-net設定網段資訊">6.1.2 為外部虛擬網路(ext-net)設定網段資訊</a></li>
</ul>
</li>
<li><a href="#62-tenant-network">6.2 Tenant network</a><ul>
<li><a href="#621-建立-tenant-virtual-network">6.2.1 建立 Tenant Virtual Network</a></li>
<li><a href="#622-在-tenant-networkdemo-net-設定網段資訊">6.2.2 在 tenant network(demo-net) 設定網段資訊</a></li>
<li><a href="#623-建立-router-作為外部網路與-tenant-network-連結之用">6.2.3 建立 router 作為外部網路與 tenant network 連結之用</a></li>
</ul>
</li>
<li><a href="#63-驗證網路服務是否設定成功">6.3 驗證網路服務是否設定成功</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#7參考資料">7、參考資料</a></li>
</ul>
</div>
</div>
</p>
<h1 id="1安裝環境說明">1、安裝環境說明</h1>
<ul>
<li><p>OS:Ubuntu 14.04 LTS</p></li>
<li><p>Controller</p>
<ul><li>IP:<strong>10.0.0.11</strong> / 24</li>
<li>Gateway:10.0.0.1</li></ul></li>
<li><p>Network <br>
</p><ul><li>Management IP:<strong>10.0.0.21</strong> / 24 (<strong>eth0</strong>)</li>
<li>Gateway:10.0.0.1</li>
<li>Instance Tunnel IP:10.0.1.21 / 24 (<strong>eth1</strong>)</li>
<li>External Interface (<strong>eth2</strong>) <br>
<ul><li>IP:不指定 IP </li>
<li>設定方式如下:(修改 <strong>/etc/network/interfaces</strong>) <br></li></ul></li></ul><p></p>
<blockquote>
<p>auto eth2 <br>
iface eth2 inet manual <br>
up ip link set dev <span>$</span>IFACE up <br>
down ip link set dev <span>$</span>IFACE down</p></blockquote></li></ul>
<li><p>Compute 1</p>
<ul><li>Management IP:<strong>10.0.0.31</strong> / 24</li>
<li>Gateway:10.0.0.1</li>
<li>Instance Tunnel IP:10.0.1.31</li></ul></li>
<p>修改每個 node 的 /etc/hosts 檔案,並加入以下內容:</p>
<blockquote>
<p>10.0.0.11 controller <br>
10.0.0.21 network <br>
10.0.0.31 compute1</p>
</blockquote>
<ul>
<li>使用者身分:root</li>
</ul>
<h1 id="2network-service-neutron-概觀">2、Network Service (Neutron) 概觀</h1>
<p>Network Service (<strong>Neutron</strong>) 負責虛擬網路架構與外部實體網路架構(包含各廠商的設備)之間的整合 & 存取,用以提供 tenant 可自行建立像是防火牆、負載平衡、VPN … 等網路環境。</p>
<p>網路設定的概念其實跟我們之前所學的並沒有差太多,包含 DHCP、VLAN、Routing … 等等。</p>
<p>比較值得一提的是 Networking Service 支援了 <strong>security group</strong> 的概念:</p>
<ul>
<li>管理者可以針對每個 security group 進行防火牆規則的設定</li>
<li>每個 VM 可以屬於一個或多個 security group</li>
</ul>
<p>有了以上的機制,讓 Firewall-as-a-Service & Load-Balancing-as-a-Service 變的很容易實現。</p>
<h1 id="3設定-controller-node">3、設定 Controller Node</h1>
<h3 id="31-建立所需資料庫-設定權限">3.1 建立所需資料庫 & 設定權限</h3>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 登入 MySQL server</span>
controller<span class="hljs-comment"># mysql -u root -p</span>
Enter password:
<span class="hljs-comment"># 建立 DB (neutron)</span>
mysql> create database neutron;
Query OK, <span class="hljs-number">1</span> row affected (<span class="hljs-number">0.00</span> sec)
<span class="hljs-comment"># 設定權限</span>
mysql> grant all privileges on neutron.* to <span class="hljs-string">'neutron'</span>@<span class="hljs-string">'localhost'</span> identified by <span class="hljs-string">'YOUR_DB_PASSWORD'</span>;
Query OK, <span class="hljs-number">0</span> rows affected (<span class="hljs-number">0.00</span> sec)
<span class="hljs-comment"># 設定權限</span>
mysql> grant all privileges on neutron.* to <span class="hljs-string">'neutron'</span>@<span class="hljs-string">'%'</span> identified by <span class="hljs-string">'YOUR_DB_PASSWORD'</span>;
Query OK, <span class="hljs-number">0</span> rows affected (<span class="hljs-number">0.00</span> sec)</code></pre>
<h3 id="32-向-identity-service-keystone-註冊-network-service">3.2 向 Identity Service (Keystone) 註冊 Network Service</h3>
<p>建立使用者 neutron</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># keystone user-create --name neutron --pass YOUR_NEUTRON_PASSWORD --email manager@example.com</span>
+----------+----------------------------------+
| Property | Value |
+----------+----------------------------------+
| email | manager@example.com |
| enabled | True |
| id | <span class="hljs-number">7</span>f3839ca2d774d0e81baf7dbba8574a8 |
| name | neutron |
| username | neutron |
+----------+----------------------------------+</code></pre>
<p>將使用者(neutron)與 Role(admin) & Tenant(service) 綁定</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># keystone user-role-add --user neutron --tenant service --role admin</span></code></pre>
<p>將 Network Service(Neutron) 註冊到 Identity Service(Keystone) 中</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># # keystone service-create --name neutron --type network --description "OpenStack Networking"</span>
+-------------+----------------------------------+
| Property | Value |
+-------------+----------------------------------+
| description | OpenStack Networking |
| enabled | True |
| id | <span class="hljs-number">577265111</span>b73447e8a235946bd4b124c |
| name | neutron |
| <span class="hljs-built_in">type</span> | network |
+-------------+----------------------------------+</code></pre>
<p>建立 Network Service 服務端點資料</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># keystone endpoint-create --service-id $(keystone service-list | awk '/ network / {print $2}') --publicurl http://controller:9696 --adminurl http://controller:9696 --internalurl http://controller:9696</span>
+-------------+----------------------------------+
| Property | Value |
+-------------+----------------------------------+
| adminurl | http://controller:<span class="hljs-number">9696</span> |
| id | <span class="hljs-number">974</span>f0c66803f427488b60404f47e4931 |
| internalurl | http://controller:<span class="hljs-number">9696</span> |
| publicurl | http://controller:<span class="hljs-number">9696</span> |
| region | regionOne |
| service_id | <span class="hljs-number">577265111</span>b73447e8a235946bd4b124c |
+-------------+----------------------------------+</code></pre>
<h3 id="33-安裝相關套件">3.3 安裝相關套件</h3>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># apt-get -y install neutron-server neutron-plugin-ml2</span></code></pre>
<h3 id="34-設定-networking-service-各元件">3.4 設定 Networking Service 各元件</h3>
<p>Networking Service 的設定包含了以下幾項:</p>
<ol>
<li>資料庫</li>
<li>認證機制</li>
<li>Message Broker</li>
<li>Topology Change Notifier</li>
<li>Modular Layer 2 Plug-in</li>
</ol>
<h4 id="341-資料庫">3.4.1 <i class="icon-archive"></i> 資料庫</h4>
<p>修改 <strong>/etc/neutron/neutron.conf</strong>,加入資料庫的設定:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[database]</span>
<span class="hljs-setting">connection = <span class="hljs-value">mysql://neutron:YOUR_DB_PASSWORD@controller/neutron</span></span></code></pre>
<p>並刪除在 <strong>[database]</strong> 區段中 SQLite 的相關設定。</p>
<h4 id="342-認證機制">3.4.2 <i class="icon-user-md"></i> 認證機制</h4>
<p>修改 <strong>/etc/neutron/neutron.conf</strong>,加入認證機制的設定:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[DEFAULT]</span>
<span class="hljs-setting">auth_strategy = <span class="hljs-value">keystone</span></span>
<span class="hljs-title">[keystone_authtoken]</span>
<span class="hljs-setting">auth_uri = <span class="hljs-value">http://controller:<span class="hljs-number">5000</span></span></span>
<span class="hljs-setting">auth_host = <span class="hljs-value">controller</span></span>
<span class="hljs-setting">auth_port = <span class="hljs-value"><span class="hljs-number">35357</span></span></span>
<span class="hljs-setting">auth_protocol = <span class="hljs-value">http</span></span>
<span class="hljs-setting">admin_tenant_name = <span class="hljs-value">service</span></span>
<span class="hljs-setting">admin_user = <span class="hljs-value">neutron</span></span>
<span class="hljs-setting">admin_password = <span class="hljs-value">YOUR_NEUTRON_PASSWORD</span></span></code></pre>
<h4 id="343-message-broker">3.4.3 <i class="icon-rss"></i> Message Broker</h4>
<p>修改 <strong>/etc/neutron/neutron.conf</strong>,加入 Message Broker 的設定:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[DEFAULT]</span>
<span class="hljs-setting">rpc_backend = <span class="hljs-value">neutron.openstack.common.rpc.impl_kombu</span></span>
<span class="hljs-setting">rabbit_host = <span class="hljs-value">controller</span></span>
<span class="hljs-setting">rabbit_password = <span class="hljs-value">RABBIT_PASS</span></span></code></pre>
<h4 id="344-topology-change-notifier">3.4.4 <i class="icon-bell-alt"></i> Topology Change Notifier</h4>
<p>首先取得 Tenant ID (service):</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># source ~/OpenStack/admin-openrc.sh</span>
controller:~<span class="hljs-comment"># keystone tenant-get service</span>
+-------------+----------------------------------+
| Property | Value |
+-------------+----------------------------------+
| description | Service Tenant |
| enabled | True |
| id | b43a362300c7478193fa26ce5bb0f5c7 |
| name | service |
+-------------+----------------------------------+</code></pre>
<p>修改 <strong>/etc/neutron/neutron.conf</strong>,加入 Neutron & Nova 的互動設定:</p>
<pre class="prettyprint"><code class="language-bash hljs ">[DEFAULT]
notify_nova_on_port_status_changes = True
notify_nova_on_port_data_changes = True
nova_url = http://controller:<span class="hljs-number">8774</span>/v2
nova_admin_username = nova
<span class="hljs-comment"># 上面的命令取得 b43a362300c7478193fa26ce5bb0f5c7</span>
nova_admin_tenant_id = SERVICE_TENANT_ID
nova_admin_password = NOVA_PASS
nova_admin_auth_url = http://controller:<span class="hljs-number">35357</span>/v2.<span class="hljs-number">0</span></code></pre>
<h4 id="345-modular-layer-2-plug-in">3.4.5 <i class="icon-gift"></i> Modular Layer 2 Plug-in</h4>
<p>修改 <strong>/etc/neutron/neutron.conf</strong>,加入 ML2 Plug-in 相關設定:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[DEFAULT]</span>
<span class="hljs-setting">core_plugin = <span class="hljs-value">ml2</span></span>
<span class="hljs-setting">service_plugins = <span class="hljs-value">router</span></span>
<span class="hljs-setting">allow_overlapping_ips = <span class="hljs-value"><span class="hljs-keyword">True</span></span></span></code></pre>
<h3 id="35-設定-modular-layer-2-ml2-plug-in">3.5 設定 Modular Layer 2 (ML2) plug-in</h3>
<p>ML2 plug-in 是透過 Opeb vSwitch 建立 VM instances 所使用的虛擬網路架構,以下進行 ML2 相關的設定。</p>
<p>修改 <strong>/etc/neutron/plugins/ml2/ml2_conf.ini</strong>,加入以下內容:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[ml2]</span>
<span class="hljs-setting">type_drivers = <span class="hljs-value">gre</span></span>
<span class="hljs-setting">tenant_network_types = <span class="hljs-value">gre</span></span>
<span class="hljs-setting">mechanism_drivers = <span class="hljs-value">openvswitch</span></span>
<span class="hljs-title">[ml2_type_gre]</span>
<span class="hljs-setting">tunnel_id_ranges = <span class="hljs-value"><span class="hljs-number">1</span>:<span class="hljs-number">1000</span></span></span>
<span class="hljs-title">[securitygroup]</span>
<span class="hljs-setting">firewall_driver = <span class="hljs-value">neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver</span></span>
<span class="hljs-setting">enable_security_group = <span class="hljs-value"><span class="hljs-keyword">True</span></span></span></code></pre>
<h3 id="36-修改-compute-相關設定">3.6 修改 Compute 相關設定</h3>
<p>大部分的預設情況下,Compute(Nova) 所使用的是 nova-network,因此這邊必須修改為使用 Neutron。</p>
<p>修改 <strong>/etc/nova/nova.conf</strong>,在 Nova 的設定中增加以下內容:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[DEFAULT]</span>
<span class="hljs-setting">network_api_class = <span class="hljs-value">nova.network.neutronv2.api.API</span></span>
<span class="hljs-setting">neutron_url = <span class="hljs-value">http://controller:<span class="hljs-number">9696</span></span></span>
<span class="hljs-setting">neutron_auth_strategy = <span class="hljs-value">keystone</span></span>
<span class="hljs-setting">neutron_admin_tenant_name = <span class="hljs-value">service</span></span>
<span class="hljs-setting">neutron_admin_username = <span class="hljs-value">neutron</span></span>
<span class="hljs-setting">neutron_admin_password = <span class="hljs-value">NEUTRON_PASS</span></span>
<span class="hljs-setting">neutron_admin_auth_url = <span class="hljs-value">http://controller:<span class="hljs-number">35357</span>/v2.<span class="hljs-number">0</span></span></span>
<span class="hljs-setting">linuxnet_interface_driver = <span class="hljs-value">nova.network.linux_net.LinuxOVSInterfaceDriver</span></span>
<span class="hljs-setting">firewall_driver = <span class="hljs-value">nova.virt.firewall.NoopFirewallDriver</span></span>
<span class="hljs-setting">security_group_api = <span class="hljs-value">neutron</span></span></code></pre>
<blockquote>
<p>預設 Compute(Nova) 使用內部的 firewall service,若 Network Service 中包含了 firewall service,就必須停用 Nova 上的 firewall service,改成使用 <strong>nova.virt.firewall.NoopFirewallDriver</strong>。</p>
</blockquote>
<h3 id="37-啟動服務">3.7 啟動服務</h3>
<p>重新啟動 Compute service (Nova):</p>
<pre class="prettyprint"><code class=" hljs bash">controller<span class="hljs-comment"># service nova-api restart</span>
controller<span class="hljs-comment"># service nova-scheduler restart</span>
controller<span class="hljs-comment"># service nova-conductor restart</span></code></pre>
<p>重新啟動 Network Service (Neutron):</p>
<pre class="prettyprint"><code class=" hljs bash">controller<span class="hljs-comment"># service neutron-server restart</span></code></pre>
<h1 id="4設定-network-node">4、設定 Network Node</h1>
<h3 id="41-調整-kernel-網路設定">4.1 調整 kernel 網路設定</h3>
<p>在 Network node 上,要先將 kernel 的某些網路功能開啟(or 關閉),修改 <strong>/etc/sysctl.conf</strong>,加入以下設定:</p>
<pre class="prettyprint"><code class=" hljs avrasm">net<span class="hljs-preprocessor">.ipv</span>4<span class="hljs-preprocessor">.ip</span>_forward=<span class="hljs-number">1</span>
net<span class="hljs-preprocessor">.ipv</span>4<span class="hljs-preprocessor">.conf</span><span class="hljs-preprocessor">.all</span><span class="hljs-preprocessor">.rp</span>_filter=<span class="hljs-number">0</span>
net<span class="hljs-preprocessor">.ipv</span>4<span class="hljs-preprocessor">.conf</span><span class="hljs-preprocessor">.default</span><span class="hljs-preprocessor">.rp</span>_filter=<span class="hljs-number">0</span></code></pre>
<p>套用 kernel 設定:</p>
<pre class="prettyprint"><code class="language-bash hljs ">network<span class="hljs-comment"># sysctl -p</span></code></pre>
<h3 id="42-安裝-networking-service-相關套件">4.2 安裝 Networking Service 相關套件</h3>
<pre class="prettyprint"><code class=" hljs bash">network<span class="hljs-comment"># apt-get -y install neutron-plugin-ml2 neutron-plugin-openvswitch-agent openvswitch-datapath-dkms neutron-l3-agent neutron-dhcp-agent</span></code></pre>
<h3 id="43-networking-一般元件設定">4.3 Networking 一般元件設定</h3>
<p>Networking 一般元件設定包含了以下幾項:</p>
<ol>
<li>認證機制</li>
<li>Message Broker</li>
<li>Modular Layer 2 Plug-in</li>
</ol>
<h4 id="431-認證機制">4.3.1 <i class="icon-user-md"></i> 認證機制</h4>
<p>修改 <strong>/etc/neutron/neutron.conf</strong>,加入以下設定:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[DEFAULT]</span>
<span class="hljs-setting">auth_strategy = <span class="hljs-value">keystone</span></span>
<span class="hljs-title">[keystone_authtoken]</span>
<span class="hljs-setting">auth_uri = <span class="hljs-value">http://controller:<span class="hljs-number">5000</span></span></span>
<span class="hljs-setting">auth_host = <span class="hljs-value">controller</span></span>
<span class="hljs-setting">auth_protocol = <span class="hljs-value">http</span></span>
<span class="hljs-setting">auth_port = <span class="hljs-value"><span class="hljs-number">35357</span></span></span>
<span class="hljs-setting">admin_tenant_name = <span class="hljs-value">service</span></span>
<span class="hljs-setting">admin_user = <span class="hljs-value">neutron</span></span>
<span class="hljs-setting">admin_password = <span class="hljs-value">YOUR_NEUTRON_PASSWORD</span></span></code></pre>
<h4 id="432-message-broker">4.3.2 <i class="icon-rss"></i> Message Broker</h4>
<p>修改 <strong>/etc/neutron/neutron.conf</strong>,加入以下設定:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[DEFAULT]</span>
<span class="hljs-setting">rpc_backend = <span class="hljs-value">neutron.openstack.common.rpc.impl_kombu</span></span>
<span class="hljs-setting">rabbit_host = <span class="hljs-value">controller</span></span>
<span class="hljs-setting">rabbit_password = <span class="hljs-value">YOUR_RABBITMQ_PASSWORD</span></span></code></pre>
<h4 id="433-modular-layer-2-plug-in">4.3.3 <i class="icon-gift"></i> Modular Layer 2 Plug-in</h4>
<p>修改 <strong>/etc/neutron/neutron.conf</strong>,加入以下設定:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[DEFAULT]</span>
<span class="hljs-setting">core_plugin = <span class="hljs-value">ml2</span></span>
<span class="hljs-setting">service_plugins = <span class="hljs-value">router</span></span>
<span class="hljs-setting">allow_overlapping_ips = <span class="hljs-value"><span class="hljs-keyword">True</span></span></span></code></pre>
<h3 id="44-設定-layer-3-agent">4.4 設定 Layer 3 agent</h3>
<p>在 virtual network 中,Layer 3 agent 提供了 routing 的功能,修改 <strong>/etc/neutron/l3_agent.ini</strong>,加入 Layer 3 agent 相關設定:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[DEFAULT]</span>
<span class="hljs-setting">interface_driver = <span class="hljs-value">neutron.agent.linux.interface.OVSInterfaceDriver</span></span>
<span class="hljs-setting">use_namespaces = <span class="hljs-value"><span class="hljs-keyword">True</span></span></span></code></pre>
<h3 id="45-設定-dhcp-agent">4.5 設定 DHCP agent</h3>
<p>修改 <strong>/etc/neutron/dhcp_agent.ini</strong>,加入 DHCP agent 相關設定:</p>
<pre class="prettyprint"><code class=" hljs avrasm">[DEFAULT]
interface_driver = neutron<span class="hljs-preprocessor">.agent</span><span class="hljs-preprocessor">.linux</span><span class="hljs-preprocessor">.interface</span><span class="hljs-preprocessor">.OVSInterfaceDriver</span>
dhcp_driver = neutron<span class="hljs-preprocessor">.agent</span><span class="hljs-preprocessor">.linux</span><span class="hljs-preprocessor">.dhcp</span><span class="hljs-preprocessor">.Dnsmasq</span>
use_namespaces = True
dnsmasq_config_file = /etc/neutron/dnsmasq-neutron<span class="hljs-preprocessor">.conf</span></code></pre>
<p>新增 <strong>/etc/neutron/dnsmasq-neutron.conf</strong> 並加入設定:</p>
<pre class="prettyprint"><code class=" hljs ruleslanguage">network<span class="hljs-array"># echo </span><span class="hljs-string">'dhcp-option-force=26,1454'</span> > /etc/neutron/dnsmasq-neutron.conf</code></pre>
<p>刪除目前存在的 dnsmasq process:</p>
<pre class="prettyprint"><code class="language-bash hljs ">network<span class="hljs-comment"># killall dnsmasq</span></code></pre>
<h3 id="46-設定-metadata-agent">4.6 設定 metadata agent</h3>
<p>metadata agent 的功能在提供存取遠端 VM instance 時的相關設定資訊。</p>
<p>修改 <strong>/etc/neutron/metadata_agent.ini</strong>,加入以下設定:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[DEFAULT]</span>
<span class="hljs-setting">auth_url = <span class="hljs-value">http://controller:<span class="hljs-number">5000</span>/v2.<span class="hljs-number">0</span></span></span>
<span class="hljs-setting">auth_region = <span class="hljs-value">regionOne</span></span>
<span class="hljs-setting">admin_tenant_name = <span class="hljs-value">service</span></span>
<span class="hljs-setting">admin_user = <span class="hljs-value">neutron</span></span>
<span class="hljs-setting">admin_password = <span class="hljs-value">YOUR_NEUTRON_PASSWORD</span></span>
<span class="hljs-setting">nova_metadata_ip = <span class="hljs-value">controller</span></span>
<span class="hljs-setting">metadata_proxy_shared_secret = <span class="hljs-value">METADATA_SECRET</span></span></code></pre>
<h4 id="461-以下兩個步驟回到-controller-node-進行設定">4.6.1 <font color="red"><strong>以下兩個步驟回到 controller node 進行設定</strong></font></h4>
<ul>
<li>修改 <strong>/etc/nova/nova.conf</strong>,加入以下設定:</li>
</ul>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[DEFAULT]</span>
<span class="hljs-setting">service_neutron_metadata_proxy = <span class="hljs-value"><span class="hljs-keyword">true</span></span></span>
<span class="hljs-setting">neutron_metadata_proxy_shared_secret = <span class="hljs-value">METADATA_SECRET</span></span></code></pre>
<ul>
<li>重新啟動 compute API service:</li>
</ul>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># service nova-api restart</span></code></pre>
<h3 id="47-設定-modular-layer-2-ml2-plug-in">4.7 設定 Modular Layer 2 (ML2) plug-in</h3>
<p>修改 <strong>/etc/neutron/plugins/ml2/ml2_conf.ini</strong>,加入以下設定:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[ml2]</span>
<span class="hljs-setting">type_drivers = <span class="hljs-value">gre</span></span>
<span class="hljs-setting">tenant_network_types = <span class="hljs-value">gre</span></span>
<span class="hljs-setting">mechanism_drivers = <span class="hljs-value">openvswitch</span></span>
<span class="hljs-title">[ml2_type_gre]</span>
<span class="hljs-setting">tunnel_id_ranges = <span class="hljs-value"><span class="hljs-number">1</span>:<span class="hljs-number">1000</span></span></span>
<span class="hljs-title">[ovs]</span>
<span class="hljs-setting">local_ip = <span class="hljs-value"><span class="hljs-number">10.0</span>.<span class="hljs-number">1.21</span></span></span>
<span class="hljs-setting">tunnel_type = <span class="hljs-value">gre</span></span>
<span class="hljs-setting">enable_tunneling = <span class="hljs-value"><span class="hljs-keyword">True</span></span></span>
<span class="hljs-title">[securitygroup]</span>
<span class="hljs-setting">firewall_driver = <span class="hljs-value">neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver</span></span>
<span class="hljs-setting">enable_security_group = <span class="hljs-value"><span class="hljs-keyword">True</span></span></span></code></pre>
<h3 id="48-設定-open-vswitchovs-service">4.8 設定 Open vSwitch(OVS) Service</h3>
<p>Open vSwitch Service 提供虛擬網路架構給 VM instance 使用,不僅處理 VM instance 之間的內部流量,也包含對外實體網路介面的對外流量。</p>
<p>執行以下命令設定 OVS:</p>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 重新啟動 Open vSwitch Service</span>
network<span class="hljs-comment"># service openvswitch-switch restart</span>
<span class="hljs-comment"># 增加處理內部流量用的 bridge interface (br-int)</span>
network<span class="hljs-comment"># ovs-vsctl add-br br-int</span>
<span class="hljs-comment"># 增加處理外部流量的 bridge interface (br-ex)</span>
network<span class="hljs-comment"># ovs-vsctl add-br br-ex</span>
<span class="hljs-comment"># 指定連結外部實體網路卡的 interface name (因內部測試先,這邊暫時先不做)</span>
network<span class="hljs-comment"># ovs-vsctl add-port br-ex INTERFACE_NAME</span></code></pre>
<h4 id="481-啟動-networking-service">4.8.1 啟動 Networking Service</h4>
<pre class="prettyprint"><code class="language-bash hljs ">network<span class="hljs-comment"># service neutron-plugin-openvswitch-agent restart</span>
network<span class="hljs-comment"># service neutron-l3-agent restart</span>
network<span class="hljs-comment"># service neutron-dhcp-agent restart</span>
network<span class="hljs-comment"># service neutron-metadata-agent restart</span></code></pre>
<h1 id="5設定-compute-node">5、設定 Compute Node</h1>
<h3 id="51-調整-kernel-網路設定">5.1 調整 kernel 網路設定</h3>
<p>在 Compute node 上,要先將 kernel 的某些網路功能開啟(or 關閉),修改 <strong>/etc/sysctl.conf</strong>,加入以下設定:</p>
<pre class="prettyprint"><code class=" hljs avrasm">net<span class="hljs-preprocessor">.ipv</span>4<span class="hljs-preprocessor">.conf</span><span class="hljs-preprocessor">.all</span><span class="hljs-preprocessor">.rp</span>_filter=<span class="hljs-number">0</span>
net<span class="hljs-preprocessor">.ipv</span>4<span class="hljs-preprocessor">.conf</span><span class="hljs-preprocessor">.default</span><span class="hljs-preprocessor">.rp</span>_filter=<span class="hljs-number">0</span></code></pre>
<p>套用設定至 kernel:</p>
<pre class="prettyprint"><code class=" hljs lasso">sysctl <span class="hljs-attribute">-p</span></code></pre>
<h3 id="52-安裝-networking-相關套件">5.2 安裝 Networking 相關套件</h3>
<p>執行以下命令:</p>
<pre class="prettyprint"><code class="language-bash hljs ">compute1<span class="hljs-comment"># apt-get -y install neutron-common neutron-plugin-ml2 neutron-plugin-openvswitch-agent openvswitch-datapath-dkms</span></code></pre>
<h3 id="53-networking-一般元件設定">5.3 Networking 一般元件設定</h3>
<p>Networking 一般元件設定包含了以下幾項:</p>
<ol>
<li>認證機制</li>
<li>Message Broker</li>
<li>Modular Layer 2 Plug-in</li>
</ol>
<h4 id="531-認證機制">5.3.1 <i class="icon-user-md"></i> 認證機制</h4>
<p>修改 <strong>/etc/neutron/neutron.conf</strong>,加入以下設定:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[DEFAULT]</span>
<span class="hljs-setting">auth_strategy = <span class="hljs-value">keystone</span></span>
<span class="hljs-title">[keystone_authtoken]</span>
<span class="hljs-setting">auth_uri = <span class="hljs-value">http://controller:<span class="hljs-number">5000</span></span></span>
<span class="hljs-setting">auth_host = <span class="hljs-value">controller</span></span>
<span class="hljs-setting">auth_protocol = <span class="hljs-value">http</span></span>
<span class="hljs-setting">auth_port = <span class="hljs-value"><span class="hljs-number">35357</span></span></span>
<span class="hljs-setting">admin_tenant_name = <span class="hljs-value">service</span></span>
<span class="hljs-setting">admin_user = <span class="hljs-value">neutron</span></span>
<span class="hljs-setting">admin_password = <span class="hljs-value">YOUR_NEUTRON_PASSWORD</span></span></code></pre>
<h4 id="532-message-broker">5.3.2 <i class="icon-rss"></i> Message Broker</h4>
<p>修改 <strong>/etc/neutron/neutron.conf</strong>,加入以下設定:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[DEFAULT]</span>
<span class="hljs-setting">rpc_backend = <span class="hljs-value">neutron.openstack.common.rpc.impl_kombu</span></span>
<span class="hljs-setting">rabbit_host = <span class="hljs-value">controller</span></span>
<span class="hljs-setting">rabbit_password = <span class="hljs-value">YOUR_RABBIT_PASS</span></span></code></pre>
<h4 id="533-modular-layer-2-plug-in">5.3.3 <i class="icon-gift"></i> Modular Layer 2 Plug-in</h4>
<p>修改 <strong>/etc/neutron/neutron.conf</strong>,加入以下設定:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[DEFAULT]</span>
<span class="hljs-setting">core_plugin = <span class="hljs-value">ml2</span></span>
<span class="hljs-setting">service_plugins = <span class="hljs-value">router</span></span>
<span class="hljs-setting">allow_overlapping_ips = <span class="hljs-value"><span class="hljs-keyword">True</span></span></span></code></pre>
<h3 id="54-設定-modular-layer-2-ml2-plug-in">5.4 設定 Modular Layer 2 (ML2) plug-in</h3>
<p>修改 <strong>/etc/neutron/plugins/ml2/ml2_conf.ini</strong>,加入以下設定:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[ml2]</span>
<span class="hljs-setting">type_drivers = <span class="hljs-value">gre</span></span>
<span class="hljs-setting">tenant_network_types = <span class="hljs-value">gre</span></span>
<span class="hljs-setting">mechanism_drivers = <span class="hljs-value">openvswitch</span></span>
<span class="hljs-title">[ml2_type_gre]</span>
<span class="hljs-setting">tunnel_id_ranges = <span class="hljs-value"><span class="hljs-number">1</span>:<span class="hljs-number">1000</span></span></span>
<span class="hljs-title">[ovs]</span>
<span class="hljs-setting">local_ip = <span class="hljs-value"><span class="hljs-number">10.0</span>.<span class="hljs-number">1.31</span></span></span>
<span class="hljs-setting">tunnel_type = <span class="hljs-value">gre</span></span>
<span class="hljs-setting">enable_tunneling = <span class="hljs-value"><span class="hljs-keyword">True</span></span></span>
<span class="hljs-title">[securitygroup]</span>
<span class="hljs-setting">firewall_driver = <span class="hljs-value">neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver</span></span>
<span class="hljs-setting">enable_security_group = <span class="hljs-value"><span class="hljs-keyword">True</span></span></span></code></pre>
<h3 id="55-設定-open-vswitchovs-service">5.5 設定 Open vSwitch(OVS) Service</h3>
<p>Open vSwitch Service 提供虛擬網路架構給 VM instance 使用,不僅處理 VM instance 之間的內部流量,也包含對外實體網路介面的對外流量。</p>
<p>執行以下命令設定 OVS:</p>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 啟動 Open vSwitch Service</span>
compute1<span class="hljs-comment"># service openvswitch-switch restart</span>
<span class="hljs-comment"># 增加處理內部流量用的 bridge interface (br-int)</span>
compute1<span class="hljs-comment"># ovs-vsctl add-br br-int</span></code></pre>
<h3 id="56-指定-compute-使用-neutron">5.6 指定 Compute 使用 Neutron</h3>
<p>大部分狀況下,Compute 所使用的是 nova-network,但因為這邊安裝的是 Neutron,因此要做一些設定上的調整,修改 <strong>/etc/nova/nova.conf</strong>,加入以下內容:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[DEFAULT]</span>
<span class="hljs-setting">network_api_class = <span class="hljs-value">nova.network.neutronv2.api.API</span></span>
<span class="hljs-setting">neutron_url = <span class="hljs-value">http://controller:<span class="hljs-number">9696</span></span></span>
<span class="hljs-setting">neutron_auth_strategy = <span class="hljs-value">keystone</span></span>
<span class="hljs-setting">neutron_admin_tenant_name = <span class="hljs-value">service</span></span>
<span class="hljs-setting">neutron_admin_username = <span class="hljs-value">neutron</span></span>
<span class="hljs-setting">neutron_admin_password = <span class="hljs-value">NEUTRON_PASS</span></span>
<span class="hljs-setting">neutron_admin_auth_url = <span class="hljs-value">http://controller:<span class="hljs-number">35357</span>/v2.<span class="hljs-number">0</span></span></span>
<span class="hljs-setting">linuxnet_interface_driver = <span class="hljs-value">nova.network.linux_net.LinuxOVSInterfaceDriver</span></span>
<span class="hljs-setting">firewall_driver = <span class="hljs-value">nova.virt.firewall.NoopFirewallDriver</span></span>
<span class="hljs-setting">security_group_api = <span class="hljs-value">neutron</span></span></code></pre>
<blockquote>
<p>因為 Compute 會預設使用畚箕的防火牆服務,但因為在 OpenStack 的環境中,防火牆服務是設定在 Network node 上面,因此要透過設定將防火牆的功能交給 Neutron 來做。</p>
</blockquote>
<h3 id="57-重新啟動相關服務">5.7 重新啟動相關服務</h3>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 重新啟動 compute service</span>
compute1<span class="hljs-comment"># service nova-compute restart</span>
<span class="hljs-comment"># 重新啟動 Open vSwitch agent</span>
compute1<span class="hljs-comment"># service neutron-plugin-openvswitch-agent restart</span></code></pre>
<h1 id="6初始化網路">6、初始化網路</h1>
<p><img src="https://lh4.googleusercontent.com/-KywQxN2TX3I/VC5SKfJzDMI/AAAAAAAAJow/VWEa4XPdyl0/w316-h833-no/installguide_neutron-initial-networks.png" alt="網路架構圖" title=""></p>
<h3 id="61-external-network">6.1 External network</h3>
<p>外部虛擬網路提供 VM instance 存取網際網路的能力,預設僅能讓 VM instance 透過 NAT 的方式連線到網際網路,若要讓外部可以存取 VM instance,則必須指定 IP & 設定 security group 規則來達成。</p>
<blockquote>
<p><strong>以下指令必須在 <font color="red">controller</font> 上執行,並非 network node</strong></p>
</blockquote>
<h4 id="611-建立外部虛擬網路-ext-net">6.1.1 <i class="icon-tasks"></i> 建立外部虛擬網路 (<strong>ext-net</strong>)</h4>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># source ~/OpenStack/admin-openrc.sh</span>
controller:~<span class="hljs-comment"># neutron net-create ext-net --shared --router:external=True</span>
Created a new network:
+---------------------------+--------------------------------------+
| Field | Value |
+---------------------------+--------------------------------------+
| admin_state_up | True |
| id | <span class="hljs-number">629</span>c575d-<span class="hljs-number">5</span>d2e-<span class="hljs-number">4258</span>-bb96<span class="hljs-operator">-d</span>2def517aa04 |
| name | ext-net |
| provider:network_<span class="hljs-built_in">type</span> | gre |
| provider:physical_network | |
| provider:segmentation_id | <span class="hljs-number">1</span> |
| router:external | True |
| shared | True |
| status | ACTIVE |
| subnets | |
| tenant_id | <span class="hljs-number">27466</span>ca061e34b469f84da1e57b5605e |
+---------------------------+--------------------------------------+</code></pre>
<h4 id="612-為外部虛擬網路ext-net設定網段資訊">6.1.2 <i class="icon-list-bullet"></i> 為外部虛擬網路(ext-net)設定網段資訊</h4>
<p>虛擬網路也像實體網路一樣,需要指定網段(subnet)資訊。</p>
<p>而 Network node 對外連接的 interface 會與外部實體網路共用相同的 subnet & gateway 等資訊。</p>
<p>因此以下將外部實體網路的 subnet & gateway 等資訊設定到 Network node 的外部虛擬網路中:</p>
<blockquote>
<p>以下以 <strong>192.168.20.0/24</strong> 作為外部網路範例</p>
</blockquote>
<pre class="prettyprint"><code class=" hljs asciidoc">controller# neutron subnet-create ext-net --name ext-subnet --allocation-pool start=192.168.20.11,end=192.168.20.30 --disable-dhcp --gateway=192.168.20.254 192.168.20.0/24
<span class="hljs-header">Created a new subnet:
+------------------+----------------------------------------------------+</span>
<span class="hljs-header">| Field | Value |
+------------------+----------------------------------------------------+</span>
| allocation<span class="hljs-emphasis">_pools | {"start": "192.168.20.11", "end": "192.168.20.30"} |
| cidr | 192.168.20.0/24 |
| dns_</span>nameservers | |
| enable<span class="hljs-emphasis">_dhcp | False |
| gateway_</span>ip | 192.168.20.254 |
| host<span class="hljs-emphasis">_routes | |
| id | 4af846a3-3e14-450d-b620-134cb1479e0d |
| ip_</span>version | 4 |
| name | ext-subnet |
| network<span class="hljs-emphasis">_id | 629c575d-5d2e-4258-bb96-d2def517aa04 |
| tenant_</span>id | 27466ca061e34b469f84da1e57b5605e |
<span class="hljs-code">+------------------+</span>----------------------------------------------------+</code></pre>
<h3 id="62-tenant-network">6.2 Tenant network</h3>
<p>tenant network 提供存取 VM instance 的內部網路,這類型的網路會以 tenant 為單位進行隔離,因此不同 tenant 之間的 VM instance 是無法互相存取的。</p>
<h4 id="621-建立-tenant-virtual-network">6.2.1 <i class="icon-sitemap"></i> 建立 Tenant Virtual Network</h4>
<blockquote>
<p><strong>以下指令必須在 <font color="red">controller</font> 上執行,並非 network node</strong></p>
</blockquote>
<p>建立 demo credential 資訊 <strong>~/OpenStack/demo-openrc.sh</strong>,並設定內容如下:</p>
<pre class="prettyprint"><code class=" hljs bash"><span class="hljs-built_in">unset</span> OS_USERNAME
<span class="hljs-built_in">unset</span> OS_PASSWORD
<span class="hljs-built_in">unset</span> OS_TENANT_NAME
<span class="hljs-built_in">unset</span> OS_AUTH_URL
<span class="hljs-keyword">export</span> OS_USERNAME=demo
<span class="hljs-keyword">export</span> OS_PASSWORD=YOUR_DEMO_PASSWORD
<span class="hljs-keyword">export</span> OS_TENANT_NAME=demo
<span class="hljs-keyword">export</span> OS_AUTH_URL=http://controller:<span class="hljs-number">35357</span>/v2.<span class="hljs-number">0</span></code></pre>
<p>新增 tenant virtual network</p>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 以 demo 的身分執行</span>
controller<span class="hljs-comment"># source ~/OpenStack/demo-openrc.sh</span>
<span class="hljs-comment"># 建立名稱為 demo-net 的 tenant virtual network</span>
controller:~<span class="hljs-comment"># neutron net-create demo-net</span>
Created a new network:
+----------------+--------------------------------------+
| Field | Value |
+----------------+--------------------------------------+
| admin_state_up | True |
| id | <span class="hljs-number">65</span>c99acc-<span class="hljs-number">6438</span>-<span class="hljs-number">493</span>e-bbde-b3c0def3f575 |
| name | demo-net |
| shared | False |
| status | ACTIVE |
| subnets | |
| tenant_id | <span class="hljs-number">7539436331</span>ca4f9783bf93163e2a2e0f |
+----------------+--------------------------------------+</code></pre>
<h4 id="622-在-tenant-networkdemo-net-設定網段資訊">6.2.2 <i class=" icon-plus-squared"></i> 在 tenant network(demo-net) 設定網段資訊</h4>
<p>如同外部網路一樣,也必須要給定 tenant network 網段資訊,這邊以上圖為範例,設定 192.168.1.0/24 網段:</p>
<pre class="prettyprint"><code class=" hljs 1c">controller<span class="hljs-preprocessor"># neutron subnet-create demo-net --name demo-subnet --gateway 192.168.3.254 192.168.3.0/24 --dns_nameservers list=true 8.8.8.8 8.8.4.4</span>
Created a new subnet:
+------------------+--------------------------------------------------+
<span class="hljs-string">| Field | Value |</span>
+------------------+--------------------------------------------------+
<span class="hljs-string">| allocation_pools | {"</span>start<span class="hljs-string">": "</span><span class="hljs-number">192.168</span>.<span class="hljs-number">3.1</span><span class="hljs-string">", "</span>end<span class="hljs-string">": "</span><span class="hljs-number">192.168</span>.<span class="hljs-number">3.253</span><span class="hljs-string">"} |</span>
<span class="hljs-string">| cidr | 192.168.3.0/24 |</span>
<span class="hljs-string">| dns_nameservers | 8.8.4.4 |</span>
<span class="hljs-string">| | 8.8.8.8 |</span>
<span class="hljs-string">| enable_dhcp | True |</span>
<span class="hljs-string">| gateway_ip | 192.168.3.254 |</span>
<span class="hljs-string">| host_routes | |</span>
<span class="hljs-string">| id | eb46a51b-c1b0-4df9-9046-a19612fa532f |</span>
<span class="hljs-string">| ip_version | 4 |</span>
<span class="hljs-string">| name | demo-subnet |</span>
<span class="hljs-string">| network_id | 65c99acc-6438-493e-bbde-b3c0def3f575 |</span>
<span class="hljs-string">| tenant_id | 7539436331ca4f9783bf93163e2a2e0f |</span>
+------------------+--------------------------------------------------+</code></pre>
<h4 id="623-建立-router-作為外部網路與-tenant-network-連結之用">6.2.3 <i class="icon-sort-alt-down"></i> 建立 router 作為外部網路與 tenant network 連結之用</h4>
<p>所有 tenant virtual network 之間的流量,以及 tenant virtual network 到外部網路的流量,都必須由 virtual router 來處理 & 過濾。</p>
<p>因此這邊有三個步驟要完成:</p>
<ol>
<li>建立 virtual router</li>
<li>將 tenant virtual network (demo-subnet) 附加到 virtual router</li>
<li>將 external network(ext-net) 附加到 virtual router</li>
</ol>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 建立 virtual router</span>
controller<span class="hljs-comment"># neutron router-create demo-router</span>
Created a new router:
+-----------------------+--------------------------------------+
| Field | Value |
+-----------------------+--------------------------------------+
| admin_state_up | True |
| external_gateway_info | |
| id | e74b7f9a-<span class="hljs-number">9</span>ebe-<span class="hljs-number">4</span>e88-<span class="hljs-number">8836</span>-cbf558cfc05f |
| name | demo-router |
| status | ACTIVE |
| tenant_id | <span class="hljs-number">7539436331</span>ca4f9783bf93163e2a2e0f |
+-----------------------+--------------------------------------+
<span class="hljs-comment"># 將 tenant virtual network (demo-subnet) 附加到 virtual router</span>
controller<span class="hljs-comment"># neutron router-interface-add demo-router demo-subnet</span>
Added interface <span class="hljs-number">5</span>ea27e34<span class="hljs-operator">-e</span>45d-<span class="hljs-number">4</span>a69-<span class="hljs-number">9</span>fdb-<span class="hljs-number">59</span>be55e07268 to router demo-router.
<span class="hljs-comment"># 將 external network(ext-net) 附加到 virtual router</span>
controller<span class="hljs-comment"># neutron router-gateway-set demo-router ext-net</span>
Set gateway <span class="hljs-keyword">for</span> router demo-router</code></pre>
<h3 id="63-驗證網路服務是否設定成功">6.3 驗證網路服務是否設定成功</h3>
<p>根據上面的設定,外部網路的網段為 192.168.20.0/24,我們分配了 192.168.20.[11-30] 給了外部網路。</p>
<p>其中 tenant router gateway 會自動使用最前面的 IP,也就是 <strong>192.168.20.11</strong>,若是有設定正確,嘗試 ping 這個 IP 就可以取得回應。</p>
<blockquote>
<p>若把 OpenStack 安裝在 VM 的話,記得把虛擬交換器的 <font color="red"><strong>promiscuous mode</strong></font> 打開,網路才會通喔!</p>
<p>我的環境是在 VMware 裡面,就把 192.168.20.0/24 這個網段所在的 port group 的 promiscuous mode 開啟。(不需要開啟整個 vSwitch 的 promiscuous mode)</p>
</blockquote>
<h1 id="7參考資料">7、參考資料</h1>
<ul>
<li><p><a href="http://cyrilwang.blogspot.tw/2012/08/vmware-promiscuous-mode.html">就是資安 Simply Security: [教戰守則] 談 VMware 虛擬交換器之 Promiscuous Mode</a></p></li>
<li><p><a href="http://wiki.weithenn.org/cgi-bin/wiki.pl?VMware_Networking">不自量力 の Weithenn: VMware Networking</a></p></li>
<li><p><a href="http://docs.openstack.org/icehouse/install-guide/install/apt/content/ch_networking.html">Chapter 7. Add a networking service - OpenStack Installation Guide for Ubuntu 12.04/14.04 (LTS) - icehouse</a></p></li>
</ul></div></body>
</html>曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com24tag:blogger.com,1999:blog-4428257381149033865.post-23456491827041707302014-09-29T14:33:00.001+08:002014-10-21T13:04:12.849+08:00安裝 OpenStack @ Ubuntu 14.04 (4) - 安裝 Compute Service (Nova)<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>安裝 OpenStack @ Ubuntu 14.04 (4) - 安裝 Compute Service (Nova)</title>
<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body><div class="container"><h1 id="目錄">目錄</h1>
<p><div class="toc"><div class="toc">
<ul>
<li><a href="#目錄">目錄</a></li>
<li><a href="#1安裝環境說明">1、安裝環境說明</a></li>
<li><a href="#2compute-service-nova-概觀">2、Compute Service (NOVA) 概觀</a><ul>
<li><ul>
<li><a href="#21-api">2.1 API</a><ul>
<li><a href="#211-nova-api-service">2.1.1 nova-api service</a></li>
<li><a href="#212-nova-api-metadata-service">2.1.2 nova-api-metadata service</a></li>
</ul>
</li>
<li><a href="#22-compute-core">2.2. Compute core</a><ul>
<li><a href="#221-nova-compute">2.2.1 nova-compute</a></li>
<li><a href="#222-nova-scheduler">2.2.2 nova-scheduler</a></li>
<li><a href="#223-nova-conductor">2.2.3 nova-conductor</a></li>
</ul>
</li>
<li><a href="#23-networking-for-vms">2.3 Networking for VMs</a><ul>
<li><a href="#231-nova-network">2.3.1 nova-network</a></li>
<li><a href="#232-nova-dhcpbridge-script">2.3.2 nova-dhcpbridge script</a></li>
</ul>
</li>
<li><a href="#24-console-interface">2.4 Console interface</a><ul>
<li><a href="#241-nova-novncproxy-daemon">2.4.1 nova-novncproxy (daemon)</a></li>
<li><a href="#242-nova-xvpnvncproxy-daemon">2.4.2 nova-xvpnvncproxy (daemon)</a></li>
<li><a href="#242-nova-consoleauth-daemon">2.4.2 nova-consoleauth (daemon)</a></li>
</ul>
</li>
<li><a href="#25-command-line-clients-and-other-interfaces">2.5 Command-line clients and other interfaces</a><ul>
<li><a href="#251-nova-client">2.5.1 nova client</a></li>
<li><a href="#252-nova-manage-client">2.5.2 nova-manage client</a></li>
</ul>
</li>
<li><a href="#26-other-components">2.6 Other components</a><ul>
<li><a href="#261-message-queue">2.6.1 Message Queue</a></li>
<li><a href="#262-sql-database">2.6.2 SQL Database</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="#3安裝-compute-service">3、安裝 Compute Service</a><ul>
<li><ul>
<li><a href="#31-設定-message-queue-vnc">3.1 設定 Message Queue & VNC</a></li>
<li><a href="#32-設定資料庫">3.2 設定資料庫</a></li>
<li><a href="#33-設定-identity-service-認證">3.3 設定 Identity Service 認證</a></li>
<li><a href="#34-向-identity-service-註冊-nova-為-compute-service">3.4 向 Identity Service 註冊 Nova 為 Compute Service</a></li>
<li><a href="#35-啟動-compute-相關服務">3.5 啟動 Compute 相關服務</a></li>
<li><a href="#36-驗證安裝是否成功">3.6 驗證安裝是否成功</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#4設定-compute-node">4、設定 Compute Node</a><ul>
<li><ul>
<li><a href="#41-安裝操作-hypervisor-用套件">4.1 安裝操作 Hypervisor 用套件</a></li>
<li><a href="#42-修改設定檔-etcnovanovaconf">4.2 修改設定檔 (/etc/nova/nova.conf)</a></li>
<li><a href="#43-檢查-compute-node-是否具備硬體加速功能-for-虛擬化">4.3 檢查 compute node 是否具備硬體加速功能 for 虛擬化</a></li>
<li><a href="#44-啟動-compute-服務">4.4 啟動 compute 服務</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#5參考資料">5、參考資料</a></li>
</ul>
</div>
</div>
</p>
<h1 id="1安裝環境說明">1、安裝環境說明</h1>
<ul>
<li><p>OS:Ubuntu 14.04 LTS</p></li>
<li><p>Controller</p>
<ul><li>IP:<strong>10.0.0.11</strong> / 24</li>
<li>Gateway:10.0.0.1</li></ul></li>
<li><p>Network <br>
</p><ul><li>Management IP:<strong>10.0.0.21</strong> / 24 (<strong>eth0</strong>)</li>
<li>Gateway:10.0.0.1</li>
<li>Instance Tunnel IP:10.0.1.21 / 24 (<strong>eth1</strong>)</li>
<li>External Interface (<strong>eth2</strong>) <br>
<ul><li>IP:不指定 IP </li>
<li>設定方式如下:(修改 <strong>/etc/network/interfaces</strong>) <br></li></ul></li></ul><p></p>
<blockquote>
<p>auto eth2 <br>
iface eth2 inet manual <br>
up ip link set dev <span>$</span>IFACE up <br>
down ip link set dev <span>$</span>IFACE down</p></blockquote></li></ul>
<li><p>Compute 1</p>
<ul><li>Management IP:<strong>10.0.0.31</strong> / 24</li>
<li>Gateway:10.0.0.1</li>
<li>Instance Tunnel IP:10.0.1.31</li></ul></li>
<p>修改每個 node 的 /etc/hosts 檔案,並加入以下內容:</p>
<blockquote>
<p>10.0.0.11 controller <br>
10.0.0.21 network <br>
10.0.0.31 compute1</p>
</blockquote>
<ul>
<li>使用者身分:root</li>
</ul>
<h1 id="2compute-service-nova-概觀">2、Compute Service (NOVA) 概觀</h1>
<p>Compute Service 在整個 IaaS 的架構中是屬於最主要的部份,同時會向 Identity Service 進行認證授權、向 Image Service 要求 image、將資料提供給 Dashboard …. 等等。</p>
<p>而整個 Compute Service (NOVA) 包含了以下幾個重要部分:</p>
<h3 id="21-api">2.1 API</h3>
<h4 id="211-nova-api-service">2.1.1 nova-api service</h4>
<p>用來處理 & 回應終端使用者的 Compute API call,除了支援 OpenStack API 之外,還支援了 Amazon EC2 以及管理用 API。</p>
<h4 id="212-nova-api-metadata-service">2.1.2 nova-api-metadata service</h4>
<p>通常會用在多個 compute node 並安裝 nova-network 時使用,用來回應來自 instance 對 metadata 的要求。</p>
<h3 id="22-compute-core">2.2. Compute core</h3>
<p>這元件包含了幾個重要的 daemon,來共同組成 Compute Core 以提供服務:</p>
<h4 id="221-nova-compute">2.2.1 nova-compute</h4>
<p>主要目的是與 hypervisor API 溝通,已建立 / 中止 VM instance。</p>
<p>簡單來說,這個 daemon 僅接受來自 Message Queue 的訊息並執行相關命令而已,例如啟動一個 KVM instance、更新 instance 在資料庫中的狀態。</p>
<h4 id="222-nova-scheduler">2.2.2 nova-scheduler</h4>
<p>取得 VM instance 的需求後,根據制定的規則 & 目前情況,決定要讓 VM 在哪一台實體主機啟動。</p>
<h4 id="223-nova-conductor">2.2.3 nova-conductor</h4>
<p>作為 nova-ompute 與 DB 之間的橋樑,目的是為了減少 nova-compute 直接存取 DB 的行為。</p>
<h3 id="23-networking-for-vms">2.3 Networking for VMs</h3>
<p>這個部分的功能已經被移進獨立的 Network Service (Neutron) 了,但還是可以簡單說明一下:</p>
<h4 id="231-nova-network">2.3.1 nova-network</h4>
<p>同樣也是一支 daemon,接收來自 Message Queue 的網路相關需求並處理,例如:設定 bridge 介面 or iptables 規則 …. 等等。</p>
<h4 id="232-nova-dhcpbridge-script">2.3.2 nova-dhcpbridge script</h4>
<p>用來追蹤在資料庫中 IP 租用 & 釋放的資訊。</p>
<h3 id="24-console-interface">2.4 Console interface</h3>
<h4 id="241-nova-novncproxy-daemon">2.4.1 nova-novncproxy (daemon)</h4>
<p>作為透過 VNC 連線時存取 instance VM 的 proxy 之用,支援 browser-based novnc client。</p>
<h4 id="242-nova-xvpnvncproxy-daemon">2.4.2 nova-xvpnvncproxy (daemon)</h4>
<p>作為透過 VNC 連線時存取 instance VM 的 proxy 之用,支援 Java client 的連線。</p>
<h4 id="242-nova-consoleauth-daemon">2.4.2 nova-consoleauth (daemon)</h4>
<p>用來驗證由 console proxy (上面的 <strong>nova-novncproxy</strong> & <strong>nova-xvpnvncproxy</strong>) 所提供的使用者 token。</p>
<h3 id="25-command-line-clients-and-other-interfaces">2.5 Command-line clients and other interfaces</h3>
<h4 id="251-nova-client">2.5.1 nova client</h4>
<p>允許使用者以 tenant admin or 一般使用者的身分執行命令。</p>
<h4 id="252-nova-manage-client">2.5.2 nova-manage client</h4>
<p>允許 OpenStack 管理者執行命令。</p>
<h3 id="26-other-components">2.6 Other components</h3>
<h4 id="261-message-queue">2.6.1 Message Queue</h4>
<p>任何實作 AMQP 的 message queue 服務,用來作為所有 daemon 通訊的中介,這邊我們所使用的 RabbitMQ。</p>
<h4 id="262-sql-database">2.6.2 SQL Database</h4>
<p>儲存在 OpenStack 上運行的所有 VM instance 的狀態、網路設定、相關專案,任何 SQLAlchemy 支援的 DB 都可以使用,我們這邊所使用的是 MySQL。</p>
<h1 id="3安裝-compute-service">3、安裝 Compute Service</h1>
<p>Compute Service 其實是由好幾個 service 一同合作,讓使用者可以啟用 VM instance。</p>
<p>安裝的時候可以將這些 service 安裝在不同的機器上,也可以都裝在相同的機器上;在這邊我們將大部分的 service 安裝在 controller node 上,而主要啟動 VM instance 的服務則安裝在 compute node 上。</p>
<p>首先在 controller node 上安裝 Compute 相關必要套件:</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># apt-get -y install nova-api nova-cert nova-conductor nova-consoleauth nova-novncproxy nova-scheduler python-novaclient</span></code></pre>
<h3 id="31-設定-message-queue-vnc">3.1 <i class="icon-gauge"></i> 設定 Message Queue & VNC</h3>
<p>修改 nova 設定檔(<font color="red"><strong>/etc/nova/nova.conf</strong></font>),指定 Message Queue 服務 & VNC 相關設定,在 <strong>[DEFAULT]</strong> 區段中加入以下設定:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[DEFAULT]</span>
<span class="hljs-setting">rpc_backend = <span class="hljs-value">rabbit</span></span>
<span class="hljs-setting">rabbit_host = <span class="hljs-value">controller</span></span>
<span class="hljs-setting">rabbit_password = <span class="hljs-value">YOUR_RABBIT_PASS</span></span>
<span class="hljs-setting">my_ip = <span class="hljs-value"><span class="hljs-number">10.0</span>.<span class="hljs-number">0.11</span></span></span>
<span class="hljs-setting">vncserver_listen = <span class="hljs-value"><span class="hljs-number">10.0</span>.<span class="hljs-number">0.11</span></span></span>
<span class="hljs-setting">vncserver_proxyclient_address = <span class="hljs-value"><span class="hljs-number">10.0</span>.<span class="hljs-number">0.11</span></span></span></code></pre>
<h3 id="32-設定資料庫">3.2 <i class="icon-upload-cloud"></i> 設定資料庫</h3>
<p>接著準備好 nova 相關 daemon 會用到的 DB & 權限設定:</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># mysql -u root -p</span>
Enter password:
mysql> create database nova;
mysql> grant all privileges on nova.* to <span class="hljs-string">'nova'</span>@<span class="hljs-string">'localhost'</span> identified by <span class="hljs-string">'YOUR_NOVA_DB_PASSWORD'</span>;
Query OK, <span class="hljs-number">0</span> rows affected (<span class="hljs-number">0.00</span> sec)
mysql> grant all privileges on nova.* to <span class="hljs-string">'nova'</span>@<span class="hljs-string">'%'</span> identified by <span class="hljs-string">'YOUR_NOVA_DB_PASSWORD'</span>;
Query OK, <span class="hljs-number">0</span> rows affected (<span class="hljs-number">0.00</span> sec)</code></pre>
<p>新增 Tables @ Nova DB:</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># sh -c "nova-manage db sync" nova</span></code></pre>
<p>修改 nova 設定檔(<font color="red"><strong>/etc/nova/nova.conf</strong></font>),加入 DB 相關設定:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[database]</span>
<span class="hljs-setting">connection = <span class="hljs-value">mysql://nova:YOUR_NOVA_DBPASS@controller/nova</span></span></code></pre>
<p>移除原本存在的 SQLite 檔案:</p>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># rm /var/lib/nova/nova.sqlite</span></code></pre>
<h3 id="33-設定-identity-service-認證">3.3 <i class="icon-desktop"></i> 設定 Identity Service 認證</h3>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 建立 nova 用的 user</span>
controlle<span class="hljs-comment"># keystone user-create --name=nova --pass=YOUR_NOVA_PASSWORD --email=admin@example.com</span>
+----------+----------------------------------+
| Property | Value |
+----------+----------------------------------+
| email | admin@example.com |
| enabled | True |
| id | <span class="hljs-number">5</span>cdbbe2f486641e5966199af5d743441 |
| name | nova |
| username | nova |
+----------+----------------------------------+
<span class="hljs-comment"># 將 user / service Tenant / admin Role 連結</span>
controller<span class="hljs-comment"># keystone user-role-add --user=nova --tenant=service --role=admin</span></code></pre>
<h3 id="34-向-identity-service-註冊-nova-為-compute-service">3.4 <i class="icon-magic"></i> 向 Identity Service 註冊 Nova 為 Compute Service</h3>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 建立 service 資訊</span>
controller<span class="hljs-comment"># keystone service-create --name=nova --type=compute --description="OpenStack Compute"</span>
+-------------+----------------------------------+
| Property | Value |
+-------------+----------------------------------+
| description | OpenStack Compute |
| enabled | True |
| id | <span class="hljs-number">87</span>c4529e337e45df94a9c101d7097db4 |
| name | nova |
| <span class="hljs-built_in">type</span> | compute |
+-------------+----------------------------------+
<span class="hljs-comment"># 建立 API 服務端點資訊並與 service 連結</span>
controller<span class="hljs-comment"># # keystone endpoint-create --service-id=$(keystone service-list | awk '/ compute / {print $2}') --publicurl=http://controller:8774/v2/%\(tenant_id\)s --internalurl=http://controller:8774/v2/%\(tenant_id\)s --adminurl=http://controller:8774/v2/%\(tenant_id\)s</span>
+-------------+-----------------------------------------------------+
| Property | Value |
+-------------+-----------------------------------------------------+
| adminurl | http://controller:<span class="hljs-number">8774</span>/v2/%(tenant_id)s |
| id | be0f81e5b41a453a920dd2360c713af6 |
| internalurl | http://controller:<span class="hljs-number">8774</span>/v2/%(tenant_id)s |
| publicurl | --publicurl=http://controller:<span class="hljs-number">8774</span>/v2/%(tenant_id)s |
| region | regionOne |
| service_id | <span class="hljs-number">87</span>c4529e337e45df94a9c101d7097db4 |
+-------------+-----------------------------------------------------+</code></pre>
<p>修改 nova 設定檔(<font color="red"><strong>/etc/nova/nova.conf</strong></font>),加入以下設定:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[DEFAULT]</span>
<span class="hljs-setting">auth_strategy = <span class="hljs-value">keystone</span></span>
<span class="hljs-title">[keystone_authtoken]</span>
<span class="hljs-setting">auth_uri = <span class="hljs-value">http://controller:<span class="hljs-number">5000</span></span></span>
<span class="hljs-setting">auth_host = <span class="hljs-value">controller</span></span>
<span class="hljs-setting">auth_port = <span class="hljs-value"><span class="hljs-number">35357</span></span></span>
<span class="hljs-setting">auth_protocol = <span class="hljs-value">http</span></span>
<span class="hljs-setting">admin_tenant_name = <span class="hljs-value">service</span></span>
<span class="hljs-setting">admin_user = <span class="hljs-value">nova</span></span>
<span class="hljs-setting">admin_password = <span class="hljs-value">YOUR_NOVA_PASS</span></span></code></pre>
<h3 id="35-啟動-compute-相關服務">3.5 <i class="icon-play"></i> 啟動 Compute 相關服務</h3>
<pre class="prettyprint"><code class="language-bash hljs ">controller<span class="hljs-comment"># service nova-api restart</span>
controller<span class="hljs-comment"># service nova-cert restart</span>
controller<span class="hljs-comment"># service nova-consoleauth restart</span>
controller<span class="hljs-comment"># service nova-scheduler restart</span>
controller<span class="hljs-comment"># service nova-conductor restart</span>
controller<span class="hljs-comment"># service nova-novncproxy restart</span></code></pre>
<h3 id="36-驗證安裝是否成功">3.6 <i class="icon-check"></i> 驗證安裝是否成功</h3>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 透過 shell script 匯入 OS_USERNAME / OS_PASSWORD / OS_TENANT_NAME / OS_AUTH_URL 等環境變數</span>
controller<span class="hljs-comment"># source ~/OpenStack/admin-openrc.sh</span>
<span class="hljs-comment"># 查詢目前 compute host 可用的 image list (向 Glance 查詢)</span>
controller<span class="hljs-comment"># nova image-list</span>
+--------------------------------------+---------------------+--------+--------+
| ID | Name | Status | Server |
+--------------------------------------+---------------------+--------+--------+
| <span class="hljs-number">0985</span>b2f3-<span class="hljs-number">058</span>e-<span class="hljs-number">4</span>ab9-<span class="hljs-number">84</span>e3-<span class="hljs-number">65</span>c51f849408 | cirros-<span class="hljs-number">0.3</span>.<span class="hljs-number">3</span>-x86_64 | ACTIVE | |
| <span class="hljs-number">77</span>c0d5f8-<span class="hljs-number">1</span>bcc-<span class="hljs-number">4937</span>-<span class="hljs-number">932</span>c-<span class="hljs-number">72</span>f4b0eccbc3 | cirros-<span class="hljs-number">0.3</span>.<span class="hljs-number">3</span>-x86_64 | ACTIVE | |
+--------------------------------------+---------------------+--------+--------+</code></pre>
<h1 id="4設定-compute-node">4、設定 Compute Node</h1>
<p>設定好 controller 上的 compute service 之後,接著要來設定實際執行 VM instance 的 compute node。</p>
<p>Compute node 主要的工作是接收來自 controller 的命令,並運行 VM instance。</p>
<h3 id="41-安裝操作-hypervisor-用套件">4.1 <i class="icon-align-justify"></i> 安裝操作 Hypervisor 用套件</h3>
<p>OpenStack 可以兼容多種 hypervisor (KVM / Xen / VMware ESXi / MS Hyper-V … etc),這邊以 KVM 為例,安裝相關操作套件:</p>
<pre class="prettyprint"><code class="language-bash hljs ">compute1<span class="hljs-comment"># apt-get -y install nova-compute-kvm</span></code></pre>
<h3 id="42-修改設定檔-etcnovanovaconf">4.2 <i class="icon-credit-card"></i> 修改設定檔 (<strong>/etc/nova/nova.conf</strong>)</h3>
<pre class="prettyprint"><code class=" hljs makefile"><span class="hljs-comment"># 設定 Message Queue 相關資訊</span>
<span class="hljs-constant">rpc_backend</span> = rabbit
<span class="hljs-constant">rabbit_host</span> = controller
<span class="hljs-constant">rabbit_password</span> = YOUR_RABBIT_PASS
<span class="hljs-comment"># 設定 compute node IP & 相關的 vnc server 位置</span>
<span class="hljs-constant">my_ip</span> = 10.0.0.31
<span class="hljs-constant">vnc_enabled</span> = True
<span class="hljs-constant">vncserver_listen</span> = 0.0.0.0
<span class="hljs-constant">vncserver_proxyclient_address</span> = 10.0.0.31
<span class="hljs-constant">novncproxy_base_url</span> = http://controller:6080/vnc_auto.html
<span class="hljs-comment"># 指定以 keystone 進行認證工作</span>
<span class="hljs-constant">auth_strategy</span> = keystone
<span class="hljs-comment"># 指定 Glace 服務所在位置(這邊設定在 controller 上)</span>
<span class="hljs-constant">glance_host</span> = controller
<span class="hljs-comment"># 資料庫相關設定</span>
[database]
<span class="hljs-constant">connection</span> = mysql://nova:YOUR_NOVA_DB_PASSWORD@controller/nova
<span class="hljs-comment"># keystone 相關設定</span>
[keystone_authtoken]
<span class="hljs-constant">auth_uri</span> = http://controller:5000
<span class="hljs-constant">auth_host</span> = controller
<span class="hljs-constant">auth_port</span> = 35357
<span class="hljs-constant">auth_protocol</span> = http
<span class="hljs-constant">admin_tenant_name</span> = service
<span class="hljs-constant">admin_user</span> = nova
<span class="hljs-constant">admin_password</span> = YOUR_KEYSTONE_PASSWORD</code></pre>
<h3 id="43-檢查-compute-node-是否具備硬體加速功能-for-虛擬化">4.3 <i class="icon-book"></i> 檢查 compute node 是否具備硬體加速功能 for 虛擬化</h3>
<p>透過以下指令:</p>
<pre class="prettyprint"><code class="language-bash hljs ">compute1<span class="hljs-comment"># egrep -c '(vmx|svm)' /proc/cpuinfo</span>
<span class="hljs-number">1</span></code></pre>
<p>若以上指令出現的數字為 0,表示目前 compute node 的 cpu 不支援虛擬化硬體加速,這時候就要編輯 <strong>/etc/nova/nova-compute.conf</strong> 檔案,將 <strong>virt_type</strong> 改成 <font color="red"><strong>qemu</strong></font>:</p>
<pre class="prettyprint"><code class=" hljs ini"><span class="hljs-title">[libvirt]</span>
<span class="hljs-setting">virt_type = <span class="hljs-value">qemu</span></span></code></pre>
<h3 id="44-啟動-compute-服務">4.4 啟動 compute 服務</h3>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 移除不需要的 SQLite 檔案</span>
compute1<span class="hljs-comment"># rm /var/lib/nova/nova.sqlite</span>
<span class="hljs-comment"># 啟動 nova-compute 服務</span>
compute1<span class="hljs-comment"># service nova-compute restart</span></code></pre>
<h1 id="5參考資料">5、參考資料</h1>
<ul>
<li><a href="http://docs.openstack.org/icehouse/install-guide/install/apt/content/index.html">OpenStack Installation Guide for Ubuntu 12.04/14.04 (LTS) - icehouse</a></li>
</ul></div></body>
</html>曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com18tag:blogger.com,1999:blog-4428257381149033865.post-10745642464591821482014-09-25T07:40:00.001+08:002014-10-04T19:36:21.798+08:00安裝 OpenStack @ Ubuntu 14.04 (3) - 安裝 Image Service (Glance)<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>安裝 OpenStack @ Ubuntu 14.04 (3) - 安裝 Image Service (Glance)</title>
<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body><div class="container"><h1 id="目錄">目錄</h1>
<p><div class="toc"><div class="toc">
<ul>
<li><a href="#目錄">目錄</a></li>
<li><a href="#1安裝環境說明">1、安裝環境說明</a></li>
<li><a href="#2image-service-概觀">2、Image Service 概觀</a></li>
<li><a href="#3安裝-glance">3、安裝 Glance</a><ul>
<li><ul>
<li><a href="#31-安裝套件">3.1 安裝套件</a></li>
<li><a href="#32-設定資料庫">3.2 設定資料庫</a></li>
<li><a href="#33-修改設定">3.3 修改設定</a></li>
<li><a href="#34-建立-glance-用-mysql-db">3.4 建立 Glance 用 MySQL DB</a></li>
<li><a href="#35-將-glance-與-identity-servicekeystone-連結">3.5 將 Glance 與 Identity Service(Keystone) 連結</a><ul>
<li><a href="#351-建立認證用帳號glance-管理者">3.5.1 建立認證用帳號(Glance 管理者)</a></li>
<li><a href="#352-註冊-image-service">3.5.2 註冊 Image Service</a></li>
</ul>
</li>
<li><a href="#36-啟動服務">3.6 啟動服務</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#4驗證-glance-安裝是否成功">4、驗證 Glance 安裝是否成功</a></li>
</ul>
</div>
</div>
</p>
<h1 id="1安裝環境說明">1、安裝環境說明</h1>
<ul>
<li><p>OS:Ubuntu 14.04 LTS</p></li>
<li><p>Controller</p>
<ul><li>IP:<strong>10.0.0.11</strong> / 24</li>
<li>Gateway:10.0.0.1</li></ul></li>
<li><p>Network <br>
</p><ul><li>Management IP:<strong>10.0.0.21</strong> / 24 (<strong>eth0</strong>)</li>
<li>Gateway:10.0.0.1</li>
<li>Instance Tunnel IP:10.0.1.21 / 24 (<strong>eth1</strong>)</li>
<li>External Interface (<strong>eth2</strong>) <br>
<ul><li>IP:不指定 IP </li>
<li>設定方式如下:(修改 <strong>/etc/network/interfaces</strong>) <br></li></ul></li></ul><p></p>
<blockquote>
<p>auto eth2 <br>
iface eth2 inet manual <br>
up ip link set dev <span>$</span>IFACE up <br>
down ip link set dev <span>$</span>IFACE down</p></blockquote></li></ul>
<li><p>Compute 1</p>
<ul><li>Management IP:<strong>10.0.0.31</strong> / 24</li>
<li>Gateway:10.0.0.1</li>
<li>Instance Tunnel IP:10.0.1.31</li></ul></li>
<p>修改每個 node 的 /etc/hosts 檔案,並加入以下內容:</p>
<blockquote>
<p>10.0.0.11 controller <br>
10.0.0.21 network <br>
10.0.0.31 compute1</p>
</blockquote>
<ul>
<li>使用者身分:root</li>
</ul>
<h1 id="2image-service-概觀">2、Image Service 概觀</h1>
<p>在 OpenStack 中,Image Service 的用途在於讓使用者可以尋找/註冊/取得虛擬機器的映像檔來使用,而提供這樣的服務的專案稱為 <strong><em>Glance</em></strong>。</p>
<p>Glance 是用來管理虛擬磁碟的 image 之用,除了可以讓使用者新增 image 之外,也可以從正在運作的 server 上取得 snapshop 來作為 image 的備份或者是其他虛擬磁碟的 image。</p>
<p>Glance 包含了以下四個主要部分:</p>
<ul>
<li><p><strong>glance-api</strong></p>
<ul><li>接受來自其他服務的 API call</li></ul></li>
<li><p><strong>glance-registry</strong></p>
<ul><li>管理 image 的 metadata 之用(例如:image 的大小 & 類型)。</li></ul></li>
<li><p><strong>Database</strong></p>
<ul><li>儲存 image metadata 之用,可選擇 MySQL or SQLite。</li></ul></li>
<li><p><strong>存放 image 的 storage repository</strong></p>
<ul><li>存放 image 的位置有很多種不同的選擇,例如:一般的檔案系統、Object Storage、RADOS Block device、甚至是 Amazon S3 也可以。(但某些 repository 僅支援唯讀模式)</li></ul></li>
</ul>
<p><img src="http://docs.openstack.org/icehouse/install-guide/install/apt/content/figures/1/a/common/figures/openstack_havana_conceptual_arch.png" alt="OpenStack conceptual architecture" title=""></p>
<p>以上是 OpenStack 的概念架構圖,從圖中可以看出 Glance 的定位:</p>
<ol>
<li>可以將 image 存於 Swift 中</li>
<li>提供 image 給 Nova 作為執行 VM 之用</li>
<li>使用者可以透過 Horizon 呼叫 Glance API 來管理 image</li>
<li>在使用 Glance API 之前,都需要通過 Keystone 的認證</li>
</ol>
<h1 id="3安裝-glance">3、安裝 Glance</h1>
<h3 id="31-安裝套件">3.1 安裝套件</h3>
<p>這個範例會將 Glance 安裝在 controller 上,執行以下指令:</p>
<blockquote>
<p>$ apt-get install glance python-glanceclient</p>
</blockquote>
<h3 id="32-設定資料庫">3.2 設定資料庫</h3>
<p>原本預設 Glance 會將資料存於 SQLite 中,為了跟其他服務一致,以下把它改成使用 MySQL,首先先在 MySQL 中建立 glance 資料庫並給定權限:</p>
<pre class="prettyprint"><code class="language-bash hljs ">root@controller:~/OpenStack<span class="hljs-comment"># mysql -u root -p</span>
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is <span class="hljs-number">107</span>
Server version: <span class="hljs-number">5.5</span>.<span class="hljs-number">38</span>-<span class="hljs-number">0</span>ubuntu0.<span class="hljs-number">14.04</span>.<span class="hljs-number">1</span> (Ubuntu)
Copyright (c) <span class="hljs-number">2000</span>, <span class="hljs-number">2014</span>, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type <span class="hljs-string">'help;'</span> or <span class="hljs-string">'\h'</span> <span class="hljs-keyword">for</span> help. Type <span class="hljs-string">'\c'</span> to clear the current input statement.
mysql> create database glance;
Query OK, <span class="hljs-number">1</span> row affected (<span class="hljs-number">0.00</span> sec)
mysql> grant all privileges on glance.* to <span class="hljs-string">'glance'</span>@<span class="hljs-string">'localohost'</span> identified by <span class="hljs-string">'YOUR_GLANCE_DBPASS'</span>;
Query OK, <span class="hljs-number">0</span> rows affected (<span class="hljs-number">0.00</span> sec)
mysql> grant all privileges on glance.* to <span class="hljs-string">'glance'</span>@<span class="hljs-string">'%'</span> identified by <span class="hljs-string">'YOUR_DB_PASSWORD'</span>;
Query OK, <span class="hljs-number">0</span> rows affected (<span class="hljs-number">0.00</span> sec)
mysql> <span class="hljs-keyword">exit</span></code></pre>
<h3 id="33-修改設定">3.3 修改設定</h3>
<p>接著修改 Glance API & Registry 的設定,分別是以下的兩個檔案:</p>
<ul>
<li>/etc/glance/glance-api.conf</li>
<li>/etc/glance/glance-registry.conf</li>
</ul>
<p>修改 <strong>[database]</strong> 區段,移除原本的 SQLite 設定,改為以下內容:</p>
<pre class="prettyprint"><code class="language-bash hljs ">[database]
connection = mysql://glance:YOUR_GLANCE_DBPASS@controller/glance</code></pre>
<h3 id="34-建立-glance-用-mysql-db">3.4 建立 Glance 用 MySQL DB</h3>
<p>建立 MySQL DB for Glance:</p>
<pre class="prettyprint"><code class="language-bash hljs ">$ sh -c <span class="hljs-string">"glance-manage db_sync"</span> glance</code></pre>
<h3 id="35-將-glance-與-identity-servicekeystone-連結">3.5 將 Glance 與 Identity Service(Keystone) 連結</h3>
<p>每個 service 都必須跟 Identity Service(Keystone) 進行連結,以下分成兩個步驟:</p>
<h4 id="351-建立認證用帳號glance-管理者">3.5.1 建立認證用帳號(Glance 管理者)</h4>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 建立認證用帳號 & E-Mail</span>
keystone user-create --name=glance --pass=YOUR_GLANCE_AUTH_PASS \
--email=admin@example.com
+----------+----------------------------------+
| Property | Value |
+----------+----------------------------------+
| email | admin@example.com |
| enabled | True |
| id | ec4848f8a9d342038668029c78f77565 |
| name | glance |
| username | glance |
+----------+----------------------------------+
<span class="hljs-comment"># 指定使用 service Tenant 並隸屬於 admin Role</span>
$ keystone user-role-add --user=glance --tenant=service --role=admin</code></pre>
<h4 id="352-註冊-image-service">3.5.2 註冊 Image Service</h4>
<p>同樣修改 API(<strong>/etc/glance/glance-api.conf</strong>) & Registry(<strong>/etc/glance/glance-registry.conf</strong>) 兩個設定檔,修改 <strong>[keystone_authtoken]</strong> & <strong>[paste_deploy]</strong> 區段內容如下:</p>
<pre class="prettyprint"><code class="language-bash hljs ">[keystone_authtoken]
auth_uri = http://controller:<span class="hljs-number">5000</span>
auth_host = controller
auth_port = <span class="hljs-number">35357</span>
auth_protocol = http
admin_tenant_name = service
admin_user = glance
admin_password = YOUR_GLANCE_AUTH_PASS
[paste_deploy]
flavor = keystone</code></pre>
<p>最後下指令將 Glance 註冊至 Keystone 中並產生 API 服務端點,讓 OpenStack 其他的 service 可以知道 Image Service(Glance) 所在的位置:</p>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 註冊 Glance 服務</span>
$ keystone service-create --name=glance --type=image --description=<span class="hljs-string">"OpenStack Image Service"</span>
+-------------+----------------------------------+
| Property | Value |
+-------------+----------------------------------+
| description | OpenStack Image Service |
| enabled | True |
| id | <span class="hljs-number">95</span>a34885c3dc486f98153cf2d3740355 |
| name | glance |
| <span class="hljs-built_in">type</span> | image |
+-------------+----------------------------------+
<span class="hljs-comment"># 註冊 Glance API 端點服務</span>
$ keystone endpoint-create --service-id=$(keystone service-list | awk <span class="hljs-string">'/ image / {print $2}'</span>) --publicurl=http://controller:<span class="hljs-number">9292</span> --internalurl=http://controller:<span class="hljs-number">9292</span> --adminurl=http://controller:<span class="hljs-number">9292</span>
+-------------+----------------------------------+
| Property | Value |
+-------------+----------------------------------+
| adminurl | http://controller:<span class="hljs-number">9292</span> |
| id | <span class="hljs-number">4</span>ca758a4fe4049c491a5c5ace5b792f2 |
| internalurl | http://controller:<span class="hljs-number">9292</span> |
| publicurl | http://controller:<span class="hljs-number">9292</span> |
| region | regionOne |
| service_id | <span class="hljs-number">95</span>a34885c3dc486f98153cf2d3740355 |
+-------------+----------------------------------+</code></pre>
<h3 id="36-啟動服務">3.6 啟動服務</h3>
<p>最後重新啟動 Glance service 讓之前的設定生效:</p>
<pre class="prettyprint"><code class="language-bash hljs ">$ service glance-registry restart
$ service glance-api restart</code></pre>
<h1 id="4驗證-glance-安裝是否成功">4、驗證 Glance 安裝是否成功</h1>
<p>我們可以透過下載隨意一個 linux image 並註冊到 Glance 來測試安裝是否成功。</p>
<p>下載 Linux image:</p>
<pre class="prettyprint"><code class="language-bash hljs ">$ mkdir /tmp/images
$ <span class="hljs-built_in">cd</span> /tmp/images/
$ wget http://cdn.download.cirros-cloud.net/<span class="hljs-number">0.3</span>.<span class="hljs-number">3</span>/cirros-<span class="hljs-number">0.3</span>.<span class="hljs-number">3</span>-x86_64-disk.img</code></pre>
<p>將下載的 Linux image 註冊到 Glance:</p>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 透過 shell script 匯入 OS_USERNAME / OS_PASSWORD / OS_TENANT_NAME / OS_AUTH_URL 等環境變數</span>
$ <span class="hljs-built_in">source</span> ~/OpenStack/admin-openrc.sh
<span class="hljs-comment"># 註冊 image 至 Glance</span>
$ glance image-create --name <span class="hljs-string">"cirros-0.3.3-x86_64"</span> --disk-format qcow2 --container-format bare --is-public <span class="hljs-literal">true</span> --progress < cirros-<span class="hljs-number">0.3</span>.<span class="hljs-number">3</span>-x86_64-disk.img
[=============================>] <span class="hljs-number">100</span>%
+------------------+--------------------------------------+
| Property | Value |
+------------------+--------------------------------------+
| checksum | <span class="hljs-number">133</span>eae9fb1c98f45894a4e60d8736619 |
| container_format | bare |
| created_at | <span class="hljs-number">2014</span>-<span class="hljs-number">09</span>-<span class="hljs-number">24</span>T23:<span class="hljs-number">29</span>:<span class="hljs-number">42</span> |
| deleted | False |
| deleted_at | None |
| disk_format | qcow2 |
| id | <span class="hljs-number">77</span>c0d5f8-<span class="hljs-number">1</span>bcc-<span class="hljs-number">4937</span>-<span class="hljs-number">932</span>c-<span class="hljs-number">72</span>f4b0eccbc3 |
| is_public | True |
| min_disk | <span class="hljs-number">0</span> |
| min_ram | <span class="hljs-number">0</span> |
| name | cirros-<span class="hljs-number">0.3</span>.<span class="hljs-number">3</span>-x86_64 |
| owner | <span class="hljs-number">27466</span>ca061e34b469f84da1e57b5605e |
| protected | False |
| size | <span class="hljs-number">13200896</span> |
| status | active |
| updated_at | <span class="hljs-number">2014</span>-<span class="hljs-number">09</span>-<span class="hljs-number">24</span>T23:<span class="hljs-number">29</span>:<span class="hljs-number">42</span> |
| virtual_size | None |
+------------------+--------------------------------------+</code></pre>
<p>因為 Linux image 都可以直接在網路上取得,所以我們也不需要真的下載到本機空間,也可以直接透過 <strong>copy-from</strong> 參數來使用外部的連結來註冊:</p>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 使用 copy-from 變數註冊來自外部的 image</span>
$ glance image-create --name <span class="hljs-string">"cirros-0.3.3-x86_64"</span> --disk-format qcow2 --container-format bare --is-public <span class="hljs-literal">true</span> --copy-from http://download.cirros-cloud.net/<span class="hljs-number">0.3</span>.<span class="hljs-number">3</span>/cirros-<span class="hljs-number">0.3</span>.<span class="hljs-number">3</span>-x86_64-disk.img
+------------------+--------------------------------------+
| Property | Value |
+------------------+--------------------------------------+
| checksum | None |
| container_format | bare |
| created_at | <span class="hljs-number">2014</span>-<span class="hljs-number">09</span>-<span class="hljs-number">24</span>T23:<span class="hljs-number">36</span>:<span class="hljs-number">17</span> |
| deleted | False |
| deleted_at | None |
| disk_format | qcow2 |
| id | <span class="hljs-number">0985</span>b2f3-<span class="hljs-number">058</span>e-<span class="hljs-number">4</span>ab9-<span class="hljs-number">84</span>e3-<span class="hljs-number">65</span>c51f849408 |
| is_public | True |
| min_disk | <span class="hljs-number">0</span> |
| min_ram | <span class="hljs-number">0</span> |
| name | cirros-<span class="hljs-number">0.3</span>.<span class="hljs-number">3</span>-x86_64 |
| owner | <span class="hljs-number">27466</span>ca061e34b469f84da1e57b5605e |
| protected | False |
| size | <span class="hljs-number">13200896</span> |
| status | queued |
| updated_at | <span class="hljs-number">2014</span>-<span class="hljs-number">09</span>-<span class="hljs-number">24</span>T23:<span class="hljs-number">36</span>:<span class="hljs-number">17</span> |
| virtual_size | None |
+------------------+--------------------------------------+</code></pre>
<p>最後透過以下指令可以查詢目前 image 的註冊狀況:</p>
<pre class="prettyprint"><code class="language-bash hljs ">$ glance image-list
+--------------------------------------+---------------------+-------------+------------------+----------+--------+
| ID | Name | Disk Format | Container Format | Size | Status |
+--------------------------------------+---------------------+-------------+------------------+----------+--------+
| <span class="hljs-number">77</span>c0d5f8-<span class="hljs-number">1</span>bcc-<span class="hljs-number">4937</span>-<span class="hljs-number">932</span>c-<span class="hljs-number">72</span>f4b0eccbc3 | cirros-<span class="hljs-number">0.3</span>.<span class="hljs-number">3</span>-x86_64 | qcow2 | bare | <span class="hljs-number">13200896</span> | active |
| <span class="hljs-number">0985</span>b2f3-<span class="hljs-number">058</span>e-<span class="hljs-number">4</span>ab9-<span class="hljs-number">84</span>e3-<span class="hljs-number">65</span>c51f849408 | cirros-<span class="hljs-number">0.3</span>.<span class="hljs-number">3</span>-x86_64 | qcow2 | bare | <span class="hljs-number">13200896</span> | active |
+--------------------------------------+---------------------+-------------+------------------+----------+--------+
</code></pre></div></body>
</html>曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com4tag:blogger.com,1999:blog-4428257381149033865.post-27026724257423416612014-09-19T17:43:00.001+08:002014-10-04T20:00:09.045+08:00安裝 OpenStack @ Ubuntu 14.04 (2) - 設定 Identity Service (Keystone)<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>安裝 OpenStack @ Ubuntu 14.04 (2) - 設定 Identity Service (Keystone)</title>
<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body><div class="container"><h1 id="目錄">目錄</h1>
<p><div class="toc"><div class="toc">
<ul>
<li><a href="#目錄">目錄</a></li>
<li><a href="#1安裝環境說明">1、安裝環境說明</a></li>
<li><a href="#2identity-service-概觀">2、Identity Service 概觀</a><ul>
<li><ul>
<li><a href="#21-重要名詞說明">2.1 重要名詞說明</a><ul>
<li><a href="#211-tenant">2.1.1 Tenant</a></li>
<li><a href="#212-role">2.1.2 Role</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><a href="#3安裝-identity-service">3、安裝 Identity Service</a></li>
<li><a href="#4設定-user-role-tenant">4、設定 user / role / tenant</a><ul>
<li><ul>
<li><a href="#41-新增-user">4.1 新增 User</a></li>
<li><a href="#42-新增-role">4.2 新增 Role</a></li>
<li><a href="#43-新增-tenant">4.3 新增 tenant</a></li>
<li><a href="#44-將-user-role-tenant-進行連結">4.4 將 user / role / tenant 進行連結</a></li>
<li><a href="#45-設定-openstack-services-之間用的認證資訊">4.5 設定 OpenStack services 之間用的認證資訊</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#5定義-services-api-服務端點">5、定義 services & API 服務端點</a></li>
<li><a href="#6驗證-identity-service-是否安裝成功">6、驗證 Identity Service 是否安裝成功</a><ul>
<li><ul>
<li><a href="#61-進行-name-based-認證">6.1 進行 name-based 認證</a></li>
<li><a href="#62-進行-tenant-based-認證">6.2 進行 tenant-based 認證</a></li>
<li><a href="#63-簡化指令的方式">6.3 簡化指令的方式</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#7參考資料">7、參考資料</a></li>
</ul>
</div>
</div>
</p>
<h1 id="1安裝環境說明">1、安裝環境說明</h1>
<ul>
<li><p>OS:Ubuntu 14.04 LTS</p></li>
<li><p>Controller</p>
<ul><li>IP:<strong>10.0.0.11</strong> / 24</li>
<li>Gateway:10.0.0.1</li></ul></li>
<li><p>Network <br>
</p><ul><li>Management IP:<strong>10.0.0.21</strong> / 24 (<strong>eth0</strong>)</li>
<li>Gateway:10.0.0.1</li>
<li>Instance Tunnel IP:10.0.1.21 / 24 (<strong>eth1</strong>)</li>
<li>External Interface (<strong>eth2</strong>) <br>
<ul><li>IP:不指定 IP </li>
<li>設定方式如下:(修改 <strong>/etc/network/interfaces</strong>) <br></li></ul></li></ul><p></p>
<blockquote>
<p>auto eth2 <br>
iface eth2 inet manual <br>
up ip link set dev <span>$</span>IFACE up <br>
down ip link set dev <span>$</span>IFACE down</p></blockquote></li></ul>
<li><p>Compute 1</p>
<ul><li>Management IP:<strong>10.0.0.31</strong> / 24</li>
<li>Gateway:10.0.0.1</li>
<li>Instance Tunnel IP:10.0.1.31</li></ul></li>
<p>修改每個 node 的 /etc/hosts 檔案,並加入以下內容:</p>
<blockquote>
<p>10.0.0.11 controller <br>
10.0.0.21 network <br>
10.0.0.31 compute1</p>
</blockquote>
<ul>
<li>使用者身分:root</li>
</ul>
<h1 id="2identity-service-概觀">2、Identity Service 概觀</h1>
<p>Identity Service 在整個 OpenStack 架構中提供了兩項功能:</p>
<ol>
<li>認證 &授權</li>
<li>提供可用服務的 API 服務端點目錄資訊</li>
</ol>
<p>Identity Service 提供了 Role-based 的管理概念,並提供傳統的 UserName/Password & Token 的認證方式。</p>
<p>以下的來自官網的圖,描述了 Identity Service(Keystone) 的完整作業流程: <br>
<img src="http://docs.openstack.org/icehouse/install-guide/install/apt/content/figures/2/figures/SCH_5002_V00_NUAC-Keystone.png" alt="Keystone 作業流程" title=""></p>
<h3 id="21-重要名詞說明">2.1 重要名詞說明</h3>
<p>Identity Service 有些觀念要先清楚,列出比較容易搞混的:</p>
<h4 id="211-tenant">2.1.1 Tenant</h4>
<p>tenant 是 identity 服務的操作者用來將特定的 resource 或是 identity objects 區隔。</p>
<p>每一個 tenant 可能會對應到一個客戶,或是一個帳號,也有可能是一個專案。</p>
<h4 id="212-role">2.1.2 Role</h4>
<p>role 包含了指定功能的使用權限,管理者可以根據不同的 role 給定不同的權限,再將 role 指定給 user,每個 user 可以同時被指定為多個 role 藉以授予系統存取權限。</p>
<blockquote>
<p>Keystone 中已經有一個預設的 Role,名稱為 <strong>_member_</strong></p>
</blockquote>
<h1 id="3安裝-identity-service">3、安裝 Identity Service</h1>
<p>接著要安裝認證用的服務:</p>
<blockquote>
<p>apt-get -y install keystone</p>
</blockquote>
<p>安裝完一卡車的套件後,這裡先為 keystone 準備儲存認證用的資料庫(MySQL),輸入以下指令:</p>
<pre class="prettyprint"><code class=" hljs oxygene"># mysql -u root -p
Enter password: ##########
mysql> <span class="hljs-keyword">create</span> database keystone;
Query OK, <span class="hljs-number">1</span> row affected (<span class="hljs-number">0.00</span> sec)
mysql> grant all privileges <span class="hljs-keyword">on</span> keystone.* <span class="hljs-keyword">to</span> <span class="hljs-string">'keystone'</span>@<span class="hljs-string">'localhost'</span> identified <span class="hljs-keyword">by</span> <span class="hljs-string">'YOURKEYSTONEDBPASSWORD'</span>;
Query OK, <span class="hljs-number">0</span> rows affected (<span class="hljs-number">0.00</span> sec)
mysql> grant all privileges <span class="hljs-keyword">on</span> keystone.* <span class="hljs-keyword">to</span> <span class="hljs-string">'keystone'</span>@<span class="hljs-string">'%'</span> identified <span class="hljs-keyword">by</span> <span class="hljs-string">'YOURKEYSTONEDBPASSWORD'</span>;
Query OK, <span class="hljs-number">0</span> rows affected (<span class="hljs-number">0.00</span> sec)
mysql> <span class="hljs-keyword">exit</span></code></pre>
<p>接著修改 keystone 設定,將資料庫指向剛剛建立的 MySQL DB,編輯 <strong>/etc/keystone/keystone.conf</strong>:</p>
<p>修改 <strong>[database]</strong> 區段的 connection 設定如下:</p>
<blockquote>
<p>[database] <br>
connection = <strong>mysql://keystone:YOURKEYSTONEDBPASSWORD@controller/keystone</strong></p>
</blockquote>
<p>並移除原本的 SQLite DB:</p>
<blockquote>
<p>rm /var/lib/keystone/keystone.db</p>
</blockquote>
<p>建立認證服務用的資料庫 table:</p>
<blockquote>
<p>su -s /bin/sh -c “keystone-manage db_sync” keystone</p>
</blockquote>
<p>產生 shared secret:</p>
<blockquote>
<p>openssl rand -hex 10</p>
</blockquote>
<p>編輯 keystone 設定(<strong>/etc/keystone/keystone.conf</strong>),加入以下兩個設定:</p>
<pre class="prettyprint"><code class=" hljs php">[<span class="hljs-keyword">DEFAULT</span>]
admin_token = YOUR_SHARED_SECRET <span class="hljs-comment">#填入上一個步驟中使用 openssl 指令產生的 shared secret</span>
log_dir = /<span class="hljs-keyword">var</span>/log/keystone</code></pre>
<p>重新啟動 keystone 服務:</p>
<blockquote>
<p>service keystone restart</p>
</blockquote>
<p>預設 keystone 的 token 是沒有過期的設定,因此透過以下指令將 token 的過期時間設定為 1 小時:</p>
<blockquote>
<p>(crontab -l -u keystone 2>&1 | grep -q token_flush) || echo ‘@hourly /usr/bin/keystone-manage token_flush >/var/log/keystone/keystone-tokenflush.log 2>&1’ >> /var/spool/cron/crontabs/keystone</p>
</blockquote>
<p>安裝好 Identity Service 之後,接著就要來設定認證相關資訊了。</p>
<h1 id="4設定-user-role-tenant">4、設定 user / role / tenant</h1>
<p>在建立 user / role / tenant 之前,必須先設定好 <strong>OS_SERVICE_TOKEN</strong> & <strong>OS_SERVICE_ENDPOINT</strong> 兩個環境變數,目的是為了以管理者的身分啟用並註冊 Identity Service:</p>
<pre class="prettyprint"><code class="language-bash hljs ">$ <span class="hljs-keyword">export</span> OS_SERVICE_TOKEN=YOUR_ADMIN_TOKEN
$ <span class="hljs-keyword">export</span> OS_SERVICE_ENDPOINT=http://controller:<span class="hljs-number">35357</span>/v2.<span class="hljs-number">0</span></code></pre>
<h3 id="41-新增-user">4.1 新增 User</h3>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 新增 user - admin</span>
$ keystone user-create --name=admin --pass=ADMIN_PASS --email=ADMIN_EMAIL
<span class="hljs-comment"># 新增 user - demo</span>
$ keystone user-create --name=demo --pass=DEMO_PASS --email=DEMO_EMAIL</code></pre>
<h3 id="42-新增-role">4.2 新增 Role</h3>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 新增 role - admin</span>
$ keystone role-create --name=admin</code></pre>
<blockquote>
<p>Keystone 已經內建 <strong>_member_</strong> 為預設 role,之後會將一般的帳號與 <strong>_member_</strong> 進行連結。</p>
</blockquote>
<h3 id="43-新增-tenant">4.3 新增 tenant</h3>
<p>最後新增兩個 tenant 類型,分別是管理者(admin)以及一般使用者(demo):</p>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 新增 tenant - admin</span>
$ keystone tenant-create --name=admin --description=<span class="hljs-string">"Admin Tenant"</span>
<span class="hljs-comment"># 新增 tenant - demo</span>
$ keystone tenant-create --name=demo --description=<span class="hljs-string">"Demo Tenant"</span></code></pre>
<h3 id="44-將-user-role-tenant-進行連結">4.4 將 user / role / tenant 進行連結</h3>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 將 user(admin) 與 role(admin) & tenant(admin) 連結</span>
$ keystone user-role-add --user=admin --tenant=admin --role=admin
<span class="hljs-comment"># 將 user(admin) 與 role(_member_) & tenant(admin) 連結</span>
$ keystone user-role-add --user=admin --role=_member_ --tenant=admin
<span class="hljs-comment"># 將 user(demo) 與 role(_member_) & tenant(demo) 連結</span>
$ keystone user-role-add --user=demo --role=_member_ --tenant=demo</code></pre>
<h3 id="45-設定-openstack-services-之間用的認證資訊">4.5 設定 OpenStack services 之間用的認證資訊</h3>
<p>同樣的,OpenStack 中不同的 service 也需要 username / role / tenant 來進行認證並存取其他的 service,以下建立 service 用的 username / role / tenant:</p>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 建立 service 用 user - service_user</span>
$ keystone user-create --name=service_user --pass=SERVICE_USER_PASS --email=SERVICE_USER_EMAIL
<span class="hljs-comment"># 建立 service 用 role</span>
$ keystone role-create --name=service_role
<span class="hljs-comment"># 建立 service 用 tenant</span>
$ keystone tenant-create --name=service --description=<span class="hljs-string">"Service Tenant"</span>
<span class="hljs-comment"># 將 user(service_user) 與 role(service_role) & tenant(service) 連結</span>
$ keystone user-role-add --user=service_user --role=service_role --tenant=service</code></pre>
<h1 id="5定義-services-api-服務端點">5、定義 services & API 服務端點</h1>
<p>之前提過 Identity Service 其中一個重要功能是「<strong>提供可用服務的 API 服務端點目錄資訊</strong>」,因此安裝好的服務都必須向 Identity Service 註冊,就連 Identity Service 自己也不例外。</p>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 註冊 keystone service</span>
$ keystone service-create --name=keystone --type=identity --description=<span class="hljs-string">"OpenStack Identity"</span>
<span class="hljs-comment"># 設定 Identity Service 的 API 服務端點</span>
$ keystone endpoint-create --service-id=$(keystone service-list | awk <span class="hljs-string">'/ identity / {print $2}'</span>) --publicurl=http://controller:<span class="hljs-number">5000</span>/v2.<span class="hljs-number">0</span> --internalurl=http://controller:<span class="hljs-number">5000</span>/v2.<span class="hljs-number">0</span> --adminurl=http://controller:<span class="hljs-number">35357</span>/v2.<span class="hljs-number">0</span></code></pre>
<h1 id="6驗證-identity-service-是否安裝成功">6、驗證 Identity Service 是否安裝成功</h1>
<p>為了確保 Identity Service 安裝正確,首先清除 <strong>OS_SERVICE_TOKEN</strong> & <strong>OS_SERVICE_ENDPOINT </strong> 兩個環境變數。</p>
<blockquote>
<p>這兩個環境變數用途只是為了以管理者的身分設定 & 註冊 Identity Service 之用。</p>
</blockquote>
<pre class="prettyprint"><code class="language-bash hljs ">$ <span class="hljs-built_in">unset</span> OS_SERVICE_TOKEN OS_SERVICE_ENDPOINT</code></pre>
<h3 id="61-進行-name-based-認證">6.1 進行 name-based 認證</h3>
<pre class="prettyprint"><code class="language-bash hljs ">$ keystone --os-username=admin --os-password=YOUR_ADMIN_PASS --os-auth-url=http://controller:<span class="hljs-number">35357</span>/v2.<span class="hljs-number">0</span> token-get</code></pre>
<p>這個指令會取得有效期間為一個小時(上面有設定)的 token,並搭配指定 user 的 id 資訊。</p>
<p><strong>【註】有 token 資訊表示 Identity Service 正確地被安裝 & 註冊</strong></p>
<h3 id="62-進行-tenant-based-認證">6.2 進行 tenant-based 認證</h3>
<pre class="prettyprint"><code class="language-bash hljs ">$ keystone --os-username=admin --os-password=YOUR_ADMIN_PASS --os-tenant-name=admin --os-auth-url=http://controller:<span class="hljs-number">35357</span>/v2.<span class="hljs-number">0</span> \
token-get</code></pre>
<p>這個指令會取得有效期間為一個小時(上面有設定)的 token,並搭配指定 user & tenant 的 id 資訊。</p>
<p><strong>【註】有 token 資訊表示 Identity Service 正確地被安裝 & 註冊</strong></p>
<h3 id="63-簡化指令的方式">6.3 簡化指令的方式</h3>
<p>看上面這麼一大串指令,看了頭都暈了,其實就是指定了好幾個參數,可以設定一個 bash 檔,指定所需要的環境變數,就可以將指令簡化,建立檔案 <strong>admin-openrc.sh</strong>,並填入以下內容:</p>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-keyword">export</span> OS_USERNAME=admin
<span class="hljs-keyword">export</span> OS_PASSWORD=YOUR_ADMIN_PASS
<span class="hljs-keyword">export</span> OS_TENANT_NAME=admin
<span class="hljs-keyword">export</span> OS_AUTH_URL=http://controller:<span class="hljs-number">35357</span>/v2.<span class="hljs-number">0</span></code></pre>
<p>透過以下指令就可以取得全新的 token:</p>
<pre class="prettyprint"><code class="language-bash hljs ">$ <span class="hljs-built_in">source</span> admin-openrc.sh
$ keystone token-get</code></pre>
<p>最後檢視一下之前設定的 user / role / tenant 是否都有對應正確:</p>
<pre class="prettyprint"><code class="language-bash hljs "><span class="hljs-comment"># 檢視目前的 user 清單 </span>
$ keystone user-list
+----------------------------------+--------------+---------+-------------------+
| id | name | enabled | email |
+----------------------------------+--------------+---------+-------------------+
| eb54ed5c89e1411a9db5cadfd825ae42 | admin | True | admin@example.com |
| bc1ae50e167f45edb064e582702c5792 | demo | True | admin@example.com |
| <span class="hljs-number">877</span>f000de0064ad0a2ef33519af6cc87 | service_user | True | admin@example.com |
+----------------------------------+--------------+---------+-------------------+
<span class="hljs-comment"># 檢視 role 與 user(admin) 的對應資訊</span>
$ keystone user-role-list --user admin --tenant admin
+----------------------------------+----------+----------------------------------+----------------------------------+
| id | name | user_id | tenant_id |
+----------------------------------+----------+----------------------------------+----------------------------------+
| <span class="hljs-number">9</span>fe2ff9ee4384b1894a90878d3e92bab | _member_ | afea5bde3be9413dbd60e479fddf9228 | e519b772cb43474582fa303da62559e5 |
| <span class="hljs-number">5</span>d3b60b66f1f438b80eaae41a77b5951 | admin | afea5bde3be9413dbd60e479fddf9228 | e519b772cb43474582fa303da62559e5 |
+----------------------------------+----------+----------------------------------+----------------------------------+</code></pre>
<h1 id="7參考資料">7、參考資料</h1>
<ul>
<li><a href="http://docs.openstack.org/icehouse/install-guide/install/apt/content/ch_basics.html">Installation Guide for Ubuntu 12.04/14.04 (LTS)</a></li>
</ul></div></body>
</html>曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-5857058674658181762014-09-10T20:36:00.001+08:002014-10-04T11:53:55.832+08:00安裝 OpenStack @ Ubuntu 14.04 (1) - 基本環境設定<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>安裝 OpenStack @ Ubuntu 14.04 (1) - 基本環境設定</title>
<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body><div class="container"><h1 id="目錄">目錄</h1>
<p><div class="toc"><div class="toc">
<ul>
<li><a href="#目錄">目錄</a></li>
<li><a href="#1前言">1、前言</a></li>
<li><a href="#2安裝環境說明">2、安裝環境說明</a></li>
<li><a href="#3套件安裝">3、套件安裝</a><ul>
<li><a href="#31-時間同步">3.1 時間同步</a></li>
<li><a href="#32-資料庫安裝-設定">3.2 資料庫安裝 & 設定</a><ul>
<li><a href="#321-controller">3.2.1 Controller</a></li>
<li><a href="#322-其他-node">3.2.2 其他 node</a></li>
</ul>
</li>
<li><a href="#33-openstack-套件">3.3 OpenStack 套件</a></li>
<li><a href="#34-messaging-server">3.4 Messaging Server</a></li>
</ul>
</li>
<li><a href="#4參考資料">4、參考資料</a></li>
</ul>
</div>
</div>
</p>
<h1 id="1前言">1、前言</h1>
<p>這次 OpenStack 的安裝過程中,在網路的部分選擇使用 <strong>Neutron</strong> 來管理,不使用 <strong>nova-network</strong>,因此需要額外一個 Network Node 來處理網路的工作,如下圖所示:</p>
<p><img src="http://docs.openstack.org/icehouse/install-guide/install/apt/content/figures/1/figures/installguide_arch-neutron.png" alt="Three-node architecture with OpenStack Networking (Neutron)" title=""></p>
<h1 id="2安裝環境說明">2、安裝環境說明</h1>
<ul>
<li><p>OS:Ubuntu 14.04 LTS</p></li>
<li><p>Controller</p>
<ul><li>IP:<strong>10.0.0.11</strong> / 24</li>
<li>Gateway:10.0.0.1</li></ul></li>
<li><p>Network <br>
</p><ul><li>Management IP:<strong>10.0.0.21</strong> / 24 (<strong>eth0</strong>)</li>
<li>Gateway:10.0.0.1</li>
<li>Instance Tunnel IP:10.0.1.21 / 24 (<strong>eth1</strong>)</li>
<li>External Interface (<strong>eth2</strong>) <br>
<ul><li>IP:不指定 IP </li>
<li>設定方式如下:(修改 <strong>/etc/network/interfaces</strong>) <br></li></ul></li></ul><p></p>
<blockquote>
<p>auto eth2 <br>
iface eth2 inet manual <br>
up ip link set dev <span>$</span>IFACE up <br>
down ip link set dev <span>$</span>IFACE down</p></blockquote></li></ul>
<li><p>Compute 1</p>
<ul><li>Management IP:<strong>10.0.0.31</strong> / 24</li>
<li>Gateway:10.0.0.1</li>
<li>Instance Tunnel IP:10.0.1.31</li></ul></li>
<p>修改每個 node 的 /etc/hosts 檔案,並加入以下內容:</p>
<blockquote>
<p>10.0.0.11 controller <br>
10.0.0.21 network <br>
10.0.0.31 compute1</p>
</blockquote>
<ul>
<li>使用者身分:root</li>
</ul>
<h1 id="3套件安裝">3、套件安裝</h1>
<h2 id="31-時間同步">3.1 時間同步</h2>
<p>架設 IaaS 平台,機器間的時間同步是非常重要的,因此這邊要安裝 ntp client 的處理這個部分的需求。</p>
<blockquote>
<p>apt-get -y install ntp</p>
</blockquote>
<h2 id="32-資料庫安裝-設定">3.2 資料庫安裝 & 設定</h2>
<p>OpenStack 在很多部分的控制都仰賴資料庫來處理,因此資料庫的安裝 & 設定也是相當重要的一環,這邊使用 MySQL 作為資料庫,而僅有 controller 需要安裝 mysql server,其他 node 則是安裝 python mysql client 即可。</p>
<h3 id="321-controller">3.2.1 Controller</h3>
<p>安裝 MySQL Server:</p>
<blockquote>
<p>apt-get -y install python-mysqldb mysql-server</p>
</blockquote>
<p>編輯 <strong>/etc/mysql/my.cnf</strong>,並將以下內容加到 <strong>[mysqld]</strong> 區段中:</p>
<pre class="prettyprint"><code class=" hljs axapta">bind-address = <span class="hljs-number">10.0</span><span class="hljs-number">.0</span><span class="hljs-number">.11</span> <span class="hljs-preprocessor">#原本的 bind-address 要移除</span>
<span class="hljs-keyword">default</span>-storage-engine = innodb
innodb_file_per_table
collation-<span class="hljs-keyword">server</span> = utf8_general_ci
init-connect = <span class="hljs-string">'SET NAMES utf8'</span>
character-set-<span class="hljs-keyword">server</span> = utf8</code></pre>
<p>重新啟動 MySQL Server:</p>
<blockquote>
<p>service mysql restart</p>
</blockquote>
<h3 id="322-其他-node">3.2.2 其他 node</h3>
<p>安裝 python mysql client:</p>
<blockquote>
<p>apt-get -y install python-mysqldb</p>
</blockquote>
<h2 id="33-openstack-套件">3.3 OpenStack 套件</h2>
<p>加入 apt 套件庫資訊並更新套件:</p>
<blockquote>
<p>apt-get -y install python-software-properties <br>
add-apt-repository cloud-archive:icehouse <br>
apt-get update <br>
apt-get -y dist-upgrade</p>
</blockquote>
<p>若是 Ubuntu 的其他版本,apt repository 的資訊可以<a href="https://wiki.ubuntu.com/ServerTeam/CloudArchive">參考此處</a>。</p>
<h2 id="34-messaging-server">3.4 Messaging Server</h2>
<p>OpenStack 使用 message broker 來整合不同服務之間的運作 & 狀態資訊,一般都是在 <strong>contoller node</strong> 上執行。</p>
<p>不同的 Linux 套件有其所支援的 message broker,而 Ubuntu 使用的是 <a href="http://www.rabbitmq.com/">RabbitMQ</a>。</p>
<p>在 contoller node 上使用以下指令安裝 RabbitMQ:</p>
<blockquote>
<p>apt-get -y install rabbitmq-server</p>
</blockquote>
<p>安裝好 RabbitMQ 之後,會自動產生一個名為 <strong>guest</strong> 的使用者帳號,以下的範例所使用的就是這個帳號(<strong>正式環境建議另外建立帳號</strong>),因此來改一下密碼:</p>
<blockquote>
<p>rabbitmqctl change_password guest <strong>YOURMESSAGEBROKERPASSWORD</strong></p>
</blockquote>
<p>之後有使用到 message broker 的 OpensStack 服務,就可以在設定檔中設定 RabbitMQ 的密碼,就可以使用到 message broker 的服務了!</p>
<h1 id="4參考資料">4、參考資料</h1>
<ul>
<li><a href="http://docs.openstack.org/icehouse/install-guide/install/apt/content/ch_basics.html">Installation Guide for Ubuntu 12.04/14.04 (LTS)</a></li>
</ul></div></body>
</html>曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com1tag:blogger.com,1999:blog-4428257381149033865.post-28901566384796623292014-08-17T20:20:00.001+08:002014-08-25T21:05:52.693+08:00Google Cloud Datastore with Go 學習筆記 - Queries<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Google Cloud Datastore with Go 學習筆記 - Queries</title>
<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
<script type="text/javascript" src="https://stackedit.io/libs/MathJax/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body><div class="container"><p>類似關聯式資料庫,應用成是同樣也可以針對 entity 進行查詢 & 排序…等操作。</p>
<ul>
<li><p>原本的 where 過濾條件,在 Datastore 中變成了 <a href="https://developers.google.com/appengine/docs/go/datastore/queries#Go_Filters"><strong>filters</strong></a> 的方式,而 filter 可用在 property 的 value、keys、或是 ancestor 上。</p></li>
<li><p>排序則是使用 <a href="https://developers.google.com/appengine/docs/go/datastore/queries#Go_Sort_orders"><strong>sort orders</strong></a> 來進行。</p></li>
<li><p>最後的回傳資料可以是完整的 entity 集合,也可以是包含部分屬性的 entity 集合,甚至可以只是 entity keys。</p></li>
</ul>
<p>而標準的查詢包含了以下資訊:</p>
<ul>
<li>entity kind</li>
<li>0 或多個 filter 條件</li>
<li>0 或多個用來排序結果的 sort orders 條件</li>
</ul>
<blockquote>
<p>為了確保執行的效能 & 節省記憶體,建議盡量每次查詢都限定回傳的資料筆數。</p>
</blockquote>
<h1 id="query-structure">Query structure</h1>
<p>每個 query 會包含有 <a href="https://developers.google.com/appengine/docs/go/datastore/entities#Go_Kinds_and_identifiers">entity kind</a>、零或多個 <a href="https://developers.google.com/appengine/docs/go/datastore/queries#Go_Filters">filter</a>、以及零或多個 <a href="https://developers.google.com/appengine/docs/go/datastore/queries#Go_Sort_orders">sort order</a>。</p>
<h2 id="filters"><i class="icon-filter"></i> Filters</h2>
<p>filter 可以用在 <a href="https://developers.google.com/appengine/docs/go/datastore/queries#Go_Property_filters">property</a> / <a href="https://developers.google.com/appengine/docs/go/datastore/queries#Go_Key_filters">key</a> / <a href="https://developers.google.com/appengine/docs/go/datastore/queries#Go_Ancestor_filters">ancestor</a> 三種資訊上。</p>
<h3 id="property-filter">Property Filter</h3>
<p>以下直接用範例來說明:</p>
<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-keyword">type</span> Person <span class="hljs-keyword">struct</span> {
Name <span class="hljs-typename">string</span>
City <span class="hljs-typename">string</span>
BirthYear <span class="hljs-typename">int</span>
Height <span class="hljs-typename">int</span>
}
<span class="hljs-keyword">func</span> handler_BasicQuery(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
<span class="hljs-comment">//查詢 Height 屬性大於 170 的資料</span>
<span class="hljs-comment">//根據 Height 屬性進行 desc 排序</span>
q := datastore.NewQuery(<span class="hljs-string">"Person"</span>).Filter(<span class="hljs-string">"Height > "</span>,<span class="hljs-number"> 170</span>).Order(<span class="hljs-string">"-Height"</span>)
<span class="hljs-keyword">var</span> people []Person
q.GetAll(c, &people)
<span class="hljs-keyword">for</span> p := <span class="hljs-keyword">range</span> people {
fmt.Fprintf(w, <span class="hljs-string">`Name=%q, City=%q, BirthYear=%d, Height=%d\n`</span>, people[p].Name, people[p].City, people[p].BirthYear, people[p].Height)
}
}</code></pre>
<h3 id="key-filter">Key Filter</h3>
<p>若要使用 entity key 來進行 filter,必須使用特別的關鍵字 <strong><em>_key_</em></strong>。</p>
<p>以下舉個例: </p>
<pre class="prettyprint"><code class="language-go hljs ">q := datastore.NewQuery(<span class="hljs-string">"Person"</span>).Filter(<span class="hljs-string">"__key__ >"</span>, lastSeenKey)</code></pre>
<p>key 值在 datastore 中是如何排序的呢? 是依照以下的順序來排:</p>
<ol>
<li>Ancestor path</li>
<li>Entity kind</li>
<li>Identifier (<strong>Numeric ID 排在自訂的 key name 之前</strong>)</li>
</ol>
<h3 id="ancestor-filter">Ancestor Filter</h3>
<p>指定 ancestor 也是種 filter 的方式,以下舉個簡單的例子:</p>
<pre class="prettyprint"><code class="language-go hljs ">q := datastore.NewQuery(<span class="hljs-string">"Person"</span>).Ancestor(ancestorKey)</code></pre>
<blockquote>
<p>ancestorKey 若是 nil 會產生錯誤,不會回傳 root entities 喔!</p>
</blockquote>
<h2 id="sort-orders"><i class="icon-list"></i> Sort orders</h2>
<p>要進行排序需要指定 <strong>property</strong> & <strong>排序方式</strong>(asc or desc),以下範例說明:</p>
<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">//Name asc</span>
q := datastore.NewQuery(<span class="hljs-string">"Person"</span>).Order(<span class="hljs-string">"Name"</span>)
<span class="hljs-comment">//Height desc</span>
q := datastore.NewQuery(<span class="hljs-string">"Person"</span>).Order(<span class="hljs-string">"-Height"</span>)
<span class="hljs-comment">//多個條件排序</span>
q := datastore.NewQuery(<span class="hljs-string">"Person"</span>).Order(<span class="hljs-string">"Name"</span>).Order(<span class="hljs-string">"-Height"</span>)</code></pre>
<h2 id="special-query-types"><i class="icon-search"></i> Special query types</h2>
<h3 id="kindless-queries">Kindless queries</h3>
<p>若查詢中沒有指定 kind & ancestor,則表示是針對此應用程式在 Datastore 中所有的 entity 進行查詢。</p>
<p>有些特別的資訊(例如:<a href="https://developers.google.com/appengine/docs/go/datastore/stats">statistics entities</a> & <a href="https://developers.google.com/appengine/docs/go/blobstore/reference#BlobInfo">Blobstore metadata entities</a>)就必須要透過這種方式搜尋。</p>
<p>而不指定 kind & ancestor 的搜尋方式也是有限制的,就是不能使用 property 進行搜尋 or 將資料排序,只能使用 <strong><em>_key_</em></strong> 關鍵字來針對 entity key 進行搜尋。</p>
<h3 id="keys-only-queries">Keys-only queries</h3>
<p>透過 KeysOnly() 方法取得 entity 的 key 值集合,舉個簡單範例:</p>
<pre class="prettyprint"><code class="language-go hljs ">q := datastore.NewQuery(<span class="hljs-string">"Person"</span>).KeysOnly()</code></pre>
<h1 id="搜尋限制">搜尋限制</h1>
<p>在 Datastore 上進行搜尋是有些限制的,說明如下:</p>
<ul>
<li><p><strong>在搜尋中沒有包含指定 property 的 entity 都將被忽略</strong> <br>
同樣 kind 底下的 entity 的 property 內容是可以不同的,因此在 filter or sort 時若指定的 property 有可能不會存在於所有的 entity 中,這時沒有該 property 的 entity 都將被忽略。</p></li>
<li><p><strong>“不等於”的 filter 最多只能用在一個 property 上</strong> </p></li>
</ul>
<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">//合法搜尋,兩個 filter 都用在相同的 property 上</span>
q := datastore.NewQuery(<span class="hljs-string">"Person"</span>).
Filter(<span class="hljs-string">"BirthYear >="</span>, minBirthYear).
Filter(<span class="hljs-string">"BirthYear <="</span>, maxBirthYear)
<span class="hljs-comment">//不合法的搜尋,兩個 filter 分別用在不同的 property 上</span>
q := datastore.NewQuery(<span class="hljs-string">"Person"</span>).
Filter(<span class="hljs-string">"BirthYear >="</span>, minBirthYear).
Filter(<span class="hljs-string">"Height <="</span>, maxHeight)
<span class="hljs-comment">//跟"="混用的話,沒有 property 數量限制(但不等於的 filter 還是只能用在同一個 property 上)</span>
q := datastore.NewQuery(<span class="hljs-string">"Person"</span>).
Filter(<span class="hljs-string">"Name ="</span>, targetName).
Filter(<span class="hljs-string">"City ="</span>, targetCity).
Filter(<span class="hljs-string">"BirthYear >="</span>, minBirthYear).
Filter(<span class="hljs-string">"BirthYear <="</span>, maxBirthYear)</code></pre>
<ul>
<li><strong>“不等於” filter 所指定的 property 必須先進行排序</strong></li>
</ul>
<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">//合法搜尋,BirthYear 為第一個排序的 property</span>
q := datastore.NewQuery(<span class="hljs-string">"Person"</span>).
Filter(<span class="hljs-string">"BirthYear >="</span>, minBirthYear).
Order(<span class="hljs-string">"BirthYear"</span>).
Order(<span class="hljs-string">"Name"</span>)
<span class="hljs-comment">//不合法搜尋,BirthYear 必須放置於第一個 property 進行排序</span>
q := datastore.NewQuery(<span class="hljs-string">"Person"</span>).
Filter(<span class="hljs-string">"BirthYear >="</span>, minBirthYear).
Order(<span class="hljs-string">"Name"</span>)
<span class="hljs-comment">//不合法搜尋,Name 為第一個排序的 property (必須是 BirthYear)</span>
q := datastore.NewQuery(<span class="hljs-string">"Person"</span>).
Filter(<span class="hljs-string">"BirthYear >="</span>, minBirthYear).
Order(<span class="hljs-string">"Name"</span>).
Order(<span class="hljs-string">"BirthYear"</span>)</code></pre>
<ul>
<li><p><strong>含有多個 value 的 property 在 filter or sort 時可能會有出乎意料之外的結果</strong> <br>
這個部分等我真的遇到再來寫…..</p></li>
<li><p><strong>在 transaction 中的 query,必須包含 ancestor filter</strong> <br>
因為在 transaction 中的 query 必須屬於相同的 entity group,因此必須帶上 ancestor filter 資訊。</p></li>
</ul>
<h1 id="取得查詢結果">取得查詢結果</h1>
<p>取得查詢結果有幾種方式,介紹如下:</p>
<h3 id="使用-run-method">使用 <a href="https://developers.google.com/appengine/docs/go/datastore/reference#Query.Run">Run</a> method</h3>
<p>透過 Run method 可以得到一個 <a href="https://developers.google.com/appengine/docs/go/datastore/reference#Iterator">Iterator</a>,並搭配 <a href="https://developers.google.com/appengine/docs/go/datastore/reference#Iterator.Next">Next</a> method 可以一個一個的取得搜尋結果,範例如下:</p>
<pre class="prettyprint"><code class="language-go hljs ">q := datastore.NewQuery(<span class="hljs-string">"Person"</span>)
t := q.Run(c)
<span class="hljs-keyword">for</span> {
<span class="hljs-keyword">var</span> p Person
k, err := t.Next(&p)
<span class="hljs-keyword">if</span> err == datastore.Done {
<span class="hljs-keyword">break</span> <span class="hljs-comment">// No further entities match the query.</span>
}
<span class="hljs-keyword">if</span> err != <span class="hljs-constant">nil</span> {
c.Errorf(<span class="hljs-string">"fetching next Person: %v"</span>, err)
<span class="hljs-keyword">break</span>
}
<span class="hljs-comment">// Do something with Person p and Key k</span>
}</code></pre>
<h3 id="使用-getall-method">使用 <a href="https://developers.google.com/appengine/docs/go/datastore/reference#Query.GetAll">GetAll</a> method</h3>
<p>這個方式可以將搜尋結果一次取回來,可參考之前的範例!</p>
<h3 id="使用-peojection-query">使用 <a href="https://developers.google.com/appengine/docs/go/datastore/projectionqueries">peojection query</a></h3>
<p>可用來取得 entity 中部分的 property 的資訊。</p>
<h3 id="使用-keys-only-query">使用 keys-only query</h3>
<p>透過 <strong>KeyOnly</strong> method 僅取得 entity key。</p>
<h3 id="使用-limit-offset-達到資料分頁目的">使用 Limit & Offset (達到資料分頁目的)</h3>
<p>可透過 Limit & Offset 兩個 method 來取得特定範圍的 entity 資料,達到資料分頁效果,範例如下:</p>
<pre class="prettyprint"><code class="language-go hljs "><span class="hljs-comment">//取得第 6~10 筆的資料</span>
q := datastore.NewQuery(<span class="hljs-string">"Person"</span>).Order(<span class="hljs-string">"-Height"</span>).Limit<span class="hljs-number">(5</span>).Offset<span class="hljs-number">(5</span>)</code></pre>
<blockquote>
<p>比較需要注意的是, 雖然 Offset 可以忽略前幾筆資料,但其實資料還是有回傳的(這些都是要收費的),因此若是要 <strong>僅回傳</strong> 特定筆數資料,就必須使用 <a href="https://developers.google.com/appengine/docs/go/datastore/queries#Go_Query_cursors">query cursor</a> 來處理。</p>
</blockquote>
<h1 id="query-cursors">Query cursors</h1>
<p>透過 query cursor 就可以取得特定範圍的資料而沒有 Offset 的問題。</p>
<p>當執行了一個取得資料的動作後,應用程式可以取得一個 cursor(base64 編碼過的字串),用來表是上一次取得結果的索引位置,如此一來就可以用 cursor 來取得下一批的資料。</p>
<p>除了可以透過 cursor 指定取得資料的起始點之外,還可以透過指定 end cursor 來限制回傳資料的範圍。</p>
<h3 id="使用限制">使用限制</h3>
<p>cursor 在使用上有些限制存在:</p>
<ul>
<li><p>cursor 僅有在相同的應用程式內,並使用相同的 query(相同的 kind & ancestor & property filter) 時才有效。</p></li>
<li><p>若用在有多個值的 property 上時,cursor 的運作可能會不如預期。</p></li>
<li><p>新的 App Engine 功能釋出時,可能會造成某些 cursor 不再有效,此時 Datastore 會回傳 error。 </p></li>
</ul></div></body>
</html>曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-14681584505576914302014-08-13T21:14:00.001+08:002014-08-13T21:18:56.095+08:00Google Cloud Datastore with Go 學習筆記 - Overview<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Google Cloud Datastore with Go 學習筆記 - Overview</title>
<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
<script type="text/javascript" src="https://stackedit.io/libs/MathJax/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body><div class="container"><h2 id="與傳統關聯式資料庫的差異">與傳統關聯式資料庫的差異</h2>
<p>與傳統資料庫比較,Google Cloud Datastore(以下簡稱 Datastore) 架構於分散式系統上,擁有高度的可延展性,在裡面存放的資料以 <strong>Entity</strong> 的形式存在。 <br>
以下有幾項重要的不同:</p>
<ul>
<li><p>Datastore 是以可延展為前提所設計,在繁忙工作時依然有高效能的表現 </p>
<ul><li>寫入 Datastore 的資料會被自動分散到不同的機器上。</li>
<li>讀取 Datastore 的資料時,假設查詢相同數量的資料(例如:50 個 Entity),不論是向擁有 100 個 Entityt 的 Dataset 查詢,或是向有 100 萬個 Entity 的 Dataset 查詢,都會是一樣的快速。 </li></ul></li>
<li><p>因為所有的查詢都必須有預先定義好的 index 來處理,因此查詢語法的變化就無法像傳統關聯式資料庫一樣多變,以下類型的查詢就不支援:</p>
<ul><li>Join</li>
<li>多欄位的 not equal 篩選</li>
<li>子查詢</li></ul></li>
<li><p>不同於關聯式資料庫,Table 中的每一筆資料的型態都要是相同的;在 Datastore 中,即使相同 kind 的 Entity 也不一定有要相同的屬性</p></li>
</ul>
<h2 id="entity">Entity</h2>
<p>存放於 Datastore 內的資料以<strong>物件(object)</strong>的形式存在,這些物件稱為 <strong>Entity</strong>。</p>
<p>Entity 內可以有一或多個屬性,這些屬性稱為 <strong>Property</strong>。</p>
<p>每個 Property 都會有其對應的 <strong>Value</strong>,這些 value 可以是各式不同的型態,包括整數、浮點數、字串 <br>
、日期、二進位資料 …. 等。</p>
<blockquote>
<p>Datastore entity 是 schemaless 的,若是要確保每個 entity 都會有相同的 property set,就必須透過程式自行控制。</p>
</blockquote>
<h3 id="kind-key-identifier"><i class="icon-file"></i> Kind / Key / Identifier</h3>
<p>每個 entity 都屬於特定的 <strong>kind</strong>,目的是可以在之後進行有分類的查詢,例如:位於人事系統中的職員資料,可能就會屬於 Employee 這個 kind。</p>
<p>每個 entity 都有專屬且唯一的 key,而 key 是由以下項目所組成:</p>
<ul>
<li>entity 所屬的 <strong>kind</strong></li>
<li><strong>Identifier</strong>,可能是一個 key name 字串,或是整數 ID</li>
<li>若是以階層式存在的 entity,還會包含 <strong>ancestor path</strong> 資訊</li>
</ul>
<p>因為 identifier 是屬於 entity key 的一部分,因此在 entity 建立時就會指派且無法變更,可以有兩種方式指派:</p>
<ol>
<li>程式中直接指定 key name 字串給 entity</li>
<li>讓 Datastore 自動指定整數 ID 給 entity (有兩種產生整數 ID 的 policy,可參考<a href="https://developers.google.com/appengine/docs/go/datastore/entities#Go_Assigning_identifiers">文章1</a>、<a href="https://developers.google.com/appengine/docs/go/config/appconfig#Go_app_yaml_Auto_ID_policy">文章2</a>)</li>
</ol>
<h3 id="ancestor-path"><i class="icon-left-circled"></i> Ancestor path</h3>
<p>就像檔案系統一樣,entity 也可以以階層式的方式存放。(entity 中還包含了 child entity)</p>
<p>沒有 parent 的 entity 稱為 <strong>root entity</strong>。</p>
<p>entity 之間的父子關係若是已經給定了就無法再更改,而 Datastore 不會指派相同的整數 ID 給同樣 parent 的 entity 或是兩個 root entity。</p>
<p>由於 entity 有父子關係,因此要完整表示一個 child entity 的 key,就必須包含類似以下的 ancestor path 資訊:</p>
<blockquote>
<p><strong>[Person:GreatGrandpa, Person:Grandpa, Person:Dad, Person:Me]</strong></p>
</blockquote>
<p>若是 root entity,ancestor path 資訊就大概會像下面這樣:</p>
<blockquote>
<p><strong>[Person:GreatGrandpa]</strong></p>
</blockquote>
<h2 id="query-index">Query & Index</h2>
<p>若想要對 Datastore 進行查詢,可以包含以下資訊:</p>
<ul>
<li>指定要查詢的 <a href="https://developers.google.com/appengine/docs/go/datastore/#Go_Kinds_keys_and_identifiers"><strong>kind</strong></a> 資訊之外</li>
<li>根據查詢需求指定 <a href="https://developers.google.com/appengine/docs/go/datastore/queries#Go_Filters"><strong>filter</strong></a>,而 filter 資訊可以是 entity 的 key / value / <a href="https://developers.google.com/appengine/docs/go/datastore/queries#Go_Ancestor_queries">ancestor</a> … 等資訊</li>
<li>用來根據 property 來排序查詢結果用的 <a href="https://developers.google.com/appengine/docs/go/datastore/queries#Go_Sort_orders"><strong>sort orders</strong></a> 資訊</li>
</ul>
<p>查詢結果可以是完整的 entity 資訊,或是僅有部分 property 的 entity,也可以只有 entity key。 </p>
<blockquote>
<p>為了確保查詢效能,建議每個查詢都包含指定有限數量的 entity,避免一次回傳太多資料而影響查詢效能。</p>
<p>若是要確保回傳的資料達到 <a href="http://en.wikipedia.org/wiki/Strong_consistency">strong consistent</a> 的狀態,在規劃資料存放的架構時,就要指定好相關的 entity 都放置於相同的 entity group 中,否則 Datastore 只能確保回傳的資料是 <a href="http://en.wikipedia.org/wiki/Eventual_consistency">eventually consistent</a>。</p>
</blockquote>
<p>App Engine 會預先在 entity 的每個 property 上定義 index,若要定義更複雜的 index 資訊,則可以修改 <a href="https://developers.google.com/appengine/docs/go/config/indexconfig"><strong>index.yaml</strong></a> 這個檔案。</p>
<h2 id="transaction">Transaction</h2>
<p>相同於傳統的關聯式資料庫,每一個交易可以包含多個 insert / update / delete 的操作,這些操作最多可以同時分布到 <strong>5</strong> 個不同的 entity group。</p>
<p>Datastore 使用 [<strong>optimistic concurrency</strong>] 的機制來管理 transaction,當多個交易同時針對相同的 entity group 進行修改時,只有第一個 transaction 的 commit 會成功,其餘會失敗,而失敗的 transaction 可以針對第一個 transaction 已經修改好的資料重新嘗試變更操作。也因為這種機制,就限制了對於相同的 entity group 可以同時進行的 transaction 數量。</p>
<p>同一個 transaction 中若是對多個 entity group 進行操作,就稱為 <strong>cross-group (XG) transaction</strong>,最多可以同時對 5 個 entity group 進行操作。</p>
<p>在 cross-group transaction 終無法執行 non-ancestor query,因為此類型的查詢可能會包含部分之前被 commit 後的交易結果。</p>
<p>而且在 cross-group transaction 中,即使只有讀取 entity group 的資料而未修改,但若有其他 transaction 同時存取相同的 entity group,也是會有衝突錯誤發生的。</p>
<h2 id="quotas-and-limits">Quotas and limits</h2>
<p>使用 Google Cloud Datastore,有幾種不同的 quota 定義必須了解:</p>
<ul>
<li><p>Datastore API Calls quota <br>
每次呼叫 Datastore API 的次數屬於此類 (有些 library 的一次呼叫會包含多次的 Datastore API Call)。</p></li>
<li><p>Data Send to Datastore API quota <br>
透過應用程式傳來的資料屬於此類。</p></li>
<li><p>Data Received from Datastore API quota <br>
應用程式接收到來自 Datastore 的資料屬於此類。</p></li>
<li><p>Stored Data quota <br>
存於 Datastore 的資料(包含 entity 的 property & key,甚至 index 都算)數量屬於此類。若要了解這些資料在 Datastore 中詳細的存放方式,可以參考 <a href="https://developers.google.com/appengine/articles/storage_breakdown">How Entities and Indexes Are Stored</a> 這篇文章。</p></li>
</ul>
<h2 id="參考資料">參考資料</h2>
<ol>
<li><a href="https://developers.google.com/appengine/docs/go/datastore/">Go Datastore API - Go — Google Developers</a></li>
</ol></div></body>
</html>曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-1892289886721029702014-08-12T11:33:00.001+08:002014-08-12T11:34:31.219+08:00[VMware] 解決 consolidation 時發生 file locked 錯誤的狀況<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>[VMware] 解決 consolidation 時發生 file locked 錯誤的狀況</title>
<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
<script type="text/javascript" src="https://stackedit.io/libs/MathJax/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body><div class="container"><p>今天早上到公司發現 vSphere Web Client 中有提示某台 VM 有 warning,進到 Summary tab 看了一下,出現了訊息如下:</p>
<blockquote>
<p>Virtual machine Consolidation Needed status <br>
Virtual machine disks consolidation is needed.</p>
</blockquote>
<p><img src="https://lh5.googleusercontent.com/quusCnvD-yBryvzhbQJvjCa9GTqlNrf366mZd4AeQa4=s0" alt="vSphere Web Client 中提示 VM 有狀況,檢視後顯示 "Virtual machine Consolidation Needed status. Virtual machine disks consolidation is needed"" title="VM 需要進行 disk consolidation"></p>
<hr>
<p>恩,一看就大概可以知道是 snapshot 時出了點狀況,所以 disk 需要執行 consolidation 的動作,於是很直覺的按照下圖執行:</p>
<blockquote>
<p><strong>VM</strong> >> <strong>All vCenter Actions</strong> >> <strong>Snapshots</strong> >> <strong>Consolidate</strong></p>
</blockquote>
<p><img src="https://lh6.googleusercontent.com/Tc-cSb3vNlIyK3jgYzojdTb8JVQH9CGX3oEXt6Dc5jk=s0" alt="執行 snapshot consolidation @ VM" title="執行 snapshot consolidation @ VM"></p>
<p>結果出現了以下錯誤訊息:</p>
<blockquote>
<p>Consolidate virtual machine disk files <br>
[VM Name] <br>
Unable to access file since it is locked</p>
</blockquote>
<p><img src="https://lh3.googleusercontent.com/uJff0QPqjnumVHFjVY1P6VOoR0w5bIRInz5NifbOyKY=s0" alt="Consolidate Error" title="Consolidate Error"></p>
<hr>
<p>後來發現原來是 VDP 搞的禍,詢問原廠人員後,他們提到有時候 VDP 在備份的時候會搭配 snapshop 的機制來進行,但有時候會發生秀逗…..</p>
<p>處理的方式很簡單,因為 VDP 在處理 snapshot 時出了 trouble,因此在 <strong>VDP</strong> 的 VM 內就會殘留有問題的 snapshot 資訊,可透過以下方式尋找:</p>
<blockquote>
<p><strong>VM</strong> >> <strong>Edit virtual machine settings</strong> >> <strong>尋找有問題的 Hard disk</strong>(此處為帶有 warning VM name 的 vmdk 檔案) >> <strong>Remove</strong></p>
<p><strong>(注意! 不要勾選 Delete files from datastore)</strong></p>
</blockquote>
<p><img src="https://lh3.googleusercontent.com/Y6xTC3uilez2mRYBvgAwI1SRA_FoF7NvpaLH8b4uk88=s0" alt="從 VDP 中移除有問題的 VMDK" title="從 VDP 中移除有問題的 VMDK"></p>
<p>當有問題的 vmdk 被移除後,最後再重新做一次 snapshot consolidate,就可以解決此 warning 囉!</p></div></body>
</html>曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-74450909612681856512014-08-08T22:32:00.001+08:002014-08-13T21:25:36.333+08:00讓 Sublime Text 3 支援 Auto Complete for Go & Google App Engine Library<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>讓 Sublime Text 3 支援 Auto Complete for Go & Google App Engine Library</title>
<link rel="stylesheet" href="https://stackedit.io/res-min/themes/base.css" />
<script type="text/javascript" src="https://stackedit.io/libs/MathJax/MathJax.js?config=TeX-AMS_HTML"></script>
</head>
<body><div class="container"><p>首先在 Ubuntu 下安裝 Sublime Text,可以參考以下這篇:</p>
<blockquote>
<p><a href="http://blog.lyhdev.com/2013/10/ubuntu-linux-sublime-text-2.html">在 Ubuntu Linux 下安裝及使用 Sublime Text 2 / 3 - 玩物尚誌</a></p>
</blockquote>
<hr>
<p>接著讓 Sublime Text 支援 Auto Complete for Go,可以參考以下這篇:</p>
<blockquote>
<p><a href="http://www.cnblogs.com/golove/p/3810931.html">基礎知識- 在Ubuntu 14.04 中配置Sublime Text 3 的Golang 開發環境- GoLove - 博客園</a></p>
</blockquote>
<hr>
<p>最後讓 Sublime Text 支援 Google App Engine Library 的 Auto Complete,步驟如下:</p>
<h4 id="1設定-gosublime">1、設定 GoSublime</h4>
<p>開啟 <strong>Preferences</strong> > <strong>Package Settings</strong> > <strong>GoSublime</strong> > <strong>Settings-User</strong>,輸入以下內容:</p>
<pre class="prettyprint prettyprinted"><code><span class="pun">{</span><span class="pln">
</span><span class="str">"use_legacy_imports"</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">,</span><span class="pln">
</span><span class="str">"installsuffix"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"appengine"</span><span class="pun">,</span><span class="pln">
</span><span class="str">"env"</span><span class="pun">:</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="str">"GOPATH"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"$GOPATH"</span><span class="pun">,</span><span class="pln">
</span><span class="str">"GOROOT"</span><span class="pun">:</span><span class="pln"> </span><span class="str">"$HOME/google-cloud-sdk/platform/google_appengine/goroot"</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code></pre>
<p>其中 <strong>$HOME/google-cloud-sdk/platform/google_appengine/goroot</strong> 是 Google Cloud SDK 在我的電腦上安裝後的路徑,必須根據自己的環境去修改。</p>
<h4 id="2加入-symbolic-link-for-google-app-engine-library">2、加入 Symbolic Link for Google App Engine Library</h4>
<p>此時重新開啟 Sublime Text,還無法自動抓取到 Google App Engine Library 的定義,因為在 $GOROOT 中的 /pkg 目錄中,library 位於 <strong>/[GOOS]<em>[GOARCH]_appengine</em></strong><em> 目錄中(我的例子是 <strong>~/google-cloud-sdk/platform/google_appengine/goroot/pkg/linux_amd64_appengine</strong>),但預設抓取的是 <strong>/[GOOS]</strong></em><strong>[GOARCH]</strong> 路徑。 <br>
因此下指令建立 symbolic link:</p>
<blockquote>
<p>cd ~/google-cloud-sdk/platform/google_appengine/goroot/pkg <br>
ln -s ~/google-cloud-sdk/platform/google_appengine/goroot/pkg/linux_amd64_appengine ./linux_amd64</p>
</blockquote>
<p>最後重新開啟 Sublime Text,就會發現 Auto Complete for Google App Engine Library 已經可以正常使用啦!!</p>
<hr>
<h2 id="參考文章">參考文章</h2>
<ol>
<li><a href="http://blog.lyhdev.com/2013/10/ubuntu-linux-sublime-text-2.html">在 Ubuntu Linux 下安裝及使用 Sublime Text 2 / 3 - 玩物尚誌</a></li>
<li><a href="http://www.cnblogs.com/golove/p/3810931.html">基礎知識- 在Ubuntu 14.04 中配置Sublime Text 3 的Golang 開發環境- GoLove - 博客園</a></li>
<li><a href="https://github.com/DisposaBoy/GoSublime/issues/418">Code Completion and Google App Engine (Bug in GoSublime or GoCode?) · Issue #418 · DisposaBoy/GoSublime · GitHub</a></li>
</ol></div></body>
</html>曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-3614968221462667722014-07-23T18:08:00.001+08:002014-08-06T21:20:00.062+08:00[Go] GoLang 資源整理目前正在學 Google Go,慢慢的有發現甚麼不錯的學習資源就擺進來...<br />
<br />
<h4>
網站</h4>
<ol>
<li><a href="http://golang.org/" target="_blank">The Go Programming Language</a><br />Go 的官方網站,首頁還有 playground 的環境可以直接寫些簡單的程式做練習用,原生 library 的文件都可以在這邊找到。</li>
</ol>
<br />
<h4>
開發工具</h4>
<h3>
<b><span style="color: blue;"><br /></span></b></h3>
<h3>
<b><span style="color: blue;">Sublime Text</span></b></h3>
<ol>
<li><a href="http://blog.lyhdev.com/2013/10/ubuntu-linux-sublime-text-2.html" target="_blank">在 Ubuntu Linux 下安裝及使用 Sublime Text 2 / 3 - 玩物尚誌</a></li>
<li><a href="http://www.cnblogs.com/golove/p/3810931.html" target="_blank">基礎知識- 在Ubuntu 14.04 中配置Sublime Text 3 的Golang 開發環境- GoLove - 博客園</a></li>
<li><a href="http://akr.tw/2012/09/inconsolata-sublime-text-2/" target="_blank">在 Sublime Text 2/3 設定 Inconsolata 字型 | akiratw Blog</a></li>
<li><a href="https://github.com/DisposaBoy/GoSublime/issues/418" target="_blank">Code Completion and Google App Engine (Bug in GoSublime or GoCode?) · Issue #418 · DisposaBoy/GoSublime · GitHub</a></li>
</ol>
<br />
<br />
<h4>
電子書</h4>
<ol>
<li><a href="https://github.com/astaxie/build-web-application-with-golang" target="_blank">Go Web 編程 @ github</a><br />這是對岸的朋友寫的,其實就是「<a href="http://www.tenlong.com.tw/items/9865712342?item_id=890039" target="_blank">21 世紀的 C 語言:史上最簡潔程式語言 Go Web 開發到底</a>」的原始版本。(書寫的還不錯,有心學習的朋友就買書來支持一下囉!)</li>
</ol>
曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-66763119522326342842014-07-13T20:53:00.000+08:002014-07-13T20:53:27.495+08:00[Go] 在 Ubuntu 14.04 中設定 Go Syntax Highlight for Vim為了在 Ubuntu 用 vim 編輯 *.go 檔案時有 syntax highlight 的效果<br />
<div>
<br /></div>
<div>
要額外安裝 vim-syntax-go 套件,並做些許設定</div>
<div>
<br /></div>
<div>
詳細步驟如下:</div>
<div>
<br /></div>
<div>
1、安裝 vim & vim-syntax-go</div>
<div>
<br /></div>
<div>
2、找到 go.vim 檔案 (在我的電腦裡是在 <span style="color: blue;"><b>/usr/share/vim/addons/syntax</b> </span>目錄中),並放到 <b><span style="color: red;">~/.vim/syntax</span></b> 目錄中</div>
<div>
<br /></div>
<div>
3、編輯 <b><span style="color: red;">~/.vim/ftdetect/go.vim</span></b> 檔案,並輸入以下內容</div>
<blockquote class="tr_bq">
au BufRead,BufNewFile *.go set filetype=go</blockquote>
<div>
4、編輯 <b><span style="color: red;">~/.vimrc</span></b> 檔案,輸入以下內容</div>
<script src="https://gist.github.com/godleon/031cd2a1994da35e9a38.js"></script>
<br />
<div>
最後登出再登入就完工囉! </div>
曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-6567407563108898292014-05-28T20:57:00.003+08:002014-05-28T20:57:54.874+08:00[VMware] 透過 VLAN 的方式在 vSwitch 中設定多個網段這功能必須透過 VLAN 的方式來達成,設定步驟如下:<br />
<br />
1、在 vSwitch 中建立 Virtual Machine Port Group,除了設定一個好記的 Network Label 之外,最重要的是<b><span style="color: red;">設定正確的 VLAN ID</span></b> (假設此處設定 50)<br />
<br />
2、新增第二個 Virtual Machine Port Group,設定 VLAN ID 為 51<br />
<br />
3、在實體的 Switch 中,將 vSwitch 所對應到實體 switch 的實體 port 上,進行以下設定:<br />
<ul style="background-color: #fefdfa; list-style-image: initial; list-style-position: initial; margin: 0.5em 0px; padding: 0px 2.5em;">
<li>Link Type:<span style="color: red;"><b>Trunk</b></span></li>
<li>PVID:<b><span style="color: red;">1</span></b></li>
<li>Tagged Membership:<b><span style="color: red;">50, 51 </span></b></li>
</ul>
<div>
如此一來,設定就完成囉,分散在不同 Port Group 的 VMs,各自所產生的網路流量都會附帶著 vlan tag 供辨識囉!</div>
<div>
<br /></div>
<div>
這樣做可以達成兩個目的:</div>
<div>
<ol>
<li>vlan tag 可被實體 switch 與 vSwitch 辨識,廣播流量不會互相干擾。</li>
<li>可在同一個 vSwitch 中設定多個網段,提升網路管理上的彈性。</li>
</ol>
</div>
曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-41007963930977600642014-05-28T20:37:00.000+08:002014-05-28T20:40:05.521+08:00[VMware] vSphere ESXi 5.5 設定 NIC Teaming (搭配 HP A5120 Switch)今天把 server 重灌成 5.5 U1 的版本,想說順便把 NIC Teaming 作一作....
<br />
<br />
測試了半天終於試成功了,為了怕未來又忘了,筆記一下...<br />
<br />
大概分成兩個部分<br />
<br />
<h2>
vSwitch 設定</h2>
1、新增 vSwitch,並指定多張(2~8)網卡與此 vSwitch 相連。<br />
<br />
2、若有設定 VMKernal Adapter,設定管理用 IP Address,可不指定 VLAN ID,若需要 vMotion / FT / Virtual SAN ... 等功能,可順便開起來。<br />
<br />
3、進入 vSwitch 設定中的 <b>Teaming and failover</b> 的功能,將選項設定如下:<br />
<br />
<ul>
<li>Load balancing:Route based on IP hash </li>
<li>Network failure detection:Link status only</li>
<li>Notify switches:Yes</li>
<li>Failback:Yes</li>
</ul>
<div>
4、除了上述設定外,還要將所有的 adapters 移動到 Active adapters 中 (放到 standby 就僅能做為 failover 用囉)。</div>
<div>
<br /></div>
<h2>
實體 Switch 設定
</h2>
1、在實體 switch 中,將對應的多個 port 設定為同一個 Link Aggregation Group (簡稱 LAG)。<br />
<br />
2、將 LAG 的 Interface Type 設定為 Static (LACP Disabled)。<br />
<br />
3、根據自家環境的設定,將 LAG 指定所需要的 PVID or 設定相對應的 Link Type(Access / Hybrid / Trunk),並 tag 所需要的 VLAN ID。<br />
<br />
以我公司的例子,必須作以下設定:(<b>只給 VLAN 10 的流量走</b>)<br />
<ul>
<li>Link Type:Access</li>
<li>PVID:10</li>
<li>Untagged Membership:10</li>
</ul>
<div>
<br /></div>
<div>
如此一來,VMKernel 的流量就可以自動分散到多條線路上囉!</div>
<div>
<br /></div>
<h2>
參考資料</h2>
<div>
<ol>
<li><a href="http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1001938" target="_blank">VMware KB: Host requirements for link aggregation for ESXi and ESX</a></li>
<li><a href="http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1004048" target="_blank">VMware KB: Sample configuration of EtherChannel / Link Aggregation Control Protocol (LACP) with ESXi/ESX and Cisco/HP switches</a></li>
</ol>
</div>
曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-13172138363793916802014-05-07T22:08:00.000+08:002014-05-07T22:30:30.648+08:00[AngularJS] AngularJS 與 Animation.css 結合<a href="http://daneden.github.io/animate.css/" target="_blank">Animation.css</a> 是一個提供相當多動畫效果的 css library<br />
<br />
裡面提供了很多很酷的動畫效果<br />
<br />
然而透過一些簡單的方式,就可以很快的跟 <a href="https://angularjs.org/" target="_blank">AngularJS</a> 整合並使用囉!<br />
<br />
詳細的資料可以參考以下連結:<br />
<br />
<a href="http://odetocode.com/blogs/scott/archive/2014/02/25/easy-animations-for-angularjs-with-animate-css.aspx" target="_blank">Easy Animations For AngularJS With Animate.css</a><br />
<br />
<a href="http://www.jvandemo.com/how-to-create-cool-animations-with-angularjs-1-2-and-animate-css/" target="_blank">How to create cool animations with AngularJS 1.2 and Animate.css</a><br />
<br />
<a href="http://www.divshot.com/blog/tips-and-tricks/angular-1-2-and-animate-css" target="_blank">Get Moving With Angular 1.2 Animation and Animate.css</a><br />曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-63439126316892580082014-04-29T09:56:00.004+08:002014-05-07T22:34:33.796+08:00[Azure] 如何讓 Azure Website 支援 json 檔案的存取預設 Azure Website 是沒有支援 json MIME Type 的<br />
<br />
要開啟的方式很簡單,修改 <b>Web.config</b> 檔案即可<br />
<br />
若沒有 Web.Config 這個檔案,直接使用以下內容:<br />
<script src="https://gist.github.com/godleon/8dcf92b633537192e011.js"></script>
<br />
儲存後,上傳至 <b><span style="color: red;">/site/wwwroot</span></b> 目錄下即可<br />
<br />
若是已經有 Web.Config 檔案,則直接加入 <b><span style="color: blue;"><mimemap></mimemap></span></b> 這個段落的設定並重新佈署即可<br />
<br />曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-8629837627301638012014-04-29T09:36:00.002+08:002014-04-29T09:36:32.464+08:00[Azure] 透過 FTP 上傳靜態網頁至 Azure WebSite今天突然有個要將靜態網頁(static html)放到 Azure WebSite 的需求<br />
<br />
想想之前都是用 Visual Studio 佈署的,只是放個網頁應該不需要用到 Visual Studio 這種龐然大物吧......?<br />
<br />
後來發現原來可以透過 FTP 簡單把網頁上傳即可,找到以下資料可供參考!<br />
<br />
<a href="http://blogs.msdn.com/b/avkashchauhan/archive/2012/06/19/windows-azure-website-uploading-downloading-files-over-ftp-and-collecting-diagnostics-logs.aspx" target="_blank">Windows Azure Website: Uploading/Downloading files over FTP and collecting Diagnostics logs - Avkash Chauhan's Blog - Site Home - MSDN Blogs</a><br />
<br />
<a href="http://blogs.msdn.com/b/tomleetaiwan/archive/2012/08/27/ftp-windows-azure-web-sites.aspx" target="_blank">運用 FTP 上傳檔案至 Windows Azure Web Sites - Tom Lee's blog - Site Home - MSDN Blogs</a><br />
<br />
透過 FTP 軟體連上後,再把網頁丟到 /site/wwwroot 目錄下就可以囉!曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-9948408630711633182014-04-20T19:57:00.001+08:002014-04-20T19:58:35.530+08:00[VMware] 學習筆記 - vSphere Installation and Setup<h2>
Introduction to vSphere Installation and Setup</h2>
<h2>
<div style="font-size: medium; font-weight: normal;">
安裝 vSphere 包含以下部分:</div>
<div style="font-size: medium; font-weight: normal;">
<ol>
<li>確認硬體與軟體的需求皆符合</li>
<li>安裝 vCenter Server</li>
<ol>
<li>(optional) 安裝 vCenter Server database<br /><b><span style="color: red;">【註】</span></b><span style="color: blue;">小型環境(5 ESXi host 或 50 VMs 以內) 可使用內建的 MS SQL Server 2008 Express 即可</span>。</li>
<li>安裝完整 vCenter 順序為:<br /><b><span style="color: red;">vCenter Single Sign-On</span></b> => <b><span style="color: red;">vSphere Web Client</span></b> => <b><span style="color: red;">vCenter Inventory Service</span></b> => <b><span style="color: red;">vCenter Server</span></b></li>
</ol>
<li>安裝 ESXi </li>
<ol>
<li>確認要安裝的位置(Local Disk or USB or .... etc)</li>
<li>安裝 ESXi 有三種選項:<br />(1) 互動式安裝<br />(2) 使用 Scritp 安裝 / 升級 / 轉移<br />(3) 使用 vSphere Auto Deploy</li>
</ol>
<li>安裝完成後,進行開機 & 網路設定</li>
<li>若本機硬碟儲存空間很有限,建議設定遠端的 syslog server,或是安裝 vSphere Syslog Collector 來收集所有 ESXi Host 上的 log</li>
</ol>
<div>
<br /></div>
</div>
</h2>
<h2>
System Requirements</h2>
安裝 ESXi 5.5,硬體限制如下:<br />
<br />
<ul>
<li>僅支援 64 位元 x86 架構的 CPU</li>
<li>至少要雙核心的主機</li>
<li>僅支援 LAHF & SAHF CPU 指令集</li>
<li>BIOS 中必須啟用 CPU 中的 NX/XD bit</li>
<li><b><span style="color: red;">主機至少必須要有 4GB 以上的記憶體</span></b>,官方建議 8GB 以上</li>
<li>若要支援 64 位元的 VM,x64 CPU 上的虛擬化的功能(Intel VT-x / AMD RVI)必須啟用</li>
<li>SATA 裝置會被視為遠端裝置,非本機裝置,因此無法作為 <a href="https://pubs.vmware.com/vsphere-50/index.jsp?topic=%2Fcom.vmware.vsphere.install.doc_50%2FGUID-F149EDB3-F00F-43AB-9508-72331F4FE8DB.html" target="_blank">scratch partition</a> 之用</li>
<li><b><span style="color: red;">ESXi 不支援在本機內的 SATA 硬碟上建立可跨多台 ESXi 主機共同分享的 VMFS datastore</span></b></li>
</ul>
<br />
<b><span style="color: red;">【註】</span><span style="color: blue;">在 ESXi 5.5 上無法將 SATA-CDROM 連接至 VM,必須改成 IDE emulation mode 才可用</span></b><br />
<h3>
ESXi Booting Requirements</h3>
vSphere 5.5 支援使用 <a href="http://www.techbang.com/posts/4361-fully-understand-uefi-bios-theory-and-actual-combat-3-liu-xiudian" target="_blank">UEFI</a> 開機,透過 UEFI,可選擇使用硬碟、光碟、甚至於 USB 隨身碟開機。<br />
<span style="color: blue;">若要使用網路開機 or 使用 VMware Auto Deploy 開機,就必須選擇傳統的 BIOS 模式</span>,不能選擇 UEFI。<br />
<b><span style="color: red;">【註】</span><span style="color: blue;">安裝完 ESXi 5.5 之後,若更改開機模式(legacy BIOS <-> UEFI) 可能會造成無法正常開機<!-----><!-----><!-----></-></span></b><br />
<br />
<div>
<ol>
</ol>
<div>
<br /></div>
</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<br />
<div style="font-size: 1em; left: 179.5px; position: absolute; top: 805.15625px; z-index: 9999;">
<div style="-webkit-border-radius: 5px !important; background-color: rgba(17,17,17,0.9) !important; border-color: #111 !important; border-width: 0px !important; box-shadow: #666 2px 2px 2px !important; color: #EEE !important; font-size: 16px !important; max-width: 300px !important; overflow: visible !important; padding: 8px !important; text-align: left !important; z-index: 999999 !important;">
<div class="lang" style="background-image: none; background-position: initial initial; background-repeat: initial initial; border: none; color: inherit; float: right; font-size: 80%;">
zh-CN → zh-TW</div>
<div class="translation" style="background-image: none; background-position: initial initial; background-repeat: initial initial; border: none; color: inherit;">
順序</div>
<div class="additional" style="background-image: none; background-position: initial initial; background-repeat: initial initial; border: none; color: inherit;">
</div>
</div>
</div>
曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0tag:blogger.com,1999:blog-4428257381149033865.post-39244563324312300792014-04-17T11:09:00.001+08:002014-04-29T09:36:49.834+08:00[Azure] 解決部署到 Cloud Service Web Role 後,第一次進入網頁速度很慢的問題最近開發的一個 Azure 上的專案,發現若是 Cloud Service 上的 web role 重新佈署後,網頁第一次瀏覽都會非常的慢,等個 30 秒以上是常態~<br />
<br />
後來發現原來是 IIS IdleTime 的問題,可以透過 startup command 來解決~<br />
<br />
詳細的原因 & 解決方式可參考以下兩個網頁:<br />
<br />
<ol>
<li><a href="http://wp.sjkp.dk/windows-azure-websites-and-cloud-services-slow-on-first-request/" target="_blank">Windows Azure WebSites and Cloud Services Slow on First Request | Simon J.K. Pedersen's SharePoint blog</a></li>
<li><a href="http://c/# - Disable IIS Idle Timeouts in Azure Web Role - Stack Overflow" target="_blank">c# - Disable IIS Idle Timeouts in Azure Web Role - Stack Overflow</a></li>
</ol>
曾建銘http://www.blogger.com/profile/00909689459926867079noreply@blogger.com0