OpenStack Cloud Computing Cookbook - Third Edition

3.9 (7 reviews total)
By Kevin Jackson , Cody Bunch , Egle Sigler
  • Instant online access to over 8,000+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Keystone – OpenStack Identity Service

About this book

OpenStack Open Source software is one of the most used cloud infrastructures to support software development and big data analysis. It is developed by a thriving community of individual developers from around the globe and backed by most of the leading players in the cloud space today.

It is simple to implement, massively scalable, and can store a large pool of data and networking resources. OpenStack has a strong ecosystem that helps you provision your cloud storage needs. Add OpenStack's enterprise features to reduce the cost of your business.

This book will show you the steps to build up a private cloud environment. At the beginning, you'll discover the uses of cloud services such as the identity service, image service, and compute service. You'll dive into Neutron, the OpenStack Networking service, and get your hands dirty with configuring ML2, networks, routers, and Distributed Virtual Routers. You’ll then gather more expert knowledge on OpenStack cloud computing by managing your cloud's security and migration. After that, we delve in to OpenStack Object storage and how to manage servers and work with objects, cluster, and storage functionalities. Also, as you go deeper into the realm of OpenStack, you'll learn practical examples of Block storage, LBaaS, and FWaaS: installation and configuration covered ground up. Finally, you will learn OpenStack dashboard, Ansible and Foreman, Keystone, and other interesting topics.

Publication date:
August 2015
Publisher
Packt
Pages
436
ISBN
9781782174783

 

Chapter 1. Keystone – OpenStack Identity Service

In this chapter, we will cover:

  • Installing the OpenStack Identity Service

  • Configuring OpenStack Identity for SSL communication

  • Creating tenants in Keystone

  • Configuring roles in Keystone

  • Adding users to Keystone

  • Defining service endpoints

  • Creating the service tenant and service users

  • Configuring OpenStack Identity for LDAP Integration

 

Introduction


The OpenStack Identity service, known as Keystone, provides services for authenticating and managing user accounts and role information for our OpenStack cloud environment. It is a crucial service that underpins the authentication and verification between all of our OpenStack cloud services and is the first service that needs to be installed within an OpenStack environment. The OpenStack Identity service authenticates users and tenants by sending a validated authorization token between all OpenStack services. This token is used for authentication and verification so that you can use that service, such as OpenStack Storage and Compute. Therefore, configuration of the OpenStack Identity service must be completed first, consisting of creating appropriate roles for users and services, tenants, the user accounts, and the service API endpoints that make up our cloud infrastructure.

In Keystone, we have the concepts of tenants, roles and users. A tenant is like a project and has resources such as users, images, and instances, as well as networks in it that are only known to that particular project. A user can belong to one or more tenants and is able to switch between these projects to gain access to those resources. Users within a tenant can have various roles assigned. In the most basic scenario, a user can be assigned either the role of admin or just be a member. When a user has admin privileges within a tenant, they are able to utilize features that can affect the tenant (such as modifying external networks), whereas a normal user is assigned the member role, which is generally assigned to perform user-related roles, such as spinning up instances, creating volumes, and creating tenant only networks.

 

Installing the OpenStack Identity Service


We will be performing an installation and configuration of the OpenStack Identity service, known as Keystone, using the Ubuntu Cloud Archive. Once configured, connecting to our OpenStack cloud environment will be performed through our new OpenStack Identity service.

The backend datastore for our OpenStack Identity service will be a MariaDB database. The environment we will be installing is shown in the following figure. In this chapter, we will be concentrating on the Controller host.

Getting ready

To ensure that we're running the Ubuntu Cloud Archive, we must first configure our Ubuntu 14.04 installation to use this service. For more information, visit http://bit.ly/OpenStackCookbookCloudArchive.

Tip

All of the steps can be found at http://www.openstackcookbook.com/.

We will configure Keystone to use MariaDB as the database backend, so this needs to be installed prior to installing Keystone.

Tip

If MariaDB is not installed, visit http://bit.ly/OpenStackCookbookPreReqs for instructions on how to do this.

Ensure that you have a suitable server available for installation of the OpenStack Identity service components. If you are using the accompanying Vagrant environment, as described in the Preface, this will be the controller node.

Make sure that you are logged in to the controller node and ensure that it has Internet access to allow us to install the required packages in our environment for running Keystone. If you created this node with Vagrant, you can execute the following command:

vagrant ssh controller

The instructions here assume that the controller node has two IP addresses. It will have a front-facing IP address, 192.168.100.200, and a backside IP address, 172.16.0.200, (which is also the address of the MariaDB server). The reason it has two addresses is that internal data will communicate over the backside IP address (for example, database traffic), and any Keystone traffic will traverse the front.

How to do it...

