Chapter 3. Learning basic OpenStack operations

This chapter covers

  • Managing the OpenStack CLI to manipulate your deployment
  • Exploring the OpenStack tenant model by building a new tenant
  • Setting up basic tenant networking with intra-tenant configuration
  • Using OpenStack networking for internal and external network configuration
  • Modifying tenant quotas to control resource allocation

This chapter builds on the deployment from chapter 2 by demonstrating basic operations you’ll encounter as an OpenStack administrator or user. Chapter 2 was more focused on end-user interaction with OpenStack, so those examples were based on the Dashboard, which is easy to use and can be used to perform many user and administrative functions. This chapter focuses on operational exercises, so examples are based on the OpenStack command-line interface (CLI).

If you have systems administration experience, you’ll certainly appreciate the ability to script a repetitive function, such as creating a thousand users. The OpenStack APIs can also be used for these tasks, and they’ll be briefly introduced. As you’ll discover, if you can perform an operation with the CLI, you can easily perform the same operation with an API directly. For the examples in this chapter, we’ll stick with using the CLI, but this chapter is constructed so that you can walk through the examples using either an API or the Dashboard once you understand the concepts demonstrated through the CLI.

The CLI also has the added benefit of using separate applications for each OpenStack component. While at first this might seem like a bad thing, it will help you better understand which component is responsible for what.

The basic OpenStack operations covered in this chapter can be applied to a DevStack deployment, like the one in chapter 2, or to a very large multiserver production deployment. In chapter 2 you used the Demo tenant (project) and the demo user. These and other objects were created by DevStack, but tenants, users, networks, and other objects won’t be created for you automatically in manual deployment. In this chapter, we’ll walk through the process of creating the necessary objects to take a test-drive in a tenant you create. By the end of the chapter, you’ll know how to separate resource assignments using the OpenStack tenant model.

The chapter starts by introducing the OpenStack CLI. Then we’ll progress through the process of creating a tenant, user, and networks. Finally, you’ll learn about quota management from the tenant perspective. As you walk through the examples, take note of the CLI applications used in each step. You’ll not only learn basic OpenStack operations, but you should get a better understanding of which OpenStack components provide what functions. In chapter 4 we’ll cover OpenStack component relations in more detail.

3.1. Using the OpenStack CLI

Let’s take a brief look at how you can interact with OpenStack on the command line. Before you can run CLI commands, you must first set the appropriate environment variables in your shell. Environment variables tell the CLI how and where to identify you. You can provide input for these variables directly to the CLI, but for the sake of clarity, all examples will be shown with the appropriate environment variables in place.

To set these variables, run the commands shown in the next listing in your shell. Each time you log in to a session, you’ll have to set your environment variables.

Listing 3.1. Set environmental variables

Setting environment variables manually

If you’re an experienced user or you’re not using DevStack, you can manually set your environmental variables by running the following commands and substituting your values for the ones in these examples:

These example commands will set the current shell user as the OpenStack admin user of the admin tenant.

To make sure your variables have been properly set, you should test if you can run an OpenStack CLI command. In your shell, run the nova image-list command, as shown in listing 3.2. This CLI command reads the environment variables you just set and uses them as identification. If you’re properly identified and have rights to do so, the CLI will query OpenStack Compute (Nova) for your currently available image-list.

Listing 3.2. Setting variables and executing a first CLI command

You should now be able to run OpenStack CLI commands as the demo user in the demo tenant. This is the same user you used in chapter 2, so any changes you make using the CLI will be reflected in the Dashboard.

Using the command in listing 3.3, you can create a new OpenStack instance, just like you did in the Dashboard. As mentioned in chapter 2, an OpenStack instance is a VM for the purposes of this book.

Listing 3.3. Launching an instance from the CLI

When you run this command, you’ll get results something like the following:

nova boot 
--flavor 3 
--image 48ab76e9-c3f2-4963-8e9b-6b22a0e9c0cf 
Test_Instance_3
+---+---------------------------------+--------+--------+

+--------------------------------------+----------------+
| Property                             | Value          |
+--------------------------------------+----------------+
| OS-DCF:diskConfig                    | MANUAL         |
| OS-EXT-AZ:availability_zone          | nova           |
| OS-EXT-STS:power_state               | 0              |
| OS-EXT-STS:task_state                | scheduling     |
| OS-EXT-STS:vm_state                  | building       |
| OS-SRV-USG:launched_at               | -              |
| OS-SRV-USG:terminated_at             | -              |
| accessIPv4                           |                |
| accessIPv6                           |                |
...
...
+--------------------------------------+----------------+

You can do everything with the OpenStack CLI that you can using the Dashboard, and more. In the preceding example, you performed the Nova boot command, which provisioned a new VM. To get help with more-advanced Nova commands, use the following command: nova help COMMAND (replacing COMMAND with the command you’re interested in). There are similar command-line utilities for Keystone, Glance, Neutron, and so on.

You now have a basic idea of how the OpenStack CLI works. In later chapters, you’ll mostly be working with the CLI, so learning how things work in DevStack should be helpful if things don’t work as expected later.

