Skip to content

Latest commit

 

History

History
172 lines (121 loc) · 5.66 KB

File metadata and controls

172 lines (121 loc) · 5.66 KB

Installation

The easiest way to get started with the keystone-ng is using the container image. It is also possible to use the compiled binary. It can be either compiled locally or downloaded from the project artifacts.

Using pre-compiled binaries

As of the moment of writing there were no releases. Due to that there are no pre-compiled binaries available yet. Every release of the project would include the pre-compiled binaries for a variety of platforms.

Compiling

In order to compile the keystone-ng it is necessary to have the rust compiler available. It may be installed from the system packages or using the rustup.rs

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Afterwards in the root of the project source tree following command may be executed to invoke the cargo

cargo build --release

It produces 2 binaries:

  • target/release/keystone (the api server)

  • target/release/keystone-db (the database management tool)

Currently keystone depends on the openssl (as a transitive dependency). Depending on the environment it may be a statically linked or dynamically. There are signals that that may be not necessary anymore once all dependencies transition to the use of rustls.

Using containers

It is possible to run Keystone-ng inside containers. A sample Dockerfile is present in the project source tree to build container image with the Keystone and the keystone-db utility. When no ready image is available it can be build like that:

docker build . -t keystone:rust

Since keystone itself communicates with the database and OpenPolicyAgent those must be provided separately. docker-compose.yaml demonstrates how this can be done.

docker run -v /etc/keystone/:/etc/keystone -p 8080:8080 ghcr.io/openstack-experimental/keystone:main -v /etc/keystone/keystone.conf

Database migrations

Rust Keystone is using different ORM and implements migration that co-exist together with alembic migrations of the python Keystone. It also ONLY manages the database schema additions and does NOT include the original database schema. Therefore it is necessary to apply both migrations.

keystone-db --config /etc/keystone/keystone.conf

It is important to also understand that the DB_URL may differ between python and rust due to the optional presence of the preferred database driver in the url. keystone-ng will ignore the the driver in the application itself, but the migration may require user to manually remove it since it is being processed by the ORM itself and not by the keystone-ng code.

OpenPolicyAgent

keystone-ng relies on the OPA for policy enforcement. Default policies are provided with the project and can be passed directly to the OPA process or compiled into the bundle.

opa run -s policies

NOTE: by default OPA process listens on the localhost only what lead to unavailability to expose it between containers. Please use -a 0.0.0.0:8181 to start listening on all interfaces.

Parallel installation with the python Keystone

Since Keystone-NG is only an addition and is not a drop-in replacement for the python Keystone it is necessary to deploy both versions together.

With the python Keystone no changes on the deployment strategy should be necessary. Whichever WSGI method is used to run the Keystone it stays this way and continues listening on the expected port.

The rust Keystone is deployed in parallel to it (usually on the same hardware) and by default it listens on the port 8080.

Next required step is to alter the http proxy server configuration. In the devstack this is usually the Apache webserver. Some operators may run nginx or haproxy in front of the default webserver with the Keystone. Depending on the preferred functionality (i.e. whether the token validation should be performed by the python or the rust implementation) redirects can be implemented. This way it is possible to decide for every single API call individually whether it should be served by python or rust implementation.

Nginx sample configuration


server {
    listen 443 ssl;
    server_name devstack.v6.rocks;

    ...

    # by default in devstack services are exposed with the url path style.
    location /identity/v4 {
      server http://localhost:8080;
    }
    proxy_pass http://<192.168.1.1>;
}

Apache sample configuration


<VirtualHost *:443>
    ServerName devstack..v6.rocks

    ...
    # Rust /v4 API
    ProxyPass "/identity/v4" http://localhost:8080/v4 retry=0
    # Python /v3 APIs are served by the uwsgi app
    ProxyPass "/identity/v3" "unix:/var/run/uwsgi/keystone-api.socket|uwsgi://uwsgi-uds-keystone-api/v3" retry=0
    # We want discovery URL to be served by Rust. The same way any /v3/ API can
    # be forwarded to rust version (where supported).
    ProxyPass "/identity" http://localhost:8080 retry=0
</VirtualHost>

Devstack integration

The devstack/ directory in the project source tree is a standard out-of-tree devstack plugin that automates the Apache reroute described above. Python Keystone still owns the base DB schema and initial admin bootstrap; the plugin builds/runs the rust binary alongside it, applies the additive DB migrations, and rewrites the Apache site devstack generated for Keystone so that /identity is proxied to the rust binary instead of python's uwsgi socket.

To use it, add to local.conf:

[[local|localrc]]
enable_plugin key-rs https://github.com/openstack-experimental/keystone
enable_service key-rs

See .github/workflows/devstack.yml for a working example that runs a minimal devstack (mysql, rabbitmq, keystone) in CI with the plugin enabled.