Carry out the following instructions to install the OpenStack Identity service:

  1. Installation of the OpenStack Identity service is done by specifying the Keystone package in Ubuntu, and we do this as follows:

    sudo apt-get update
    sudo apt-get install ntp keystone python-keyring
    
  2. Once installed, we need to configure the backend database store, so we first create the keystone database in MariaDB. We do this as follows (here, we have a user in MariaDB called root with the password openstack, which can create databases):

    MYSQL_ROOT_PASS=openstack
    mysql -uroot -p$MYSQL_ROOT_PASS -e "CREATE DATABASE \
        keystone;"
    
  3. It is good practice to create a user that is specific to our OpenStack Identity service, so we create a Keystone user in the database as follows:

    MYSQL_KEYSTONE_PASS=openstack
    mysql -uroot -p$MYSQL_ROOT_PASS -e "GRANT ALL PRIVILEGES ON \keystone.* TO 'keystone'@'localhost' IDENTIFIED BY \'$MYSQL_KEYSTONE_PASS';"
    mysql -uroot -p$MYSQL_ROOT_PASS -e "GRANT ALL PRIVILEGES ON \keystone.* TO 'keystone'@'%' IDENTIFIED BY \'$MYSQL_KEYSTONE_PASS';"
    
  4. We then need to configure the OpenStack Identity service by editing the /etc/keystone/keystone.conf file to have the following content:

    [DEFAULT]
    admin_token = ADMIN
    log_dir=/var/log/keystone
    
    [database]
    connection = mysql://keystone:[email protected]/keystone
    
    [extra_headers]
    Distribution = Ubuntu
    use_syslog = True
    syslog_log_facility = LOG_LOCAL0
  5. We can now restart the keystone service to pick up these changes:

    sudo stop keystone
    sudo start keystone
    
  6. With keystone started, we can now populate the keystone database with the required tables by issuing the following command:

    sudo keystone-manage db_sync
    

Congratulations! We have now installed the OpenStack Identity service and it is ready for use in our OpenStack environment.

How it works...

A convenient way to install the OpenStack Identity service in our OpenStack environment is by using the Ubuntu packages. Once installed, we configure our MariaDB database server with a keystone database and set up the keystone.conf configuration file with the corresponding values. After starting the Keystone service, running the keystone-manage db_sync command populates the keystone database with the appropriate tables ready for us to add in the required users, roles, and tenants required in our OpenStack environment.

 

Configuring OpenStack Identity for SSL communication


One of the many updates to this book will be a more hardened all-around approach. To that end, we begin by enabling SSL communication for services with Keystone by default. It is important to note that we will be doing this via self-signed certificates to illustrate how to configure the services. It is strongly recommended that you acquire the appropriate certificates from a Certificate Authority (CA) for deployment in production.

Getting ready

Ensure that you are logged in to the controller node and that it has Internet access to allow us to install the required packages in our environment for running Keystone. If you created this node with Vagrant, you can execute the following command:

vagrant ssh controller

How to do it...

Carry out the following instructions to configure the Keystone service:

  1. Before we can configure Keystone to use SSL, we need to generate the required OpenSSL Certificates. To do so, log in to the server that is running Keystone and issue the following commands:

    sudo apt-get install python-keystoneclient
    keystone-manage ssl_setup --keystone-user keystone \--keystone-group keystone
    

    Tip

    The command keystone-manage ssl_setup is not intended for production use. This is a convenient tool for creating self-signed certificates for Keystone.

  2. Once our certificates are generated, we can use them when communicating with our Keystone service. We can refer to the generated CA file for our other services by placing this in an accessible place. To do so, issue the following commands:

    sudo cp /etc/keystone/ssl/certs/ca.pem /etc/ssl/certs/ca.pem
    sudo c_rehash /etc/ssl/certs/ca.pem
    
  3. We also take the same CA and CA Key file to use on our client, so copy these where you will be running the relevant python-*client tools. In our Vagrant environment, we can copy this to our host as follows:

    sudo cp /etc/keystone/ssl/certs/ca.pem /vagrant/ca.pem
    sudo cp /etc/keystone/ssl/certs/cakey.pem /vagrant/cakey.pem
    
  4. We then need to edit the Keystone configuration file /etc/keystone/keystone.conf to include the following section:

    [ssl]
    enable = True
    certfile = /etc/keystone/ssl/certs/keystone.pem
    keyfile = /etc/keystone/ssl/private/keystonekey.pem
    ca_certs = /etc/keystone/ssl/certs/ca.pem
    cert_subject=/C=US/ST=Unset/L=Unset/O=Unset/CN=192.168.100.200
    ca_key = /etc/keystone/ssl/certs/cakey.pem
  5. Finally, restart the Keystone service:

    sudo stop keystone
    sudo start keystone
    

How it works...

The OpenStack services normally intercommunicate via standard HTTP requests. This provides a large degree of flexibility, but it comes at the cost of all communication happening in plain text. By adding SSL certificates and changing Keystone's configuration, all communication with Keystone will now be encrypted via HTTPS.

 

Creating tenants in Keystone


A tenant in OpenStack is a project, and the two terms are generally used interchangeably. Users can't be created without having a tenant assigned to them, so these must be created first. For this section, we will create a tenant called cookbook for our users.

Getting ready

We will be using the keystone client to operate Keystone. If the python-keystoneclient tool isn't available, follow the steps described at http://bit.ly/OpenStackCookbookClientInstall.

Ensure that we have our environment set correctly to access our OpenStack environment for administrative purposes:

export OS_TENANT_NAME=cookbook
export OS_USERNAME=admin
export OS_PASSWORD=openstack
export OS_AUTH_URL=https://192.168.100.200:5000/v2.0/
export OS_NO_CACHE=1
export OS_KEY=/vagrant/cakey.pem
export OS_CACERT=/vagrant/ca.pem

Tip