Before we move on to the tenant examples, let’s take a look at the mechanics of the OpenStack APIs.

3.2. Using the OpenStack APIs

At this point you might be wondering, “How does the OpenStack CLI work?” The answer to this is that the CLI applications call APIs specific to OpenStack components. The component-specific APIs interface with a number of sources, including other APIs and relational databases. This also holds true for the Dashboard, which you used in chapter 2. All OpenStack interactions eventually lead back to the OpenStack API layer.

It could certainly be argued that the inherent vendor neutrality provided by the OpenStack APIs is OpenStack’s greatest benefit. An entire book could be devoted to working with the OpenStack APIs. People who integrate external systems or debug OpenStack code will find themselves looking at the API layer. The thing to keep in mind is that all roads lead to the OpenStack APIs. If you have further interest in them, see the sidebar, “Debug CLI/Expose API.”

To get started using the OpenStack APIs directly, you can follow the example in listing 3.4. This command will query the OpenStack APIs for information, which will be returned in JavaScript Object Notation (JSON) format. Python is used to parse the JSON so it can be read on your screen.

Listing 3.4. Executing a first API command

Debug CLI/Expose API

Every CLI command will output its API command if the debug flag is set. To enable debugging for a specific CLI command, pass the --debug argument before any other variables as shown here:

devstack@devstack:~$ nova --debug image-list

REQ: curl -i 'http://10.0.2.32:5000/v2.0/tokens'
-X POST -H "Content-Type: application/json"
-H "Accept: application/json"
-H "User-Agent: python-novaclient"
-d '{"auth": {"tenantName": "admin", "passwordCredentials":
{"username": "admin", "password": "devstack"}}}'

...

Now that you understand the mechanics of the OpenStack CLI and APIs, you’re ready to put these skills to use. In the next section we’ll walk through creating a new tenant (project) using the CLI. This is an operational function you’ll perform for each new department, user, or project you want to separate from a more general tenant.

3.3. Tenant model operations

OpenStack is natively multi-tenant-aware. As mentioned in chapter 2, you can think of your OpenStack deployment as a hotel. A person can’t be a resident of a hotel unless they have a room, so you can think of tenants as hotel rooms. Instead of beds and a TV, Hotel OpenStack provides computational resources. Just as a hotel room is configurable (single or double beds, a suite or a room, and so on), so are tenants. The number of resources (vCPU, RAM, storage, and the like), images (tenant-specific software images), and the configuration of the network are all based on tenant-specific configurations. Users are independent of tenants, but users may hold roles for specific tenants. A single user might hold the role of administrator in multiple tenants. Every time a new user is added to OpenStack, they must be assigned a tenant. Every time a new instance (VM) is created, it must be created in a tenant. Management of all OpenStack resources is based on the management of tenant resources.

Because your access to OpenStack resources is based on tenant configurations, you must understand how to create new tenants, users, roles, and quotas. In chapter 2 you used DevStack, which created a few sample tenants and users for you. In the next few subsections, you’ll walk through creating a new tenant and all the related objects that go with it, from scratch. As an OpenStack administrator, this will be a common task. A department or even a project might be a new tenant. Tenants will be the fundamental way that you divide and manage configurations and resources in OpenStack.

3.3.1. The tenant model

Before you start the process of creating tenant and user identity objects, you need to get an idea of how these items are related. Using our Hotel OpenStack analogy, figure 3.1 shows the interplay among tenants, members, and roles in OpenStack. You can see that a role is a designation independent of a tenant until a user is assigned a role in a tenant. You can see that user is an admin in the General tenant and a Member in the Another tenant. Notice that both users and roles have one-to-many relationships with tenants. As you move forward in this chapter’s examples, you’ll create several of the components shown in this figure.

Figure 3.1. The relation of tenants, users, and roles in OpenStack Identity (Keystone). Tenants can thought of as projects or departments. Like hotel rooms, they’re available in different configurations.

As you can see in figure 3.1, tenants are the way OpenStack organizes role assignments. In OpenStack all resource configuration (users with roles, instances, networks, and so on) is organized based on tenant separation. In OpenStack jargon, the term tenant can be used synonymously with project, so think of using a tenant for a particular project or organizational division. It’s worth noting that roles are defined outside of tenants, but users are created with an initial tenant assignment. It would be reasonable for a user to be created in a departmental tenant (for example, John Doe is created in the General tenant) and be assigned a role in another tenant (John Doe is a Member of Another tenant). This means that every tenant can have a specific user with the role Member, but that specific user would only have one home tenant.

I’ll use the OpenStack CLI to demonstrate examples in this section. I could just as easily use the Dashboard, but demonstrations using the CLI can often be more clearly explained because the CLI forces you to direct your request to the specific CLI application that deals with that function. When using the Dashboard, it’s hard to tell which component is controlling what. Once you understand the process through the CLI, using the Dashboard will be trivial.

Using DevStack from Chapter 2

The examples covered in this chapter are executed on the OpenStack instance deployed by DevStack, as described in chapter 2. If you already have your OpenStack instance from chapter 2 set up, you’re ready to run the examples in this chapter.

