diff --git a/doc/source/install/compute-install-ubuntu.rst b/doc/source/install/compute-install-ubuntu.rst
deleted file mode 100644
index 98754648c..000000000
--- a/doc/source/install/compute-install-ubuntu.rst
+++ /dev/null
@@ -1,236 +0,0 @@
-Install and configure a compute node for Ubuntu
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-This section describes how to install and configure the Container service on a
-compute node for Ubuntu 16.04 (LTS).
-
-Prerequisites
--------------
-
-Before you install and configure Zun, you must have Docker and
-Kuryr-libnetwork installed properly in the compute node, and have Etcd
-installed properly in the controller node. Refer `Get Docker
-`_
-for Docker installation and `Kuryr libnetwork installation guide
-`_,
-`Etcd installation guide
-`_
-
-Install and configure components
---------------------------------
-
-#. Create zun user and necessary directories:
-
- * Create user:
-
- .. code-block:: console
-
- # groupadd --system zun
- # useradd --home-dir "/var/lib/zun" \
- --create-home \
- --system \
- --shell /bin/false \
- -g zun \
- zun
-
- * Create directories:
-
- .. code-block:: console
-
- # mkdir -p /etc/zun
- # chown zun:zun /etc/zun
-
-#. Clone and install zun:
-
- .. code-block:: console
-
- # apt-get install python-pip
- # cd /var/lib/zun
- # git clone https://git.openstack.org/openstack/zun.git
- # chown -R zun:zun zun
- # cd zun
- # pip install -r requirements.txt
- # python setup.py install
-
-#. Generate a sample configuration file:
-
- .. code-block:: console
-
- # su -s /bin/sh -c "oslo-config-generator \
- --config-file etc/zun/zun-config-generator.conf" zun
- # su -s /bin/sh -c "cp etc/zun/zun.conf.sample \
- /etc/zun/zun.conf" zun
- # su -s /bin/sh -c "cp etc/zun/rootwrap.conf \
- /etc/zun/rootwrap.conf" zun
- # su -s /bin/sh -c "mkdir -p /etc/zun/rootwrap.d" zun
- # su -s /bin/sh -c "cp etc/zun/rootwrap.d/* \
- /etc/zun/rootwrap.d/" zun
-
-#. Configure sudoers for ``zun`` users:
-
- .. code-block:: console
-
- # echo "zun ALL=(root) NOPASSWD: /usr/local/bin/zun-rootwrap \
- /etc/zun/rootwrap.conf *" | sudo tee /etc/sudoers.d/zun-rootwrap
-
-#. Edit the ``/etc/zun/zun.conf``:
-
- * In the ``[DEFAULT]`` section,
- configure ``RabbitMQ`` message queue access:
-
- .. code-block:: ini
-
- [DEFAULT]
- ...
- transport_url = rabbit://openstack:RABBIT_PASS@controller
-
- Replace ``RABBIT_PASS`` with the password you chose for the
- ``openstack`` account in ``RabbitMQ``.
-
- * In the ``[DEFAULT]`` section,
- configure the path that is used by Zun to store the states:
-
- .. code-block:: ini
-
- [DEFAULT]
- ...
- state_path = /var/lib/zun
-
- * In the ``[database]`` section, configure database access:
-
- .. code-block:: ini
-
- [database]
- ...
- connection = mysql+pymysql://zun:ZUN_DBPASS@controller/zun
-
- Replace ``ZUN_DBPASS`` with the password you chose for
- the zun database.
-
- * In the ``[keystone_auth]`` section, configure
- Identity service access:
-
- .. code-block:: ini
-
- [keystone_auth]
- memcached_servers = controller:11211
- www_authenticate_uri = http://controller:5000
- project_domain_name = default
- project_name = service
- user_domain_name = default
- password = ZUN_PASS
- username = zun
- auth_url = http://controller:5000
- auth_type = password
- auth_version = v3
- auth_protocol = http
- service_token_roles_required = True
- endpoint_type = internalURL
-
-
- * 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 = ZUN_PASS
- username = zun
- auth_url = http://controller:5000
- auth_type = password
-
- Replace ZUN_PASS with the password you chose for the zun user in the
- Identity service.
-
- * In the ``[oslo_concurrency]`` section, configure the ``lock_path``:
-
- .. code-block:: ini
-
- [oslo_concurrency]
- ...
- lock_path = /var/lib/zun/tmp
-
- .. note::
-
- Make sure that ``/etc/zun/zun.conf`` still have the correct
- permissions. You can set the permissions again with:
-
- # chown zun:zun /etc/zun/zun.conf
-
-#. Configure Docker and Kuryr:
-
- * Create the directory ``/etc/systemd/system/docker.service.d``
-
- .. code-block:: console
-
- # mkdir -p /etc/systemd/system/docker.service.d
-
- * Create the file ``/etc/systemd/system/docker.service.d/docker.conf``.
- Configure docker to listen to port 2375 as well as the default
- unix socket. Also, configure docker to use etcd3 as storage backend:
-
- .. code-block:: ini
-
- [Service]
- ExecStart=
- ExecStart=/usr/bin/dockerd --group zun -H tcp://compute1:2375 -H unix:///var/run/docker.sock --cluster-store etcd://controller:2379
-
- * Restart Docker:
-
- .. code-block:: console
-
- # systemctl daemon-reload
- # systemctl restart docker
-
- * Edit the Kuryr config file ``/etc/kuryr/kuryr.conf``.
- Set ``capability_scope`` to ``global`` and
- ``process_external_connectivity`` to ``False``:
-
- .. code-block:: ini
-
- [DEFAULT]
- ...
- capability_scope = global
- process_external_connectivity = False
-
- * Restart Kuryr-libnetwork:
-
- .. code-block:: console
-
- # systemctl restart kuryr-libnetwork
-
-Finalize installation
----------------------
-
-#. Create an upstart config, it could be named as
- ``/etc/systemd/system/zun-compute.service``:
-
- .. code-block:: bash
-
- [Unit]
- Description = OpenStack Container Service Compute Agent
-
- [Service]
- ExecStart = /usr/local/bin/zun-compute
- User = zun
-
- [Install]
- WantedBy = multi-user.target
-
-#. Enable and start zun-compute:
-
- .. code-block:: console
-
- # systemctl enable zun-compute
- # systemctl start zun-compute
-
-#. Verify that zun-compute services are running:
-
- .. code-block:: console
-
- # systemctl status zun-compute
diff --git a/doc/source/install/compute-install.rst b/doc/source/install/compute-install.rst
index d457df3a3..8d0d553f0 100644
--- a/doc/source/install/compute-install.rst
+++ b/doc/source/install/compute-install.rst
@@ -11,7 +11,266 @@ compute node.
additional compute nodes, prepare them in a similar fashion. Each additional
compute node requires a unique IP address.
-.. toctree::
- :glob:
+Prerequisites
+-------------
+
+Before you install and configure Zun, you must have Docker and
+Kuryr-libnetwork installed properly in the compute node, and have Etcd
+installed properly in the controller node. Refer `Get Docker
+`_
+for Docker installation and `Kuryr libnetwork installation guide
+`_,
+`Etcd installation guide
+`_
+
+Install and configure components
+--------------------------------
+
+#. Create zun user and necessary directories:
+
+ * Create user:
+
+ .. code-block:: console
+
+ # groupadd --system zun
+ # useradd --home-dir "/var/lib/zun" \
+ --create-home \
+ --system \
+ --shell /bin/false \
+ -g zun \
+ zun
+
+ * Create directories:
+
+ .. code-block:: console
+
+ # mkdir -p /etc/zun
+ # chown zun:zun /etc/zun
+
+#. Install the following dependencies:
+
+ For Ubuntu, run:
+
+ .. code-block:: console
+
+ # apt-get install python-pip git
+
+ For CentOS, run:
+
+ .. code-block:: console
+
+ # yum install python-pip git python-devel libffi-devel gcc openssl-devel
+
+ .. note::
+
+ ``python-pip`` package is not in CentOS base repositories,
+ may need to install EPEL repository in order to have
+ ``python-pip`` available.
+
+#. Clone and install zun:
+
+ .. code-block:: console
+
+ # cd /var/lib/zun
+ # git clone https://git.openstack.org/openstack/zun.git
+ # chown -R zun:zun zun
+ # cd zun
+ # pip install -r requirements.txt
+ # python setup.py install
+
+#. Generate a sample configuration file:
+
+ .. code-block:: console
+
+ # su -s /bin/sh -c "oslo-config-generator \
+ --config-file etc/zun/zun-config-generator.conf" zun
+ # su -s /bin/sh -c "cp etc/zun/zun.conf.sample \
+ /etc/zun/zun.conf" zun
+ # su -s /bin/sh -c "cp etc/zun/rootwrap.conf \
+ /etc/zun/rootwrap.conf" zun
+ # su -s /bin/sh -c "mkdir -p /etc/zun/rootwrap.d" zun
+ # su -s /bin/sh -c "cp etc/zun/rootwrap.d/* \
+ /etc/zun/rootwrap.d/" zun
+
+#. Configure sudoers for ``zun`` users:
+
+ .. note::
+
+ CentOS install binary files into ``/usr/bin/``,
+ replace ``/usr/local/bin/`` directory with the correct
+ in the following command.
+
+ .. code-block:: console
+
+ # echo "zun ALL=(root) NOPASSWD: /usr/local/bin/zun-rootwrap \
+ /etc/zun/rootwrap.conf *" | sudo tee /etc/sudoers.d/zun-rootwrap
+
+#. Edit the ``/etc/zun/zun.conf``:
+
+ * In the ``[DEFAULT]`` section,
+ configure ``RabbitMQ`` message queue access:
+
+ .. code-block:: ini
+
+ [DEFAULT]
+ ...
+ transport_url = rabbit://openstack:RABBIT_PASS@controller
+
+ Replace ``RABBIT_PASS`` with the password you chose for the
+ ``openstack`` account in ``RabbitMQ``.
+
+ * In the ``[DEFAULT]`` section,
+ configure the path that is used by Zun to store the states:
+
+ .. code-block:: ini
+
+ [DEFAULT]
+ ...
+ state_path = /var/lib/zun
+
+ * In the ``[database]`` section, configure database access:
+
+ .. code-block:: ini
+
+ [database]
+ ...
+ connection = mysql+pymysql://zun:ZUN_DBPASS@controller/zun
+
+ Replace ``ZUN_DBPASS`` with the password you chose for
+ the zun database.
+
+ * In the ``[keystone_auth]`` section, configure
+ Identity service access:
+
+ .. code-block:: ini
+
+ [keystone_auth]
+ memcached_servers = controller:11211
+ www_authenticate_uri = http://controller:5000
+ project_domain_name = default
+ project_name = service
+ user_domain_name = default
+ password = ZUN_PASS
+ username = zun
+ auth_url = http://controller:5000
+ auth_type = password
+ auth_version = v3
+ auth_protocol = http
+ service_token_roles_required = True
+ endpoint_type = internalURL
+
+
+ * 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 = ZUN_PASS
+ username = zun
+ auth_url = http://controller:5000
+ auth_type = password
+
+ Replace ZUN_PASS with the password you chose for the zun user in the
+ Identity service.
+
+ * In the ``[oslo_concurrency]`` section, configure the ``lock_path``:
+
+ .. code-block:: ini
+
+ [oslo_concurrency]
+ ...
+ lock_path = /var/lib/zun/tmp
+
+ .. note::
+
+ Make sure that ``/etc/zun/zun.conf`` still have the correct
+ permissions. You can set the permissions again with:
+
+ # chown zun:zun /etc/zun/zun.conf
+
+#. Configure Docker and Kuryr:
+
+ * Create the directory ``/etc/systemd/system/docker.service.d``
+
+ .. code-block:: console
+
+ # mkdir -p /etc/systemd/system/docker.service.d
+
+ * Create the file ``/etc/systemd/system/docker.service.d/docker.conf``.
+ Configure docker to listen to port 2375 as well as the default
+ unix socket. Also, configure docker to use etcd3 as storage backend:
+
+ .. code-block:: ini
+
+ [Service]
+ ExecStart=
+ ExecStart=/usr/bin/dockerd --group zun -H tcp://compute1:2375 -H unix:///var/run/docker.sock --cluster-store etcd://controller:2379
+
+ * Restart Docker:
+
+ .. code-block:: console
+
+ # systemctl daemon-reload
+ # systemctl restart docker
+
+ * Edit the Kuryr config file ``/etc/kuryr/kuryr.conf``.
+ Set ``capability_scope`` to ``global`` and
+ ``process_external_connectivity`` to ``False``:
+
+ .. code-block:: ini
+
+ [DEFAULT]
+ ...
+ capability_scope = global
+ process_external_connectivity = False
+
+ * Restart Kuryr-libnetwork:
+
+ .. code-block:: console
+
+ # systemctl restart kuryr-libnetwork
+
+Finalize installation
+---------------------
+
+#. Create an upstart config, it could be named as
+ ``/etc/systemd/system/zun-compute.service``:
+
+ .. note::
+
+ CentOS install binary files into ``/usr/bin/``,
+ replace ``/usr/local/bin/`` directory with the correct
+ in the following example file.
+
+ .. code-block:: bash
+
+ [Unit]
+ Description = OpenStack Container Service Compute Agent
+
+ [Service]
+ ExecStart = /usr/local/bin/zun-compute
+ User = zun
+
+ [Install]
+ WantedBy = multi-user.target
+
+#. Enable and start zun-compute:
+
+ .. code-block:: console
+
+ # systemctl enable zun-compute
+ # systemctl start zun-compute
+
+#. Verify that zun-compute services are running:
+
+ .. code-block:: console
+
+ # systemctl status zun-compute
- compute-install-ubuntu.rst
diff --git a/doc/source/install/controller-install-ubuntu.rst b/doc/source/install/controller-install-ubuntu.rst
deleted file mode 100644
index ccac3d514..000000000
--- a/doc/source/install/controller-install-ubuntu.rst
+++ /dev/null
@@ -1,378 +0,0 @@
-Install and configure controller node for Ubuntu
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-This section describes how to install and configure the Container
-service for Ubuntu 16.04 (LTS).
-
-Prerequisites
--------------
-
-Before you install and configure Zun, 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
-
- * Create the ``zun`` database:
-
- .. code-block:: console
-
- MariaDB [(none)] CREATE DATABASE zun;
-
- * Grant proper access to the ``zun`` database:
-
- .. code-block:: console
-
- MariaDB [(none)]> GRANT ALL PRIVILEGES ON zun.* TO 'zun'@'localhost' \
- IDENTIFIED BY 'ZUN_DBPASS';
- MariaDB [(none)]> GRANT ALL PRIVILEGES ON zun.* TO 'zun'@'%' \
- IDENTIFIED BY 'ZUN_DBPASS';
-
- Replace ``ZUN_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 ``zun`` user:
-
- .. code-block:: console
-
- $ openstack user create --domain default --password-prompt zun
- User Password:
- Repeat User Password:
- +-----------+----------------------------------+
- | Field | Value |
- +-----------+----------------------------------+
- | domain_id | e0353a670a9e496da891347c589539e9 |
- | enabled | True |
- | id | ca2e175b851943349be29a328cc5e360 |
- | name | zun |
- +-----------+----------------------------------+
-
- * Add the ``admin`` role to the ``zun`` user:
-
- .. code-block:: console
-
- $ openstack role add --project service --user zun admin
-
- .. note::
-
- This command provides no output.
-
- * Create the ``zun`` service entities:
-
- .. code-block:: console
-
- $ openstack service create --name zun \
- --description "Container Service" container
- +-------------+----------------------------------+
- | Field | Value |
- +-------------+----------------------------------+
- | description | Container Service |
- | enabled | True |
- | id | 727841c6f5df4773baa4e8a5ae7d72eb |
- | name | zun |
- | type | container |
- +-------------+----------------------------------+
-
-#. Create the Container service API endpoints:
-
- .. code-block:: console
-
- $ openstack endpoint create --region RegionOne \
- container public http://controller:9517/v1
- +--------------+-----------------------------------------+
- | Field | Value |
- +--------------+-----------------------------------------+
- | enabled | True |
- | id | 3f4dab34624e4be7b000265f25049609 |
- | interface | public |
- | region | RegionOne |
- | region_id | RegionOne |
- | service_id | 727841c6f5df4773baa4e8a5ae7d72eb |
- | service_name | zun |
- | service_type | container |
- | url | http://controller:9517/v1 |
- +--------------+-----------------------------------------+
-
- $ openstack endpoint create --region RegionOne \
- container internal http://controller:9517/v1
- +--------------+-----------------------------------------+
- | Field | Value |
- +--------------+-----------------------------------------+
- | enabled | True |
- | id | 9489f78e958e45cc85570fec7e836d98 |
- | interface | internal |
- | region | RegionOne |
- | region_id | RegionOne |
- | service_id | 727841c6f5df4773baa4e8a5ae7d72eb |
- | service_name | zun |
- | service_type | container |
- | url | http://controller:9517/v1 |
- +--------------+-----------------------------------------+
-
- $ openstack endpoint create --region RegionOne \
- container admin http://controller:9517/v1
- +--------------+-----------------------------------------+
- | Field | Value |
- +--------------+-----------------------------------------+
- | enabled | True |
- | id | 76091559514b40c6b7b38dde790efe99 |
- | interface | admin |
- | region | RegionOne |
- | region_id | RegionOne |
- | service_id | 727841c6f5df4773baa4e8a5ae7d72eb |
- | service_name | zun |
- | service_type | container |
- | url | http://controller:9517/v1 |
- +--------------+-----------------------------------------+
-
-Install and configure components
---------------------------------
-
-#. Create zun user and necessary directories:
-
- * Create user:
-
- .. code-block:: console
-
- # groupadd --system zun
- # useradd --home-dir "/var/lib/zun" \
- --create-home \
- --system \
- --shell /bin/false \
- -g zun \
- zun
-
- * Create directories:
-
- .. code-block:: console
-
- # mkdir -p /etc/zun
- # chown zun:zun /etc/zun
-
-#. Clone and install zun:
-
- .. code-block:: console
-
- # apt-get install python-pip
- # cd /var/lib/zun
- # git clone https://git.openstack.org/openstack/zun.git
- # chown -R zun:zun zun
- # cd zun
- # pip install -r requirements.txt
- # python setup.py install
-
-#. Generate a sample configuration file:
-
- .. code-block:: console
-
- # su -s /bin/sh -c "oslo-config-generator \
- --config-file etc/zun/zun-config-generator.conf" zun
- # su -s /bin/sh -c "cp etc/zun/zun.conf.sample \
- /etc/zun/zun.conf" zun
-
-#. Copy api-paste.ini:
-
- .. code-block:: console
-
- # su -s /bin/sh -c "cp etc/zun/api-paste.ini /etc/zun" zun
-
-#. Edit the ``/etc/zun/zun.conf``:
-
- * In the ``[DEFAULT]`` section,
- configure ``RabbitMQ`` message queue access:
-
- .. code-block:: ini
-
- [DEFAULT]
- ...
- transport_url = rabbit://openstack:RABBIT_PASS@controller
-
- Replace ``RABBIT_PASS`` with the password you chose for the
- ``openstack`` account in ``RabbitMQ``.
-
- * In the ``[api]`` section, configure the IP address that Zun API
- server is going to listen:
-
- .. code-block:: ini
-
- [api]
- ...
- host_ip = 10.0.0.11
- port = 9517
-
- Replace ``10.0.0.11`` 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://zun:ZUN_DBPASS@controller/zun
-
- Replace ``ZUN_DBPASS`` with the password you chose for
- the zun database.
-
- * In the ``[keystone_auth]`` section, configure
- Identity service access:
-
- .. code-block:: ini
-
- [keystone_auth]
- memcached_servers = controller:11211
- www_authenticate_uri = http://controller:5000
- project_domain_name = default
- project_name = service
- user_domain_name = default
- password = ZUN_PASS
- username = zun
- auth_url = http://controller:5000
- auth_type = password
- auth_version = v3
- auth_protocol = http
- service_token_roles_required = True
- endpoint_type = internalURL
-
-
- * 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 = ZUN_PASS
- username = zun
- auth_url = http://controller:5000
- auth_type = password
- auth_version = v3
- auth_protocol = http
- service_token_roles_required = True
- endpoint_type = internalURL
-
- Replace ZUN_PASS with the password you chose for the zun user in the
- Identity service.
-
- * In the ``[oslo_concurrency]`` section, configure the ``lock_path``:
-
- .. code-block:: ini
-
- [oslo_concurrency]
- ...
- lock_path = /var/lib/zun/tmp
-
- * In the ``[oslo_messaging_notifications]`` section, configure the
- ``driver``:
-
- .. code-block:: ini
-
- [oslo_messaging_notifications]
- ...
- driver = messaging
-
- * In the ``[websocket_proxy]`` section, configure the IP address that
- the websocket proxy is going to listen to:
-
- .. code-block:: ini
-
- [websocket_proxy]
- ...
- wsproxy_host = 10.0.0.11
- wsproxy_port = 6784
- base_url = ws://controller:6784/
-
- .. note::
-
- This ``base_url`` will be used by end users to access the console of
- their containers so make sure this URL is accessible from your
- intended users and the port ``6784`` is not blocked by firewall.
-
- Replace ``10.0.0.11`` with the management interface IP address
- of the controller node if different.
-
- .. note::
-
- Make sure that ``/etc/zun/zun.conf`` still have the correct
- permissions. You can set the permissions again with:
-
- # chown zun:zun /etc/zun/zun.conf
-
-#. Populate Zun database:
-
- .. code-block:: console
-
- # su -s /bin/sh -c "zun-db-manage upgrade" zun
-
-Finalize installation
----------------------
-
-#. Create an upstart config, it could be named as
- ``/etc/systemd/system/zun-api.service``:
-
- .. code-block:: bash
-
- [Unit]
- Description = OpenStack Container Service API
-
- [Service]
- ExecStart = /usr/local/bin/zun-api
- User = zun
-
- [Install]
- WantedBy = multi-user.target
-
-#. Create an upstart config, it could be named as
- ``/etc/systemd/system/zun-wsproxy.service``:
-
- .. code-block:: bash
-
- [Unit]
- Description = OpenStack Container Service Websocket Proxy
-
- [Service]
- ExecStart = /usr/local/bin/zun-wsproxy
- User = zun
-
- [Install]
- WantedBy = multi-user.target
-
-#. Enable and start zun-api and zun-wsproxy:
-
- .. code-block:: console
-
- # systemctl enable zun-api
- # systemctl enable zun-wsproxy
-
- .. code-block:: console
-
- # systemctl start zun-api
- # systemctl start zun-wsproxy
-
-#. Verify that zun-api and zun-wsproxy services are running:
-
- .. code-block:: console
-
- # systemctl status zun-api
- # systemctl status zun-wsproxy
diff --git a/doc/source/install/controller-install.rst b/doc/source/install/controller-install.rst
index 17c2d5083..9d1638ffb 100644
--- a/doc/source/install/controller-install.rst
+++ b/doc/source/install/controller-install.rst
@@ -2,8 +2,403 @@ Install and configure controller node
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This section describes how to install and configure the Container service
-on the controller node.
+on the controller node for Ubuntu 16.04 (LTS) and CentOS 7.
-.. toctree::
+Prerequisites
+-------------
+
+Before you install and configure Zun, 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
+
+ * Create the ``zun`` database:
+
+ .. code-block:: console
+
+ MariaDB [(none)] CREATE DATABASE zun;
+
+ * Grant proper access to the ``zun`` database:
+
+ .. code-block:: console
+
+ MariaDB [(none)]> GRANT ALL PRIVILEGES ON zun.* TO 'zun'@'localhost' \
+ IDENTIFIED BY 'ZUN_DBPASS';
+ MariaDB [(none)]> GRANT ALL PRIVILEGES ON zun.* TO 'zun'@'%' \
+ IDENTIFIED BY 'ZUN_DBPASS';
+
+ Replace ``ZUN_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 ``zun`` user:
+
+ .. code-block:: console
+
+ $ openstack user create --domain default --password-prompt zun
+ User Password:
+ Repeat User Password:
+ +-----------+----------------------------------+
+ | Field | Value |
+ +-----------+----------------------------------+
+ | domain_id | e0353a670a9e496da891347c589539e9 |
+ | enabled | True |
+ | id | ca2e175b851943349be29a328cc5e360 |
+ | name | zun |
+ +-----------+----------------------------------+
+
+ * Add the ``admin`` role to the ``zun`` user:
+
+ .. code-block:: console
+
+ $ openstack role add --project service --user zun admin
+
+ .. note::
+
+ This command provides no output.
+
+ * Create the ``zun`` service entities:
+
+ .. code-block:: console
+
+ $ openstack service create --name zun \
+ --description "Container Service" container
+ +-------------+----------------------------------+
+ | Field | Value |
+ +-------------+----------------------------------+
+ | description | Container Service |
+ | enabled | True |
+ | id | 727841c6f5df4773baa4e8a5ae7d72eb |
+ | name | zun |
+ | type | container |
+ +-------------+----------------------------------+
+
+#. Create the Container service API endpoints:
+
+ .. code-block:: console
+
+ $ openstack endpoint create --region RegionOne \
+ container public http://controller:9517/v1
+ +--------------+-----------------------------------------+
+ | Field | Value |
+ +--------------+-----------------------------------------+
+ | enabled | True |
+ | id | 3f4dab34624e4be7b000265f25049609 |
+ | interface | public |
+ | region | RegionOne |
+ | region_id | RegionOne |
+ | service_id | 727841c6f5df4773baa4e8a5ae7d72eb |
+ | service_name | zun |
+ | service_type | container |
+ | url | http://controller:9517/v1 |
+ +--------------+-----------------------------------------+
+
+ $ openstack endpoint create --region RegionOne \
+ container internal http://controller:9517/v1
+ +--------------+-----------------------------------------+
+ | Field | Value |
+ +--------------+-----------------------------------------+
+ | enabled | True |
+ | id | 9489f78e958e45cc85570fec7e836d98 |
+ | interface | internal |
+ | region | RegionOne |
+ | region_id | RegionOne |
+ | service_id | 727841c6f5df4773baa4e8a5ae7d72eb |
+ | service_name | zun |
+ | service_type | container |
+ | url | http://controller:9517/v1 |
+ +--------------+-----------------------------------------+
+
+ $ openstack endpoint create --region RegionOne \
+ container admin http://controller:9517/v1
+ +--------------+-----------------------------------------+
+ | Field | Value |
+ +--------------+-----------------------------------------+
+ | enabled | True |
+ | id | 76091559514b40c6b7b38dde790efe99 |
+ | interface | admin |
+ | region | RegionOne |
+ | region_id | RegionOne |
+ | service_id | 727841c6f5df4773baa4e8a5ae7d72eb |
+ | service_name | zun |
+ | service_type | container |
+ | url | http://controller:9517/v1 |
+ +--------------+-----------------------------------------+
+
+Install and configure components
+--------------------------------
+
+#. Create zun user and necessary directories:
+
+ * Create user:
+
+ .. code-block:: console
+
+ # groupadd --system zun
+ # useradd --home-dir "/var/lib/zun" \
+ --create-home \
+ --system \
+ --shell /bin/false \
+ -g zun \
+ zun
+
+ * Create directories:
+
+ .. code-block:: console
+
+ # mkdir -p /etc/zun
+ # chown zun:zun /etc/zun
+
+#. Install the following dependencies:
+
+ For Ubuntu, run:
+
+ .. code-block:: console
+
+ # apt-get install python-pip git
+
+ For CentOS, run:
+
+ .. code-block:: console
+
+ # yum install python-pip git python-devel libffi-devel gcc openssl-devel
+
+ .. note::
+
+ ``python-pip`` package is not in CentOS base repositories,
+ may need to install EPEL repository in order to have
+ ``python-pip`` available.
+
+#. Clone and install zun:
+
+ .. code-block:: console
+
+ # cd /var/lib/zun
+ # git clone https://git.openstack.org/openstack/zun.git
+ # chown -R zun:zun zun
+ # cd zun
+ # pip install -r requirements.txt
+ # python setup.py install
+
+#. Generate a sample configuration file:
+
+ .. code-block:: console
+
+ # su -s /bin/sh -c "oslo-config-generator \
+ --config-file etc/zun/zun-config-generator.conf" zun
+ # su -s /bin/sh -c "cp etc/zun/zun.conf.sample \
+ /etc/zun/zun.conf" zun
+
+#. Copy api-paste.ini:
+
+ .. code-block:: console
+
+ # su -s /bin/sh -c "cp etc/zun/api-paste.ini /etc/zun" zun
+
+#. Edit the ``/etc/zun/zun.conf``:
+
+ * In the ``[DEFAULT]`` section,
+ configure ``RabbitMQ`` message queue access:
+
+ .. code-block:: ini
+
+ [DEFAULT]
+ ...
+ transport_url = rabbit://openstack:RABBIT_PASS@controller
+
+ Replace ``RABBIT_PASS`` with the password you chose for the
+ ``openstack`` account in ``RabbitMQ``.
+
+ * In the ``[api]`` section, configure the IP address that Zun API
+ server is going to listen:
+
+ .. code-block:: ini
+
+ [api]
+ ...
+ host_ip = 10.0.0.11
+ port = 9517
+
+ Replace ``10.0.0.11`` 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://zun:ZUN_DBPASS@controller/zun
+
+ Replace ``ZUN_DBPASS`` with the password you chose for
+ the zun database.
+
+ * In the ``[keystone_auth]`` section, configure
+ Identity service access:
+
+ .. code-block:: ini
+
+ [keystone_auth]
+ memcached_servers = controller:11211
+ www_authenticate_uri = http://controller:5000
+ project_domain_name = default
+ project_name = service
+ user_domain_name = default
+ password = ZUN_PASS
+ username = zun
+ auth_url = http://controller:5000
+ auth_type = password
+ auth_version = v3
+ auth_protocol = http
+ service_token_roles_required = True
+ endpoint_type = internalURL
+
+
+ * 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 = ZUN_PASS
+ username = zun
+ auth_url = http://controller:5000
+ auth_type = password
+ auth_version = v3
+ auth_protocol = http
+ service_token_roles_required = True
+ endpoint_type = internalURL
+
+ Replace ZUN_PASS with the password you chose for the zun user in the
+ Identity service.
+
+ * In the ``[oslo_concurrency]`` section, configure the ``lock_path``:
+
+ .. code-block:: ini
+
+ [oslo_concurrency]
+ ...
+ lock_path = /var/lib/zun/tmp
+
+ * In the ``[oslo_messaging_notifications]`` section, configure the
+ ``driver``:
+
+ .. code-block:: ini
+
+ [oslo_messaging_notifications]
+ ...
+ driver = messaging
+
+ * In the ``[websocket_proxy]`` section, configure the IP address that
+ the websocket proxy is going to listen to:
+
+ .. code-block:: ini
+
+ [websocket_proxy]
+ ...
+ wsproxy_host = 10.0.0.11
+ wsproxy_port = 6784
+ base_url = ws://controller:6784/
+
+ .. note::
+
+ This ``base_url`` will be used by end users to access the console of
+ their containers so make sure this URL is accessible from your
+ intended users and the port ``6784`` is not blocked by firewall.
+
+ Replace ``10.0.0.11`` with the management interface IP address
+ of the controller node if different.
+
+ .. note::
+
+ Make sure that ``/etc/zun/zun.conf`` still have the correct
+ permissions. You can set the permissions again with:
+
+ # chown zun:zun /etc/zun/zun.conf
+
+#. Populate Zun database:
+
+ .. code-block:: console
+
+ # su -s /bin/sh -c "zun-db-manage upgrade" zun
+
+Finalize installation
+---------------------
+
+#. Create an upstart config, it could be named as
+ ``/etc/systemd/system/zun-api.service``:
+
+ .. note::
+
+ CentOS install binary files into ``/usr/bin/``,
+ replace ``/usr/local/bin/`` directory with the correct
+ in the following example files.
+
+ .. code-block:: bash
+
+ [Unit]
+ Description = OpenStack Container Service API
+
+ [Service]
+ ExecStart = /usr/local/bin/zun-api
+ User = zun
+
+ [Install]
+ WantedBy = multi-user.target
+
+#. Create an upstart config, it could be named as
+ ``/etc/systemd/system/zun-wsproxy.service``:
+
+ .. code-block:: bash
+
+ [Unit]
+ Description = OpenStack Container Service Websocket Proxy
+
+ [Service]
+ ExecStart = /usr/local/bin/zun-wsproxy
+ User = zun
+
+ [Install]
+ WantedBy = multi-user.target
+
+#. Enable and start zun-api and zun-wsproxy:
+
+ .. code-block:: console
+
+ # systemctl enable zun-api
+ # systemctl enable zun-wsproxy
+
+ .. code-block:: console
+
+ # systemctl start zun-api
+ # systemctl start zun-wsproxy
+
+#. Verify that zun-api and zun-wsproxy services are running:
+
+ .. code-block:: console
+
+ # systemctl status zun-api
+ # systemctl status zun-wsproxy
- controller-install-ubuntu.rst