You can use the controller node if no other machines are available on your network, as this has the python-keystoneclient and the relevant access to the OpenStack environment. If you are using the Vagrant environment issue the following command to get access to the Controller:

vagrant ssh controller

How to do it...

To create a tenant in our OpenStack environment, perform the following steps:

  1. We start by creating a tenant called cookbook:

    keystone tenant-create \
        --name cookbook \
        --description "Default Cookbook Tenant" \
        --enabled true
    

    This will produce output similar to:

    +-------------+----------------------------------+
    |   Property  |              Value               |
    +-------------+----------------------------------+
    | description |     Default Cookbook Tenant      |
    |   enabled   |               True               |
    |      id     | fba7b31689714d1ab39a751bc9483efd |
    |     name    |             cookbook             |
    +-------------+----------------------------------+
    
  2. We also need an admin tenant so that when we create users in this tenant, they have access to our complete environment. We do this in the same way as in the previous step:

    keystone tenant-create \
        --name admin \
        --description "Admin Tenant" \
        --enabled true
    

How it works...

Creation of the tenants is achieved by using the keystone client, specifying the tenant-create option with the following syntax:

keystone tenant-create \
    --name tenant_name \
    --description "A description" \
    --enabled true

The tenant_name is an arbitrary string and must not contain spaces. On creation of the tenant, this returns an ID associated with it that we use when adding users to this tenant. To see a list of tenants and the associated IDs in our environment, we can issue the following command:

keystone tenant-list
 

Configuring roles in Keystone


Roles are the permissions given to users within a tenant. Here, we will configure two roles: an admin role that allows for the administration of our environment, and a member role that is given to ordinary users who will be using the cloud environment.

Getting ready

We will be using the keystone client to operate Keystone. If the python-keystoneclient tool isn't available, follow the steps described at http://bit.ly/OpenStackCookbookClientInstall.

Ensure that we have our environment set correctly to access our OpenStack environment for administrative purposes:

export OS_TENANT_NAME=cookbook
export OS_USERNAME=admin
export OS_PASSWORD=openstack
export OS_AUTH_URL=https://192.168.100.200:5000/v2.0/
export OS_NO_CACHE=1
export OS_KEY=/vagrant/cakey.pem
export OS_CACERT=/vagrant/ca.pem

Tip

You can use the controller node if no other machines are available on your network, as this has the python-keystoneclient and the relevant access to the OpenStack environment. If you are using the Vagrant environment, issue the following command to get access to the Controller:

vagrant ssh controller

How to do it...

To create the required roles in our OpenStack environment, perform the following steps:

  1. Create the admin role as follows:

    # admin role
    keystone role-create --name admin
    You will get an output like this:
    +----------+----------------------------------+
    | Property |              Value               |
    +----------+----------------------------------+
    |    id    | 625b81ae9f024366bbe023a62ab8a18d |
    |   name   |              admin               |
    +----------+----------------------------------+
    
  2. To create the Member role, we repeat the step and specify the Member role:

    # Member role
    keystone role-create --name Member
    

How it works...

Creation of the roles is simply achieved by using the keystone client and specifying the role-create option with the following syntax:

keystone role-create --name role_name

The role_name attribute can't be arbitrary for admin and Member roles. The admin role has been set by default in /etc/keystone/policy.json as having administrative rights:

{
    "admin_required": [["role:admin"], ["is_admin:1"]]
}

The Member role is also configured by default in the OpenStack Dashboard, Horizon, for a non-admin user created through the web interface.

On creation of the role, the ID associated with is returned, and we can use it when assigning roles to users. To see a list of roles and the associated IDs in our environment, we can issue the following command:

keystone role-list
 

Adding users to Keystone


Adding users to the OpenStack Identity service requires that the user has a tenant that they can exist in and there is a defined role that can be assigned to them. For this section, we will create two users. The first user will be named admin and will have the admin role assigned to them in the cookbook tenant. The second user will be named demo and will have the Member role assigned to them in the same cookbook tenant.

Getting ready

We will be using the keystone client to operate Keystone. If the python-keystoneclient tool isn't available, follow the steps described at http://bit.ly/OpenStackCookbookClientInstall.

Ensure that we have our environment set correctly to access our OpenStack environment for administrative purposes:

export OS_TENANT_NAME=cookbook
export OS_USERNAME=admin
export OS_PASSWORD=openstack
export OS_AUTH_URL=https://192.168.100.200:5000/v2.0/
export OS_NO_CACHE=1
export OS_KEY=/vagrant/cakey.pem
export OS_CACERT=/vagrant/ca.pem

Tip

You can use the controller node if no other machines are available on your network, as this has the python-keystoneclient and the relevant access to the OpenStack environment. If you are using the Vagrant environment, issue the following command to get access to the Controller:

vagrant ssh controller

How to do it...