In listing 3.1 you set your environment variables to represent the Demo user in the Demo tenant. Because you’ll be creating a new tenant, you’ll need to set your environment variables to represent the Admin user in the Admin tenant, as shown in the following listing.

Listing 3.5. Prepare your shell session as admin

Admin or Demo

In the previous subsection, you set environmental variables to refer to the demo user. Under Linux, running as the root user when it’s not necessary is considered bad practice because it’s too easy to make possibly disruptive changes by accident. You can consider unnecessarily running commands as the admin user to be a similarly bad practice in OpenStack.

3.3.2. Creating tenants, users, and roles

In this section, you’ll create a new tenant and user. You’ll then assign a role to your new user in your new tenant.

Creating a tenant

Use the command shown in the following listing to create your new tenant.

Listing 3.6. Creating a new tenant
keystone tenant-create --name General

When you run the command, you’ll see output like the following:

+-------------+----------------------------------+
|   Property  |              Value               |
+-------------+----------------------------------+
| description |                                  |
|   enabled   |               True               |
|      id     | 9932bc0607014caeab4c3d2b94d5a40c |
|     name    |             General              |
+-------------+----------------------------------+

You’ve now created a new tenant that will be referenced when creating other OpenStack objects. Take note of the tenant ID generated in this process; you’ll need this ID for the next steps. Figure 3.2 illustrates the tenant you just created. The admin and Member roles were created as part of the DevStack deployment of OpenStack. The sidebar “Listing tenants and roles” explains how to list all tenants and roles for a particular OpenStack deployment.

Figure 3.2. The created tenant

Listing tenants and roles

You can list all tenants on the system as follows:

devstack@devstack:~/devstack$ keystone tenant-list
+----------------------------------+--------------------+---------+
|                id                |        name        | enabled |
+----------------------------------+--------------------+---------+
| 9932bc0607014caeab4c3d2b94d5a40c |      General       |   True  |
| b1c52f4025d244f883dd47f61791d5cf |       admin        |   True  |
| 166c9cab0722409d8dbc2085acea70d4 |      alt_demo      |   True  |
| 324d7477c2514b60ac0ae417ce3cefc0 |        demo        |   True  |
| fafc5f46aaca4018acf8d05370f2af57 | invisible_to_admin |   True  |
| 81548fee3bb84e7db93ad4c917291473 |      service       |   True  |
+----------------------------------+--------------------+---------+

You can similarly list all roles on the system with the following command:

devstack@devstack:~/devstack$ keystone role-list
+----------------------------------+---------------+
|                id                |      name     |
+----------------------------------+---------------+
| 4b303a1c20d64deaa6cb9c4dfacc33a9 |     Member    |
| 291d6a3008c642ba8439e42c95de22d0 | ResellerAdmin |
| 9fe2ff9ee4384b1894a90878d3e92bab |    _member_   |
| 714aaa9d30794920afe25af4791511a1 |     admin     |
| b2b1621ddc7741bd8ab90221907285e0 |  anotherrole  |
| b4183a4790e14ffdaa4995a24e08b7a2 |    service    |
+----------------------------------+---------------+
Creating a user

Now that the tenant has been created, you can create a new user, as shown in the next listing.

Listing 3.7. Creating a new user

When you run the command, you’ll get output like the following:

+----------+----------------------------------+
| Property |              Value               |
+----------+----------------------------------+
|  email   |        [email protected]        |
| enabled  |               True               |
|    id    | 21b27d5f7ba04817894d290b660f3f44 |
|   name   |             johndoe              |
| tenantId | 9932bc0607014caeab4c3d2b94d5a40c |
+----------+----------------------------------+

You’ve now created a new user. Take note of the user ID generated in this process because it will be needed in the next step. Figure 3.3 now includes the user you just created in the General tenant.

Figure 3.3. The created user

Listing users in a tenant

You can list all users in a tenant with the following command:

You now need to add a role to your new user in your new tenant. We’ll do that next.

Assigning a role

In order to assign a role to a user in a specific tenant, you need to define the tenant-id, user-id, and role-id.

You can use the General tenant, which was created at the beginning of this section, and the johndoe user, which was created in the previous step. You want to allow the user johndoe to be able to create instances in the General tenant, and to do this you must assign the Memberrole-id to johndoe in the General tenant.

To find the Memberrole-id, you need to query OpenStack Identity roles, as shown in the following listing.

Listing 3.8. Listing OpenStack roles

The list of roles will look something like this:

+----------------------------------+---------------+
|                id                |      name     |
+----------------------------------+---------------+
| 4b303a1c20d64deaa6cb9c4dfacc33a9 |     Member    |
| 291d6a3008c642ba8439e42c95de22d0 | ResellerAdmin |
| 9fe2ff9ee4384b1894a90878d3e92bab |    _member_   |
| 714aaa9d30794920afe25af4791511a1 |     admin     |
| b2b1621ddc7741bd8ab90221907285e0 |  anotherrole  |
| b4183a4790e14ffdaa4995a24e08b7a2 |    service    |
+----------------------------------+---------------+

