Understanding Keystone Endpoints
Jun 08, 2023 • 6 Minute Read
(OpenStacks Identity Service)
OpenStack Identity (Keystone) provides a central directory of users mapped to the OpenStack services they can access. It acts as a common authentication system across the cloud operating system and can integrate with existing backend directory services like LDAP. It supports multiple forms of authentication including standard username and password credentials, token-based systems and AWS-style (i.e. Amazon Web Services) logins. Additionally, the catalog provides a queryable list of all of the services deployed in an OpenStack cloud in a single registry. Users and third-party tools can programmatically determine which resources they can access. https://en.wikipedia.org/wiki/OpenStack#Identity_Service_.28Keystone.29In OpenStack before we can start utilizing the the vast ecosystem of services and applications that are available ie: (Nova, Swift, Neutron, Glance, etc), we first have to authorize our users. There are some very important terms that we need to understand when working with OpenStack Identity (keystone).I would like to take a moment to address one of the biggest confusions when setting up endpoints in keystone today. First let's start out by defining what an endpoint even is. An endpoint in keystone is just a URL that can be used to access a service within OpenStack. An endpoint is just like a point of contact for YOU (the user) to use an OpenStack service. The adminurl (we will show these further down) is for the admin users, the internalurl are what the other services use to talk to each other. And the publicurl is what everyone else accessing the service endpoint uses.Lets understand the following terms:A service is any OpenStack service such as Nova, Swift, and even keystone itself.A role is the level of authorization that a user has.Tokens are an alphanumeric string that allows us access to services depending on it's access level or the (see above role).Users are just people that are going to be accessing the service. This can also traditionally be used as a (service account) that the service itself uses.And finally tenants are really just a group of users.(part 1)1) First we need to actually create two tenants that we are going to simply name admin (this will be the Administrators tenant remember tenants are just groups of users) and the other tenant will be called service (this is the Service Group ie: tenant for our services.. in our example here we use the nova service).
$ keystone tenant-create --name=admin --description="Admin Tenant"$ keystone tenant-create --name=service --description="Service Tenant"2) Now we need to create the administrative user called admin using the password linuxacademy123
# keystone user-create --name=admin --pass=linuxacademy123 --email=admin@linuxacedmy1233) We now need to create a new role for our administrative task in OpenStack called admin. This default policy for the admin policy allows access to most services.
# keystone role-create --name=admin4) We have to add roles to users. Users always log in with a tenant, and roles are assigned to users WITHIN these tenants. Here we are going to add the admin role to the admin user when logging in with the admin tenant.
# keystone user-role-add --user=admin --tenant=admin --role=admin(part 2)In the following example we are going to create a Nova user and then link it to our tenant called service, then we link it to our admin role. We are then going to create the actual compute (nova) service. Finally we are then going to create our endpoint using the returned ID value of our newly created nova service.5) Create a user called nova. We are going to define our password as linuxacademy123.
$ keystone user-create --name nova --pass linuxacademy123+----------+----------------------------------+| Property | Value |+----------+----------------------------------+| email | || enabled | True || id | f1a06c73141a441da5df57c46c3b69c5 || name | nova || username | nova |+----------+----------------------------------+6) Now we are going to link this new user nova to the service tenant that we created in part1 as well as the role that we also named admin.
$ keystone user-role-add --user nova --tenant service --role admin7) It is now time to create our actual service that will be called nova in which its type of service is the NOVA compute service.
$ keystone service-create --name nova --type compute --description "OpenStack Compute"+-------------+----------------------------------+| Property | Value |+-------------+----------------------------------+| description | OpenStack Compute || enabled | True || id | 5844875f25c54e52a0d5c7f6076bff86 || name | nova || type | compute |+-------------+----------------------------------+8) We have now reached the actual portion of our setup in which we create the actual endpoint for the nova compute service.But first I think it's very important to mention a common mistake I see when users are following along on OpenStacks documentation when creating these endpoints. Most of the documentation uses the following for example:
$ keystone endpoint-create --service-id $(keystone service-list | awk '/ compute / {print $2}') --publicurl https://controller:8774/v2/%(tenant_id)s --internalurl https://controller:8774/v2/%(tenant_id)s --adminurl https://controller:8774/v2/%(tenant_id)s --region regionOne+-------------+-----------------------------------------+| Property | Value |+-------------+-----------------------------------------+| adminurl | https://controller:8774/v2/%(tenant_id)s || id | c397438bd82c41198ec1a9d85cb7cc74 || internalurl | https://controller:8774/v2/%(tenant_id)s || publicurl | https://controller:8774/v2/%(tenant_id)s || region | regionOne || service_id | 6c7854f52ce84db795557ebc0373f6b9 |+-------------+-----------------------------------------+Let's go over this line by line. In the first line we are using the endpoint-create command to start creating the endpoint. In line two we are using the --service-id to return the service id of the nova service that we are creating this actual URL authentication endpoint with. However, almost all of the newer versions of OpenStack Documentation is using the following search string in which we see as well on line two:$(keystone service-list | awk '/ compute / {print $2}')In a nutshell the above string is opening up a background sub-shell within the $(). Within the () we run the actual search string with a shell scripting language known as awk. So first it's calling the keystone command keystone service-list which list all of the available services in rows and columns that has the name, the actual service id, description etc. We then pipe that out | using a search string of / compute / because we want to work with that line to pull what the service id is FOR nova compute. {print $2} is pulling from that line the second column (2) which happens to be the id of the service compute service. The first line would be the | character. For example if we did the following command:keystone service-listThen we would see:+----------------------------------+------------+----------------+------------------------------+| id | name | type | description |+----------------------------------+------------+----------------+------------------------------+| 9b1737a7632241cd8b38ba6f141bbffe | ceilometer | metering | Telemetry || 5844875f25c54e52a0d5c7f6076bff86 | nova | compute | OpenStack Compute |Notice the first return on the nova compute line is | the second return which again is the service id using {print $2} is the service ID itself: 5844875f25c54e52a0d5c7f6076bff86While this is a great way to quickly breeze through when setting up all the services in order and following a setup guide this sometimes causes issues if for example you setup services in a different order. Therefore I recommend that when setting up your endpoints with keystone endpoint-create that you manually use the service id rather that search for it by doing the following:
$ keystone endpoint-create --service-id=5844875f25c54e52a0d5c7f6076bff86 --publicurl=https://controller:8774/v2/%(tenant_id)s --internalurl=https://controller:8774/v2/%(tenant_id)s --adminurl=https://controller:8774/v2/%(tenant_id)s --region=regionOneLastly I want to mention the --region flag which specifies your region name. The other thing that trips up endpoints not working is when you fail to use this flag it will sometimes create a region name for you that doesn't exit or the case of that region name might look different as well. For example regionOne, RegionOne, and regionone are all different regions because the case of the name matters.I hope this post helps some of you that come across this issue that I see quite often. New to OpenStack? Check out LinuxAcademy.com OpenStack courses at https://linuxacademy.com/openstack and check back often for more courses in the future!