OpenStack 學習筆記 (一)

後續的文章都貼在:臭蛋上python

這一系列筆記已經記錄很長一段時間了,種種緣由沒有貼出來,如今陸陸續續的貼出來。可能因爲本身理解的shell

錯誤和疏忽,致使存在錯誤,歡迎你們指正,交流。json

      全部的源碼分析都是基於OpenStack Folsom版本。api

      參考文檔:http://hi.baidu.com/chenshake/item/184767c22c1231ba0d0a7bc7 數組

      參考文檔:https://www.ibm.com/developerworks/community/blogs/e93514d3-c4f0-4aa0-8844-497f370090f5/entry/openstack_keystone_workflow_token_scoping?lang=zh 函數

      這篇博客的前半部分基本上參照ibm(連接如上)的內容。源碼分析

      在理解OpenStack 受權機制以前,先明白其中的一些基本概念:post

  1. User: 所謂的User表明着一些人或者可以經過keystone獲取訪問的something。User經過自身的證書例如username & password 或者 api keys來訪問服務。
  2. Tenant:Tenant表明nova中的一個project,就是可以聚合一些服務中的一些資源。例如,一個tenant可以有一些nova中的虛擬機,glance中的一些images,quantum中的一些networks,users默認的綁定到某個tenant中。
  3. Role:表明一組用戶可以必定程度的訪問資源。例如可以訪問nova中的vms,glance中的images。Users可以被添加到全部的tenants中或者某個tenant。用戶就獲取了對相應tenant中對應角色獲取的訪問資源的權限。
  4. service: 某類型的服務,例如nova, quantum, glance等等都是服務
  5. endpoint: 訪問服務的入口點,一個http路徑。例如:catalog.RegionOne.image.internalURL = http://10.10.102.14:9292,能夠經過此URL訪問image服務

接下來,分析用戶在訪問一個服務的過程當中,keystone都作了哪些工做,整個過程描述以下:加密

1. 獲取tokenurl

      首先,須要確認你將訪問那個tenant,必須使用keystone來獲取一個unscoped token(意味着這個token沒有和特定的tenant綁定),這個unscoped token可以用來深刻查詢keystone service,肯定你能訪問哪些tenants。獲取一個unscoped token,使用典型的REST API,在request的body中不指定tenantName。例如:

  通過成功的驗證,返回的response大體以下,其中的token id就是獲取到的unscoped token(訪問路徑:/access/token/id),token id 將被在下一次的請求中做爲X-Auth-Token的值,用來標識身份。

2. 獲取tenants

  接下來的一步是,使用unscoped token來獲取能訪問的tenants,其中租期已經由你分配的角色決定了,對於每一個tenant,都有一個肯定的角色。全部在service endpoint上執行的操做都須要一個scoped token。獲取能訪問的tenants,使用 GET /tenants keystone API,其中將unscoped token寫入X-Auth-Token。例如:

  返回的響應以下:

  這是一個tenants數組,包含了可以訪問的tenants。

3. 獲取scoped tokens

  獲取了可以訪問的tenants以後,決定訪問某個tenants,就開始須要獲取一個scoped token,這個scoped token與某個特定的tenant綁定,可以提供這個tenant的metadata和在tenant中的角色。獲取scoped token須要使用POST /tokens keystone API,像第一步同樣,這有兩種形式的API。

  1. 使用第一步中同樣的request body,傳遞user id 和 credentials,還指定tenantName

  2. 使用包含unscoped token和tenant name的request body,這樣無需再post credentials。

  在返回的response中,包含一個scoped token和相關的metadata。

  更重要的是,其中包含了一組service endpoints。這些endpoints 肯定了獲取的token可以訪問的服務,Keystone service manage都是基於service/endpoing catalog的.經過這些endpoings,決定訪問其中的service。

  關於keystone 管理的endpoint/service catalog:

  l  Keystone管理了一些的service,這些service在keyston的service catalog中定義了,定義方式大體是,type,name,description

  l  在service catalog中,endpoint包含了region中一些基本的URL。

  l  每一個endpoint與一個service關聯。

  l  Endpoint url都是base urls,做爲api方位的前綴。