You now have all of the information you need to assign your newly created user as a Member of your newly created tenant. Run the command shown in the following listing, substituting the appropriate IDs for your system.

Listing 3.9. Adding a role

This command will generate no output if it’s successful.

You’ve now assigned a role to a user in a tenant. Figure 3.4 illustrates the role you just assigned to the johndoe user in the General tenant.

Figure 3.4. The assigned role

At this point you can access the OpenStack Dashboard and log in using the johndoe user and openstack1 password. When you do, you’ll be taken to the General tenant/project management screen. If you try to create a new instance, you’ll notice that no networks exist. You’ll create a new tenant network next.

3.3.3. Tenant networks

OpenStack Networking (Neutron) is both loved and hated. To make sure you have more of the former experience than the latter, you should get your feet wet as soon as possible. In this section, we’ll run through some simple tenant network configurations.

First, though, you need to understand the basic differences between how traditional “flat” networks are configured for virtual and physical machines and how OpenStack Networking will be demonstrated. The term flat refers to the absence of a virtual routing tier as part of the virtual server platform; in traditional configurations, the VM has direct access to a network, as if you plugged a physical device into a physical network switch. Figure 3.5 illustrates a flat network connected to a physical router.

Figure 3.5. Traditional routed network

In this type of deployment, all network services (Dynamic Host Configuration Protocol (DHCP), load balancing, routing, and so on) beyond simply switching (Open System Interconnection (OSI) Model, Layer 2), must be provided outside of the virtual environment. For most systems administrators, this type of configuration will be very familiar, but this is not how we’ll demonstrate the power of OpenStack. You can make OpenStack Networking behave like a traditional flat network, but that approach will limit the benefits of the OpenStack framework.

In this section, you’ll build an OpenStack tenant network from scratch. Figure 3.6 illustrates the differences between a more traditional network and the type of network you’ll build.

Figure 3.6. OpenStack tenant network

Note that compared to the traditional flat network, the OpenStack tenant network includes an additional router that resides within the virtual environment. The addition of the virtual router in the tenant separates the internal network, shown as GENERAL_NETWORK, from the external network, shown as PUBLIC_NETWORK. VMs communicate with each other using the internal network, and the virtual router, shown as GENERAL_ROUTER, uses the external network for communication outside the tenant.

Set your environment variables

The configurations in the following subsections require that the OpenStack CLI environmental variables are set. To set the environment variables, execute the commands shown in listing 3.5.

Network (Neutron) console

Neutron commands can be entered through the Neutron console (which is like a command line for a network router or switch) or directly through the CLI. The console is very handy if you know what you’re doing, and it’s a natural choice for those familiar with the Neutron command set. But for the sake of clarity, I’ll demonstrate each action as a separate command using CLI commands. There are many things you can do with the Neutron CLI and console that you can’t do in the Dashboard.

The distinction between the Neutron console and Neutron CLI will be made clear in the following subsections. While the examples in this chapter are executed using the CLI, you’ll still need to know how to access the Neutron console. As you can see from the following listing, it’s a simple matter of using the neutron command.

Listing 3.10. Accessing the Neutron console

You can now access the Neutron interactive console. Any CLI configurations can be made in the interactive console or directly on the command line. That’s how you’ll create a new network.

Creating internal networks

The first step in creating a tenant-based network is to configure the internal network that will be used directly by instances in your tenant. The internal network works on ISO Layer 2 (L2), so for the network types this is the virtual equivalent of providing a network switch to be used exclusively for a particular tenant. The next listing shows the code used to create a new network for your tenant.

Listing 3.11. Creating an internal network

You’ll see output like the following when you create the network:

Created a new network:
+---------------------------+--------------------------------------+
| Field                     | Value                                |
+---------------------------+--------------------------------------+
| admin_state_up            | True                                 |
| id                        | 35a387fd-892f-47ad-a226-e8d0f2f0636b |
| name                      | GENERAL_NETWORK                      |
| provider:network_type     | local                                |
| provider:physical_network |                                      |
| provider:segmentation_id  |                                      |
| shared                    | False                                |
| status                    | ACTIVE                               |
| subnets                   |                                      |
| tenant_id                 | 9932bc0607014caeab4c3d2b94d5a40c     |
+---------------------------+--------------------------------------+

Figure 3.7 illustrates the GENERAL_NETWORK created for your tenant. The figure shows the network connected to a VM, which will be accurate once you create a new instance and attach the network you just created.

Figure 3.7. The newly created internal network

You’ve now created an internal network. The next step is to create an internal subnet for this network.

Creating internal subnets

The internal network you just created inside your tenant is completely isolated from other tenants. This is a strange concept to those who work with physical servers, or even to those who generally expose their virtual machines directly to physical networks. Most people are used to connecting their servers to the network, and network services are generally provided on a data center or enterprise level. We don’t typically think about networking and computation being controlled under the same framework.