To create the required users in our OpenStack environment, perform the following steps:

  1. To create a user in the cookbook tenant, we first need to get the cookbook tenant ID. To do this, issue the following command, which we conveniently store in a variable named TENANT_ID with the tenant-list option:

    TENANT_ID=$(keystone tenant-list \
        | awk '/\ cookbook\ / {print $2}')
    
  2. Now that we have the tenant ID, the admin user in the cookbook tenant is created using the user-create option and a password is chosen for the user:

    PASSWORD=openstack
    keystone user-create \
        --name admin \
        --tenant_id $TENANT_ID \
        --pass $PASSWORD \
        --email [email protected] \
        --enabled true
    

    The preceding code will produce the following output:

    +----------+----------------------------------+
    | Property |              Value               |
    +----------+----------------------------------+
    |  email   |          [email protected]          |
    | enabled  |               True               |
    |    id    | 2e23d0673e8a4deabe7c0fb70dfcb9f2 |
    |   name   |              admin               |
    | tenantId | 14e34722ac7b4fe298886371ec17cf40 |
    | username |              admin               |
    +----------+----------------------------------+
    
  3. As we are creating the admin user, which we are assigning the admin role, we need the admin role ID. We pick out the ID of the admin role and conveniently store it in a variable to use it when assigning the role to the user with the role-list option:

    ROLE_ID=$(keystone role-list \
        | awk '/\ admin\ / {print $2}')
    
  4. To assign the role to our user, we need to use the user ID that was returned when we created that user. To get this, we can list the users and pick out the ID for that particular user with the following user-list option:

    USER_ID=$(keystone user-list \
        | awk '/\ admin\ / {print $2}')
    
  5. With the tenant ID, user ID, and an appropriate role ID available, we can assign that role to the user with the following user-role-add option:

    keystone user-role-add \
        --user $USER_ID \
        --role $ROLE_ID \
        --tenant_id $TENANT_ID
    

    Tip

    Note that there is no output produced on successfully running this command.

  6. The admin user also needs to be in the admin tenant for us to be able to administer the complete environment. To do this, we need to get the admin tenant ID and then repeat the previous step using this new tenant ID:

    ADMIN_TENANT_ID=$(keystone tenant-list \
        | awk '/\ admin\ / {print $2}')
    keystone user-role-add \
        --user $USER_ID \
        --role $ROLE_ID \
        --tenant_id $ADMIN_TENANT_ID
    
  7. To create the demo user in the cookbook tenant with the Member role assigned, we repeat the process defined in steps 1 to 5:

    # Get the cookbook tenant ID
    TENANT_ID=$(keystone tenant-list \
        | awk '/\ cookbook\ / {print $2}')
    
    # Create the user
    PASSWORD=openstack
    keystone user-create \
        --name demo \
        --tenant_id $TENANT_ID \
        --pass $PASSWORD \
        --email [email protected] \
        --enabled true
    
    # Get the Member role ID
    ROLE_ID=$(keystone role-list \
        | awk '/\ Member\ / {print $2}')
    
    # Get the demo user ID
    USER_ID=$(keystone user-list \
        | awk '/\ demo\ / {print $2}')
    
    # Assign the Member role to the demo user in cookbook
    keystone user-role-add \
        --user $USER_ID \
        -–role $ROLE_ID \
        --tenant_id $TENANT_ID
    

How it works...

Adding users in the OpenStack Identity service involves a number of steps and dependencies. First, a tenant is required for the user to be part of. Once the tenant exists, the user can be added. At this point, the user has no role associated, so the final step is to designate the role to this user, such as Member or admin.

Use the following syntax to create a user with the user-create option:

keystone user-create \
    --name user_name \
    --tenant_id TENANT_ID \
    --pass PASSWORD \
    --email email_address \
    --enabled true

The user_name attribute is an arbitrary name but cannot contain any spaces. A password attribute must be present. In the previous examples, these were set to openstack. The email_address attribute must also be present.

To assign a role to a user with the user-role-add option, use the following syntax:

keystone user-role-add \
    --user USER_ID \
    --role ROLE_ID \
    --tenant_id TENANT_ID

This means that we need to have the ID of the user, the ID of the role, and the ID of the tenant in order to assign roles to users. These IDs can be found using the following commands:

keystone tenant-list
keystone user-list
keystone role-list
 

Defining service endpoints


Each of the services in our cloud environment runs on a particular URL and port—these are the endpoint addresses for our services. When a client communicates with our OpenStack environment that runs the OpenStack Identity service, it is this service that returns the endpoint URLs that the user can use in an OpenStack environment. To enable this feature, we must define these endpoints. In a cloud environment, we can define multiple regions. Regions can be thought of as different datacenters, which would imply that they would have different URLs or IP addresses. Under the OpenStack Identity service, we can define these URL endpoints separately for each region. As we only have a single environment, we will reference this as RegionOne.

Getting ready

We will be using the keystone command line client to operate Keystone. If the python-keystoneclient tool isn't available, follow the steps described at http://bit.ly/OpenStackCookbookClientInstall.

Ensure that we have our environment set correctly to access our OpenStack environment for administrative purposes:

export OS_TENANT_NAME=cookbook
export OS_USERNAME=admin
export OS_PASSWORD=openstack
export OS_AUTH_URL=https://192.168.100.200:5000/v2.0/
export OS_NO_CACHE=1
export OS_KEY=/vagrant/cakey.pem
export OS_CACERT=/vagrant/ca.pem

Tip

You can use the controller node if no other machines are available on your network, as this has the python-keystoneclient and has the relevant access to the OpenStack environment. If you are using the Vagrant environment, issue the following command to get access to the Controller:

vagrant ssh controller

How to do it...

