Installing and Configuring the Identity ServiceInstall the Identity service on any server that is accessible
to the other servers you intend to use for OpenStack services, as
root:#apt-get install keystone python-keystone python-keystoneclient$yum install openstack-utils openstack-keystone python-keystoneclient$zypper install openstack-utils openstack-keystone python-keystoneclientAfter installing, you need to delete the sqlite database it
creates, then change the configuration to point to a MySQL
database. This configuration enables easier scaling scenarios
since you can bring up multiple Keystone front ends when needed,
and configure them all to point back to the same database. Plus a
database backend has built-in data replication features and
documentation surrounding high availability and data redundancy
configurations.Delete the keystone.db file created in
the /var/lib/keystone
directory.#rm /var/lib/keystone/keystone.dbDelete the keystone.db file created in
the /var/lib/keystone
directory.$sudo rm /var/lib/keystone/keystone.dbConfigure the production-ready backend data store rather than
using the catalog supplied by default for the ability to back up
the service and endpoint data. This example shows MySQL.The following sequence of commands will create a MySQL
database named "keystone" and a MySQL user named "keystone" with
full access to the "keystone" MySQL database.On Fedora, RHEL, CentOS, and openSUSE, you can configure the Keystone
database with the openstack-db
command.$sudo openstack-db --init --service keystoneTo manually create the database, start the mysql command line client by
running:$mysql -u root -pEnter the mysql root user's password when prompted.To configure the MySQL database, create the keystone
database.mysql>CREATE DATABASE keystone;Create a MySQL user for the newly-created keystone database that has full control of the
keystone database.NoteChoose a secure password for the keystone user and replace
all references to
[YOUR_KEYSTONEDB_PASSWORD] with
this password.mysql>GRANT ALL ON keystone.* TO 'keystone'@'%' IDENTIFIED BY '[YOUR_KEYSTONEDB_PASSWORD]';mysql>GRANT ALL ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY '[YOUR_KEYSTONEDB_PASSWORD]';In the above commands, even though the 'keystone'@'%' also matches
'keystone'@'localhost', you must explicitly specify the
'keystone'@'localhost' entry.By default, MySQL will create entries in the user table with User=''
and Host='localhost'. The User='' acts as a wildcard,
matching all users. If you do not have the 'keystone'@'localhost' account,
and you try to log in as the keystone user, the precedence rules of MySQL will match against
the User='' Host='localhost' account before it matches against the
User='keystone' Host='%' account. This will result in an error message
that looks like:ERROR 1045 (28000): Access denied for user 'keystone'@'localhost' (using password: YES)Thus, we create a separate User='keystone' Host='localhost' entry
that will match with higher precedence.See the MySQL documentation on connection verification for more details on how MySQL
determines which row in the user table it uses when authenticating connections.Enter quit at the mysql> prompt to exit
MySQL.mysql>quitReminderRecall that this document assumes the Cloud Controller node
has an IP address of 192.168.206.130.Once Keystone is installed, it is configured via a primary
configuration file
(/etc/keystone/keystone.conf), a PasteDeploy
configuration file
(/etc/keystone/keystone-paste.ini) and by
initializing data into keystone using the command line client. By
default, Keystone's data store is sqlite. To change the data store
to mysql, change the line defining connection in
/etc/keystone/keystone.conf like so:connection = mysql://keystone:[YOUR_KEYSTONEDB_PASSWORD]@192.168.206.130/keystoneAlso, ensure that the proper service token is used in the
keystone.conf file. An example is provided in the Appendix or you can
generate a random string. The sample token is:admin_token = 012345SECRET99TOKEN012345$export ADMIN_TOKEN=$(openssl rand -hex 10)$sudo openstack-config --set /etc/keystone/keystone.conf DEFAULT admin_token $ADMIN_TOKENBy default Keystone will use PKI tokens. To
create the signing keys and certificates run:$ sudo keystone-manage pki_setup
$ sudo chown -R keystone:keystone /etc/keystone/* /var/log/keystone/keystone.log#keystone-manage pki_setup#chown -R keystone:keystone /etc/keystone/* /var/log/keystone/keystone.log#keystone-manage pki_setup#chown -R keystone:keystone /etc/keystone/* /var/log/keystone/keystone.logIn Ubuntu, keystone.conf is shipped as
root:root 644, but /etc/keystone has permissions for keystone:keystone
700 so the files under it are protected from unauthorized users.Next, restart the keystone service so that it picks up the new
database configuration.#sudo service keystone restart$sudo service openstack-keystone start && sudo chkconfig openstack-keystone on#systemctl restart openstack-keystone.service#systemctl enable openstack-keystone.serviceLastly, initialize the new keystone database, as root:#keystone-manage db_syncConfiguring Services to work with KeystoneOnce Keystone is installed and running, you set up users and
tenants and services to be configured to work with it. You can
either follow the manual
steps or use a
script.Setting up tenants, users, and roles - manuallyYou need to minimally define a tenant, user, and role to
link the tenant and user as the most basic set of details to
get other services authenticating and authorizing with the
Identity service.Scripted method availableThese are the manual, unscripted steps using the
keystone client. A scripted method is available at Setting up tenants,
users, and roles - scripted.Typically, you would use a username and password to
authenticate with the Identity service. However, at this point
in the install, we have not yet created a user. Instead, we
use the service token to authenticate against the Identity
service. With the keystone command-line,
you can specify the token and the endpoint as arguments, as
follows:$keystone --token 012345SECRET99TOKEN012345 --endpoint http://192.168.206.130:35357/v2.0 <command parameters>You can also specify the token and endpoint as environment
variables, so they do not need to be explicitly specified each time. If
you are using the bash shell, the following commands will set these
variables in your current session so you don't have to pass them to the
client each time. Best practice for bootstrapping the first
administrative user is to use the OS_SERVICE_ENDPOINT and
OS_SERVICE_TOKEN together as environment
variables.$export OS_SERVICE_TOKEN=012345SECRET99TOKEN012345$export OS_SERVICE_ENDPOINT=http://192.168.206.130:35357/v2.0In the remaining examples, we will assume you have set the above environment
variables.Because it is more secure to use a username and password to authenticate rather than the
service token, when you use the token the keystone client may output the
following warning, depending on the version of python-keystoneclient you are
running:WARNING: Bypassing authentication using a token & endpoint (authentication credentials are being ignored).First, create a default tenant. We'll name it
demo in this example. There is an --enabled
parameter available for tenant-create and user-create that defaults to
true. Refer to the help in keystone help user-create
and keystone help user-update for more
details.$keystone tenant-create --name demo --description "Default Tenant" +-------------+----------------------------------+
| Property | Value |
+-------------+----------------------------------+
| description | Default Tenant |
| enabled | True |
| id | b5815b046cfe47bb891a7b64119e7f80 |
| name | demo |
+-------------+----------------------------------+Set the id value from previous command as a shell variable.
$export TENANT_ID=b5815b046cfe47bb891a7b64119e7f80
Create a default user named admin.$keystone user-create --tenant-id $TENANT_ID --name admin --pass secrete +----------+----------------------------------+
| Property | Value |
+----------+----------------------------------+
| email | |
| enabled | True |
| id | a4c2d43f80a549a19864c89d759bb3fe |
| name | admin |
| tenantId | b5815b046cfe47bb891a7b64119e7f80 |
+----------+----------------------------------+Set the admin id value from previous command's output as a shell variable.
$export ADMIN_USER_ID=a4c2d43f80a549a19864c89d759bb3fe
Create an administrative role based on keystone's default
policy.json file,
admin.$keystone role-create --name admin +----------+----------------------------------+
| Property | Value |
+----------+----------------------------------+
| id | e3d9d157cc95410ea45d23bbbc2e5c10 |
| name | admin |
+----------+----------------------------------+Set the role id value from previous command's output as a shell variable.
$export ROLE_ID=e3d9d157cc95410ea45d23bbbc2e5c10
Grant the admin role to the
admin user in the
demo tenant with
"user-role-add".$keystone user-role-add --user-id $ADMIN_USER_ID --tenant-id $TENANT_ID --role-id $ROLE_IDCreate a service tenant named service. This tenant contains all the
services that we make known to the service catalog.$keystone tenant-create --name service --description "Service Tenant" +-------------+----------------------------------+
| Property | Value |
+-------------+----------------------------------+
| description | Service Tenant |
| enabled | True |
| id | eb7e0c10a99446cfa14c244374549e9d |
| name | service |
+-------------+----------------------------------+Set the tenant id value from previous command's output as a shell variable.
$export SERVICE_TENANT_ID=eb7e0c10a99446cfa14c244374549e9d
Create a glance service user in the service tenant. You'll do this
for any service you add to be in the Identity service catalog.$keystone user-create --tenant-id $SERVICE_TENANT_ID --name glance --pass glanceWARNING: Bypassing authentication using a token & endpoint (authentication credentials are being ignored).
+----------+----------------------------------+
| Property | Value |
+----------+----------------------------------+
| email | |
| enabled | True |
| id | 46b2667a7807483d983e0b4037a1623b |
| name | glance |
| tenantId | eb7e0c10a99446cfa14c244374549e9d |
+----------+----------------------------------+Set the id value from previous command as a shell variable.
$export GLANCE_USER_ID=46b2667a7807483d983e0b4037a1623b
Grant the admin role to the
glance user in the
service tenant.$keystone user-role-add --user-id $GLANCE_USER_ID --tenant-id $SERVICE_TENANT_ID --role-id $ROLE_IDCreate a nova service user in the service tenant.$keystone user-create --tenant-id $SERVICE_TENANT_ID --name nova --pass novaWARNING: Bypassing authentication using a token & endpoint (authentication credentials are being ignored).
+----------+----------------------------------+
| Property | Value |
+----------+----------------------------------+
| email | |
| enabled | True |
| id | 54b3776a8707834d983e0b4037b1345c |
| name | nova |
| tenantId | eb7e0c10a99446cfa14c244374549e9d |
+----------+----------------------------------+Set the nova user's id value from previous command's output as a shell variable.
$export NOVA_USER_ID=54b3776a8707834d983e0b4037b1345c
Grant the admin role to the
nova user in the
service tenant.$keystone user-role-add --user-id $NOVA_USER_ID --tenant-id $SERVICE_TENANT_ID --role-id $ROLE_IDCreate a cinder service user in the service tenant.$keystone user-create --tenant-id $SERVICE_TENANT_ID --name cinder --pass openstackWARNING: Bypassing authentication using a token & endpoint (authentication credentials are being ignored).
+----------+----------------------------------+
| Property | Value |
+----------+----------------------------------+
| email | |
| enabled | True |
| id | c95bf79153874ac69b4758ebf75498a6 |
| name | cinder |
| tenantId | eb7e0c10a99446cfa14c244374549e9d |
+----------+----------------------------------+Set the cinder user's id value from previous command's output as a shell variable.
$export CINDER_USER_ID=c95bf79153874ac69b4758ebf75498a6
Grant the admin role to the
cinder user in the service
tenant.$keystone user-role-add --user-id $CINDER_USER_ID --tenant-id $SERVICE_TENANT_ID --role-id $ROLE_IDCreate an ec2 service user in the service tenant.$keystone user-create --tenant-id $SERVICE_TENANT_ID --name ec2 --pass ec2 +----------+----------------------------------+
| Property | Value |
+----------+----------------------------------+
| email | |
| enabled | True |
| id | 32e7668b8707834d983e0b4037b1345c |
| name | ec2 |
| tenantId | eb7e0c10a99446cfa14c244374549e9d |
+----------+----------------------------------+Set the ec2 user's id value from previous command's output as a shell variable.
$export EC2_USER_ID=32e7668b8707834d983e0b4037b1345c
Grant the admin role to the
ec2 user in the
service tenant.$keystone user-role-add --user-id $EC2_USER_ID --tenant-id $SERVICE_TENANT_ID --role-id $ROLE_IDCreate an Object Storage service user in the service tenant.$keystone user-create --tenant-id $SERVICE_TENANT_ID --name swift --pass swiftpass +----------+----------------------------------+
| Property | Value |
+----------+----------------------------------+
| email | |
| enabled | True |
| id | 4346677b8909823e389f0b4037b1246e |
| name | swift |
| tenantId | eb7e0c10a99446cfa14c244374549e9d |
+----------+----------------------------------+Set the swift user's id value from previous command's output as a shell variable.
$export SWIFT_USER_ID=4346677b8909823e389f0b4037b1246e
Grant the admin role to the
swift user in the
service tenant.$keystone user-role-add --user-id $SWIFT_USER_ID --tenant-id $SERVICE_TENANT_ID --role-id $ROLE_IDNext you create definitions for the services.Defining ServicesKeystone also acts as a service catalog to let other
OpenStack systems know where relevant API endpoints exist for
OpenStack Services. The OpenStack Dashboard, in particular, uses
the service catalog heavily. This must
be configured for the OpenStack Dashboard to
properly function.There are two alternative ways of defining services with
keystone: Using a template fileUsing a database backend While using a template file is simpler, it is not
recommended except for development environments such as DevStack. The
template file does not enable CRUD operations on the service
catalog through keystone commands, but you can use the
service-list command when using the template catalog. A database
backend can provide better reliability, availability, and data
redundancy. This section describes how to populate the Keystone
service catalog using the database backend. Your
/etc/keystone/keystone.conf file should
contain the following lines if it is properly configured to use
the database backend.[catalog]
driver = keystone.catalog.backends.sql.CatalogElements of a Keystone service catalog entryFor each service in the catalog, you must perform two
keystone operations: Use the keystone service-create
command to create a database entry for the service, with
the following attributes: --nameName of the service (e.g.,
nova,
ec2,
glance,
keystone)--typeType of service (e.g.,
compute,
ec2,
image,
identity)--descriptionA description of the service, (e.g.,
"Nova Compute
Service")Use the keystone endpoint-create
command to create a database entry that describes how
different types of clients can connect to the service,
with the following attributes:--regionthe region name you've given to the OpenStack
cloud you are deploying (e.g., RegionOne)--service-idThe ID field returned by the keystone
service-create (e.g.,
935fd37b6fa74b2f9fba6d907fa95825)--publicurlThe URL of the public-facing endpoint for the
service (e.g.,
http://192.168.206.130:9292
or
http://192.168.206.130:8774/v2/%(tenant_id)s)
--internalurlThe URL of an internal-facing endpoint for the
service.This typically has the same value as
publicurl.--adminurlThe URL for the admin endpoint for the
service. The Keystone and EC2 services use
different endpoints for
adminurl and
publicurl, but for other
services these endpoints will be the same.Keystone allows some URLs to contain special variables,
which are automatically substituted with the correct value at
runtime. Some examples in this document employ the
tenant_id variable, which we use when
specifying the Volume and Compute service endpoints. Variables
can be specified using either
%(varname)s
or $(varname)s
notation. In this document, we always use the
%(varname)s
notation (e.g., %(tenant_id)s) since
$ is interpreted as a special character
by Unix shells.Creating keystone services and service endpointsHere we define the services and their endpoints. Recall that you must have the following
environment variables
set.$export OS_SERVICE_TOKEN=012345SECRET99TOKEN012345$export OS_SERVICE_ENDPOINT=http://192.168.206.130:35357/v2.0Define the Identity service:$keystone service-create --name=keystone --type=identity --description="Identity Service"
+-------------+----------------------------------+
| Property | Value |
+-------------+----------------------------------+
| description | Identity Service |
| id | 15c11a23667e427e91bc31335b45f4bd |
| name | keystone |
| type | identity |
+-------------+----------------------------------+$keystone endpoint-create \
--region RegionOne \
--service-id=15c11a23667e427e91bc31335b45f4bd \
--publicurl=http://192.168.206.130:5000/v2.0 \
--internalurl=http://192.168.206.130:5000/v2.0 \
--adminurl=http://192.168.206.130:35357/v2.0+-------------+-----------------------------------+
| Property | Value |
+-------------+-----------------------------------+
| adminurl | http://192.168.206.130:35357/v2.0 |
| id | 11f9c625a3b94a3f8e66bf4e5de2679f |
| internalurl | http://192.168.206.130:5000/v2.0 |
| publicurl | http://192.168.206.130:5000/v2.0 |
| region | RegionOne |
| service_id | 15c11a23667e427e91bc31335b45f4bd |
+-------------+-----------------------------------+
Define the Compute service, which requires a separate
endpoint for each tenant. Here we use the
service tenant from the previous section. The %(tenant_id)s and single quotes
around the publicurl,
internalurl, and
adminurl must be typed exactly as
shown for both the Compute endpoint and the Volume
endpoint.$keystone service-create --name=nova --type=compute --description="Compute Service"+-------------+----------------------------------+
| Property | Value |
+-------------+----------------------------------+
| description | Compute Service |
| id | abc0f03c02904c24abdcc3b7910e2eed |
| name | nova |
| type | compute |
+-------------+----------------------------------+
$keystone endpoint-create \
--region RegionOne \
--service-id=abc0f03c02904c24abdcc3b7910e2eed \
--publicurl='http://192.168.206.130:8774/v2/%(tenant_id)s' \
--internalurl='http://192.168.206.130:8774/v2/%(tenant_id)s' \
--adminurl='http://192.168.206.130:8774/v2/%(tenant_id)s'+-------------+----------------------------------------------+
| Property | Value |
+-------------+----------------------------------------------+
| adminurl | http://192.168.206.130:8774/v2/%(tenant_id)s |
| id | 935fd37b6fa74b2f9fba6d907fa95825 |
| internalurl | http://192.168.206.130:8774/v2/%(tenant_id)s |
| publicurl | http://192.168.206.130:8774/v2/%(tenant_id)s |
| region | RegionOne |
| service_id | abc0f03c02904c24abdcc3b7910e2eed |
+-------------+----------------------------------------------+
Define the Volume service, which also requires a separate
endpoint for each tenant.$keystone service-create --name=cinder --type=volume --description="Volume Service"
+-------------+----------------------------------+
| Property | Value |
+-------------+----------------------------------+
| description | Volume Service |
| id | 1ff4ece13c3e48d8a6461faebd9cd38f |
| name | volume |
| type | volume |
+-------------+----------------------------------+
$keystone endpoint-create \
--region RegionOne \
--service-id=1ff4ece13c3e48d8a6461faebd9cd38f \
--publicurl='http://192.168.206.130:8776/v1/%(tenant_id)s' \
--internalurl='http://192.168.206.130:8776/v1/%(tenant_id)s' \
--adminurl='http://192.168.206.130:8776/v1/%(tenant_id)s'
+-------------+----------------------------------------------+
| Property | Value |
+-------------+----------------------------------------------+
| adminurl | http://192.168.206.130:8776/v1/%(tenant_id)s |
| id | 1ff4ece13c3e48d8a6461faebd9cd38f |
| internalurl | http://192.168.206.130:8776/v1/%(tenant_id)s |
| publicurl | http://192.168.206.130:8776/v1/%(tenant_id)s |
| region | RegionOne |
| service_id | 8a70cd235c7d4a05b43b2dffb9942cc0 |
+-------------+----------------------------------------------+
Define the Image service:$keystone service-create --name=glance --type=image --description="Image Service"
+-------------+----------------------------------+
| Property | Value |
+-------------+----------------------------------+
| description | Image Service |
| id | 7d5258c490144c8c92505267785327c1 |
| name | glance |
| type | image |
+-------------+----------------------------------+
$keystone endpoint-create \
--region RegionOne \
--service-id=7d5258c490144c8c92505267785327c1 \
--publicurl=http://192.168.206.130:9292 \
--internalurl=http://192.168.206.130:9292 \
--adminurl=http://192.168.206.130:9292
+-------------+-----------------------------------+
| Property | Value |
+-------------+-----------------------------------+
| adminurl | http://192.168.206.130:9292 |
| id | 3c8c0d749f21490b90163bfaed9befe7 |
| internalurl | http://192.168.206.130:9292 |
| publicurl | http://192.168.206.130:9292 |
| region | RegionOne |
| service_id | 7d5258c490144c8c92505267785327c1 |
+-------------+-----------------------------------+
Define the EC2 compatibility service:$keystone service-create --name=ec2 --type=ec2 --description="EC2 Compatibility Layer"+-------------+----------------------------------+
| Property | Value |
+-------------+----------------------------------+
| description | EC2 Compatibility Layer |
| id | 181cdad1d1264387bcc411e1c6a6a5fd |
| name | ec2 |
| type | ec2 |
+-------------+----------------------------------+
$keystone endpoint-create \
--region RegionOne \
--service-id=181cdad1d1264387bcc411e1c6a6a5fd \
--publicurl=http://192.168.206.130:8773/services/Cloud \
--internalurl=http://192.168.206.130:8773/services/Cloud \
--adminurl=http://192.168.206.130:8773/services/Admin
+-------------+--------------------------------------------+
| Property | Value |
+-------------+--------------------------------------------+
| adminurl | http://192.168.206.130:8773/services/Admin |
| id | d2a3d7490c61442f9b2c8c8a2083c4b6 |
| internalurl | http://192.168.206.130:8773/services/Cloud |
| publicurl | http://192.168.206.130:8773/services/Cloud |
| region | RegionOne |
| service_id | 181cdad1d1264387bcc411e1c6a6a5fd |
+-------------+--------------------------------------------+
Define the Object Storage service:$keystone service-create --name=swift --type=object-store --description="Object Storage Service"+-------------+---------------------------------+
| Property | Value |
+-------------+----------------------------------+
| description | Object Storage Service |
| id | 272efad2d1234376cbb911c1e5a5a6ed |
| name | swift |
| type | object-store |
+-------------+----------------------------------+
$keystone endpoint-create \
--region RegionOne \
--service-id=272efad2d1234376cbb911c1e5a5a6ed \
--publicurl 'http://192.168.206.130:8888/v1/AUTH_%(tenant_id)s' \
--internalurl 'http://192.168.206.130:8888/v1/AUTH_%(tenant_id)s' \
--adminurl 'http://192.168.206.130:8888/v1'
+-------------+---------------------------------------------------+
| Property | Value |
+-------------+---------------------------------------------------+
| adminurl | http://192.168.206.130:8888/v1 |
| id | e32b3c4780e51332f9c128a8c208a5a4 |
| internalurl | http://192.168.206.130:8888/v1/AUTH_%(tenant_id)s |
| publicurl | http://192.168.206.130:8888/v1/AUTH_%(tenant_id)s |
| region | RegionOne |
| service_id | 272efad2d1234376cbb911c1e5a5a6ed |
+-------------+---------------------------------------------------+
Setting up Tenants, Users, Roles, and Services -
ScriptedThe Keystone project offers a bash script for populating
tenants, users, roles and services at http://git.openstack.org/cgit/openstack/keystone/plain/tools/sample_data.sh
with sample data. This script uses 127.0.0.1 for all endpoint
IP addresses. This script also defines services for you.