As previously mentioned, OpenStack can be configured to work in a flat network configuration, but there are many advantages to letting OpenStack manage the network stack. In this section, you’ll create a subnet for your tenant; this can be thought of as an ISO Layer 3 (L3) provisioning of your tenant. You might be thinking to yourself, “What are you talking about? You can’t just provision L3 services on the network!” or perhaps, “I already have L3 services centralized in my data center. I don’t want OpenStack to do this for me!” By the end of this section, or perhaps by the end of the book, you’ll have your own answers to these questions. For the time being, just trust that the OpenStack experience includes benefits that are either enriched or not otherwise possible without the advanced network virtualization provided by OpenStack Networking.

What does it mean to create a new subnet for a specific network? Basically, you describe the network you want to work with, and then describe the address ranges you plan on using on that network. In this case, you’ll assign the new subnet to the GENERAL_NETWORK in the General tenant. You must also provide an address range for the subnet. In this context, the term subnet refers to both an OpenStack subnet, which is defined as part of the OpenStack network, and the IP subnet, which is defined as part of the OpenStack subnet creation process. You can use your own address range as long as it doesn’t exist in the tenant or a shared tenant. One of the interesting things about OpenStack is that you could use the same address range for every internal subnet in every tenant.

The following listing shows the command used to create a subnet.

Listing 3.12. Creating an internal subnet for a network

When you run this command, you’ll see output like the following:

Created a new subnet:
+------------------+-------------------------------------------------+
| Field            | Value                                           |
+------------------+-------------------------------------------------+
| allocation_pools | {"start":"172.24.220.2","end":"172.24.220.254"} |
| cidr             | 172.24.220.0/24                                 |
| dns_nameservers  |                                                 |
| enable_dhcp      | True                                            |
| gateway_ip       | 172.24.220.1                                    |
| host_routes      |                                                 |
| id               | 40d39310-44a3-45a8-90ce-b04b19eb5bb7            |
| ip_version       | 4                                               |
| name             |                                                 |
| network_id       | 35a387fd-892f-47ad-a226-e8d0f2f0636b            |
| tenant_id        | 9932bc0607014caeab4c3d2b94d5a40c                |
+------------------+-------------------------------------------------+
Classless Inter-Domain Routing (CIDR)

CIDR is a compact way to represent subnets.

For internal subnets, most people use a private class C address range, which was actually a class C of the original public classful ranges. In the case of a class C range, 8 bits are used for the subnet mask, so there are 2^8 = 256 addresses, but CIDR is expressed in the form <First address>/<Size of host bit field>, where 32 bits – 8 bits = 24 bits.

This might seem confusing, but luckily there are many online subnet calculators you can use if you aren’t up on your binary math.

You now have a new subnet assigned to your GENERAL_NETWORK. Figure 3.8 illustrates the assignment of the subnet to the GENERAL_NETWORK. This subnet is still isolated, but you’re one step closer to connecting your private network with a public network.

Figure 3.8. The newly created internal subnet

Next, you need to add a router to the subnet you just created. Make a note of your subnet ID, because it will be needed in the following sections.

Creating routers

Routers, put simply, route traffic between interfaces. In this case, you have an isolated network on your tenant and you want to be able to communicate with other tenant networks or networks outside of OpenStack. The following listing shows how to create a new tenant router.

Listing 3.13. Creating a router

When you create the router, you’ll see output like the following:

Created a new router:
+-----------------------+--------------------------------------+
| Field                 | Value                                |
+-----------------------+--------------------------------------+
| admin_state_up        | True                                 |
| external_gateway_info |                                      |
| id                    | df3b3d29-104f-46ca-8b8d-50658aea3f24 |
| name                  | GENERAL_ROUTER                       |
| status                | ACTIVE                               |
| tenant_id             | 9932bc0607014caeab4c3d2b94d5a40c     |
+-----------------------+--------------------------------------+

Figure 3.9 illustrates the router you created in your tenant.

Figure 3.9. The newly created internal router

You have a new router, but your tenant router and subnet aren’t yet connected. The following listing shows how to connect your subnet to your router.

Listing 3.14. Adding a router to the internal subnet

When the router is created, you’ll see output like the following (IDs are autogenerated, so yours will be unique):

Added interface 0a1a97e3-ad63-45bf-a55f-c7cd6c8cf4b4 to
router df3b3d29-104f-46ca-8b8d-50658aea3f24

Figure 3.10 illustrates the new GENERAL_ROUTER connected to your internal network, GENERAL_NETWORK.

Figure 3.10. The new router connected to the internal network

The process of adding a router to a subnet will actually create a port on the local virtual switch. You can think of a port as a device plugged into your virtual network port. In this case, the device is the GENERAL_ROUTER, the network is the GENERAL_NETWORK, and the subnet is 172.24.220.0/24.

DHCP agents

In past versions of OpenStack Networking, you had to manually add Dynamic Host Configuration Protocol (DHCP) agents to your network—the DHCP agent is used to provide your instances with an IP address. In current versions, the agent is automatically added for you the first time you create an instance, but in advanced configurations it’s still handy to know that agents (of all kinds) can be manipulated through Neutron.

