• 検索結果がありません。

openstack Open source software to build public and private clouds. About OpenStack Identity (keystone) Internet Initiative Japan Inc. / Japan OpenStac

N/A
N/A
Protected

Academic year: 2021

シェア "openstack Open source software to build public and private clouds. About OpenStack Identity (keystone) Internet Initiative Japan Inc. / Japan OpenStac"

Copied!
27
0
0

読み込み中.... (全文を見る)

全文

(1)

open

stack

Open source software to build public and private clouds.

About OpenStack Identity (keystone)

Internet Initiative Japan Inc. / Japan OpenStack User Group

さいとうひでき (twitterid: @saito_hideki)

(2)

本セッションの概要

OpenStack

が提供する各コンポーネントが利用

する認証基盤OpenStack Identity(keystone)の概

要と認証・認可の仕組み、利用のされ方につい

て紹介する約30分のセッションです。

(3)

目次

自己紹介

OpenStack Identity(keystone)

について

keystone

の構造

認証・認可の仕組み

普通の利用方法

ちょっと変わった利用方法

まとめ

(4)

自己紹介

なまえ:

齊藤 秀喜 (さいとう ひでき)

TwitterId: @saito_hideki

しごと:

クラウド関連のちょっとした開発

クラウド関連のちょっとした運用

クラウド関連のちょっとした火消しとかお詫び

しゅみ:

OpenStack(

嗜む程度)

(5)

OpenStack Identity(keystone)

について

OpenStack

の各コンポーネントが利用する共

通の認証基盤としてシステム全体に統合認証

機能を提供しています。

OpenStack

を利用する上では嫌でもダダをこ

ねても避けて通ることはできない重要なサー

ビスです。

goo

辞書によると....

1 《建築》(アーチ頂上の)かなめ石,

くさび石.

2 (組織の)中枢, 中心;(学説などの

)根本原理.

(6)

OpenStack Identity(keystone)

について

各コンポーネントとの相関図は以下のような

感じ。コレは動かないと結構ヤバそう。

(7)

認証・認可の仕組み

実際に認証と認可の仕組みを追ってみる。キーワー

ドは以下の4つ。

ユーザID/パスワード

認証とトークンを取得するのに必要なユーザIDとパスワード

トークン

認証成功時に発行されるAPIアクセスに必須となる許可証

テナント

仮想リソースをグループ化したもの。ユーザは所属するテナントに対

して認可された操作権を持つ。

エンドポイント

指定テナント内でユーザに認可されたサービスとそのAPIのURL情報

(8)

認証・認可の仕組み

keystone-all

はクライアントからのリクエスト

(REST

ベース)を処理することにより認証・認可

を行う。POSTする情報はjsonまたはxml形式。

(1)ユーザID/パスワードでトークンを要求

(2)

トークン

(3)権限を持つテナント情報を要求

(4)テナントリスト

(5)テナントに対するエンドポイント情報を要求

(6)認可されているエンドポイントリスト

client

keystone-all

backend

(9)

認証・認可の仕組み

Openstack

のクライアントがendpointを取得する

動きをpythonスクリプトで再現してみる。

#!/usr/bin/env python # coding: utf-8 -*-from getpass import getpass

from httplib import HTTPConnection Import json

user = raw_input("user: ") password = getpass("password: ")

session = HTTPConnection("%s:%s" % (HOST, PORT)) auth_result = get_token(user, password, session) token = auth_result['access']['token']['id']

tenant_result = get_tenant(token, session) tenant = tenant_result["tenants"][0]["id"]

endpoint_result = get_endpoint(token, tenant, session) session.close()

print "=" * 70

print json.dumps(auth_result, sort_keys=True, indent=2) print "-" * 70

print json.dumps(tenant_result, sort_keys=True, indent=2)

get_token()

(1)ユーザID/パスワードからトークンを要求

(2)トークン取得

get_tenant()

(3)権限を持つテナント情報を要求

(4)テナントリスト取得

get_endpoint()

(5)テナントに対するエンドポイント情報を要求

(6)認可されているエンドポイントリスト取得

