Change-Id: I34ab86d5ec47063be1b8c4204af7aefca5978ac2 Story: 2001577 Task: 22098changes/76/575076/2
@ -0,0 +1,161 @@ | |||
.. | |||
Copyright 2018 Catalyst IT Ltd | |||
All Rights Reserved. | |||
not use this file except in compliance with the License. You may obtain | |||
a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
License for the specific language governing permissions and limitations | |||
under the License. | |||
Config Qinling with existing Kubernetes cluster | |||
=============================================== | |||
In most cases, it's not ideal to set up a new dedicated Kubernetes cluster for | |||
Qinling. The component which works with Kubernetes cluster in Qinling is the | |||
``qinling-engine``. Follow the steps below to configure Qinling to work with an | |||
existing Kubernetes cluster, and make Qinling access the Kubernetes API with | |||
authentication and authorization. | |||
Configurations | |||
~~~~~~~~~~~~~~ | |||
Below are the options that relate to accessing the Kubernetes API in Qinling's | |||
configuration file, all of them are under the ``kubernetes`` section. | |||
.. code-block:: ini | |||
[kubernetes] | |||
kube_host = http://127.0.0.1:8001 | |||
use_api_certificate = True | |||
ssl_ca_cert = /etc/qinling/pki/kubernetes/ca.crt | |||
cert_file = /etc/qinling/pki/kubernetes/qinling.crt | |||
key_file = /etc/qinling/pki/kubernetes/qinling.key | |||
For now, just update the ``kube_host`` to the URI which the Kubernetes API | |||
serves for HTTPS connections with authentication and authorization, for | |||
example, ``kube_host = https://kube-api.example.com:6443``. We will cover the | |||
other options in the following sections. | |||
Authentication and Authorization | |||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||
The access to the Kubernetes API is controlled by several modules, refer to | |||
`Controlling Access to the Kubernetes API <https://kubernetes.io/docs/admin/accessing-the-api/>`_ | |||
for more details. | |||
By default, Qinling engine is configured to access the Kubernetes API with | |||
a client certificate for authentication(``use_api_certificate`` is set to | |||
``True``), so make sure that the Kubernetes API server is running with the | |||
``--client-ca-file=SOMEFILE`` option for client certificate authentication to | |||
be enabled. The common name of the subject in the client certificate is used as | |||
the user name for the requests that Qinling engine makes to the Kubernetes API | |||
server. Refer to | |||
`Authentication in Kubernetes <https://kubernetes.io/docs/admin/authentication/>`_. | |||
If `RBAC Authorization <https://kubernetes.io/docs/admin/authorization/rbac/>`_ | |||
is enabled in the Kubernetes API, we will also have to grant access to resources | |||
in Kubernetes for the specific user that Qinling uses to make requests to the | |||
Kubernetes API. Using RBAC Authorization can ensure that Qinling access the | |||
Kubernetes API with only the permission that it needs. | |||
Generate Client Certificate for Qinling | |||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||
See `Managing Certificates <https://kubernetes.io/docs/concepts/cluster-administration/certificates/>`_ | |||
for how to generate a client cert. We use ``cfssl`` as the example here. | |||
#) Download and prepare the command line tools. | |||
.. code-block:: console | |||
curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /tmp/cfssl | |||
chmod +x /tmp/cfssl | |||
curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /tmp/cfssljson | |||
chmod +x /tmp/cfssljson | |||
#) Generate the client ceritificate for Qinling. Note that the common name | |||
of the subject is set to ``qinling`` in the example CSR located at | |||
``example/kubernetes/cfssl-client-csr.json``. | |||
.. code-block:: console | |||
mkdir certs; cd certs | |||
/tmp/cfssl gencert -ca=/path/to/kubernetes_ca_crt \ | |||
-ca-key=/path/to/kubernetes_ca_key \ | |||
-config=QINLING_SOURCE/example/kubernetes/cfssl-ca-config.json \ | |||
-profile=client \ | |||
QINLING_SOURCE/example/kubernetes/cfssl-client-csr.json | /tmp/cfssljson -bare client | |||
#) Copy the needed files to the locations. The command above generates two | |||
files named ``client-key.pem`` and ``client.pem``, the former is the key | |||
file of the client certificate, and the latter is the certificate file | |||
itself. | |||
.. code-block:: console | |||
mkdir -p /etc/qinling/pki/kubernetes | |||
cp client-key.pem /etc/qinling/pki/kubernetes/qinling.key | |||
cp client.pem /etc/qinling/pki/kubernetes/qinling.crt | |||
cp /path/to/kubernetes_ca_crt /etc/qinling/pki/kubernetes/ca.crt | |||
.. note:: | |||
Make sure both ``/etc/qinling/pki/kubernetes`` and ``/etc/qinling/pki`` | |||
belong to Qinling service user. You can set the permissions with | |||
``chown -R qinling:qinling /etc/qinling/pki`` | |||
Create Role and RoleBinding in Kubernetes | |||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||
If RBAC Authorization is enabled, we can limit the permissions that Qinling | |||
access the Kubernetes API. Before you procceed the steps in this section, | |||
make sure that the Kubernetes API server is running with the | |||
``--authorization-mode=RBAC`` option. | |||
Qinling provides a single file located at | |||
``example/kubernetes/k8s_qinling_role.yaml`` for users to | |||
create a ``Role`` and a ``ClusterRole`` with the permissions that Qinling | |||
needs, and bind the roles to the user named ``qinling``, which is from | |||
the common name of the subject in the client certificate. The role is defined | |||
within a namespace named ``qinling``, which is the default namespace that | |||
Qinling uses and the name is configurable. | |||
#) Grant access to the resources in the Kubernetes cluster for Qinling. The | |||
following command can be running on any host that kubectl is installed | |||
to interact with Kubernetes. | |||
.. code-block:: console | |||
curl -sSL https://raw.githubusercontent.com/openstack/qinling/master/example/kubernetes/k8s_qinling_role.yaml | kubectl create -f - | |||
The command above creates a ``ClusterRole`` named ``qinling`` with the | |||
cluster-wide permissions that Qinling needs and binds it to the ``qinling`` | |||
user. It also creates a ``Role`` named ``qinling`` within a newly created | |||
``qinling`` namespace and binds it to the specific user. So the access to | |||
resources within that namespace is also granted. | |||
Start Qinling Engine | |||
~~~~~~~~~~~~~~~~~~~~ | |||
Start the qinling-engine service after the steps above are done. And now | |||
Qinling is accessing the Kubernetes API with itself authenticated by a client | |||
certificate. And the requests that Qinling makes to the Kubernetes API | |||
are also authorized. | |||
Access the Kubernetes API Insecurely (For Testing ONLY) | |||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |||
Qinling can also connect to the Kubernetes API insecurely if the Kubernetes API | |||
server serves for insecure connections. However this is not recommended and | |||
should be used for testing purpose only. | |||
In the configuration file, under the ``kubernetes`` section, set ``kube_host`` | |||
to the URI which the Kubernetes API serves for insecure HTTP connections, for | |||
example, ``kube_host = http://localhost:8080``, and set ``use_api_certificate`` | |||
to ``False`` to disable Qinling using a client certificate to access the | |||
Kubernetes API. |
@ -0,0 +1,19 @@ | |||
.. | |||
Copyright 2018 Catalyst IT Ltd | |||
All Rights Reserved. | |||
not use this file except in compliance with the License. You may obtain | |||
a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
License for the specific language governing permissions and limitations | |||
under the License. | |||
Install Qinling in DevStack | |||
=========================== | |||
Refer to | |||
`Developer Guide <https://docs.openstack.org/qinling/latest/contributor/development-environment-devstack.html>`_ |
@ -0,0 +1,372 @@ | |||
.. | |||
Copyright 2018 Catalyst IT Ltd | |||
All Rights Reserved. | |||
not use this file except in compliance with the License. You may obtain | |||
a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
License for the specific language governing permissions and limitations | |||
under the License. | |||
Install Qinling on Ubuntu 16.04 | |||
=============================== | |||
This section describes how to install and configure the Function management | |||
service, code-named qinling on the controller node that runs Ubuntu 16.04 (LTS). | |||
Prerequisites | |||
------------- | |||
Before you install and configure Qinling, you must create a database, | |||
service credentials, and API endpoints. | |||
#. To create the database, complete these steps: | |||
* Use the database access client to connect to the database | |||
server as the ``root`` user: | |||
.. code-block:: console | |||
# mysql -u root -p | |||
* Create the ``qinling`` database: | |||
.. code-block:: console | |||
CREATE DATABASE qinling; | |||
* Grant proper access to the ``qinling`` database: | |||
.. code-block:: console | |||
GRANT ALL PRIVILEGES ON qinling.* TO 'qinling'@'localhost' \ | |||
IDENTIFIED BY 'QINLING_DBPASS'; | |||
GRANT ALL PRIVILEGES ON qinling.* TO 'qinling'@'%' \ | |||
IDENTIFIED BY 'QINLING_DBPASS'; | |||
Replace ``QINLING_DBPASS`` with a suitable password. | |||
* Exit the database access client. | |||
#. Source the ``admin`` credentials to gain access to | |||
admin-only CLI commands: | |||
.. code-block:: console | |||
$ . admin-openrc | |||
#. To create the service credentials, complete these steps: | |||
* Create the ``qinling`` user: | |||
.. code-block:: console | |||
$ openstack user create --domain default --password-prompt qinling | |||
User Password: | |||
Repeat User Password: | |||
+---------------------+----------------------------------+ | |||
| Field | Value | | |||
+---------------------+----------------------------------+ | |||
| domain_id | default | | |||
| enabled | True | | |||
| id | f77c97367087440da5f923bfcc66f68b | | |||
| name | qinling | | |||
| options | {} | | |||
| password_expires_at | None | | |||
+---------------------+----------------------------------+ | |||
* Add the ``admin`` role to the ``qinling`` user: | |||
.. code-block:: console | |||
$ openstack role add --project service --user qinling admin | |||
.. note:: | |||
This command provides no output. | |||
* Create the ``qinling`` service entities: | |||
.. code-block:: console | |||
$ openstack service create function-engine \ | |||
--name qinling --description="Function Service" | |||
+-------------+----------------------------------+ | |||
| Field | Value | | |||
+-------------+----------------------------------+ | |||
| description | Function Service | | |||
| enabled | True | | |||
| id | 8811fab348b548e3adef6ff0b149edfb | | |||
| name | qinling | | |||
| type | function-engine | | |||
+-------------+----------------------------------+ | |||
#. Create the Function engine service API endpoints: | |||
.. code-block:: console | |||
$ openstack endpoint create --region RegionOne \ | |||
function-engine public http://controller:7070 | |||
+--------------+----------------------------------+ | |||
| Field | Value | | |||
+--------------+----------------------------------+ | |||
| enabled | True | | |||
| id | 70937a84ed434256b11853b7e8a05d91 | | |||
| interface | public | | |||
| region | RegionOne | | |||
| region_id | RegionOne | | |||
| service_id | 8811fab348b548e3adef6ff0b149edfb | | |||
| service_name | qinling | | |||
| service_type | function-engine | | |||
| url | http://controller:7070 | | |||
+--------------+----------------------------------+ | |||
$ openstack endpoint create --region RegionOne \ | |||
function-engine internal http://controller:7070 | |||
+--------------+----------------------------------+ | |||
| Field | Value | | |||
+--------------+----------------------------------+ | |||
| enabled | True | | |||
| id | 7249f13c00cf4ca788da3df3fac9cfe2 | | |||
| interface | internal | | |||
| region | RegionOne | | |||
| region_id | RegionOne | | |||
| service_id | 8811fab348b548e3adef6ff0b149edfb | | |||
| service_name | qinling | | |||
| service_type | function-engine | | |||
| url | http://controller:7070 | | |||
+--------------+----------------------------------+ | |||
$ openstack endpoint create --region RegionOne \ | |||
function-engine admin http://controller:7070 | |||
+--------------+----------------------------------+ | |||
| Field | Value | | |||
+--------------+----------------------------------+ | |||
| enabled | True | | |||
| id | 7726669d928d47198388c599bfcd62a5 | | |||
| interface | admin | | |||
| region | RegionOne | | |||
| region_id | RegionOne | | |||
| service_id | 8811fab348b548e3adef6ff0b149edfb | | |||
| service_name | qinling | | |||
| service_type | function-engine | | |||
| url | http://controller:7070 | | |||
+--------------+----------------------------------+ | |||
Install and configure Qinling components | |||
---------------------------------------- | |||
#. Create qinling user and necessary directories: | |||
* Create user: | |||
.. code-block:: console | |||
# groupadd --system qinling | |||
# useradd --home-dir "/var/lib/qinling" \ | |||
--create-home \ | |||
--system \ | |||
--shell /bin/false \ | |||
-g qinling \ | |||
qinling | |||
* Create directories: | |||
.. code-block:: console | |||
# mkdir -p /etc/qinling /var/lib/qinling/package | |||
# chown -R qinling:qinling /etc/qinling /var/lib/qinling/package | |||
#. Clone and install qinling: | |||
.. code-block:: console | |||
# apt install -y python-pip | |||
# cd /var/lib/qinling | |||
# git clone https://git.openstack.org/openstack/qinling.git | |||
# chown -R qinling:qinling qinling | |||
# cd qinling | |||
# pip install -e . | |||
#. Generate a sample configuration file: | |||
.. code-block:: console | |||
# su -s /bin/sh -c "oslo-config-generator \ | |||
--config-file tools/config/config-generator.qinling.conf \ | |||
--output-file etc/qinling.conf.sample" qinling | |||
# su -s /bin/sh -c "cp etc/qinling.conf.sample \ | |||
/etc/qinling/qinling.conf" qinling | |||
# su -s /bin/sh -c "cp etc/policy.json.sample \ | |||
/etc/qinling/policy.json" qinling | |||
#. Edit the ``/etc/qinling/qinling.conf``: | |||
* In the ``[DEFAULT]`` section, | |||
configure ``RabbitMQ`` message queue access: | |||
.. code-block:: ini | |||
[DEFAULT] | |||
... | |||
transport_url = rabbit://openstack:RABBIT_PASS@controller:5672/ | |||
Replace ``RABBIT_PASS`` with the password you chose for the | |||
``openstack`` account in ``RabbitMQ``. | |||
* In the ``[api]`` section, configure the IP address that Qinling API | |||
server is going to listen: | |||
.. code-block:: ini | |||
[api] | |||
... | |||
host = 10.0.0.9 | |||
port = 7070 | |||
Replace ``10.0.0.9`` with the management interface IP address | |||
of the controller node if different. | |||
* In the ``[database]`` section, configure database access: | |||
.. code-block:: ini | |||
[database] | |||
... | |||
connection = mysql+pymysql://qinling:QINLING_DBPASS@controller/qinling?charset=utf8 | |||
Replace ``QINLING_DBPASS`` with the password you chose for | |||
the qinling database. | |||
* In the ``[storage]`` section, configure function package storage path: | |||
.. code-block:: ini | |||
[storage] | |||
... | |||
file_system_dir = /var/lib/qinling/package | |||
* In the ``[oslo_policy]`` section, configure the policy file path for | |||
Qinling service: | |||
.. code-block:: ini | |||
[oslo_policy] | |||
... | |||
policy_file = /etc/qinling/policy.json | |||
* In the ``[keystone_authtoken]`` section, configure | |||
Identity service access: | |||
.. code-block:: ini | |||
[keystone_authtoken] | |||
... | |||
memcached_servers = controller:11211 | |||
www_authenticate_uri = http://controller:5000 | |||
project_domain_name = default | |||
project_name = service | |||
user_domain_name = default | |||
password = QINLING_PASS | |||
username = qinling | |||
auth_url = http://controller:5000 | |||
auth_type = password | |||
auth_version = v3 | |||
Replace QINLING_PASS with the password you chose for the qinling user in | |||
the Identity service. | |||
.. note:: | |||
Make sure that ``/etc/qinling/qinling.conf`` still have the correct | |||
permissions. You can set the permissions again with: | |||
# chown qinling:qinling /etc/qinling/qinling.conf | |||
#. Populate Qinling database: | |||
.. code-block:: console | |||
# su -s /bin/sh -c "qinling-db-manage --config-file \ | |||
/etc/qinling/qinling.conf upgrade head" qinling | |||
Install and configure Kubernetes and etcd | |||
----------------------------------------- | |||
Installing Kubernetes in not in the scope of this guide, you can refer to | |||
`Kubernetes installation guide <https://kubernetes.io/docs/setup/>`_ for more | |||
information. | |||
For etcd installation, you can refer to | |||
`OpenStack Installation Guide <https://docs.openstack.org/install-guide/environment-etcd.html>`_. | |||
#. Config kubernetes in Qinling. Refer to | |||
`Config Qinling using existing Kubernetes cluster <https://docs.openstack.org/qinling/latest/admin/install/config_kubernetes.html>`_. | |||
#. Config etcd. In the ``[etcd]`` section of ``/etc/qinling/qinling.conf``, | |||
configure the IP address and port that etcd service is listening on. | |||
.. code-block:: ini | |||
[etcd] | |||
... | |||
host = 10.0.0.9 | |||
port = 2379 | |||
Finalize installation | |||
--------------------- | |||
#. Create an upstart config for qinling-api, it could be named as | |||
``/etc/systemd/system/qinling-api.service``: | |||
.. code-block:: bash | |||
cat <<EOF > /etc/systemd/system/qinling-api.service | |||
[Unit] | |||
Description = OpenStack Function Management Service API | |||
[Service] | |||
ExecStart = /usr/local/bin/qinling-api | |||
User = qinling | |||
[Install] | |||
WantedBy = multi-user.target | |||
EOF | |||
#. Create an upstart config for qinling-engine, it could be named as | |||
``/etc/systemd/system/qinling-engine.service``: | |||
.. code-block:: bash | |||
cat <<EOF > /etc/systemd/system/qinling-engine.service | |||
[Unit] | |||
Description = OpenStack Function Management Service Engine | |||
[Service] | |||
ExecStart = /usr/local/bin/qinling-engine | |||
User = qinling | |||
[Install] | |||
WantedBy = multi-user.target | |||
EOF | |||
#. Enable and start qinling-api and qinling-engine: | |||
.. code-block:: console | |||
# systemctl enable qinling-api | |||
# systemctl enable qinling-engine | |||
.. code-block:: console | |||
# systemctl start qinling-api | |||
# systemctl start qinling-engine | |||
#. Verify that qinling-api and qinling-engine services are running: | |||
.. code-block:: console | |||
# systemctl status qinling-api | |||
# systemctl status qinling-engine |
@ -0,0 +1,51 @@ | |||
.. | |||
Copyright 2018 Catalyst IT Ltd | |||
All Rights Reserved. | |||
not use this file except in compliance with the License. You may obtain | |||
a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |||
License for the specific language governing permissions and limitations | |||
under the License. | |||
Service Overview | |||
================ | |||
The Qinling project consists of the following components: | |||
qinling-api | |||
A WSGI app that authenticates and routes requests to qinling-engine after | |||
a preliminary handling for the request. | |||
qinling-engine | |||
A standalone service whose purpose is to process operations such as runtime | |||
maintenance, function execution operations, function autoscaling, etc. | |||
kubernetes | |||
Qinling uses kubernetes as the default backend orchestrator, in order to | |||
manage and maintain the underlying pods to run the functions. | |||
database | |||
Qinling needs to interact with the database(usually MySQL) to store and | |||
retrieve resource information. | |||
etcd | |||
etcd is a distributed key-value store that provides fast read/write | |||
operations for some specific internal resources in Qinling such as the | |||
mapping from functions to the function services, mapping from function to the | |||
workers, etc. In addition, etcd provides the locking mechanism in Qinling. | |||
Messaging queue | |||
Routes information between the Qinling processes. | |||
Additionally, users can interact with Qinling service either by sending HTTP | |||
request or using openstack CLI provided by | |||
`python-qinlingclient <https://docs.openstack.org/python-qinlingclient/latest/>`_ | |||
.. note:: | |||
The horizon plugin for Qinling is still not available now. |