Defining the services and their endpoints in the OpenStack Identity service involves running the keystone client command. Although we might not have all services currently running in our environment, we will be configuring them within the OpenStack Identity service for future use. To define endpoints for services in our OpenStack environment, carry out the following steps:

  1. We can now define the actual services that the OpenStack Identity service needs to know about in our environment:

    # OpenStack Compute Nova API Endpoint
    keystone service-create \
        --name nova \
        --type compute \
        --description 'OpenStack Compute Service'
    # OpenStack Compute EC2 API Endpoint
    keystone service-create \
        --name ec2 \
        --type ec2 \
        --description 'EC2 Service'
    
    # Glance Image Service Endpoint
    keystone service-create \
        --name glance \
        --type image \
        --description 'OpenStack Image Service'
    
    # Keystone Identity Service Endpoint
    keystone service-create \
        --name keystone \
        --type identity \
        --description 'OpenStack Identity Service'
    
    # Neutron Networking Service Endpoint
    keystone service-create \
        --name network \
        --type network \
        --description 'OpenStack Network Service'
    
    #Cinder Block Storage Endpoint
    keystone service-create \
        --name volume \
        --type volume \
        --description 'Volume Service'
    
  2. After we have done this, we can add in the service endpoint URLs that these services run on. To do this, we need the ID that was returned for each of the service endpoints created in the previous step. The ID is then used as a parameter when specifying the endpoint URLS for that service.

    Tip

    The OpenStack Identity service can be configured to service requests on three URLs: a public facing URL (that the end users use), an administration URL (that users with administrative access can use that might have a different URL), and an internal URL (that is appropriate when presenting the services on either side of a firewall to the public URL).

  3. For the following services, we will configure separate public, admin, and internal service URLs to provide appropriate separation for our environment. The public endpoint in the accompanying lab environment will be the nominated public interface IP of our controller, which is 192.168.100.200. The internal endpoint will be 172.16.0.200. The admin endpoint will also be the public IP of 192.168.100.200. To do this run the following commands:

    # OpenStack Compute Nova API
    NOVA_SERVICE_ID=$(keystone service-list \
        | awk '/\ nova\ / {print $2}')
    
    PUBLIC_ENDPOINT=192.168.100.200
    ADMIN_ENDPOINT=192.168.100.200
    INT_ENDPOINT=172.16.0.200
    
    PUBLIC="http://$PUBLIC_ENDPOINT:8774/v2/\$(tenant_id)s"
    ADMIN="http://$ADMIN_ENDPOINT:8774/v2/\$(tenant_id)s"
    INTERNAL="http://$INT_ENDPOINT:8774/v2/\$(tenant_id)s"
    
    keystone endpoint-create \
        --region RegionOne \
        --service_id $NOVA_SERVICE_ID \
        --publicurl $PUBLIC \
        --adminurl $ADMIN \
        --internalurl $INTERNAL
    

    You will get output similar to what is shown below:

    +-------------+------------------------------------------------+
    |   Property  |                     Value                      |
    +-------------+------------------------------------------------+
    |   adminurl  | http://192.168.100.200:8774/v2/$(tenant_id)s   |
    |      id     |        87b59c5ce8314d8b9029bf1efd5044d7        |
    | internalurl |   http://172.16.0.100:8774/v2/$(tenant_id)s    |
    |  publicurl  |   http://192.168.100.200:8774/v2/$(tenant_id)s |
    |    region   |                   RegionOne                    |
    |  service_id |        a3529dcbeab44d479d1f258ae6d202b4        |
    +-------------+------------------------------------------------+
  4. We continue to define the rest of our service endpoints, as shown in the following steps:

    # OpenStack Compute EC2 API
    EC2_SERVICE_ID=$(keystone service-list \
        | awk '/\ ec2\ / {print $2}')
    
    PUBLIC="http://$PUBLIC_ENDPOINT:8773/services/Cloud"
    ADMIN="http://$ADMIN_ENDPOINT:8773/services/Admin"
    INTERNAL="http://$INT_ENDPOINT:8773/services/Cloud"
    
    keystone endpoint-create \
        --region RegionOne \
        --service_id $EC2_SERVICE_ID \
        --publicurl $PUBLIC \
        --adminurl $ADMIN \
        --internalurl $INTERNAL
    
    # Glance Image Service
    GLANCE_SERVICE_ID=$(keystone service-list \
        | awk '/\ glance\ / {print $2}')
    
    PUBLIC="http://$PUBLIC_ENDPOINT:9292/v1"
    ADMIN="http://$ADMIN_ENDPOINT:9292/v1"
    INTERNAL="http://$INT_ENDPOINT:9292/v1"
    
    keystone endpoint-create \
        --region RegionOne \
        --service_id $GLANCE_SERVICE_ID \
        --publicurl $PUBLIC \
        --adminurl $ADMIN \
        --internalurl $INTERNAL
    
    
    # Keystone OpenStack Identity Service
    # Note we're using SSL HTTPS here
    KEYSTONE_SERVICE_ID=$(keystone service-list \
        | awk '/\ keystone\ / {print $2}')
    
    PUBLIC="https://$PUBLIC_ENDPOINT:5000/v2.0"
    ADMIN="https://$ADMIN_ENDPOINT:35357/v2.0"
    INTERNAL="https://$INT_ENDPOINT:5000/v2.0"
    
    keystone endpoint-create \
        --region RegionOne \
        --service_id $KEYSTONE_SERVICE_ID \
        --publicurl $PUBLIC \
        --adminurl $ADMIN \
        --internalurl $INTERNAL
    
    
    # Neutron Networking Service
    NEUTRON_SERVICE_ID=$(keystone service-list \
        | awk '/\ network\ / {print $2}')
    
    PUBLIC="http://$PUBLIC_ENDPOINT:9696"
    ADMIN="http://$ADMIN_ENDPOINT:9696"
    INTERNAL="http://$INT_ENDPOINT:9696"
    
    keystone endpoint-create \
        --region RegionOne \
        --service_id $NEUTRON_SERVICE_ID  \
        --publicurl $PUBLIC \
        --adminurl $ADMIN \
        --internalurl $INTERNAL
    
    #Cinder Block Storage Service
    CINDER_SERVICE_ID=$(keystone service-list \
        | awk '/\ volume\ / {print $2}')
    
    PUBLIC="http://$PUBLIC_ENDPOINT:8776/v1/%(tenant_id)s"
    ADMIN=$PUBLIC
    INTERNAL=$PUBLIC
    
    keystone endpoint-create \
        --region RegionOne \
        --service_id $CINDER_SERVICE_ID  \
        --publicurl $PUBLIC \
        --adminurl $ADMIN \
        --internalurl $INTERNAL
    