4. 獲取scoped tokens

  如今已經獲取了scoped tokens,而且知道了endpoint API的url,下一步就是調用這些service endpoint。在這一步,使用keystone來確證token的有效性。存在兩種類型的token,一種基於UUID的,一種基於PKI(Public Key Infrastructure)。

   l  UUID  Keystone 將維護一個token的UUID到他們的metadata和有效性的索引,token id沒有攜帶嵌入的metadata,則endpoint service將調用keystone的service,應用這個token id的有效性,keystone將會返回這個token所相關聯的metadata,包括角色,tenancy(租期),可以用在處理api請求的內部使用,endpoint service會爲每一個api request去調用keystone服務驗證有效性。

  l  PKI  PKI使得endpoint service不須要每次api request都進行調用keystone驗證token的有效性。PKI使用public/private certificate pair,基於X.509 技術。Keystone 擁有Public private certificate。任何人都能經過REST API獲取到public certificate,private certificate只能keystone擁有。當使用PKI,第一次使用endpoint service時,endpoint service將請求keystone的public certificate,而且保存起來。使用PKI模式,keystone將會建立json格式的對象,包含token的metadata,使用private certificate來加密token,再使用MD5來爲加密的token建立指紋,這樣的token將做爲第三步中token ID返回,這樣token ID包含了metadata而不只是一個UUID字符串。Endpoint service將會確認簽名,使用public certificate解密token。這樣,token包含全部的metadata了,endpoint service不須要再去找keystone獲取這些信息。

         可以在keystone.conf配置文件中配置token_format.

5. 驗證role metadata

  Endpoint service 使用token的metadata來驗證用戶可以訪問請求的服務。這通常都涉及到Role Base Access Control(RBAC)。基於服務的policy.json文件,使用rule engine來決定用戶的token包含適當的角色訪問。

6. service API request

  到此,user就可以去經過api訪問有權限訪問的資源。

 

   有了上面基本知識,下面結合具體的代碼粗略的描述上面的流程。

   從最開始的shell命令行開始,譬如,nova list命令,但在使用命令以前,咱們須要配置一下環境變量:

  將這些參數配置正確,便可以正確的執行nova list命令了。從nova 命令啓動以後,python-novaclient 的main函數首先獲取一個base parser,用來解析命令行,在獲取這個base parser的過程當中,就會添加參數,例如os-username等等,而且設置其默認值爲,從環境變量中讀取出來的值。例以下面的os-username

  接着,從命令行參數中去獲取os_username,os_password,os_tenant_name,os_auth_url,endpoint_type等等和受權相關的參數,有些參數如endpoint_type爲空,則獲取默認的,若os_username,os_password,os_auth_url都爲空,則命令報錯。

      若是endpoint_type是空的,則讀取默認的值publicURL,前面介紹過service endpoint type的類型,有三類,publicURL,adminURL,internalURL。若service_type爲空,則讀取默認的值compute或者經過命令具體執行的命令是屬於什麼類型的service來肯定。(在定義一個命令行將調用的函數時,能夠爲它添加裝飾器,指定所屬的service)

  譬如經過命令 nova volume-list,就會獲知service_type爲volume,而不是默認的compute。

      而後,從auth_url指定的服務中獲取受權,程序運行到這兒以後,就到了前面介紹的第一步了,獲取tokens,而且在body中指定了tenantName。

 

  在返回的body中,就已經獲取了全部的service catalog,根據service_type,endpoint_type則能夠生成management_url.http://10.10.102.31:8774/v2/eacac8f7935348c7a6aa3ea6fe54e18c,此url則是訪問nova compute服務的base url。而後在此url基礎上,加上命令的具體參數,就訪問此URL的服務--nova compute。

  nova compute接受到此請求以後,會驗證次請求,而後完成請求。

相關文章
相關標籤/搜索