系列2:
在实际测试中,发现nova在调用keystonemiddleware的时候,keystonemiddleware也会访问memcached服务。
如果memcached开启SASL认证功能,而keystonemiddleware没有这个认证功能,就会出现访问失败的现象;
在keystonemiddleware组件中的class AuthProtocol(BaseAuthProtocol)函数中会注册配置项:
self._conf = config.Config('auth_token',
_base.AUTHTOKEN_GROUP,
list_opts(),
conf)
AUTHTOKEN_GROUP = 'keystone_authtoken'
而"keystone_authtoken"配置组在/etc/nova/nova.conf中有配置:
[keystone_authtoken]
memcached_servers = localhost:11211
cafile = /opt/stack/data/ca-bundle.pem
project_domain_name = Default
project_name = service
user_domain_name = Default
password = 3c8b9e6f4ce0cb7d6d64
username = nova
auth_url = http://192.168.117.156/identity
auth_type = password
也在/etc/nova/nova--cpu.conf中有配置:
[keystone_authtoken]
memcached_servers = localhost:11211
cafile = /opt/stack/data/ca-bundle.pem
project_domain_name = Default
project_name = service
user_domain_name = Default
password = 3c8b9e6f4ce0cb7d6d64
username = nova
auth_url = http://192.168.117.156/identity
auth_type = password
可以看出两个配置文件中的配置信息是一样的。
如果是多节点部署的话:
所有组件中的nova.conf都要改变参数
在\keystonemiddleware\auth_token\_opts.py文件中有一个_OPTS的配置项,应该在这个配置项中加上3个参数
memcache_sasl_enable = true
memcache_usrname = usrname
memcache_password = *******
下面看一下keystonemiddleware中的代码:
keystonemiddleware\auth_token\__init__.py文件中调用filter_factory中的代码,在调用AuthProtocol(app, conf)这个函数
在调用self._token_cache = self._token_cache_factory()这个函数:
在上面这个函数中会构造cache_kwargs字典,应该将上面的三个参数加到这个里面
cache_kwargs = dict(
cache_time=int(self._conf.get('token_cache_time')),
env_cache_name=self._conf.get('cache'),
memcached_servers=self._conf.get('memcached_servers'),
use_advanced_pool=self._conf.get('memcache_use_advanced_pool'),
dead_retry=self._conf.get('memcache_pool_dead_retry'),
maxsize=self._conf.get('memcache_pool_maxsize'),
unused_timeout=self._conf.get('memcache_pool_unused_timeout'),
conn_get_timeout=self._conf.get('memcache_pool_conn_get_timeout'),
socket_timeout=self._conf.get('memcache_pool_socket_timeout'),
#add the information for bmemcached
sasl_enable = self._conf.get("memcache_sasl_enable")
usrname = self._conf.get("memcache_usrname")
password = self._conf.get("memcache_password")
)
if security_strategy.lower() != 'none':这个判断是否加密,其实走的流程是一样的,最终都是调用到:
_cache.TokenCache(self.log, **cache_kwargs)这个函数中。
在这个函数中,将cache_kwargs参数赋值给
self._memcache_pool_options = kwargs
def _get_cache_pool(self, cache):
if cache:
return _EnvCachePool(cache)
elif self._use_advanced_pool and self._memcached_servers:
return _MemcacheClientPool(self._memcached_servers,
self._arguments,
**self._memcache_pool_options)
else:
return _CachePool(self._memcached_servers, self._LOG)
然后返回_get_cache_pool函数:
如果cache的话,直接返回这个存储后端
如果打开_use_advanced_pool则调用_MemcacheClientPool,这个后面要着重说明,实现这个功能即可!
反之则执行_CachePool,这个函数直接是:import memcache,然后调用memcache.Client,没什么好说的!
后面需要改变的组件有:
/etc/nova/nova.conf:71:[keystone_authtoken]
/etc/nova/nova-cpu.conf:69:[keystone_authtoken]
/etc/cinder/cinder.conf:2:[keystone_authtoken]
/etc/placement/placement.conf:15:[keystone_authtoken]
/etc/glance/glance-registry.conf:20:[keystone_authtoken]
/etc/glance/glance-api.conf:24:[keystone_authtoken]
/etc/neutron/neutron.conf:873:[keystone_authtoken]
以及swift下面的配置文件!
前文我们介绍了如何部署Keystone中间件以及中间件的配置点. 这里给出所有Keystone中间件的配置项. 概括起来, Keystone中间件的配置项具有以下特点,
1. 以 "auth_" 开头的配置项需要指向Keystone的Admin服务, Keystone中间件使用这些配置信息从Keystone服务处获取令牌的有效信息.
2. 提供管理员身份凭证(admin_user, admin_tenant_name, admin_password)的目的是获取一个具有管理权限的令牌, 该令牌用于给普通用户的令牌授权.
3. "cache" 的值可以设置为swift.cache, 也可以不设置. 表示中间件缓存令牌的位置, 既可以是Swift的memcache, 也可以是与其他服务统一的基于memcached的缓存池. 下文将会详细介绍该配置项.
4. "include_service_catalog" 缺省为True, 意味着在验证普通用户令牌的时候, 中间件会从Keystone那里取回服务目录并存储在HTTP头的"X-Service-Catalog"字段. Swift并不适用"X-Service-Catalog"字段, 因此Swift的"include_service_catalog"推荐设置为False.
5. 若使用Keystone的第三版身份API, 需要将配置项"auth_version"设置为 "v3.0".
一. 与Keystone服务相关的配置
identity_uri
完整的Keystone管理API端点, 这里不应该在路径中指明身份API版本(如http://localhost:35357/). 该选项给keystone中间件一个keystone服务端的终端,keystone中间件在向该终端认证后才可以执行验证用户令牌、获取令牌撤销列表等API。
auth_uri
完整的Keystone公共API端点(如 http://localhost:5000/). 配置该选项的目的是一旦用户的请求中没有携带令牌或者携带的令牌已经失效,那么将这个地址通过HTTP响应头“www-Authenticate”返回给用户,告诉他这里可以获取一个新的令牌。
admin_user, admin_password, admin_tenant_name
如果没有提供"admin_token", 那么这三个选项应是已经在Keystone中配置好的服务账户.
auth_version
要使用的Keystone管理API版本.
delay_auth_decision
(默认False). 如果是True, 中间将将不会拒绝无效的认证请求,而是将决策的权利委托给下游的WSGI组件.
http_connect_timeout
(默认None). 向Keystone服务端请求的超时秒数.
http_request_max_retries
(默认3). 向Keystone服务端请求的最大重试次数.
certfile
keystone中间件的公钥证书。如果Keystone服务端要求客户端提供证书,那么该项必须设置.
keyfile
keystone中间件的私钥,用于签名。如果Keystone服务端要求客户端提供证书, 那么该项必须设置.
cafile
(默认None). 给keystone中间件公钥证书签名的CA证书。用来验证https连接的PEM编码的CA 文件路径.
insecure
(默认False). 是否验证https连接. True代表允许不安全的连接; False代表不允许不安全的连接。
signing_dir
储存与PKI令牌相关文件的目录. 用来存放keystone的公钥证书、CA证书和从keystone那里获取的令牌撤销列表。
include_service_catalog
(可选, 默认True). 指示是否设置 "X-Service-Catalog" 字段. 如果为False, 中间件在验证令牌的过程中将不获取服务目录, 也不会设置 "X-Service-Catalog" 字段.
enforce_token_bind
(默认 permissive). 用来控制令牌绑定的使用和类型. 设置为 "disabled" 将不会检查令牌绑定, 设为"permissive" 将会验证系统已知的绑定类型,忽略那些系统中没有定义的绑定类型; 设为 "strict" 验证系统已知的绑定类型, 拒绝系统未知类型的令牌绑定; 设为 "required" 允许任何类型的令牌绑定. 最后, 令牌绑定的方法必须出现在令牌中.
二. 与memcached服务端相关的配置
memcached_servers
(旧名: memcache_servers). 如果设置, 指定用于缓存令牌的 memcached server(s); 如果没有设置, 中间件会将令牌缓存在进程中(cached in-process).
cache
(默认None). Swift缓存的环境键, 可以设置成 "swift.cache", 表示在Swift中使用其自带的缓存机制.
memcache_security_strategy
(可选, 默认None). 如果设置, 指示令牌数据是否需要认证或认证加密。可接受的值包括MAC、ENCRYPT和空值(或None). MAC选项将会在缓存中采用HMAC算法认证令牌, ENCRYPT选项将会在缓存中加密和认证. 任何不是这两个值或空值中的一个, 那么中间件将会在初始化阶段报错.
memcache_secret_key
(如果设置了"memcache_security_strategy", 则必须设置该选项). 该选项用来导出存储令牌的键
memcache_pool_dead_retry
(可选, 默认5*60). 重试memcached服务端前等待的秒数.
memcache_pool_maxsize
(可选, 默认10). 每个memcached服务端最大开放连接数.
memcache_pool_socket_timeout
(可选). 套接字连接memcache服务端的超时上限(秒).
memcache_pool_unused_timeout
(可选). 不使用的memcached连接多久会被关闭(秒).
memcache_pool_conn_get_timeout
(可选, 默认10). 从连接池中获得一个memcache客户端连接的超时上限(秒).
memcache_use_advanced_pool
(可选, 默认False). 是否采用高级(eventlet安全的)memcache客户池, 当前该高级连接池仅适用于Python 2.x.
token_cache_time
(默认300). 令牌缓存时间(秒). 为了避免过度请求和验证, 中间件会缓存每一个自己见到额令牌. 该选项仅在设置了 "memcached_servers" 选项后才生效,设为-1将会完全关闭缓存.
hash_algorithms
(默认md5). 中间件存储PKI令牌时用来哈希PKI令牌的算法. 可以设为一个或多个值, 只要是Python的hashlib.new()方法支持的算法即可. 中间件会按照该选项给出的顺序对PKI令牌进行哈希, 所以将偏好的算法靠前设置. 当从一个较不安全的哈希算法向一个较安全的哈希算法过渡时, 该选选项通常设置为多个值, 一旦所有旧令牌都过期, 该项应该被设置成单一的值从而提升性能.
check_revocations_for_cached
(默认False). 是否检查已缓存令牌是否被撤销. 如果设为True, 则会检查已被缓存令牌的撤销列表, 要求Keystone服务端使用的是PKI令牌.
revocation_cache_time
(默认10). 多少秒从Keystone服务端获取一次令牌撤销列表,撤销行为发生得越频繁, 撤销列表缓存的时间越短, 那么性能越差.