How it works...

Configuring the services and endpoints within the OpenStack Identity service is done with the keystone client command.

We first add the service definitions using the keystone client and the service-create option with the following syntax:

keystone service-create \
    --name service_name \
    --type service_type \
    --description 'description'

In the service_name is an arbitrary name or label defining our service of a particular type. We refer to the name when defining the endpoint to fetch the ID of the service.

The type option can be one of the following: compute, object-store, image-service, network, and identity-service. Note that we haven't configured the OpenStack Object Storage service (type object-store) at this stage, as this is covered in later recipes in the book.

The description field is again an arbitrary field describing the service.

Once we have added in our service definitions, we can tell OpenStack Identity service from where these services run by defining the endpoints using the keystone client and the endpoint-create option. The syntax is as follows:

keystone endpoint-create \
    --region region_name \
    --service_id service_id \
    --publicurl public_url \
    -–adminurl admin_url \
    --internalurl internal_url

Here, service_id is the ID of the service when we created the service definitions in the first step. The list of our services and IDs can be obtained by running the following command:

keystone service-list

As OpenStack is designed for global deployments, a region defines a physical datacenter or a geographical area that comprises of multiple connected datacenters. For our purpose, we define just a single region—RegionOne. This is an arbitrary name that we can reference when specifying what runs in what datacenter/area and we carry the region name through to when we configure our client for use with these regions.

All of our services can be configured to run on three different URLs, as follows, depending on how we want to configure our OpenStack cloud environment:

  • public_url: This parameter is the URL that end users would connect on. In a public cloud environment, this would be a public URL that resolves to a public IP address.

  • admin_url: This parameter is a restricted address for conducting administration. In a public deployment, you would keep this separate from the public_url by presenting the service you are configuring on a different, restricted URL. Some services have a different URI for the admin service, so this is configured using this attribute.

  • internal_url: This parameter would be the IP or URL that existed only within the private local area network. The reason for this is that you can connect to services from your cloud environment internally without connecting over a public IP address space, which could incur data charges for traversing the Internet. It is also potentially more secure and less complex to do so.

    Tip

    Once the initial keystone database has been set up, after running the initial keystone-manage db_sync command on the OpenStack Identity service server, administration can be done remotely using the keystone client.

 

Creating the service tenant and service users


Now that the service endpoints are created, we can configure them so that our other OpenStack services can utilize them. To do this, each service is configured with a username and password within a special service tenant. Configuring each service to have its own username and password allows for greater security, troubleshooting, and auditing within our environment. When setting up a service to use the OpenStack Identity service for authentication and authorization, we specify these details in their relevant configuration file. Each service itself has to authenticate with keystone in order for it to be available within OpenStack. Configuration of that service is then done using these credentials. For example, for glance, we specify the following lines in /etc/glance/glance-registry.conf, when used with OpenStack Identity service, which matches what we created previously:

[keystone_authtoken]
identity_uri = https://192.168.100.200:35357
admin_tenant_name = service
admin_user = glance
admin_password = glance
insecure = True

Tip

The use of insecure = True here is only required as self-signed certificates are used throughout this book. In production, we would use issued certificates and omit this option in our configs.

Getting ready

We will be using the keystone client to operate Keystone. If the python-keystoneclient tool isn't available, follow the steps described at http://bit.ly/OpenStackCookbookClientInstall.

Ensure that we have our environment set correctly to access our OpenStack environment for administrative purposes:

export OS_TENANT_NAME=cookbook
export OS_USERNAME=admin
export OS_PASSWORD=openstack
export OS_AUTH_URL=https://192.168.100.200:5000/v2.0/
export OS_NO_CACHE=1
export OS_KEY=/vagrant/cakey.pem
export OS_CACERT=/vagrant/ca.pem

Tip

You can use the controller node if no other machines are available on your network, as this has the python-keystoneclient and the relevant access to the OpenStack environment. If you are using the Vagrant environment, issue the following command to get access to the Controller:

vagrant ssh controller

How to do it...

To configure an appropriate service tenant, carry out the following steps:

  1. Create the service tenant as follows:

    keystone tenant-create \
        --name service \
        --description "Service Tenant" \
        --enabled true
    

    This produces output similar to what is shown as follows:

    +-------------+----------------------------------+
    |   Property  |              Value               |
    +-------------+----------------------------------+
    | description |          Service Tenant          |
    |   enabled   |               True               |
    |      id     | 8e77d9c13e884bf4809077722003bba0 |
    |     name    |             service              |
    +-------------+----------------------------------+
    
  2. Record the ID of the service tenant so that we can assign service users to this ID:

    SERVICE_TENANT_ID=$(keystone tenant-list \
        | awk '/\ service\ / {print $2}')
    
  3. For each of the services in this section, we will create the user accounts to be named the same as the services and set the password to be the same as the service name too. For example, we will add a user called nova with a password nova in the service tenant by using the user-create option:

    keystone user-create \
        --name nova \
        --pass nova \
        --tenant_id $SERVICE_TENANT_ID \
        --email [email protected] \
        --enabled true
    

    The preceding code will produce an output similar to what is shown here:

    +----------+----------------------------------+
    | Property |              Value               |
    +----------+----------------------------------+
    |  email   |          [email protected]          |
    | enabled  |               True               |
    |    id    | 50ea356a4b6f4cb7a9fa22c1fb08549b |
    |   name   |               nova               |
    | tenantId | 42e5c284de244e3190e12cc44fbbbe62 |
    | username |               nova               |
    +----------+----------------------------------+
    
  4. We then repeat this for each of our other services that will use OpenStack Identity service:

    keystone user-create \
        --name glance \
        --pass glance \
        --tenant_id $SERVICE_TENANT_ID \
        --email [email protected] \
        --enabled true
    
    keystone user-create \
        --name keystone \
        --pass keystone \
        --tenant_id $SERVICE_TENANT_ID \
        --email [email protected] \
        --enabled true
    
    keystone user-create \
        --name neutron \
        --pass neutron \
        --tenant_id $SERVICE_TENANT_ID \
        --email [email protected] \
        --enabled true
    
    keystone user-create \
        --name cinder \
        --pass cinder \
        --tenant_id $SERVICE_TENANT_ID \
        --email [email protected] \
        --enabled true
    
  5. We can now assign these users the admin role in the service tenant. To do this, we use the user-role-add option after retrieving the user ID of the nova user. For example, to add the admin role to the nova user in the service tenant, we use the following code:

    # Get the nova user id
    NOVA_USER_ID=$(keystone user-list \
        | awk '/\ nova\ / {print $2}')
    
    # Get the admin role id
    ADMIN_ROLE_ID=$(keystone role-list \
        | awk '/\ admin\ / {print $2}')
    
    # Assign the nova user the admin role in service tenant
    keystone user-role-add \
        --user $NOVA_USER_ID \
        --role $ADMIN_ROLE_ID \
        --tenant_id $SERVICE_TENANT_ID
  6. We then repeat this for our other service users, glance, keystone, neutron, and cinder:

    # Get the glance user id
    GLANCE_USER_ID=$(keystone user-list \
        | awk '/\ glance\ / {print $2}')
    
    # Assign the glance user the admin role in service tenant
    keystone user-role-add \
        --user $GLANCE_USER_ID \
        --role $ADMIN_ROLE_ID \
        --tenant_id $SERVICE_TENANT_ID
    # Get the keystone user id
    KEYSTONE_USER_ID=$(keystone user-list \
        | awk '/\ keystone\ / {print $2}')
    
    # Assign the keystone user the admin role in service tenant
    keystone user-role-add \
        --user $KEYSTONE_USER_ID \
        --role $ADMIN_ROLE_ID \
        --tenant_id $SERVICE_TENANT_ID
    
    # Get the cinder user id
    NEUTRON_USER_ID=$(keystone user-list \
        | awk '/\ neutron \ / {print $2}')
    
    # Assign the neutron user the admin role in service tenant
    keystone user-role-add \
        --user $NEUTRON_USER_ID \
        --role $ADMIN_ROLE_ID \
        --tenant_id $SERVICE_TENANT_ID
    
    # Get the cinder user id
    CINDER_USER_ID=$(keystone user-list \
        | awk '/\ cinder \ / {print $2}')
    
    # Assign the cinder user the admin role in service tenant
    keystone user-role-add \
        --user $CINDER_USER_ID \
        --role $ADMIN_ROLE_ID \
        --tenant_id $SERVICE_TENANT_ID

How it works...

Creation of the service tenant, which is populated with the services required to run OpenStack, is no different from creating any other users on our system that require the admin role. We create the usernames and passwords and ensure that they exist in the service tenant with the admin role assigned to each user. We then use these credentials when configuring the services to authenticate with the OpenStack Identity service.

Tip

Downloading the example code

You can download the example code files for this book at https://github.com/OpenStackCookbook/OpenStackCookbook. All the support files are available here.

 

Configuring OpenStack Identity for LDAP Integration


The OpenStack Identity service that we have built so far provides you with a functional, but isolated, set up for your OpenStack environment. This is a useful setup for Proof of Concept and lab environments. However, it is likely that you will need to integrate OpenStack with your existing authentication system. OpenStack Identity provides a pluggable authentication back end for this, with LDAP being the most widely used.

Getting ready

We will be using the keystone client to operate Keystone. If the python-keystoneclient tool isn't available, follow the steps described at http://bit.ly/OpenStackCookbookClientInstall.

Ensure that we have our environment set correctly to access our OpenStack environment for administrative purposes:

export OS_TENANT_NAME=cookbook
export OS_USERNAME=admin
export OS_PASSWORD=openstack
export OS_AUTH_URL=https://192.168.100.200:5000/v2.0/
export OS_NO_CACHE=1
export OS_KEY=/vagrant/cakey.pem
export OS_CACERT=/vagrant/ca.pem

Tip

You can use the controller node if no other machines are available on your network, as this has the python-keystoneclient and the relevant access to the OpenStack environment. If you are using the Vagrant environment, issue the following command to get access to the Controller:

vagrant ssh controller

Additionally, to connect to an external LDAP service, you will need to possess the hostname or IP address of the LDAP server and have appropriate access to the server. You will also need to have the LDAP path information for an admin user, and for the Organizational Units that contain the Users, Roles, and Tenants.

Note

We have provided a sample OpenLDAP server that is prepopulated with the required values as part of this book's supplementary materials, and instructions on how to use it located on our book blog at http://bit.ly/OpenStackCookbookLDAP

How to do it...

To configure OpenStack Identity to communicate with LDAP, perform the following steps:

  1. Using your favorite editor, enable LDAP authentication in the keystone.conf file:

    [identity]
    driver=keystone.identity.backends.ldap.Identity
  2. Next, create the ldap section and add the URL to your existing LDAP server:

    [ldap]
    url = ldap://openldap
  3. On the following lines, specify the LDAP path for the admin user you will use, along with its password and the suffix, or where you would like Keystone to begin searching LDAP:

    user = cn=admin,dc=cook,dc=book
    password = openstack
    suffix = cn=cook,cn=book
  4. In the same [ldap] section, we tell Keystone four pieces of information about how to find users. user_tree_dn specifies which OU within the LDAP tree to search for users. user_objectclass specifies how a user is represented within LDAP. user_id_attribute tells Keystone which property of the user to use as a username. Similarly, user_mail_attribute tells Keystone where to find the user's e-mail address. The code is as follows:

    user_tree_dn = ou=Users,dc=cook,dc=book
    user_objectclass = inetOrgPerson
    user_id_attribute = cn
    user_mail_attribute = mail
  5. Next, add the same details for Tenants and Roles:

    tenant_tree_dn = ou=Projects,dc=cook,dc=book
    tenant_objectclass = groupOfNames
    tenant_id_attribute = cn
    tenant_desc_attribute = description
    
    role_tree_dn = ou=Roles,dc=cook,dc=book
    role_objectclass = organizationalRole
    role_id_attribute = cn
    role_member_attribute = roleOccupant
  6. Save the file and restart keystone:

    sudo stop keystone
    sudo start keystone
    

How it works...

The OpenStack Identity service, like other OpenStack services, is based on plugins. In its default state, Keystone will store and access all user identity and authentication data from a SQL database. However, when integrating OpenStack into an existing environment, this is not always the most desirable or secure method. To accommodate this, we changed the identity back end to LDAP. This allows for integration with OpenLDAP, Active Directory, and many others. However, when configuring the backend, you need to pay special attention to the LDAP paths.

Note

Where are the entries for the services catalog? These are still stored in Keystone's SQL database, as they aren't specifically related to user identity or authentication.

About the Authors

  • Kevin Jackson

    Kevin Jackson is married and has three children. He is an IT professional with over 20 years of experience, working with businesses and enterprises of all sizes at Rackspace, as an OpenStack and private cloud specialist. Kevin has been working with OpenStack since the fist release, and he has extensive experience of various flavors of Linux, Unix, and hosting environments. Kevin authored the fist edition of this book, and coauthored the second and third editions. Kevin also coauthored OpenStack Architecture Design Guide, OpenStack Foundation, during a 5-day book sprint in California. He also regularly speaks at OpenStack community events.

    Browse publications by this author
  • Cody Bunch

    Cody Bunch is a principal architect in the Rackspace Private Cloud group, based out of San Antonio, Texas. Cody has been working with OpenStack since early 2012, coauthored the second edition of this book, and also coauthored OpenStack Security Guide, OpenStack Foundation. Cody has extensive experience with virtualized and cloud environments in variously sized enterprises and hosting environments.

    Browse publications by this author
  • Egle Sigler

    Egle Sigler is an OpenStack Foundation board member and a principal architect in the Rackspace Private Cloud group, based out of San Antonio, Texas. Egle holds an MS degree in computer science. She started her career as a software developer and still has a soft spot for all the people who write, test, and deploy code, since she has had the chance to do all of these tasks throughout her career. Egle dreams about a day when writing, testing, and deploying code will be a seamless and easy process—bug and frustration free for all. Egle believes that knowledge should be shared and has tried to do this by writing this book, giving talks and workshops at conferences, and blogging.

    Browse publications by this author

Latest Reviews

(7 reviews total)
Good
Excellent
Good
Book Title
Access this book, plus 8,000 other titles for FREE
Access now