分享

keystone两个配置参数

arsenduan 发表于 2015-11-19 16:51:23 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 0 10006


查看配置文件,一般地有:(uuid更简单,但是大规模环境可能对keystone节点造成性能瓶颈)
provider=keystone.token.providers.uuid.Provider #如何产生token
driver=keystone.token.persistence.backends.sql.Token #如何存取token

如果provider是pki则需要在配置文件中指定certfile,keyfile等,之后会说。


##############################################################

更多:
每次说openstack,一般情况主要关注nova的能力,一方面nova是最大的模块,同时早期的openstack可以说大部分功能就揉在nova中,后来分离了网络,存储,鉴权等,

从前面说nova,说ironic,对每个模块来说wsgi和rpc服务都是一样的方式(ironic略有不同),抛开框架上的因素,我觉得剩下的部分最难的是keystone和neutron两部分,又

以neutron最杂,当然这和网络本身的复杂性有关,我之前看时做了几十页的笔记,既然要搬出来,我也不想再纯粘贴,我打算重新理一遍。


和nova或者ironic不同,keystone中没有cmd的模块,启动keystone的服务时调用/usr/bin/keystone-all (Centos)脚本,keystone的client服务由脚本/usr/bin/keystone脚本启动,前面说“curl调试”时用rest call 去获得token等过程是在keystone-all脚本中完成的:

servers.append(create_server(paste_config,
                                 'admin',
                                 CONF.admin_bind_host,
                                 int(CONF.admin_port),
                                 admin_worker_count))

servers.append(create_server(paste_config,
                                 'main',
                                 CONF.public_bind_host,
                                 int(CONF.public_port),
                                 public_worker_count))

我们看keystone的keystone-paste.ini配置文件时,发现keystone和其他的service不同,有两个composite入口:

[composite:main]
use = egg:Paste#urlmap
/v2.0 = public_api
/v3 = api_v3
/ = public_version_api

[composite:admin]
use = egg:Paste#urlmap
/v2.0 = admin_api
/v3 = api_v3
/ = admin_version_api
回想一下前几节说horizon的情况,admin 用户和普通用户执行的操作是不一样的(tips:在horizon里面有两个admin的概念,一个是超级管理员,可以操作

任何tenant,就像是网站的administrator,一个是admin本身是一个tenant),这里尤其是这样,涉及到鉴权的问题,admin和普通tenant的用户必然是不一样的。

create_server执行:

server = environment.Server(app, host=host, port=port,
                                keepalive=CONF.tcp_keepalive,
                                keepidle=CONF.tcp_keepidle)

ps: 在keystone/common/environment中的__init__.py中有 __all__ = ['Server', 'httplib', 'subprocess']

在environment中的eventlet_server中的Server类,有start方法,监听需要绑定的端口(一般指定为admin的35357和public的5000),启动WSGI服务,

不错,仅仅是WSGI服务,没有RPC什么事。

开启服务之后和前面说的WSGI服务一样,接收到rest call,通过mapper找到对应的controller,根据mapper中指定的方法找到controller具体的执行方法。

比如我们想获取一个token,应该是5000还是35357端口呢(admin还是public呢),答案是没关系:

def public_app_factory(global_conf, **local_conf):
    controllers.register_version('v2.0')
    return wsgi.ComposingRouter(routes.Mapper(),
                                [assignment.routers.Public(),
                                 token.routers.Router(),
                                 routers.VersionV2('public'),
                                 routers.Extension(False)])


@fail_gracefully
def admin_app_factory(global_conf, **local_conf):
    controllers.register_version('v2.0')
    return wsgi.ComposingRouter(routes.Mapper(),
                                [identity.routers.Admin(),
                                 assignment.routers.Admin(),
                                    token.routers.Router(),
                                    routers.VersionV2('admin'),
                                    routers.Extension()])

不错,他们走到了同一个Router中,在Router中有mapper.connect:

mapper.connect('/tokens',
                       controller=token_controller,
                       action='authenticate',
                       conditions=dict(method=['POST']))

在authenticate的方法注释中:

            {
                "auth":{
                    "passwordCredentials":{
                        "username":"test_user",
                        "password":"mypass"
                    },
                    "tenantName":"customer-x"
                }
            }

和前面我们说rest 调试的地方获取token时一样,你只要能指定tenant名字,对用户x来说,你对了名字和密码我就会给你一个token。

ps:在命令行中,我们有时会执行类型 source keystone_admin或者sourcekeystone_demo的操作,那是给keystone client用的命令行执行,此处拿到token是

给rest call用的,两者没有关系, 之后会说。


如果你希望做一些鉴权方面的改动,可以继续traceauthenticate方法,

identity_api.assert_user_enabled #check user

self.assignment_api.assert_project_enabled #check tenant

token_provider_api.issue_v2_token #产生token

这里的identity_api,token_provider_api在Auth类的装饰器上:

@dependency.requires('assignment_api', 'catalog_api', 'identity_api', 'token_provider_api', 'trust_api')

ps: 有requires就有provider,否则会报错,查看keystone/common/dependency.py中provider方法和requires方法,provider

会在REGISTRY中注册自己,requires则会从REGISTRY中在需要的时候拿取,是不是很像前面说stevedore在entry_points中注册,在需要的时候拿取,

都是python的魔法弹, 对了还有个@optional,和@requires类似,不过没有provider时候会返回而None不是报错
其中token_provider_api会根据provider不同产生token,provider包括:

UUID,PKI,PKIZ

查看配置文件,一般地有:(uuid更简单,但是大规模环境可能对keystone节点造成性能瓶颈)
provider=keystone.token.providers.uuid.Provider #如何产生token
driver=keystone.token.persistence.backends.sql.Token #如何存取token

如果provider是pki则需要在配置文件中指定certfile,keyfile等,之后会说。


btw,提一句,拿到token之后,每个rest call 需要指定“X-Auth-Token”,这个token是在哪里发挥作用的呢?答案从keystone-paste.ini而来:

在[pipeline:public_api] 和 [pipeline:admin_api]

都有filter:

token_auth admin_token_auth,trace进去就知道是通过token做了check


没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条