(10)

認証・認可の仕組み

(1)

ユーザID/パスワードでトークンを要求

(2)

トークン取得

def get_token(user, password, session): token_path = "/v2.0/tokens"

header = { "Content-Type": "application/json" } request = ''' { "auth": { "passwordCredentials": { "username":"%s", "password":"%s" } } }''' % (user, password)

session.request("POST", token_path, request, header) return json.load(session.getresponse())

接続先URLは

http://<host>:<port>/v2.0/tokens

リクエストヘッダでデータ形式をjson

に指定する。

トークンを取得するAPIリクエストを

生成する。

リクエスト送信!(POST)

keystone-allからトークンが返される。

(11)

認証・認可の仕組み

(1)

ユーザID/パスワードでトークンを要求

(2)

トークン取得

{

"access": {

"serviceCatalog": {},

"token": {

"expires": "2012-11-18T05:23:51Z",

"id": "84e9f54aef284bf6a8dc79699045ad99"

},

"user": {

"id": "d60717fe43e94c908bd9248b87d8e045",

"name": "foo",

"roles": [],

"roles_links": [],

"username": "foo"

}

}

}

keystone-all

から返されるトークン

情報。リクエスト時にjson形式を

指定しているので形式は当然なが

らjson形式となっている。

以降のリクエストでは、ヘッダに

X-Auth-Token: トークンID

を付加することにより認証された

リクエストであること証明する。

(12)

認証・認可の仕組み

(3)

権限を持つテナント情報を要求

(4)

テナントリスト取得

接続先URLは

http://<host>:<port>/v2.0/tenants

リクエストヘッダでデータ形式をjson

に指定するだけでなく、X-Auth-Token

に取得済みのトークンIDを指定する。

def get_tenant(token, session):

tenant_path = "/v2.0/tenants"

header = {

"Content-Type": "application/json",

"X-Auth-Token": token,

}

session.request("GET", tenant_path, "", header)

return json.load(session.getresponse())

リクエスト送信!(GET)

(13)

認証・認可の仕組み

(3)

権限を持つテナント情報を要求

(4)

テナントリスト取得

keystone-allから返されるテナント

情報は、リストとなっているので

注意。1つだけでも当然リストと

なる。

次の段階のエンドポイントリスト

を取得するには、このテナントID

を利用する。

{

"tenants": [

{

"description": "Default Tenant",

"enabled": true,

"id": "7695c8332c1b4450a6be1376b3a1f5c4",

"name": "openstackDemo"

}

],

"tenants_links": []

}

(14)

認証・認可の仕組み

(5)

テナントに対するエンドポイント情報を要求

(6)

認可されているエンドポイントリスト取得

def get_endpoint(token, tenant, session): token_path = "/v2.0/tokens" header = { "Content-Type": "application/json", "X-Auth-Token": token, } endpoint_request = ''' { "auth": { "token": { "id":"%s" }, "tenantId": "%s" } }''' % (token, tenant) session.request(

"POST", "/v2.0/tokens" , endpoint_request, header) return json.load(session.getresponse())

接続先URLは

http://<host>:<port>/v2.0/tokens

リクエストヘッダでデータ形式をjson

に指定するだけでなく、X-Auth-Token

に取得済みのトークンIDを指定する。

取得済みのトークンIDとテナントIDで

エンドポイント情報を取得するAPIリク

エストを生成する。

リクエスト送信!(POST)

keystone-allからトークンが返される。

(15)

認証・認可の仕組み

(5)

テナントに対するエンドポイント情報を要求

(6)

認可されているエンドポイントリスト取得

{ "access": { <!-- 中略 --> "serviceCatalog": [ { "endpoints": [ { "adminURL": "http://172.16.100.100:8774/v2/7695c8332c1b4450a6be1376b3a1f5c4", "id": "48567a3d0f7a40fc9aa57172b9cc46e8", "internalURL": "http://172.16.100.100:8774/v2/7695c8332c1b4450a6be1376b3a1f5c4", "publicURL": "http://172.16.100.100:8774/v2/7695c8332c1b4450a6be1376b3a1f5c4", "region": "RegionOne" } ], "endpoints_links": [], "name": "nova", "type": "compute" }, <!-- 中略 --> }

keystone-all

から返されるエンドポイント

情報の中にnova/glanceなどのリソースを

操作するためのAPIのURLが含まれる

(16)

keystone

の構造

本体: keystone-all

keystone-all

の認証/認可用バックエンド

KVS Backend

SQL Backend

PAM Backend

Template Backend

LDAP Backend

<keystone.conf

内>

driver=keystone.identity.backends.*

REST API

keystone-all

(17)

keystone

の構造

mysql> show tables;

+---+

| Tables_in_keystone |

+---+

| ec2_credential |

| endpoint |

| metadata |

| migrate_version |

| role |

| service |

| tenant |

| token |

| user |

| user_tenant_membership |

+---+

10 rows in set (0.00 sec)

SQL

バックエンドで見るkeystoneのデータ構造

keystone

のSQLバックエンドデータベ

ースのテーブル数はessex / folsom と

もに10個

migrate_version

テーブルに記録されて

いるデータベースのバージョン情報は

上がっている。

essex : 1

folsom: 4

データ構造的に見ると変更箇所はtoken

テーブルにvalidフィールドが追加と

なったのみ。

tokenテーブルに発行されたtokenが延

々と登録され続けていくんだけど...

これ溢れないのかな?

(18)

普通の利用方法

それぞれのコンポーネントでkeystoneを利用す

るための設定が必要。

1. keystone

自身の設定

2. nova

からkeystoneを利用するための設定

3. glance

からkeystoneを利用するための設定

ココを参考に設定してください!

http://d.hatena.ne.jp/pyde/20121111/

(19)

普通の利用方法

keystone

コマンドを利用して初期情報を登録し

ます。

1.

テナントの登録

2.

ユーザの登録

3.

ロールの登録

4.

テナント・ユーザ・ロールの関連付け

5. ec2

互換APIを利用する場合はec2クレデンシャルを登録

ココを参考にして作ってください!

http://aikotobaha.blogspot.jp/2012/04/openstackessex-configuration-02keystone.html

(20)

ちょっと変わった利用方法

$ export OS_USERNAME=foo

$ export OS_PASSWORD=bar

$ export OS_TENANT_NAME=openstackDemo

$ export OS_AUTH_URL="http://172.16.100.14:5000/v2.0"

$ nova flavor-list

+----+---+---+---+---+---+---+---+

| ID | Name | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor |

+----+---+---+---+---+---+---+---+

| 1 | m1.tiny | 512 | 0 | 0 | | 1 | 1.0 |

| 2 | m1.small | 2048 | 10 | 20 | | 1 | 1.0 |

| 3 | m1.medium | 4096 | 10 | 40 | | 2 | 1.0 |

| 4 | m1.large | 8192 | 10 | 80 | | 4 | 1.0 |

| 5 | m1.xlarge | 16384 | 10 | 160 | | 8 | 1.0 |

| 6 | m1.minimal | 64 | 0 | 0 | | 1 | 1.0 |

+----+---+---+---+---+---+---+---+

keystone

認証させつつ、novaコマンドと同等の

動きをするpythonスクリプトを書いてみる。

例えばflavorのリスト取得。これが...

keystone認証のための情報

を環境変数に設定する。

(21)

ちょっと変わった利用方法

keystone

さえマスターすれば、こんな感じに

python

でもワンライナーで簡単に書ける!

渾身のワンライナーでflavorリストを取得する

$ python -c 'from httplib import HTTPConnection as c;from json import load as l;s=c("172.16.100.100:5000");s.request("POST","/v2.0/tokens","{\"auth\":

{\"tenantName\":\"openstackDemo\",\"passwordCredentials\":{\"username\":\"foo\",\"password\":\"bar\"}}}",{"Content-Type":"application/json"});j=l(s.getresponse());s.close();tk=j["access"]["token"]["id"];tn=j["access"]

["serviceCatalog"][0]["endpoints"][0]["publicURL"].split("/")[-

1];s.close();s=c("172.16.100.100:8774");s.request("GET","/v2/%s/flavors"%tn,"",{"X-Auth-Token":tk});j=l(s.getresponse());s.close();print [(x["id"],x["name"],x["links"][0]["href"]) for x in j["flavors"]]'

結果(なんかそれっぽい!)

[(u'1', u'm1.tiny', u'http://172.16.100.100:8774/v2/7695c8332c1b4450a6be1376b3a1f5c4/flavors/1'), (u'2',

u'm1.small', u'http://172.16.100.100:8774/v2/7695c8332c1b4450a6be1376b3a1f5c4/flavors/2'), (u'3', u'm1.medium', u'http://172.16.100.100:8774/v2/7695c8332c1b4450a6be1376b3a1f5c4/flavors/3'), (u'4', u'm1.large',

u'http://172.16.100.100:8774/v2/7695c8332c1b4450a6be1376b3a1f5c4/flavors/4'), (u'5', u'm1.xlarge', u'http://172.16.100.100:8774/v2/7695c8332c1b4450a6be1376b3a1f5c4/flavors/5'), (u'6', u'm1.minimal', u'http://172.16.100.100:8774/v2/7695c8332c1b4450a6be1376b3a1f5c4/flavors/6')]

(22)

ちょっと変わった利用方法

続いて、OSイメージのリストも取得してみる。

先ほど既に環境変数としてkeystone認証に必要

となる情報を設定しているのでnovaコマンドで

取得できる。

$ nova image-list

+---+---+---+---+

| ID | Name | Status | Server |

+---+---+---+---+

| c9ef36c7-e6f4-414e-b603-257e36836e76 | tty-linux | ACTIVE | |

| 732ccc6c-093f-4ff3-88ec-d2c97df45014 | tty-linux-kernel | ACTIVE | |

| 1d51d35e-cd1f-4205-9e62-d249e439536b | tty-linux-ramdisk | ACTIVE | |

+---+---+---+---+

(23)

ちょっと変わった利用方法

もちろんpythonのワンライナーでも簡単。

渾身のワンライナーでimageリストを取得する

$ python -c 'from httplib import HTTPConnection as c;from json import load as l;s=c("172.16.100.100:5000");s.request("POST","/v2.0/tokens","{\"auth\":

{\"tenantName\":\"openstackDemo\",\"passwordCredentials\":{\"username\":\"foo\",\"password\":\"bar\"}}}",{"Content-Type":"application/json"});j=l(s.getresponse());s.close();tk=j["access"]["token"]["id"];tn=j["access"]

["serviceCatalog"][0]["endpoints"][0]["publicURL"].split("/")[-

1];s.close();s=c("172.16.100.100:8774");s.request("GET","/v2/%s/images"%tn,"",{"X-Auth-Token":tk});j=l(s.getresponse());s.close();print [(x["id"],x["links"][0]["href"]) for x in j["images"]]'

結果(これまたなんとなく取れてる気がする!)

[(u'c9ef36c7-e6f4-414e-b603-257e36836e76', u'http://172.16.100.100:8774/v2/7695c8332c1b4450a6be1376b3a1f5c4/images/c9ef36c7-e6f4-414e-b603-257e36836e76'), (u'1d51d35e-cd1f-4205-9e62-d249e439536b', u'http://172.16.100.100:8774/v2/7695c8332c1b4450a6be1376b3a1f5c4/images/1d51d35e-cd1f-4205-9e62-d249e439536b'), (u'732ccc6c-093f-4ff3-88ec-d2c97df45014', u'http://172.16.100.100:8774/v2/7695c8332c1b4450a6be1376b3a1f5c4/images/732ccc6c-093f-4ff3-88ec-d2c97df45014')]

(24)

ちょっと変わった利用方法

UI

なしでVMも作れます!

じゃぁじゃぁ...渾身のワンライナーでVMインスタンスを作成!

※このあたりでsessionって1回張ればいいじゃない?って気がつくけど面倒だからそのまま。

$ python -c 'from httplib import HTTPConnection as c;from json import load as l;s=c("172.16.100.100:5000");s.request("POST","/v2.0/tokens","{\"auth\": {\"tenantName\":\"openstackDemo\",\"passwordCredentials\":{\"username\":\"foo\",\"password\":\"bar\"}}}",{"Content-Type":"application/json"});j=l(s.getresponse());s.close();tk=j["access"]["token"]["id"];tn=j["access"] ["serviceCatalog"][0]["endpoints"][0]["publicURL"].split("/")[-1];s.close();s=c("172.16.100.100:8774");s.request("POST","/v2/%s/servers"%tn,"{\"server\": {\"name\":\"josug009\",\"imageRef\":\"c9ef36c7-e6f4-414e-b603- 257e36836e76\",\"flavorRef\":\"6\",\"OS_DCF:diskConfig\":\"MANUAL\"}}",{"Content-Type":"application/json","X-Auth-Token":tk});j=l(s.getresponse());s.close();print j'

結果(おぉ!できた!のか!?)

{u'server': {u'links': [{u'href':

u'http://172.16.100.100:8774/v2/7695c8332c1b4450a6be1376b3a1f5c4/servers/2e81b265-0a33-416d-b60c-afc511395279', u'rel': u'self'}, {u'href': u'http://172.16.100.100:8774/7695c8332c1b4450a6be1376b3a1f5c4/servers/2e81b265-0a33-416d-b60c-afc511395279', u'rel': u'bookmark'}], u'OS-DCF:diskConfig': u'MANUAL', u'id': u'2e81b265-0a33-416d-b60c-afc511395279', u'security_groups': [{u'name': u'default'}], u'adminPass': u'vhcq2X8G4eXz'}}

(25)

ちょっと変わった利用方法

VM

インスタンスのリスト取得だってUI不要。

渾身のワンライナーでちょいちょいのドーンよ!

$ python -c 'from httplib import HTTPConnection as c;from json import load as l;s=c("172.16.100.100:5000");s.request("POST","/v2.0/tokens","{\"auth\":

{\"tenantName\":\"openstackDemo\",\"passwordCredentials\":{\"username\":\"foo\",\"password\":\"bar\"}}}",{"Content-Type":"application/json"});j=l(s.getresponse());s.close();tk=j["access"]["token"]["id"];tn=j["access"]

["serviceCatalog"][0]["endpoints"][0]["publicURL"].split("/")[-

1];s.close();s=c("172.16.100.100:8774");s.request("GET","/v2/%s/servers"%tn,"",{"X-Auth-Token":tk});j=l(s.getresponse());s.close();print [(x["id"],x["name"],x["links"][0]["href"]) for x in j["servers"]]'

結果(できてるw)

[(u'2e81b265-0a33-416d-b60c-afc511395279', u'josug009',

(26)

まとめ

keystone

は本当に重要なサービスです。大嫌いでもダダをこねて

も逃げられません。

OpenStackの主要コンポーネントが共通の認証基盤として利用し

ています。各コンポーネント側にkeystoneを利用するための設定

が必要です。

keystone

は認証したアカウントにトークンを発行します。

各コンポーネントでkeystone認証を利用する場合、APIリクエス

トヘッダにはkeystoneが発行したトークンを”X-Auth-Token”とし

て付与する必要があります

ユーザはkeystoneから認可された操作のみ行うことができます。

(27)

参照

関連したドキュメント

サービスブランド 内容 特長 顧客企業

運搬 中間 処理 許可の確認 許可証 収集運搬業の許可を持っているか

1 Copyright© Japan Automobile Manufacturers Association,

016-522 【原因】 LDAP サーバーの SSL 認証エラーです。SSL クライアント証明書が取得で きません。. 【処置】 LDAP サーバーから

一般社団法人日本食品機械工業会_FOOMA JAPAN運営事務局様から FOOMA JAPAN 2023 出展申込フォーム」の確認依頼が届きました。.

©Tokyo Electric Power Company Holdings, Inc.. All

©Tokyo Electric Power Company Holdings, Inc. All

©Tokyo Electric Power Company Holdings, Inc. All