The router will use the address specified during subnet creation (defaulting to the first available address), and unless you’ve already created an instance on this network, this will be the first port (device) on this network. If you create an instance, you should be able to communicate with the router address of 172.24.220.1, but you won’t yet be able to route packets to other networks. A router isn’t much good when it’s only connected to one network, so your next step is to connect the router to a public network.

Connecting a router to a public network

Before you can add a public interface, you need to find it. In previous steps, you created an internal network, internal subnet, and router, so you knew their ID values. If you’re working with the OpenStack deployment produced by DevStack in chapter 2, a public interface will already exist, and the following listing shows how you can list your external networks.

Listing 3.15. Listing external networks
neutron net-external-list

The preceding command will produce output like the following. If no external networks exist, jump ahead to the next subsection, “Creating an external network,” and create a new external network.

You’ve now listed all public networks; make a note of the network ID. In the example, there will be a single public network, but in a production environment, there could be many. You can select the appropriate network ID, based on the desired subnet in the listing. The network ID will be used along with the previously referenced router ID to add the existing public network to your router.

In listing 3.14 you used the command router-interface-add to connect your internal network to your router. You could use the same command to add the public network, but you’re going to designate this public network as the router gateway so you’ll use the router-gateway-set command. The router gateway will be used to translate (route) traffic from internal OpenStack networks to external networks.

Add the public network as the gateway for the router using the following command.

Listing 3.16. Add existing external network as router gateway

The preceding command will produce the following output:

Set gateway for router df3b3d29-104f-4
6ca-8b8d-50658aea3f24

Figure 3.11 illustrates the external PUBLIC_NETWORK you added to GENERAL_ROUTER as a network gateway.

Figure 3.11. An existing network assigned as a router gateway

Creating an external network

The configurations in the following subsections require that OpenStack CLI environmental variables are set as shown in listing 3.5.

In the subsection “Creating internal networks,” you created a network that was specifically for your tenant. In this subsection, you’ll create a public network that can be used by multiple tenants. This public network can be attached to a private router as a network gateway, as described in the previous section.

Using the DevStack network from chapter 2

The examples covered in this section will be executed on an OpenStack instance deployed by DevStack, as described in chapter 2. The deployment performed in that chapter provided the necessary network configuration to allow the addition of external networks. If you already have your OpenStack instance from chapter 2, you’re ready to complete the examples in this section.

In upcoming chapters, you’ll learn to manually make the network configurations that the previous DevStack deployment made for you.

In listing 3.15 you saw how to list networks that were designated as “external.” If you’re working from the DevStack deployment from chapter 2, an external network will already exist. This isn’t a problem, because you can have many external networks in OpenStack Networking.

Only the admin user can create external networks, and if not specified, the new external network will be created in the admin tenant. Create a new external network as shown in the following listing.

Listing 3.17. Creating an external network

When the network is created, you’ll see output like this:

Created a new network:
+---------------------------+--------------------------------------+
| Field                     | Value                                |
+---------------------------+--------------------------------------+
| admin_state_up            | True                                 |
| id                        | 8701c5f1-7852-4468-9dae-ff8a205296aa |
| name                      | new_public                           |
| provider:network_type     | local                                |
| provider:physical_network |                                      |
| provider:segmentation_id  |                                      |
| router:external           | True                                 |
| shared                    | False                                |
| status                    | ACTIVE                               |
| subnets                   |                                      |
| tenant_id                 | b1c52f4025d244f883dd47f61791d5cf     |
+---------------------------+--------------------------------------+
Confirming the network’s tenant

If you want to confirm that the network was created in the admin tenant, you can retrieve all tenant IDs as shown in the sidebar “Listing tenants and roles” in the subsection “Creating a tenant.”

You now have a network that’s designated as an external network, as shown in figure 3.12. This network will be in the admin tenant, and would not currently be visible in the General tenant.

Figure 3.12. Created external network

Before you can use this network as a gateway for your tenant router, you must first add a subnet to the external network you just created. You’ll do that next.

Creating an external subnet

You must now create an external subnet, shown next.

Listing 3.18. Creating an external subnet

When the subnet is created, you’ll see output like the following:

Created a new subnet:
+------------------+--------------------------------------------------+
| Field            | Value                                            |
+------------------+--------------------------------------------------+
| allocation_pools | {"start": "192.168.2.2", "end": "192.168.2.254"} |
| cidr             | 192.168.2.0/24                                   |
| dns_nameservers  |                                                  |
| enable_dhcp      | False                                            |
| gateway_ip       | 192.168.2.1                                      |
| host_routes      |                                                  |
| id               | 2cfa7201-d7f3-4e0c-983b-4c9f3fcf3caa             |
| ip_version       | 4                                                |
| name             |                                                  |
| network_id       | 8701c5f1-7852-4468-9dae-ff8a205296aa             |
| tenant_id        | b1c52f4025d244f883dd47f61791d5cf                 |
+------------------+--------------------------------------------------+

You now have the subnet 192.168.2.0/24 assigned to the external new_public network. The subnet and external network you just created, as shown in figure 3.13, can now be used by an OpenStack Networking router as a gateway.

Figure 3.13. The newly created external subnet

Figure 3.14 shows your current state, assuming you followed the examples in the previous subsections.

Figure 3.14. External gateways for tenants

Even if your network doesn’t resemble the figure, the main idea here is to illustrate that there are two possible external networks that could be assigned as gateways for the tenant router. new_public and PUBLIC_NETWORKS are separate virtual networks and have been assigned different subnets. Currently the PUBLIC_NETWORK is assigned as the gateway for your GENERAL_ROUTER. This means that any instance network traffic that’s not directly network-connected to your tenant (such as access to the internet or other tenants) will use this (gateway) network as its link to the outside world.

Listing routers

To list all the routers in the system, use the neutron router-list command, like this:

devstack@devstack:~/devstack$ neutron router-list
+--------+----------------+-------------------------------------------+
| id     | name           | external_gateway_info                     |
+--------+----------------+-------------------------------------------+
| df..24 | GENERAL_ROUTER | {"network_id": "4e..3d", "enable_snat": ..|
+--------+----------------+-------------------------------------------+
Remove floating addresses

Floating addresses are external IP addresses that have a one-to-one relationship with internal IP addresses assigned to instances. Floating IP addresses must be removed from instances and be deallocated before removing the router gateway. Floating addresses are directly associated with the external network, so any attempt to remove an external network with these associations still in place will result in failure.

Let’s assume you want to change the current gateway from PUBLIC_NETWORK to new_public. You must first remove the old gateway, and then add the new one. The following listing shows how to clear the existing gateway.

Listing 3.19. Clearing a router gateway

When the gateway is removed, you’ll get the following confirmation:

Removed gateway from router df3b3d29-104f-46ca-8b8d-50658aea3f24

Once the existing gateway has been removed, your tenant will be configured in the state shown in figure 3.15, where no external networks are connected to the tenant.

Figure 3.15. Removed router gateway

Your tenant network configuration is now back to where it was before you added the existing external network as a gateway in the previous section. You can now add the new_public external network as a gateway instead of PUBLIC_NETWORK. The following listing shows the commands required to complete the network configuration.

Listing 3.20. Adding a new external network as the router gateway

When the gateway is set, you’ll see output like the following:

Set gateway for router
df3b3d29-104f-46ca-8b8d-50658aea3f24

Figure 3.16 illustrates the assignment of the new network, new_public, as the gateway for the GENERAL_ROUTER in the General tenant. You can confirm this setting by running the neutron router-show <router-id> command, where <router-id> is the ID of the GENERAL_ROUTER. The command will return the external_gateway_info, which lists the currently assigned gateway network. Optionally, you can log in to the OpenStack Dashboard and look at your tenant network. The PUBLIC_NETWORK will no longer be there, and it will be replaced by the new_public network.

Figure 3.16. The new network assigned as a router gateway

You’ve now learned how to create tenants, users, and networks. The tenant model allows multiple users to operate under the same environment without affecting each other. As an OpenStack administrator, you wouldn’t want a single tenant to be able to use more resources than their share, so OpenStack implements a quota system for several of the major components, including Compute, Block Storage (Cinder), Object Storage (Swift), and Networking services. In this book, we’ll work with Block Storage, not Object Storage, so all references to Storage identify Cinder, not Swift.

We’ll look at quotas next.

3.4. Quotas

Quotas are applied on the tenant and tenant-user level to limit the amount of resources any one tenant can use. When you create a new tenant, a default quota is applied. Likewise, when you add users to your tenant, the tenant quota is applied to them. By default, all users have the same quota as the tenant quota, but you have the option of reducing a user’s quota in a tenant independently of the overall tenant quota.

Consider the case where you have an application administrator and database administrator sharing the same tenant for a project. You might want to assign half of the tenant resource to each user. On the other hand, if you increase a user’s quota in a tenant in excess of the tenant quota, the tenant quota will increase to match the new user value.

Quota management is an important operational component for an OpenStack administrator to understand. In the rest of this subsection, you’ll work through some CLI exercises to display and update quotas for tenants and tenant users via the Compute component. As with the majority of tenant configurations, you can also make these changes through the Dashboard or directly with an API.

3.4.1. Tenant quotas

In order to modify quota settings, you’ll need to know the tenant ID you want to work with and a user ID that’s currently in that tenant. The following example shows how you can list all tenants on the system and find the tenant ID:

devstack@devstack:~/devstack$ keystone tenant-list
+----------------------------------+--------------------+---------+
|                id                |        name        | enabled |
+----------------------------------+--------------------+---------+
| 9932bc0607014caeab4c3d2b94d5a40c |      General       |   True  |
| b1c52f4025d244f883dd47f61791d5cf |       admin        |   True  |
| 166c9cab0722409d8dbc2085acea70d4 |      alt_demo      |   True  |
| 324d7477c2514b60ac0ae417ce3cefc0 |        demo        |   True  |
| fafc5f46aaca4018acf8d05370f2af57 | invisible_to_admin |   True  |
| 81548fee3bb84e7db93ad4c917291473 |      service       |   True  |
+----------------------------------+--------------------+---------+

The following listing shows the command you can use to show the quota settings for a particular tenant.

Listing 3.21. Showing the Compute quota for a tenant

The quota information will be displayed as follows. (Consult the OpenStack operations manual for current quota items and unit values: http://docs.openstack.org/openstack-ops/content/projects_users.html.)

+-----------------------------+-------+
| Quota                       | Limit |
+-----------------------------+-------+
| instances                   | 10    |
| cores                       | 10    |
| ram                         | 51200 |
| floating_ips                | 10    |

| fixed_ips                   | -1    |
| metadata_items              | 128   |
| injected_files              | 5     |
| injected_file_content_bytes | 10240 |
| injected_file_path_bytes    | 255   |
| key_pairs                   | 100   |
| security_groups             | 10    |
| security_group_rules        | 20    |
+-----------------------------+-------+

You now know the quota for a particular tenant. To retrieve the default quota assigned to new tenants, simply omit the tenant ID from the command (nova quota-show).

Now suppose you’re an OpenStack administrator and you’ve created a tenant for a department in your company. This department has just been tasked with deploying a new application, which will require resources that exceed their existing tenant quota. In this case, you’d want to increase the quota for the entire tenant. The command for doing this is shown in the following listing.

Listing 3.22. Updating the Compute quota for tenant

A list of quota keys can be obtained by displaying the quota values, as shown previously in listing 3.21. In the following example, the cores<quota_key> is updated:

You’ve now successfully updated your tenant quota, and your users can now start assigning additional resources. If you rerun the command shown in listing 3.21, you’ll see that the quota has been updated.

Next we’ll look at how you can work with quotas on the tenant-user level. As you’ll soon see, the ability to apply quotas on the user level for a specific tenant can be very useful in managing resource utilization.

3.4.2. Tenant-user quotas

In some cases, there might be only a single user in a tenant. In these cases, you’d only need quota management on the tenant level. But what if there are multiple users in one tenant? OpenStack provides the ability to manage quotas for individual users on a tenant level. This means that an individual user can have separate quotas for each tenant of which they are a member.

Suppose that one of your users with a role on a specific tenant is only responsible for a single instance. Despite being responsible for only one instance, this user has on several occasions added additional instances to this tenant. The additional instances count against the overall tenant quota, so although the user in question should only have one instance, they might actually have several. To prevent this from happening, you can adjust the user’s quota for the tenant, and not the entire tenant quota. The following listing displays the existing quota for a particular user.

Listing 3.23. Showing the Compute quota for a tenant user

The following example shows the user ID related to johndoe, which you created in the subsection “Creating a user,” and the tenant ID related to the General tenant, which you created in the subsection “Creating a tenant.” Your actual IDs will differ from the examples listed here.

As you can see, the user quotas are the same size as the original tenant quota. By default, users added to a tenant can use all resources assigned to that tenant. For this tenant, you updated the cores value in a previous example, but that only updated the tenant quota, which, as you can see, doesn’t automatically increase a user’s tenant quota.

Assume that user johndoe is a problem user that you want to restrict to running a single instance in the General tenant. The next listing shows the command you can use to do this.

Listing 3.24. Updating the Compute quota for a tenant user

In the following example, the user johndoe is configured an instance-quota-metric limitation of 1 instance (instance - quota = 1) in the General tenant:

You have now restricted the user johndoe to running a single instance. You might further want to restrict the resources this user can utilize for their individual instance, such as limiting the number of cores to 4.

3.4.3. Additional quotas

There are additional quota systems for OpenStack Storage and Networking. The arguments for these quota systems are more or less the same, but the quota keys will be different.

You need to access each quota system through the CLI command assigned to the related system component. For OpenStack Compute the command is nova, for Storage it’s cinder, and for Networking it’s neutron. The following two listings illustrate accessing quota information for OpenStack Storage and Networking.

Listing 3.25. Showing Storage tenant quota

The following example demonstrates how to display the current Neutron quota for a specific tenant.

Listing 3.26. Showing Networking tenant quota

As you can see, the CLI commands for Storage and Networking quotas are very similar to the ones you used with Compute. You can also use the Dashboard for quota configuration.

3.5. Summary

  • The Dashboard is intended for end users.
  • The CLI and APIs are intended for administration, scripting, and repetitive tasks.
  • Anything you can do with the Dashboard, you can do with the CLI or an API.
  • The CLI can be configured to output the API-level calls that are used for a specific command.
  • Resources managed by OpenStack are reserved and provisioned based on tenants (projects).
  • The terms tenant and project are used interchangeably in OpenStack, but projects related to resources, users, and rights shouldn’t be confused with OpenStack projects like Compute, Network, and so on.
  • Roles determine the rights of a user in a specific tenant.
  • Users are assigned a home tenant, but they might hold many roles in other tenants.
  • Tenant networks and subnets are generally isolated private networks for a specific tenant.
  • Public networks and subnets are generally shared between tenants and are used for external (public) network access.
  • Layer 3 services (DHCP, metadata services, and the like) can be provisioned on networks.
  • Virtual routers are used to route network traffic from tenant (private) networks to public networks.
  • Quotas are assigned to both tenants and to specific users in a tenant.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset