From 22067e6126a3ec04e3ec209b8d9c2ddf14985ad8 Mon Sep 17 00:00:00 2001 From: Leoswaldo Macias Date: Thu, 31 Mar 2016 11:23:50 -0600 Subject: [PATCH 01/25] Delete old openstack docs Signed-off-by: Leoswaldo Macias --- source/openstack_block_storage.rst | 478 ----------- .../openstack_bundle_and_service_summary.rst | 2 +- source/openstack_compute.rst | 527 ------------ source/openstack_dashboard.rst | 33 - source/openstack_identity-openrc.rst | 75 -- source/openstack_identity.rst | 416 ---------- source/openstack_image.rst | 277 ------- source/openstack_installing_bundles.rst | 26 - source/openstack_networking.rst | 672 --------------- source/openstack_object_storage.rst | 772 ------------------ source/openstack_orchestration.rst | 393 --------- source/openstack_supporting-database.rst | 52 -- source/openstack_supporting-messaging.rst | 47 -- source/openstack_sys_req_and_pw_summary.rst | 68 -- source/openstack_telemetry.rst | 260 ------ 15 files changed, 1 insertion(+), 4097 deletions(-) delete mode 100644 source/openstack_block_storage.rst delete mode 100644 source/openstack_compute.rst delete mode 100644 source/openstack_dashboard.rst delete mode 100644 source/openstack_identity-openrc.rst delete mode 100644 source/openstack_identity.rst delete mode 100644 source/openstack_image.rst delete mode 100644 source/openstack_installing_bundles.rst delete mode 100644 source/openstack_networking.rst delete mode 100644 source/openstack_object_storage.rst delete mode 100644 source/openstack_orchestration.rst delete mode 100644 source/openstack_supporting-database.rst delete mode 100644 source/openstack_supporting-messaging.rst delete mode 100644 source/openstack_sys_req_and_pw_summary.rst delete mode 100644 source/openstack_telemetry.rst diff --git a/source/openstack_block_storage.rst b/source/openstack_block_storage.rst deleted file mode 100644 index 296b6550..00000000 --- a/source/openstack_block_storage.rst +++ /dev/null @@ -1,478 +0,0 @@ -.. _openstack_block_storage: - -Block Storage -######################## - -The OpenStack* Block Storage service (cinder) adds persistent storage to -a virtual machine. Block Storage provides an infrastructure for managing -volumes, and interacts with OpenStack Compute to provide volumes for -instances. The service also enables management of volume snapshots and -volume types. - -Install and configure controller node -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This section describes how to install and configure the Block -Storage service, code-named cinder, on the controller node. This -service requires at least one additional storage node that provides -volumes to instances. - -Prerequisites: --------------- - -Before you install and configure the Block Storage service, 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:: - - $ mysql -u root -p - - * Create the ``cinder`` database:: - - CREATE DATABASE cinder; - - * Grant proper access to the ``cinder`` database:: - - GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'localhost' \ - IDENTIFIED BY 'CINDER_DBPASS'; - GRANT ALL PRIVILEGES ON cinder.* TO 'cinder'@'%' \ - IDENTIFIED BY 'CINDER_DBPASS'; - - Replace ``CINDER_DBPASS`` with a suitable password. - - * Exit the database access client. - -#. Source the ``admin`` credentials to gain access to admin-only - CLI commands:: - - $ source admin-openrc.sh - -#. To create the service credentials, complete these steps: - - * Create a ``cinder`` user:: - - $ openstack user create --domain default --password-prompt cinder - User Password: - Repeat User Password: - +-----------+----------------------------------+ - | Field | Value | - +-----------+----------------------------------+ - | domain_id | default | - | enabled | True | - | id | bb279f8ffc444637af38811a5e1f0562 | - | name | cinder | - +-----------+----------------------------------+ - - * Add the ``admin`` role to the ``cinder`` user:: - - $ openstack role add --project service --user cinder admin - - * Create the ``cinder`` and ``cinderv2`` service entities:: - - $ openstack service create --name cinder \ - --description "OpenStack Block Storage" volume - +-------------+----------------------------------+ - | Field | Value | - +-------------+----------------------------------+ - | description | OpenStack Block Storage | - | enabled | True | - | id | ab3bbbef780845a1a283490d281e7fda | - | name | cinder | - | type | volume | - +-------------+----------------------------------+ - - $ openstack service create --name cinderv2 \ - --description "OpenStack Block Storage" volumev2 - +-------------+----------------------------------+ - | Field | Value | - +-------------+----------------------------------+ - | description | OpenStack Block Storage | - | enabled | True | - | id | eb9fd245bdbc414695952e93f29fe3ac | - | name | cinderv2 | - | type | volumev2 | - +-------------+----------------------------------+ - - .. note:: - - The Block Storage services requires two service entities. - -#. Create the Block Storage service API endpoints:: - - $ openstack endpoint create --region RegionOne \ - volume public http://controller:8776/v1/%\(tenant_id\)s - +--------------+-----------------------------------------+ - | Field | Value | - +--------------+-----------------------------------------+ - | enabled | True | - | id | 03fa2c90153546c295bf30ca86b1344b | - | interface | public | - | region | RegionOne | - | region_id | RegionOne | - | service_id | ab3bbbef780845a1a283490d281e7fda | - | service_name | cinder | - | service_type | volume | - | url | http://controller:8776/v1/%(tenant_id)s | - +--------------+-----------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - volume internal http://controller:8776/v1/%\(tenant_id\)s - +--------------+-----------------------------------------+ - | Field | Value | - +--------------+-----------------------------------------+ - | enabled | True | - | id | 94f684395d1b41068c70e4ecb11364b2 | - | interface | internal | - | region | RegionOne | - | region_id | RegionOne | - | service_id | ab3bbbef780845a1a283490d281e7fda | - | service_name | cinder | - | service_type | volume | - | url | http://controller:8776/v1/%(tenant_id)s | - +--------------+-----------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - volume admin http://controller:8776/v1/%\(tenant_id\)s - +--------------+-----------------------------------------+ - | Field | Value | - +--------------+-----------------------------------------+ - | enabled | True | - | id | 4511c28a0f9840c78bacb25f10f62c98 | - | interface | admin | - | region | RegionOne | - | region_id | RegionOne | - | service_id | ab3bbbef780845a1a283490d281e7fda | - | service_name | cinder | - | service_type | volume | - | url | http://controller:8776/v1/%(tenant_id)s | - +--------------+-----------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - volumev2 public http://controller:8776/v2/%\(tenant_id\)s - +--------------+-----------------------------------------+ - | Field | Value | - +--------------+-----------------------------------------+ - | enabled | True | - | id | 513e73819e14460fb904163f41ef3759 | - | interface | public | - | region | RegionOne | - | region_id | RegionOne | - | service_id | eb9fd245bdbc414695952e93f29fe3ac | - | service_name | cinderv2 | - | service_type | volumev2 | - | url | http://controller:8776/v2/%(tenant_id)s | - +--------------+-----------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - volumev2 internal http://controller:8776/v2/%\(tenant_id\)s - +--------------+-----------------------------------------+ - | Field | Value | - +--------------+-----------------------------------------+ - | enabled | True | - | id | 6436a8a23d014cfdb69c586eff146a32 | - | interface | internal | - | region | RegionOne | - | region_id | RegionOne | - | service_id | eb9fd245bdbc414695952e93f29fe3ac | - | service_name | cinderv2 | - | service_type | volumev2 | - | url | http://controller:8776/v2/%(tenant_id)s | - +--------------+-----------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - volumev2 admin http://controller:8776/v2/%\(tenant_id\)s - +--------------+-----------------------------------------+ - | Field | Value | - +--------------+-----------------------------------------+ - | enabled | True | - | id | e652cf84dd334f359ae9b045a2c91d96 | - | interface | admin | - | region | RegionOne | - | region_id | RegionOne | - | service_id | eb9fd245bdbc414695952e93f29fe3ac | - | service_name | cinderv2 | - | service_type | volumev2 | - | url | http://controller:8776/v2/%(tenant_id)s | - +--------------+-----------------------------------------+ - - .. note:: - - The Block Storage services requires endpoints for each service - entity. - -Install and configure components --------------------------------- - -#. Install OpenStack Block Storage Controller bundle:: - - # swupd bundle-add openstack-block-storage-controller - -#. Custom configurations will be located at ``/etc/cinder``. - - * Create ``/etc/cinder`` directory:: - - # mkdir /etc/cinder - - * Create empty cinder configuration file in - ``/etc/cinder/cinder.conf``:: - - # touch /etc/cinder/cinder.conf - -#. Edit the ``/etc/cinder/cinder.conf`` file and complete the following - actions: - - * In the ``[database]`` section, configure database access. Replace - ``CINDER_DBPASS`` with the password you chose for the - database:: - - [database] - ... - connection=mysql://cinder:CINDER_DBPASS@controller/cinder - - * In the ``[DEFAULT]`` and ``[oslo_messaging_rabbit]`` section, - configure RabbitMQ message queue access. Replace ``RABBIT_PASS`` - with the password you chose for the account in - RabbitMQ:: - - [DEFAULT] - ... - rpc_backend = rabbit - - [oslo_messaging_rabbit] - ... - rabbit_host = controller - rabbit_userid = openstack - rabbit_password = RABBIT_PASS - - * In the ``[DEFAULT]`` and ``[keystone_authtoken]`` sections, configure - Identity service access. Replace ``CINDER_PASS`` with the password you - chose for the ``cinder`` user in the Identity service.:: - - [DEFAULT] - ... - auth_strategy = keystone - - [keystone_authtoken] - ... - auth_uri = http://controller:5000 - auth_url = http://controller:35357 - auth_plugin = password - project_domain_id = default - user_domain_id = default - project_name = service - username = cinder - password = CINDER_PASS - - * In the ``[DEFAULT]`` section, configure the ``my_ip`` option to - use the management interface IP address of the controller node:: - - [DEFAULT] - ... - my_ip = 10.0.0.11 - -#. Populate the Block Storage database:: - - # su -s /bin/sh -c "cinder-manage db sync" cinder - -Configure Compute to use Block Storage --------------------------------------- - -* Edit the ``/etc/nova/nova.conf`` file and add the following - to it:: - - [cinder] - os_region_name = RegionOne - -Finalize installation ---------------------- - -#. Restart the Compute API service:: - - # systemctl restart uwsgi@nova-api.service - -#. Start the Block Storage services and configure them to start when - the system boots:: - - # systemctl enable cinder-api cinder-scheduler - # systemctl start cinder-api cinder-scheduler - -Install and configure a storage node -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This section describes how to install and configure storage nodes -for the Block Storage service. For simplicity, this configuration -references one storage node with an empty local block storage device. -The instructions use ``/dev/sdb``, but you can substitute a different -value for your particular node. - -The service provisions logical volumes on this device using the -LVM driver and provides them to instances via iSCSI transport. -You can follow these instructions with minor modifications to -horizontally scale your environment with additional storage nodes. - -Prerequisites -------------- - -#. Install the Openstack Block Storage bundle:: - - # swupd bundle-add openstack-block-storage - -#. Create the LVM physical volume: ``/dev/sdb1`` If your system uses a - different device name, adjust these steps accordingly:: - - # pvcreate /dev/sdb1 - Physical volume "/dev/sdb1" successfully created - -#. Create the LVM volume group ``cinder-volumes``:: - - # vgcreate cinder-volumes /dev/sdb1 - Volume group "cinder-volumes" successfully created - - The Block Storage service creates logical volumes in this volume - group. - -#. Only instances can access Block Storage volumes. However, the - underlying operating system manages the devices associated with the - volumes. By default, the LVM volume scanning tool scans the ``/dev`` - directory for block storage devices that contain volumes. If projects - use LVM on their volumes, the scanning tool detects these volumes and - attempts to cache them which can cause a variety of problems with - both the underlying operating system and project volumes. You must - reconfigure LVM to scan only the devices that contain the - ``cinder-volume`` volume group. Edit the ``/etc/lvm/lvm.conf`` file - and complete the following action: - - * In the ``devices`` section, add a filter that accepts the - ``/dev/sdb`` device and rejects all other devices:: - - devices { - ... - filter = [ "a/sdb/", "r/.*/"] - -Install and configure components --------------------------------- - -#. Edit the ``/etc/cinder/cinder.conf`` file and complete the following - actions: - - * In the ``[database]`` section, configure database access. Replace - ``CINDER_DBPASS`` with the password you chose for the Block Storage - database:: - - [database] - ... - connection = mysql://cinder:CINDER_DBPASS@controller/cinder - - * In the ``[DEFAULT]`` and ``[oslo_messaging_rabbit]`` sections, - configure ``RabbitMQ`` message queue access. Replace ``RABBIT_PASS`` - with the password you chose for the openstack account in - ``RabbitMQ``:: - - [DEFAULT] - ... - rpc_backend = rabbit - - [oslo_messaging_rabbit] - ... - rabbit_host = controller - rabbit_userid = openstack - rabbit_password = RABBIT_PASS - - * In the ``[DEFAULT]`` and ``[keystone_authtoken]`` sections, - configure Identity service access. Replace ``CINDER_PASS`` with the - password you chose for the cinder user in the Identity service:: - - [DEFAULT] - ... - auth_strategy = keystone - - [keystone_authtoken] - ... - auth_uri = http://controller:5000 - auth_url = http://controller:35357 - auth_plugin = password - project_domain_id = default - user_domain_id = default - project_name = service - username = cinder - password = CINDER_PASS - - * In the ``[DEFAULT]`` section, configure the ``my_ip`` option. - Replace ``MANAGEMENT_INTERFACE_IP_ADDRESS`` with the IP address - of the management network interface on your storage node, - typically 10.0.0.41 for the first node in the example - architecture:: - - [DEFAULT] - ... - my_ip = MANAGEMENT_INTERFACE_IP_ADDRESS - - * In the ``[lvm]`` section, configure the LVM back end with the LVM - driver, ``cinder-volumes`` volume group, iSCSI protocol, and - appropriate iSCSI service:: - - [lvm] - ... - volume_driver = cinder.volume.drivers.lvm.LVMVolumeDriver - volume_group = cinder-volumes - iscsi_protocol = iscsi - iscsi_helper = tgtadm - - * In the ``[DEFAULT]`` section, enable the LVM back end:: - - [DEFAULT] - ... - enabled_backends = lvm - - * In the ``[DEFAULT]`` section, configure the location of the Image - service:: - - [DEFAULT] - ... - glance_host = controller - -#. Ensure files have proper ownership by running the following command:: - - # systemctl restart update-triggers.target - -Finalize installation ---------------------- - -#. Start the Block Storage volume service including its dependencies - and configure them to start when the system boots:: - - # systemctl enable iscsid tgtd cinder-volume - # systemctl start iscsid tgtd cinder-volume - -Configuring a compute node to use Block Storage ------------------------------------------------ - -#. Perform the following steps to enable a compute node to work with - block storage:: - - # systemctl enable iscsid - # systemctl start iscsi-gen-initiatorname iscsid - -Verify operation -~~~~~~~~~~~~~~~~ -Verify operation of the Block Storage service. - -#. Source the ``admin`` credentials to gain access to - admin-only CLI commands:: - - $ source admin-openrc.sh - -#. List service components to verify successful launch of each process:: - - $ cinder service-list - +------------------+------------+------+---------+-------+----------------------------+-----------------+ - | Binary | Host | Zone | Status | State | Updated_at | Disabled Reason | - +------------------+------------+------+---------+-------+----------------------------+-----------------+ - | cinder-scheduler | controller | nova | enabled | up | 2014-10-18T01:30:54.000000 | None | - | cinder-volume | block1@lvm | nova | enabled | up | 2014-10-18T01:30:57.000000 | None | - +------------------+------------+------+---------+-------+----------------------------+-----------------+ - -Next topic: :ref:`openstack_dashboard`. diff --git a/source/openstack_bundle_and_service_summary.rst b/source/openstack_bundle_and_service_summary.rst index 6a87fe72..d34b2210 100644 --- a/source/openstack_bundle_and_service_summary.rst +++ b/source/openstack_bundle_and_service_summary.rst @@ -63,4 +63,4 @@ uses a two-node architecture. using overlay segmentation methods. Additionally, this option provides the foundation for advanced services such as LBaaS and FWaaS. -Next topic: :ref:`openstack_sys_req_and_pw_summary`. +Next topic: :ref:``. diff --git a/source/openstack_compute.rst b/source/openstack_compute.rst deleted file mode 100644 index 18414c39..00000000 --- a/source/openstack_compute.rst +++ /dev/null @@ -1,527 +0,0 @@ -.. _openstack_compute: - -Compute -################## - -Use OpenStack Compute to host and manage cloud computing systems. -OpenStack Compute interacts with OpenStack Identity for authentication, -OpenStack Image Service for disk and server images, and OpenStack -Dashboard for the user and administrative interface. Image access is -limited by projects, and by users; quotas are limited per project (the -number of instances, for example). OpenStack Compute can scale -horizontally on standard hardware and download images to launch -instances. - -Install and configure controller node -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This section describes how to install and configure the -Compute service, code-named nova, on the controller node. - -Prerequisites -------------- - -Before you install and configure the Compute service, 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:: - - $ mysql -u root -p - - * Create the ``nova`` database:: - - CREATE DATABASE nova; - - * Grant proper access to the nova database. Replace ``NOVA_DBPASS`` - with a suitable password:: - - GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'localhost' \ - IDENTIFIED BY 'NOVA_DBPASS'; - GRANT ALL PRIVILEGES ON nova.* TO 'nova'@'%' \ - IDENTIFIED BY 'NOVA_DBPASS'; - - * Exit the database access client. - -#. Source the admin credentials to gain access to admin-only CLI - commands:: - - $ source admin-openrc.sh - -#. To create the service credentials, complete these steps: - - * Create the ``nova`` user:: - - $ openstack user create --domain default --password-prompt nova - User Password: - Repeat User Password: - +-----------+----------------------------------+ - | Field | Value | - +-----------+----------------------------------+ - | domain_id | default | - | enabled | True | - | id | 8c46e4760902464b889293a74a0c90a8 | - | name | nova | - +-----------+----------------------------------+ - - * Add the ``admin`` role to the ``nova`` user:: - - $ openstack role add --project service --user nova admin - - * Create the ``nova`` service entity:: - - $ openstack service create --name nova \ - --description "OpenStack Compute" compute - +-------------+----------------------------------+ - | Field | Value | - +-------------+----------------------------------+ - | description | OpenStack Compute | - | enabled | True | - | id | 060d59eac51b4594815603d75a00aba2 | - | name | nova | - | type | compute | - +-------------+----------------------------------+ - -#. Create the Compute service API endpoints:: - - $ openstack endpoint create --region RegionOne \ - compute public http://controller:8774/v2/%\(tenant_id\)s - +--------------+-----------------------------------------+ - | Field | Value | - +--------------+-----------------------------------------+ - | enabled | True | - | id | 3c1caa473bfe4390a11e7177894bcc7b | - | interface | public | - | region | RegionOne | - | region_id | RegionOne | - | service_id | e702f6f497ed42e6a8ae3ba2e5871c78 | - | service_name | nova | - | service_type | compute | - | url | http://controller:8774/v2/%(tenant_id)s | - +--------------+-----------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - compute internal http://controller:8774/v2/%\(tenant_id\)s - +--------------+-----------------------------------------+ - | Field | Value | - +--------------+-----------------------------------------+ - | enabled | True | - | id | e3c918de680746a586eac1f2d9bc10ab | - | interface | internal | - | region | RegionOne | - | region_id | RegionOne | - | service_id | e702f6f497ed42e6a8ae3ba2e5871c78 | - | service_name | nova | - | service_type | compute | - | url | http://controller:8774/v2/%(tenant_id)s | - +--------------+-----------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - compute admin http://controller:8774/v2/%\(tenant_id\)s - +--------------+-----------------------------------------+ - | Field | Value | - +--------------+-----------------------------------------+ - | enabled | True | - | id | 38f7af91666a47cfb97b4dc790b94424 | - | interface | admin | - | region | RegionOne | - | region_id | RegionOne | - | service_id | e702f6f497ed42e6a8ae3ba2e5871c78 | - | service_name | nova | - | service_type | compute | - | url | http://controller:8774/v2/%(tenant_id)s | - +--------------+-----------------------------------------+ - -Installing and configuring the Compute controller components -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To install and configure the Compute controller components: - -#. Install OpenStack Compute Controller bundle:: - - # swupd bundle-add openstack-compute-controller - -#. Custom configurations will be located at ``/etc/nova``. - - * Create ``/etc/nova directory``:: - - # mkdir /etc/nova - - * Create empty nova configuration file ``/etc/nova/nova.conf``:: - - # touch /etc/nova/nova.conf - -#. Edit the ``/etc/nova/nova.conf`` file and complete the following - actions: - - * In the ``[database]`` section, configure database access. Replace - ``NOVA_DBPASS`` with the password you chose for the Compute database:: - - [database] - ... - connection=mysql://nova:NOVA_DBPASS@controller/nova - - * In the ``[DEFAULT]`` and ``[oslo_messaging_rabbit]`` sections, - configure ``RabbitMQ`` message queue access. Replace ``RABBIT_PASS`` - with the password you chose for the guest account in RabbitMQ:: - - [DEFAULT] - ... - rpc_backend = rabbit - - [oslo_messaging_rabbit] - ... - rabbit_host = controller - rabbit_userid = openstack - rabbit_password = RABBIT_PASS - - * In the ``[DEFAULT]`` and ``[keystone_authtoken]`` sections, - configure Identity service access. Replace ``NOVA_PASS`` with the - password you chose for the nova user in the Identity service:: - - [DEFAULT] - ... - auth_strategy = keystone - - [keystone_authtoken] - ... - auth_uri = http://controller:5000 - auth_url = http://controller:35357 - auth_plugin = password - project_domain_id = default - user_domain_id = default - project_name = service - username = nova - password = NOVA_PASS - - - * In the ``[DEFAULT]`` section, configure the ``my_ip`` option to - use the management interface IP address of the controller node:: - - [DEFAULT] - ... - my_ip = 10.0.0.11 - - * In the ``[DEFAULT]`` section, enable support for the Networking service:: - - [DEFAULT] - ... - network_api_class = nova.network.neutronv2.api.API - security_group_api = neutron - linuxnet_interface_driver = nova.network.linux_net.NeutronLinuxBridgeInterfaceDriver - firewall_driver = nova.virt.firewall.NoopFirewallDriver - - * In the ``[vnc]`` section, configure the VNC proxy to use the - management interface IP address of the controller node:: - - [vnc] - ... - vncserver_listen = 10.0.0.11 - vncserver_proxyclient_address = 10.0.0.11 - - * In the ``[glance]`` section, configure the location of the - Image Service:: - - [glance] - ... - host = controller - -#. Ensure files have proper ownership by running the following command:: - - # systemctl restart update-triggers.target - -#. Populate the Compute database:: - - su -s /bin/sh -c "nova-manage db sync" nova - -Finalizing Compute installation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Complete the following steps to finalize Compute installation: - -#. Create the ``/etc/nginx`` directory if doesn't exists and setup nova-api - and nova-metadata to start with the Nginx http server:: - - # mkdir -p /etc/nginx - # ln -s /usr/share/nginx/conf.d/nova-api.template /etc/nginx/nova-api.conf - -#. Restart the Nginx server to reload new configurations:: - - # systemctl restart nginx - -#. Start the Compute Service services and configure them to start - when the system boots:: - - # systemctl enable uwsgi@nova-api.socket \ - uwsgi@nova-metadata.socket nova-cert.service \ - nova-consoleauth.service nova-scheduler.service \ - nova-conductor.service nova-novncproxy.service - # systemctl start uwsgi@nova-api.socket \ - uwsgi@nova-metadata.socket nova-cert.service \ - nova-consoleauth.service nova-scheduler.service \ - nova-conductor.service nova-novncproxy.service - -Install and configure a compute note -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This section describes how to install and configure the Compute service -on a compute node. This configuration uses the QEMU hypervisor with the -KVM extension on compute nodes that support hardware acceleration for -virtual machines. - -Install and configure components --------------------------------- - -#. Install OpenStack Compute bundle:: - - # clr_bundle_add openstack-compute - -#. Custom configurations will be located at ``/etc/nova``. - - * Create ``/etc/nova`` directory:: - - # mkdir /etc/nova - - * Create empty nova configuration file ``/etc/nova/nova.conf``:: - - # touch /etc/nova/nova.conf - -#. Edit the ``/etc/nova/nova.conf`` file and complete the following - actions: - - * In the ``[DEFAULT]`` and ``[oslo_messaging_rabbit]`` sections, - configure RabbitMQ message broker access. Replace ``RABBIT_PASS`` - with the password you chose for the ``openstack`` account in ``RabbitMQ``:: - - [DEFAULT] - ... - rpc_backend = rabbit - - [oslo_messaging_rabbit] - ... - rabbit_host = controller - rabbit_userid = openstack - rabbit_password = RABBIT_PASS - - * In the ``[DEFAULT]`` and ``[keystone_authtoken]`` sections, - configure Identity service access. Replace ``NOVA_PASS`` with the - password you chose for the nova user in the Identity service:: - - [DEFAULT] - ... - auth_strategy = keystone - - [keystone_authtoken] - ... - auth_uri = http://controller:5000 - auth_url = http://controller:35357 - auth_plugin = password - project_domain_id = default - user_domain_id = default - project_name = service - username = nova - password = NOVA_PASS - - * In the ``[DEFAULT]`` section, configure the ``my_ip`` option. - Replace ``MANAGEMENT_INTERFACE_IP_ADDRESS`` with the IP address of - the management network interface on your compute node, typically - ``10.0.0.31`` for the first node in the example architecture:: - - [DEFAULT] - ... - my_ip = MANAGEMENT_INTERFACE_IP_ADDRESS - - * In the ``[DEFAULT]`` section, enable support for the Networking service:: - - [DEFAULT] - ... - network_api_class = nova.network.neutronv2.api.API - security_group_api = neutron - linuxnet_interface_driver = nova.network.linux_net.NeutronLinuxBridgeInterfaceDriver - firewall_driver = nova.virt.firewall.NoopFirewallDriver - - * In the ``[vnc]`` section, enable and configure remote console access:: - - [vnc] - ... - enabled = True - vncserver_listen = 0.0.0.0 - vncserver_proxyclient_address = MANAGEMENT_INTERFACE_IP_ADDRESS - novncproxy_base_url = http://controller:6080/vnc_auto.html - - The server component listens on all IP addresses and the proxy - component only listens on the management interface IP address of - the compute node. The base URL indicates the location where you - can use a web browser to access remote consoles of instances on - this compute node. - - * In the ``[glance]`` section, configure the location of the - Image Service:: - - [glance] - ... - host = controller - -Finalize compute node installation ----------------------------------- - -#. Determine whether your compute node supports hardware acceleration - for virtual machines:: - - $ egrep -c '(vmx|svm)' /proc/cpuinfo - - If this command returns a value of ``one or greater``, your compute - node supports hardware acceleration which typically requires no - additional configuration. - - If this command returns a value of ``zero`` , your compute node does - not support hardware acceleration and you must configure ``libvirt`` - to use QEMU instead of KVM. - - * Edit the ``[libvirt]`` section in the ``/etc/nova/nova.conf`` file - as follows:: - - [libvirt] - ... - virt_type = qemu - -#. Ensure files have proper ownership by running the following command:: - - # systemctl restart update-triggers.target - -#. Start the Compute service including its dependencies and configure - them to start automatically when the system boots:: - - # systemctl enable libvirtd.service \ - nova-compute.service - # systemctl start libvirtd.service \ - nova-compute.service - -Verify operation -~~~~~~~~~~~~~~~~ -Verify operation of the Compute service. - -*Note:* Perform these commands on the controller node. - -#. Source the ``admin`` credentials to gain access to - admin-only CLI commands:: - - $ source admin-openrc.sh - -#. List service components to verify successful launch and - registration of each process:: - - $ nova service-list - +----+------------------+------------+----------+---------+-------+--------------+-----------------+ - | Id | Binary | Host | Zone | Status | State | Updated_at | Disabled Reason | - +----+------------------+------------+----------+---------+-------+--------------+-----------------+ - | 1 | nova-conductor | controller | internal | enabled | up | 2014-09-16.. | - | - | 2 | nova-consoleauth | controller | internal | enabled | up | 2014-09-16.. | - | - | 3 | nova-scheduler | controller | internal | enabled | up | 2014-09-16.. | - | - | 4 | nova-cert | controller | internal | enabled | up | 2014-09-16.. | - | - | 5 | nova-compute | compute1 | nova | enabled | up | 2014-09-16.. | - | - +----+------------------+------------+----------+---------+-------+--------------+-----------------+ - -#. List API endpoints in the Identity service to verify connectivity - with the Identity service:: - - $ nova endpoints - +-----------+------------------------------------------------------------+ - | nova | Value | - +-----------+------------------------------------------------------------+ - | id | 1fb997666b79463fb68db4ccfe4e6a71 | - | interface | public | - | region | RegionOne | - | region_id | RegionOne | - | url | http://controller:8774/v2/ae7a98326b9c455588edd2656d723b9d | - +-----------+------------------------------------------------------------+ - +-----------+------------------------------------------------------------+ - | nova | Value | - +-----------+------------------------------------------------------------+ - | id | bac365db1ff34f08a31d4ae98b056924 | - | interface | admin | - | region | RegionOne | - | region_id | RegionOne | - | url | http://controller:8774/v2/ae7a98326b9c455588edd2656d723b9d | - +-----------+------------------------------------------------------------+ - +-----------+------------------------------------------------------------+ - | nova | Value | - +-----------+------------------------------------------------------------+ - | id | e37186d38b8e4b81a54de34e73b43f34 | - | interface | internal | - | region | RegionOne | - | region_id | RegionOne | - | url | http://controller:8774/v2/ae7a98326b9c455588edd2656d723b9d | - +-----------+------------------------------------------------------------+ - - +-----------+----------------------------------+ - | glance | Value | - +-----------+----------------------------------+ - | id | 41ad39f6c6444b7d8fd8318c18ae0043 | - | interface | admin | - | region | RegionOne | - | region_id | RegionOne | - | url | http://controller:9292 | - +-----------+----------------------------------+ - +-----------+----------------------------------+ - | glance | Value | - +-----------+----------------------------------+ - | id | 50ecc4ce62724e319f4fae3861e50f7d | - | interface | internal | - | region | RegionOne | - | region_id | RegionOne | - | url | http://controller:9292 | - +-----------+----------------------------------+ - +-----------+----------------------------------+ - | glance | Value | - +-----------+----------------------------------+ - | id | 7d3df077a20b4461a372269f603b7516 | - | interface | public | - | region | RegionOne | - | region_id | RegionOne | - | url | http://controller:9292 | - +-----------+----------------------------------+ - - +-----------+----------------------------------+ - | keystone | Value | - +-----------+----------------------------------+ - | id | 88150c2fdc9d406c9b25113701248192 | - | interface | internal | - | region | RegionOne | - | region_id | RegionOne | - | url | http://controller:5000/v2.0 | - +-----------+----------------------------------+ - +-----------+----------------------------------+ - | keystone | Value | - +-----------+----------------------------------+ - | id | cecab58c0f024d95b36a4ffa3e8d81e1 | - | interface | public | - | region | RegionOne | - | region_id | RegionOne | - | url | http://controller:5000/v2.0 | - +-----------+----------------------------------+ - +-----------+----------------------------------+ - | keystone | Value | - +-----------+----------------------------------+ - | id | fc90391ae7cd4216aca070042654e424 | - | interface | admin | - | region | RegionOne | - | region_id | RegionOne | - | url | http://controller:35357/v2.0 | - +-----------+----------------------------------+ - - *Note:* Ignore any warnings in this output. - -#. List images in the Image service catalog to verify connectivity - with the Image service:: - - $ nova image-list - +--------------------------------------+--------+--------+--------+ - | ID | Name | Status | Server | - +--------------------------------------+--------+--------+--------+ - | 38047887-61a7-41ea-9b49-27987d5e8bb9 | cirros | ACTIVE | | - +--------------------------------------+--------+--------+--------+ - -Next topic: :ref:`openstack_block_storage`. diff --git a/source/openstack_dashboard.rst b/source/openstack_dashboard.rst deleted file mode 100644 index a77d3c28..00000000 --- a/source/openstack_dashboard.rst +++ /dev/null @@ -1,33 +0,0 @@ -.. _openstack_dashboard: - -Dashboard -#################### - -The OpenStack* Dashboard, also known as Horizon, is a web-based interface -for cloud administrators and users to manage various OpenStack resources -and services. - -The Dashboard enables web-based interactions with the -OpenStack Compute cloud controller through the OpenStack APIs. - -Installation and configuration ------------------------------- - -The dashboard relies on functional core services including -Identity, Image service, Compute, and either Networking (neutron) -or legacy networking (nova-network). Environments with -stand-alone services such as Object Storage cannot use the -dashboard. - -To get started with OpenStack Dashboard services: - -#. Install the OpenStack Dashboard bundle:: - - # swupd bundle-add openstack-dashboard - -#. Enable and start the dashboard socket and the Nginx server:: - - # systemctl enable nginx uwsgi@horizon.socket - # systemctl restart nginx uwsgi@horizon.socket - -Next topic: :ref:`openstack_networking`. diff --git a/source/openstack_identity-openrc.rst b/source/openstack_identity-openrc.rst deleted file mode 100644 index 724333db..00000000 --- a/source/openstack_identity-openrc.rst +++ /dev/null @@ -1,75 +0,0 @@ -.. _openstack_identity-openrc: - -Create OpenStack* client environment scripts -############################################ - -The previous section used a combination of environment variables and -command options to interact with the Identity service via the -``openstack`` client. To increase efficiency of client operations, -OpenStack supports simple client environment scripts also known as -OpenRC files. These scripts typically contain common options for -all clients but also support unique options. For more information, see the -`OpenStack User Guide `__. - -Creating the scripts --------------------- - -Create client environment scripts for the ``admin`` and ``demo`` -projects and users. Future portions of this guide reference these -scripts to load appropriate credentials for client operations. - -#. Create the ``admin-openrc.sh`` file and add the following content:: - - export OS_PROJECT_DOMAIN_ID=default - export OS_USER_DOMAIN_ID=default - export OS_PROJECT_NAME=admin - export OS_TENANT_NAME=admin - export OS_USERNAME=admin - export OS_PASSWORD=ADMIN_PASS - export OS_AUTH_URL=http://controller:35357/v3 - export OS_IDENTITY_API_VERSION=3 - - Replace ``ADMIN_PASS`` with the password you chose - for the ``admin`` user in the Identity service. - -#. Create the ``demo-openrc.sh`` file and add the following content:: - - export OS_PROJECT_DOMAIN_ID=default - export OS_USER_DOMAIN_ID=default - export OS_PROJECT_NAME=demo - export OS_TENANT_NAME=demo - export OS_USERNAME=demo - export OS_PASSWORD=DEMO_PASS - export OS_AUTH_URL=http://controller:5000/v3 - export OS_IDENTITY_API_VERSION=3 - - Replace ``DEMO_PASS`` with the password you chose - for the ``demo`` user in the Identity service. - -Using the scripts ------------------ - -To run clients as a specific project and user, you can simply load -the associated client environment script prior to running them. -For example: - -#. Load the ``admin-openrc.sh`` file to populate - environment variables with the location of the Identity service - and the ``admin`` project and user credentials:: - - $ source admin-openrc.sh - -#. Request an authentication token:: - - $ openstack token issue - +------------+----------------------------------+ - | Field | Value | - +------------+----------------------------------+ - | expires | 2015-03-25T01:45:49.950092Z | - | id | cd4110152ac24bdeaa82e1443c910c36 | - | project_id | cf12a15c5ea84b019aec3dc45580896b | - | user_id | 4d411f2291f34941b30eef9bd797505a | - +------------+----------------------------------+ - -Next topic: :ref:`openstack_image`. \ No newline at end of file diff --git a/source/openstack_identity.rst b/source/openstack_identity.rst deleted file mode 100644 index 934d7999..00000000 --- a/source/openstack_identity.rst +++ /dev/null @@ -1,416 +0,0 @@ -.. _openstack_identity: - -Identity Service -################### - -The OpenStack Identity service provides a single point of integration for -managing authentication, authorization, and service catalog services. -Additionally, it provides information about users but that are not included in -OpenStack (such as LDAP services) can be integrated into a pre-existing -infrastructure. - -When installing OpenStack Identity service, you must register each -service in your OpenStack installation. Identity service can then track -which OpenStack services are installed and where they are located on -the network. - -Install and configure -~~~~~~~~~~~~~~~~~~~~~ - -This section describes how to install and configure the OpenStack -Identity service, code-named keystone, on the controller node. For -performance, this configuration deploys the Nginx* HTTP server to handle -requests. - -Prerequisites -------------- - -Before you configure the OpenStack Identity service, you must create a -database and an administration token. - -#. To create the database, complete the following actions: - - * Use the database access client to connect to the database server as the - ``root`` user.:: - - $ mysql -u root -p - - * Create the ``keystone`` database.:: - - CREATE DATABASE keystone; - - * Grant proper access to the ``keystone`` databaseReplace ``KEYSTONE_DBPASS`` - with a suitable password.:: - - GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' \ - IDENTIFIED BY 'KEYSTONE_DBPASS'; - GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' \ - IDENTIFIED BY 'KEYSTONE_DBPASS'; - - - * Exit the database access client. - -#. Generate a random value to use as the administration token during - initial configuration:: - - $ openssl rand -hex 10 - -Install and configure components --------------------------------- - -#. Run the following command to install the packages.:: - - # swupd bundle-add openstack-identity - -#. Custom configurations will be located at ``/etc/keystone/``. - - * Create the ``/etc/keystone`` directory.:: - - # mkdir /etc/keystone - - * Create keystone configuration file ``/etc/keystone/keystone.conf``.:: - - # touch /etc/keystone/keystone.conf - -#. Edit the ``/etc/keystone/keystone.conf`` file and complete the following - actions: - - * In the ``[DEFAULT]`` section, define the value of the initial - administration token. Replace ``ADMIN_TOKEN`` with the random value that - you generated in a previous step.:: - - [DEFAULT] - ... - admin_token = ADMIN_TOKEN - - * In the ``[database]`` section, configure database access. Replace - ``KEYSTONE_DBPASS`` with the password you chose for the database.:: - - [database] - ... - connection = mysql://keystone:KEYSTONE_DBPASS@controller/keystone - - -#. Ensure files have proper ownership by running the following command:: - - # systemctl restart update-triggers.target - -#. Populate the Identity service database:: - - # su -s /bin/sh -c "keystone-manage db_sync" keystone - -Finalize the installation -------------------------- - -#. Keystone is deployed as a uwsgi module. To start the Identity - service, you should enable and start the nginx service.:: - - # systemctl enable nginx uwsgi@keystone-admin.socket \ - uwsgi@keystone-public.socket - - # systemctl start nginx uwsgi@keystone-admin.socket \ - uwsgi@keystone-public.socket - - -Create the service entity and API endpoints -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The Identity service provides a catalog of services and their locations. -Each service that you add to your OpenStack environment requires a -service entity and several API endpoints in the catalog. - -Prerequisites -------------- - -You must pass the value of the authentication token to the `openstack` -command with the ``--os-token`` parameter or set the OS_TOKEN -environment variable. Similarly, you must also pass the value of the -Identity service URL to the `openstack` command with the ``--os-url`` -parameter or set the OS_URL environment variable. This guide uses -environment variables to reduce command length. - -#. Configure the authentication token:: - - $ export OS_TOKEN=ADMIN_TOKEN - - Replace ``ADMIN_TOKEN`` with the authentication token that you - generated before. For example:: - - $ export OS_TOKEN=294a4c8a8a475f9b9836 - -#. Configure the endpoint URL:: - - $ export OS_URL=http://controller:35357/v3 - -#. Configure the Identity API version:: - - $ export OS_IDENTITY_API_VERSION=3 - -#. Install the OpenStack Python clients bundle:: - - # swupd bundle-add openstack-python-clients - - -Create the service entity and API endpoints -------------------------------------------- - - -#. The Identity service manages a catalog of services in your OpenStack - environment. Services use this catalog to determine the other services - available in your environment. - - Create the service entity for the Identity service:: - - $ openstack service create \ - --name keystone --description "OpenStack Identity" identity - +-------------+----------------------------------+ - | Field | Value | - +-------------+----------------------------------+ - | description | OpenStack Identity | - | enabled | True | - | id | 4ddaae90388b4ebc9d252ec2252d8d10 | - | name | keystone | - | type | identity | - +-------------+----------------------------------+ - -#. The Identity service manages a catalog of API endpoints associated with - the services in your OpenStack environment. Services use this catalog to - determine how to communicate with other services in your environment. - - OpenStack uses three API endpoint variants for each service: admin, - internal, and public. The admin API endpoint allows modifying users and - tenants by default, while the public and internal APIs do not allow these - operations. In a production environment, the variants might reside on - separate networks that service different types of users for security - reasons. For instance, the public API network might be visible from the - Internet so customers can manage their clouds. The admin API network - might be restricted to operators within the organization that manages - cloud infrastructure. The internal API network might be restricted to - the hosts that contain OpenStack services. Also, OpenStack supports - multiple regions for scalability. For simplicity, this guide uses the - management network for all endpoint variations and the default - ``RegionOne`` region. - - Create the Identity service API endpoints:: - - $ openstack endpoint create --region RegionOne \ - identity public http://controller:5000/v3 - +--------------+----------------------------------+ - | Field | Value | - +--------------+----------------------------------+ - | enabled | True | - | id | 30fff543e7dc4b7d9a0fb13791b78bf4 | - | interface | public | - | region | RegionOne | - | region_id | RegionOne | - | service_id | 8c8c0927262a45ad9066cfe70d46892c | - | service_name | keystone | - | service_type | identity | - | url | http://controller:5000/v3 | - +--------------+----------------------------------+ - - $ openstack endpoint create --region RegionOne \ - identity internal http://controller:5000/v3 - +--------------+----------------------------------+ - | Field | Value | - +--------------+----------------------------------+ - | enabled | True | - | id | 57cfa543e7dc4b712c0ab137911bc4fe | - | interface | internal | - | region | RegionOne | - | region_id | RegionOne | - | service_id | 6f8de927262ac12f6066cfe70d99ac51 | - | service_name | keystone | - | service_type | identity | - | url | http://controller:5000/v3 | - +--------------+----------------------------------+ - - $ openstack endpoint create --region RegionOne \ - identity admin http://controller:35357/v3 - +--------------+----------------------------------+ - | Field | Value | - +--------------+----------------------------------+ - | enabled | True | - | id | 78c3dfa3e7dc44c98ab1b1379122ecb1 | - | interface | admin | - | region | RegionOne | - | region_id | RegionOne | - | service_id | 34ab3d27262ac449cba6cfe704dbc11f | - | service_name | keystone | - | service_type | identity | - | url | http://controller:35357/v3 | - +--------------+----------------------------------+ - -Creating projects, users and roles -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Complete the following steps to create projects, users and roles: - -#. Create an administrative project, user, and role for administrative - operations in your environment: - - * Create the ``admin`` project:: - - $ openstack project create --domain default \ - --description "Admin Project" admin - +-------------+----------------------------------+ - | Field | Value | - +-------------+----------------------------------+ - | description | Admin Project | - | domain_id | default | - | enabled | True | - | id | 343d245e850143a096806dfaefa9afdc | - | is_domain | False | - | name | admin | - | parent_id | None | - +-------------+----------------------------------+ - - * Create the ``admin`` user:: - - $ openstack user create --domain default \ - --password-prompt admin - User Password: - Repeat User Password: - +-----------+----------------------------------+ - | Field | Value | - +-----------+----------------------------------+ - | domain_id | default | - | email | admin@example.com | - | enabled | True | - | id | ac3377633149401296f6c0d92d79dc16 | - | name | admin | - +-----------+----------------------------------+ - - * Create the ``admin`` role:: - - $ openstack role create admin - +-------+----------------------------------+ - | Field | Value | - +-------+----------------------------------+ - | id | cd2cb9a39e874ea69e5d4b896eb16128 | - | name | admin | - +-------+----------------------------------+ - - * Add the ``admin`` role to the ``admin`` project and user:: - - $ openstack role add --project admin --user admin admin - -#. This guide uses a service project that contains a unique user for each - service that you add to your environment. Create the ``service`` - project:: - - $ openstack project create --domain default \ - --description "Service Project" service - +-------------+----------------------------------+ - | Field | Value | - +-------------+----------------------------------+ - | description | Service Project | - | domain_id | default | - | enabled | True | - | id | 894cdfa366d34e9d835d3de01e752262 | - | is_domain | False | - | name | service | - | parent_id | None | - +-------------+----------------------------------+ - -#. Regular (non-admin) tasks should use an unprivileged project and user. - As an example, this guide creates the ``demo`` project and user. - - * Create the ``demo`` project:: - - $ openstack project create --domain default \ - --description "Demo Project" demo - +-------------+----------------------------------+ - | Field | Value | - +-------------+----------------------------------+ - | description | Demo Project | - | domain_id | default | - | enabled | True | - | id | ed0b60bf607743088218b0a533d5943f | - | is_domain | False | - | name | demo | - | parent_id | None | - +-------------+----------------------------------+ - - * Create the ``demo`` user:: - - $ openstack user create --domain default \ - --password-prompt demo - User Password: - Repeat User Password: - +-----------+----------------------------------+ - | Field | Value | - +-----------+----------------------------------+ - | domain_id | default | - | email | demo@example.com | - | enabled | True | - | id | 58126687cbcc4888bfa9ab73a2256f27 | - | name | demo | - +-----------+----------------------------------+ - - * Create the ``user`` role:: - - $ openstack role create user - +-------+----------------------------------+ - | Field | Value | - +-------+----------------------------------+ - | id | 997ce8d05fc143ac97d83fdfb5998552 | - | name | user | - +-------+----------------------------------+ - - * Add the ``user`` role to the ``demo`` project and user:: - - $ openstack role add --project demo --user demo user - -Verify operation -~~~~~~~~~~~~~~~~ - -Verify operation of the Identity service before installing other -services. - -#. For security reasons, remove admin_token from - ``/etc/keystone/keystone.conf``: - - Edit the ``[DEFAULT]`` section and remove ``admin_token``. - -#. Restart the keystone-admin service to reload the changes:: - - # systemctl restart uwsgi@keystone-admin.service - -#. Unset the temporary ``OS_TOKEN`` and ``OS_URL`` environment variables:: - - $ unset OS_TOKEN OS_URL - -#. As the ``admin`` user, request an authentication token:: - - $ openstack --os-auth-url http://controller:35357/v3 \ - --os-project-domain-id default --os-user-domain-id default \ - --os-project-name admin --os-username admin --os-auth-type password \ - token issue - Password: - +------------+----------------------------------+ - | Field | Value | - +------------+----------------------------------+ - | expires | 2015-03-24T18:55:01Z | - | id | ff5ed908984c4a4190f584d826d75fed | - | project_id | cf12a15c5ea84b019aec3dc45580896b | - | user_id | 4d411f2291f34941b30eef9bd797505a | - +------------+----------------------------------+ - -#. As the ``demo`` user, request an authentication token:: - - $ openstack --os-auth-url http://controller:5000/v3 \ - --os-project-domain-id default --os-user-domain-id default \ - --os-project-name demo --os-username demo --os-auth-type password \ - token issue - Password: - +------------+----------------------------------+ - | Field | Value | - +------------+----------------------------------+ - | expires | 2014-10-10T12:51:33Z | - | id | 1b87ceae9e08411ba4a16e4dada04802 | - | project_id | 4aa51bb942be4dd0ac0555d7591f80a6 | - | user_id | 7004dfa0dda84d63aef81cf7f100af01 | - +------------+----------------------------------+ - -Next topic: :ref:`openstack_identity-openrc`. diff --git a/source/openstack_image.rst b/source/openstack_image.rst deleted file mode 100644 index 32b7b391..00000000 --- a/source/openstack_image.rst +++ /dev/null @@ -1,277 +0,0 @@ -.. _openstack_image: - -Image Service -################ - -The OpenStack Image service (glance) enables users to discover, register, and -retrieve virtual machine images. - -Install and configure the Image Service ---------------------------------------- - -This section describes how to install and configure the Image service, -code-named glance, on the controller node. For simplicity, this configuration -stores images on the local file system. By default, this directory is -``/var/lib/glance/images/``. - -Prerequisites -~~~~~~~~~~~~~ - -Before you install and configure the Image service, 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.:: - - $ mysql -u root -p - - * Create the ``glance`` database:: - - CREATE DATABASE glance; - - * Grant proper access to the ``glance`` database. Replace ``GLANCE_DBPASS`` - with a suitable password.:: - - GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'localhost' \ - IDENTIFIED BY 'GLANCE_DBPASS'; - GRANT ALL PRIVILEGES ON glance.* TO 'glance'@'%' \ - IDENTIFIED BY 'GLANCE_DBPASS'; - - * Exit the database access client. - -#. Source the ``admin`` credentials to gain access to admin-only CLI commands.:: - - $ source admin-openrc.sh - -#. To create the service credentials, complete these steps: - - * Create the ``glance`` user:: - - $ openstack user create --domain default --password-prompt glance - User Password: - Repeat User Password: - +-----------+----------------------------------+ - | Field | Value | - +-----------+----------------------------------+ - | domain_id | default | - | enabled | True | - | id | e38230eeff474607805b596c91fa15d9 | - | name | glance | - +-----------+----------------------------------+ - - * Add the ``admin`` role to the ``glance`` user and ``service`` project.:: - - $ openstack role add --project service --user glance admin - - * Create the ``glance`` service entity.:: - - $ openstack service create --name glance \ - --description "OpenStack Image service" image - +-------------+----------------------------------+ - | Field | Value | - +-------------+----------------------------------+ - | description | OpenStack Image service | - | enabled | True | - | id | 8c2c7f1b9b5049ea9e63757b5533e6d2 | - | name | glance | - | type | image | - +-------------+----------------------------------+ - -#. Create the Image service API endpoints.:: - - $ openstack endpoint create --region RegionOne \ - image public http://controller:9292 - +--------------+----------------------------------+ - | Field | Value | - +--------------+----------------------------------+ - | enabled | True | - | id | 340be3625e9b4239a6415d034e98aace | - | interface | public | - | region | RegionOne | - | region_id | RegionOne | - | service_id | 8c2c7f1b9b5049ea9e63757b5533e6d2 | - | service_name | glance | - | service_type | image | - | url | http://controller:9292 | - +--------------+----------------------------------+ - - $ openstack endpoint create --region RegionOne \ - image internal http://controller:9292 - +--------------+----------------------------------+ - | Field | Value | - +--------------+----------------------------------+ - | enabled | True | - | id | a6e4b153c2ae4c919eccfdbb7dceb5d2 | - | interface | internal | - | region | RegionOne | - | region_id | RegionOne | - | service_id | 8c2c7f1b9b5049ea9e63757b5533e6d2 | - | service_name | glance | - | service_type | image | - | url | http://controller:9292 | - +--------------+----------------------------------+ - - $ openstack endpoint create --region RegionOne \ - image admin http://controller:9292 - +--------------+----------------------------------+ - | Field | Value | - +--------------+----------------------------------+ - | enabled | True | - | id | 0c37ed58103f4300a84ff125a539032d | - | interface | admin | - | region | RegionOne | - | region_id | RegionOne | - | service_id | 8c2c7f1b9b5049ea9e63757b5533e6d2 | - | service_name | glance | - | service_type | image | - | url | http://controller:9292 | - +--------------+----------------------------------+ - -Install and configure components --------------------------------- - -#. Install OpenStack Image bundle.:: - - # swupd bundle-add openstack-image - -#. Configurations will be located at ``/etc/glance``. - - * Create ``/etc/glance`` directory.:: - - # mkdir /etc/glance - - * Create ``/etc/glance/glance-api.conf`` and - ``/etc/glance/glance-registry.conf`` configuration files.:: - - # touch /etc/glance/glance-{api,registry}.conf - -#. Edit the ``/etc/glance/glance-api.conf`` file and complete the following - actions: - - * In the ``[database]`` section, configure database access. Replace - ``GLANCE_DBPASS`` with the password you chose for the Image service - database.:: - - [database] - ... - connection = mysql://glance:GLANCE_DBPASS@controller/glance - - * In the ``[keystone_authtoken]`` section, configure Identity service access. - Replace ``GLANCE_PASS`` with the password you chose for the ``glance`` user - in the Identity service.:: - - [keystone_authtoken] - ... - auth_uri = http://controller:5000 - auth_url = http://controller:35357 - auth_plugin = password - project_domain_id = default - user_domain_id = default - project_name = service - username = glance - password = GLANCE_PASS - -#. Edit the ``/etc/glance/glance-registry.conf`` file and complete the following - actions: - - * In the ``[database]`` section, configure database access. Replace - ``GLANCE_DBPASS`` with the password you chose for the Image service - database.:: - - [database] - ... - connection = mysql://glance:GLANCE_DBPASS@controller/glance - - * In the ``[keystone_authtoken]`` section, configure Identity service - access. Replace ``GLANCE_PASS`` with the password you chose for the - ``glance`` user in the Identity service.:: - - [keystone_authtoken] - ... - auth_uri = http://controller:5000 - auth_url = http://controller:35357 - auth_plugin = password - project_domain_id = default - user_domain_id = default - project_name = service - username = glance - password = GLANCE_PASS - -#. Ensure files have proper ownership by running the following command:: - - # systemctl restart update-triggers.target - -#. Populate the Image Service database:: - - # su -s /bin/sh -c "glance-manage db_sync" glance - -Finalize installation ---------------------- - -#. Start the Image Service services and configure them to start when the - system boots:: - - # systemctl enable glance-api.service glance-registry.service - # systemctl start glance-api.service glance-registry.service - -Verify operation -~~~~~~~~~~~~~~~~ - -Verify operation of the Image service using -`CirrOS `__, a small -Linux image that helps you test your OpenStack deployment. - -#. In each client environment script, configure the Image service - client to use API version 2.0:: - - $ echo "export OS_IMAGE_API_VERSION=2" \ - | tee -a admin-openrc.sh demo-openrc.sh - -#. Source the ``admin`` credentials to gain access to admin-only CLI commands:: - - $ source admin-openrc.sh - -#. Download the source image:: - - $ curl -Ok http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img - -#. Upload the image to the Image service using the `QCOW2` disk format, `bare` - container format, and public visibility so all projects can access it:: - - $ openstack image create cirros --file cirros-0.3.4-x86_64-disk.img \ - --disk-format qcow2 --container-format bare --public - +------------------+------------------------------------------------------+ - | Field | Value | - +------------------+------------------------------------------------------+ - | checksum | ee1eca47dc88f4879d8a229cc70a07c6 | - | container_format | bare | - | created_at | 2015-10-26T23:40:03Z | - | disk_format | qcow2 | - | file | /v2/images/fcf6fa55-56e9-4402-8137-3e9315c84905/file | - | id | fcf6fa55-56e9-4402-8137-3e9315c84905 | - | min_disk | 0 | - | min_ram | 0 | - | name | cirros | - | owner | 2e3093872ebf4143a122e2cc01a50d13 | - | protected | False | - | schema | /v2/schemas/image | - | size | 13287936 | - | status | active | - | tags | | - | updated_at | 2015-10-26T23:40:03Z | - | virtual_size | None | - | visibility | public | - +------------------+------------------------------------------------------+ - -#. Confirm upload of the image and validate attributes:: - - $ openstack image list - +--------------------------------------+--------+ - | ID | Name | - +--------------------------------------+--------+ - | 38047887-61a7-41ea-9b49-27987d5e8bb9 | cirros | - +--------------------------------------+--------+ - -Next topic: :ref:`openstack_compute`. diff --git a/source/openstack_installing_bundles.rst b/source/openstack_installing_bundles.rst deleted file mode 100644 index 7a963437..00000000 --- a/source/openstack_installing_bundles.rst +++ /dev/null @@ -1,26 +0,0 @@ -.. _openstack_installing_bundles: - -Installing OpenStack* MVP bundles -############################################################ - -Note: This article walks through an OpenStack MVP installation by using -bundles available for Clear Linux* OS for Intel® Architecture. The sample -configuration files that are included would likely require modification -for your environment. - -To install, continue with the following topics: - -* `Database `_ -* `Message queue `_ -* `OpenStack Identity `_ -* `Create OpenStack client environment scripts `_ -* `OpenStack Image `_ -* `OpenStack Compute `_ -* `OpenStack Block Storage `_ -* `OpenStack Dashboard `_ -* `OpenStack Networking `_ -* `OpenStack Orchestration `_ -* `OpenStack Telemetry `_ -* `OpenStack Object Storage `_ - -Next topic: :ref:`openstack_supporting-database`. diff --git a/source/openstack_networking.rst b/source/openstack_networking.rst deleted file mode 100644 index 4d302cea..00000000 --- a/source/openstack_networking.rst +++ /dev/null @@ -1,672 +0,0 @@ -.. _openstack_networking: - -Networking -############################################################ - -OpenStack* Networking allows you to create and attach interface devices -managed by other OpenStack services to networks. Plug-ins can be -implemented to accommodate different networking equipment and software, -providing flexibility to OpenStack architecture and deployment. - -Installing and configuring the controller node ----------------------------------------------- - -Prerequisites -~~~~~~~~~~~~~ - -Before configuring the OpenStack Networking (neutron) service, create a -database, service credentials, and an API endpoint. - -#. Create the database: - - * Use the database access client to connect to the database server - as the ``root`` user:: - - $ mysql -u root -p - - * Create the ``neutron`` database:: - - CREATE DATABASE neutron; - - * Grant proper access to the ``neutron`` database. Replace - *'NEUTRON_DBPASS'* with a suitable password:: - - GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'localhost' \ - IDENTIFIED BY 'NEUTRON_DBPASS'; - GRANT ALL PRIVILEGES ON neutron.* TO 'neutron'@'%' \ - IDENTIFIED BY 'NEUTRON_DBPASS'; - - * Exit the database access client. - -#. Source the ``admin`` credentials to gain access to admin-only CLI commands:: - - $ source admin-openrc.sh - -#. To create the service credentials, complete these steps: - - * Create the ``neutron`` user:: - - $ openstack user create --domain default --password-prompt neutron - User Password: - Repeat User Password: - +-----------+----------------------------------+ - | Field | Value | - +-----------+----------------------------------+ - | domain_id | default | - | enabled | True | - | id | e51ef98012974e5287d857bc709f89d0 | - | name | neutron | - +-----------+----------------------------------+ - - * Add the ``admin`` role to the ``neutron`` user:: - - $ openstack role add --project service --user neutron admin - - Note: This command provides no output. - - * Create the ``neutron`` service entity:: - - $ openstack service create --name neutron \ - --description "OpenStack Networking" network - +-------------+----------------------------------+ - | Field | Value | - +-------------+----------------------------------+ - | description | OpenStack Networking | - | enabled | True | - | id | a56bcd5695b943afba528192acceff01 | - | name | neutron | - | type | network | - +-------------+----------------------------------+ - -#. Create the Networking service API endpoints: - - * :: - - $ openstack endpoint create --region RegionOne \ - network public http://controller:9696 - +--------------+----------------------------------+ - | Field | Value | - +--------------+----------------------------------+ - | enabled | True | - | id | 61a8b881c8654026be84c12b943e4ee3 | - | interface | public | - | region | RegionOne | - | region_id | RegionOne | - | service_id | a56bcd5695b943afba528192acceff01 | - | service_name | neutron | - | service_type | network | - | url | http://controller:9696 | - +--------------+----------------------------------+ - - * :: - - $ openstack endpoint create --region RegionOne \ - network internal http://controller:9696 - +--------------+----------------------------------+ - | Field | Value | - +--------------+----------------------------------+ - | enabled | True | - | id | 83bf338752984e1cb5305b9a6a4b4e67 | - | interface | internal | - | region | RegionOne | - | region_id | RegionOne | - | service_id | a56bcd5695b943afba528192acceff01 | - | service_name | neutron | - | service_type | network | - | url | http://controller:9696 | - +--------------+----------------------------------+ - - * :: - - $ openstack endpoint create --region RegionOne \ - network admin http://controller:9696 - +--------------+----------------------------------+ - | Field | Value | - +--------------+----------------------------------+ - | enabled | True | - | id | 19cfff5a2e9a43298182f8785ea90414 | - | interface | admin | - | region | RegionOne | - | region_id | RegionOne | - | service_id | a56bcd5695b943afba528192acceff01 | - | service_name | neutron | - | service_type | network | - | url | http://controller:9696 | - +--------------+----------------------------------+ - -Installing the Networking components -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Complete the following step to install the Networking components: - -#. Install OpenStack networking bundle:: - - # swupd bundle-add openstack-network - -Configuring the Networking server component -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Complete the following steps to configure the Networking server component: - -#. Custom configurations will be located at ``/etc/neutron/``. - - * Create the ``/etc/neutron`` directory:: - - # mkdir /etc/neutron - - * Create empty neutron configuration file ``/etc/neutron/neutron.conf``:: - - # touch /etc/neutron/neutron.conf - -#. Edit the ``/etc/neutron/neutron.conf`` file: - - * In the ``[database]`` section, configure database access. Replace - *NEUTRON_DBPASS* with the password you chose for the database.:: - - [database] - ... - connection = mysql://neutron:NEUTRON_DBPASS@controller/neutron - - * In the ``[DEFAULT]`` section, enable the Modular Layer 2 (ML2) plug-in, - router service, and overlapping IP addresses:: - - [DEFAULT] - ... - core_plugin = ml2 - service_plugins = router - allow_overlapping_ips = True - - * In the ``[DEFAULT]`` and ``[oslo_messaging_rabbit]`` sections, configure - RabbitMQ message queue access. Replace *RABBIT_PASS* with the password you - chose for the ``openstack`` account in RabbitMQ:: - - [DEFAULT] - ... - rpc_backend = rabbit - - [oslo_messaging_rabbit] - ... - rabbit_host = controller - rabbit_userid = openstack - rabbit_password = RABBIT_PASS - - * In the ``[DEFAULT]`` and ``[keystone_authtoken]`` sections, configure - Identity service access. Replace *NEUTRON_PASS* with the password you - chose for the ``neutron`` user in the Identity service:: - - [DEFAULT] - ... - auth_strategy = keystone - - [keystone_authtoken] - ... - auth_uri = http://controller:5000 - auth_url = http://controller:35357 - auth_plugin = password - project_domain_id = default - user_domain_id = default - project_name = service - username = neutron - password = NEUTRON_PASS - - * In the ``[DEFAULT]`` and ``[nova]`` sections, configure Networking to - notify Compute of network topology changes. Replace *NOVA_PASS* with the - password you chose for the ``nova`` user in the Identity service:: - - [DEFAULT] - ... - notify_nova_on_port_status_changes = True - notify_nova_on_port_data_changes = True - nova_url = http://controller:8774/v2 - - [nova] - ... - auth_url = http://controller:35357 - auth_plugin = password - project_domain_id = default - user_domain_id = default - region_name = RegionOne - project_name = service - username = nova - password = NOVA_PASS - -Configuring the Modular Layer 2 (ML2) plug-in -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The ML2 plug-in uses the Linux bridge mechanism to build layer-2 (bridging and -switching) virtual networking infrastructure for instances. - -#. Custom configuration will be located at ``/etc/neutron/plugins/ml2``. - - * Create the ``/etc/neutron/plugins/ml2`` directory:: - - # mkdir -p /etc/neutron/plugins/ml2 - - * Create empty ML2 configuration file - ``/etc/neutron/plugins/ml2/ml2_conf.ini``:: - - # touch /etc/neutron/plugins/ml2/ml2_conf.ini - -#. Edit the ``/etc/neutron/plugins/ml2/ml2_conf.ini`` file and complete the - following actions: - - * In the ``[ml2]`` section, enable flat, VLAN and VXLAN networks:: - - [ml2] - ... - type_drivers = flat,vlan,vxlan - - * In the ``[ml2]`` section, enable VXLAN project (private) networks:: - - [ml2] - ... - tenant_network_types = vxlan - - * In the ``[ml2]`` section, enable the Linux bridge and layer-2 population - mechanisms:: - - [ml2] - ... - mechanism_drivers = linuxbridge,l2population - - * In the ``[ml2]`` section, enable the port security extension driver:: - - [ml2] - ... - extension_drivers = port_security - - * In the ``[ml2_type_flat]`` section, configure the public flat provider - network:: - - [ml2_type_flat] - ... - flat_networks = public - - * In the [ml2_type_vxlan] section, configure the VXLAN network identifier - range for private networks:: - - [ml2_type_vxlan] - ... - vni_ranges = 1:1000 - - * In the [securitygroup] section, enable ipset to increase efficiency of - security group rules:: - - [securitygroup] - ... - enable_ipset = True - -Configure the Linux bridge agent -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The Linux bridge agent builds layer-2 (bridging and switching) virtual -networking infrastructure for instances including VXLAN tunnels for private -networks and handles security groups. - -#. Custom configuration for Linux bridge agent will be stored in - ``/etc/neutron/plugins/ml2/linuxbridge_agent.ini``:: - - # touch /etc/neutron/plugins/ml2/linuxbridge_agent.ini - -#. Edit the ``/etc/neutron/plugins/ml2/linuxbridge_agent.ini`` file and - complete the following actions: - - * In the ``[linux_bridge]`` section, map the public virtual network to the - public physical network interface. Replace *PUBLIC_INTERFACE_NAME* with - the name of the underlying physical public network interface:: - - [linux_bridge] - physical_interface_mappings = public:PUBLIC_INTERFACE_NAME - - * In the ``[vxlan]`` section, enable VXLAN overlay networks, configure the - IP address of the physical network interface that handles overlay networks, - and enable layer-2 population. Replace *OVERLAY_INTERFACE_IP_ADDRESS* - with the IP address of the underlying physical network interface that - handles overlay networks:: - - [vxlan] - enable_vxlan = True - local_ip = OVERLAY_INTERFACE_IP_ADDRESS - l2_population = True - - * In the ``[agent]`` section, enable ARP spoofing protection:: - - [agent] - ... - prevent_arp_spoofing = True - - * In the ``[securitygroup]`` section, enable security groups and configure - the Linux bridge iptables firewall driver:: - - [securitygroup] - ... - enable_security_group = True - firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver - - -Configure the layer-3 agent -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The Layer-3 (L3) agent provides routing and NAT services for virtual networks. - -#. Custom configuration for the Layer-3 agent will be stored in - ``/etc/neutron/l3_agent.ini``:: - - # touch /etc/neutron/l3_agent.ini - -#. Edit the ``/etc/neutron/l3_agent.ini`` file and complete the following - actions: - - * In the ``[DEFAULT]`` section, configure the Linux bridge interface driver - and external network bridge:: - - [DEFAULT] - ... - interface_driver = neutron.agent.linux.interface.BridgeInterfaceDriver - external_network_bridge = - - Note: The ``external_network_bridge`` option intentionally lacks a value to - enable multiple external networks on a single agent. - -Configure the DHCP agent -~~~~~~~~~~~~~~~~~~~~~~~~ - -The DHCP agent provides DHCP services for virtual networks. - -#. Custom configuration for Linux bridge agent will be stored in - ``/etc/neutron/dhcp_agent.ini``:: - - # touch /etc/neutron/dhcp_agent.ini - -#. Edit the /etc/neutron/dhcp_agent.ini file and complete the following actions: - - * In the ``[DEFAULT]`` section, configure the Linux bridge interface driver, - Dnsmasq DHCP driver, and enable isolated metadata so instances on public - networks can access metadata over the network:: - - [DEFAULT] - ... - interface_driver = neutron.agent.linux.interface.BridgeInterfaceDriver - dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq - enable_isolated_metadata = True - -Configure the metadata agent -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The metadata agent provides configuration information such as credentials to -instances. - -#. Custom configuration for the metadata agent will be stored in - ``/etc/neutron/metadata_agent.ini``:: - - # touch /etc/neutron/metadata_agent.ini - -#. Edit the ``/etc/neutron/metadata_agent.ini`` file and complete the - following actions: - - * In the ``[DEFAULT]`` section, configure access parameters. Replace - *NEUTRON_PASS* with the password you chose for the ``neutron`` user - in the Identity service:: - - [DEFAULT] - ... - auth_uri = http://controller:5000 - auth_url = http://controller:35357 - auth_region = RegionOne - auth_plugin = password - project_domain_id = default - user_domain_id = default - project_name = service - username = neutron - password = NEUTRON_PASS - - * In the ``[DEFAULT]`` section, configure the metadata host:: - - [DEFAULT] - ... - nova_metadata_ip = controller - - * In the ``[DEFAULT]`` section, configure the metadata proxy shared secret - Replace *METADATA_SECRET* with a suitable secret for the metadata proxy:: - - [DEFAULT] - ... - metadata_proxy_shared_secret = METADATA_SECRET - - -Configuring Compute to use Networking -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -#. Edit the ``/etc/nova/nova.conf`` file on the controller node as follows: - - * In the ``[neutron]`` section, configure access parameters, enable the - metadata proxy, and configure the secret. - - Replace *NEUTRON_PASS* with the password you chose for the ``neutron`` - user in the Identity service. - - Replace *METADATA_SECRET* with the secret you chose for the metadata - proxy:: - - [neutron] - ... - url = http://controller:9696 - auth_url = http://controller:35357 - auth_plugin = password - project_domain_id = default - user_domain_id = default - region_name = RegionOne - project_name = service - username = neutron - password = NEUTRON_PASS - - service_metadata_proxy = True - metadata_proxy_shared_secret = METADATA_SECRET - -Finalizing installation -~~~~~~~~~~~~~~~~~~~~~~~~ - -#. The Networking service initialization scripts expect a symbolic link - ``/etc/neutron/plugin.ini`` pointing to the ML2 plug-in configuration - file, ``/etc/neutron/plugins/ml2/ml2_conf.ini``. If this symbolic - link does not exist, create it using the following command:: - - # ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini - -#. Ensure files have proper ownership by running the following command:: - - # systemctl restart update-triggers.target - -#. Populate the database:: - - # su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron.conf \ - --config-file /etc/neutron/plugins/ml2/ml2_conf.ini upgrade head" neutron - -#. Restart the Compute services:: - - # systemctl restart uwsgi@nova-api.service nova-scheduler.service nova-conductor.service - -#. Start the Networking service and configure it to start when the - system boots:: - - # systemctl enable neutron-server.service \ - neutron-linuxbridge-agent.service \ - neutron-dhcp-agent.service \ - neutron-metadata-agent.service \ - neutron-l3-agent.service - # systemctl start neutron-server.service \ - neutron-linuxbridge-agent.service \ - neutron-dhcp-agent.service \ - neutron-metadata-agent.service \ - neutron-l3-agent.service - -Install and configure compute node ----------------------------------- - -Install the components -~~~~~~~~~~~~~~~~~~~~~~ - -* Install OpenStack networking bundle:: - - # swupd bundle-add openstack-network - -Configure the common component -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -#. Edit the ``/etc/neutron/neutron.conf`` file and complete the following - actions: - - * In the ``[DEFAULT]`` and ``[oslo_messaging_rabbit]`` sections, configure - RabbitMQ message queue access. Replace *RABBIT_PASS* with the password you - chose for the openstack account in RabbitMQ.:: - - [DEFAULT] - ... - rpc_backend = rabbit - - [oslo_messaging_rabbit] - ... - rabbit_host = controller - rabbit_userid = openstack - rabbit_password = RABBIT_PASS - - * In the ``[DEFAULT]`` and ``[keystone_authtoken]`` sections, configure - Identity service access. Replace *NEUTRON_PASS* with the password you chose - for the ``neutron`` user in the Identity service:: - - [DEFAULT] - ... - auth_strategy = keystone - - [keystone_authtoken] - ... - auth_uri = http://controller:5000 - auth_url = http://controller:35357 - auth_plugin = password - project_domain_id = default - user_domain_id = default - project_name = service - username = neutron - password = NEUTRON_PASS - -Configure the Linux bridge agent -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -#. Edit the ``/etc/neutron/plugins/ml2/linuxbridge_agent.ini`` file and complete - the following actions: - - * In the ``[linux_bridge]`` section, map the public virtual network to the - public physical network interface:: - - [linux_bridge] - physical_interface_mappings = public:PUBLIC_INTERFACE_NAME - - * In the ``[vxlan]`` section, enable VXLAN overlay networks, configure the - IP address of the physical network interface that handles overlay - networks, and enable layer-2 population:: - - [vxlan] - enable_vxlan = True - local_ip = OVERLAY_INTERFACE_IP_ADDRESS - l2_population = True - - * In the ``[agent]`` section, enable ARP spoofing protection:: - - [agent] - ... - prevent_arp_spoofing = True - - * In the ``[securitygroup]`` section, enable security groups and configure - the Linux bridge iptables firewall driver:: - - [securitygroup] - ... - enable_security_group = True - firewall_driver = neutron.agent.linux.iptables_firewall.IptablesFirewallDriver - -Configure Compute to use Networking -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -#. Edit the ``/etc/nova/nova.conf`` file and complete the following actions: - - * In the ``[neutron]`` section, configure access parameters. Replace - *NEUTRON_PASS* with the password you chose for the ``neutron`` user in - the Identity service.:: - - [neutron] - ... - url = http://controller:9696 - auth_url = http://controller:35357 - auth_plugin = password - project_domain_id = default - user_domain_id = default - region_name = RegionOne - project_name = service - username = neutron - password = NEUTRON_PASS - -Finalize installation -~~~~~~~~~~~~~~~~~~~~~ - -#. Restart the Compute service:: - - # systemctl restart nova-compute.service - -#. Restart the Linux bridge agent:: - - # systemctl enable neutron-linuxbridge-agent.service - # systemctl restart neutron-linuxbridge-agent.service - -Verify Operation ----------------- - -#. Source the ``admin`` credentials to gain access to admin-only CLI commands:: - - $ source admin-openrc.sh - -#. List loaded extensions to verify successful launch of the neutron-server - process:: - - $ neutron ext-list - +-----------------------+-----------------------------------------------+ - | alias | name | - +-----------------------+-----------------------------------------------+ - | dns-integration | DNS Integration | - | address-scope | Address scope | - | ext-gw-mode | Neutron L3 Configurable external gateway mode | - | binding | Port Binding | - | agent | agent | - | subnet_allocation | Subnet Allocation | - | l3_agent_scheduler | L3 Agent Scheduler | - | external-net | Neutron external network | - | flavors | Neutron Service Flavors | - | net-mtu | Network MTU | - | quotas | Quota management support | - | l3-ha | HA Router extension | - | provider | Provider Network | - | multi-provider | Multi Provider Network | - | extraroute | Neutron Extra Route | - | router | Neutron L3 Router | - | extra_dhcp_opt | Neutron Extra DHCP opts | - | security-group | security-group | - | dhcp_agent_scheduler | DHCP Agent Scheduler | - | rbac-policies | RBAC Policies | - | port-security | Port Security | - | allowed-address-pairs | Allowed Address Pairs | - | dvr | Distributed Virtual Router | - +-----------------------+-----------------------------------------------+ - -#. List agents to verify successful launch of the neutron agents:: - - $ neutron agent-list - +--------------------------------------+--------------------+------------+-------+----------------+---------------------------+ - | id | agent_type | host | alive | admin_state_up | binary | - +--------------------------------------+--------------------+------------+-------+----------------+---------------------------+ - | 08905043-5010-4b87-bba5-aedb1956e27a | Linux bridge agent | compute1 | :-) | True | neutron-linuxbridge-agent | - | 27eee952-a748-467b-bf71-941e89846a92 | Linux bridge agent | controller | :-) | True | neutron-linuxbridge-agent | - | 830344ff-dc36-4956-84f4-067af667a0dc | L3 agent | controller | :-) | True | neutron-l3-agent | - | dd3644c9-1a3a-435a-9282-eb306b4b0391 | DHCP agent | controller | :-) | True | neutron-dhcp-agent | - | f49a4b81-afd6-4b3d-b923-66c8f0517099 | Metadata agent | controller | :-) | True | neutron-metadata-agent | - +--------------------------------------+--------------------+------------+-------+----------------+---------------------------+ - -Next topic: :ref:`openstack_orchestration`. diff --git a/source/openstack_object_storage.rst b/source/openstack_object_storage.rst deleted file mode 100644 index 75452069..00000000 --- a/source/openstack_object_storage.rst +++ /dev/null @@ -1,772 +0,0 @@ -.. _openstack_object_storage: - -OpenStack* Object Storage -######################### - -The OpenStack Object Storage services (swift) work together to provide -object storage and retrieval through a REST API. Your environment must -at least include the Identity service (keystone) prior to deploying Object Storage. - -OpenStack Object Storage ------------------------- - -The OpenStack Object Storage is a multi-tenant object storage system. -It is highly scalable and can manage large amounts of unstructured data -at low cost through a RESTful HTTP API. - -It includes the following components: - -**Proxy servers (swift-proxy-server)** - Accepts OpenStack Object Storage API and raw HTTP requests to upload files, modify metadata, - and create containers. It also serves file or container listings to web browsers. To improve performance, - the proxy server can use an optional cache that is usually deployed with memcache. - -**Account servers (swift-account-server)** - Manages accounts defined with Object Storage. - -**Container servers (swift-container-server)** - Manages the mapping of containers or folders, within Object Storage. - -**Object servers (swift-object-server)** - Manages actual objects, such as files, on the storage nodes. - -**Various periodic processes** - Performs housekeeping tasks on the large data store. The replication - services ensure consistency and availability through the cluster. - Other periodic processes include auditors, updaters, and reapers. - -**WSGI middleware** - Handles authentication and is usually OpenStack Identity. - -**swift client** - Enables users to submit commands to the REST API through a - command-line client authorized as either a admin user, reseller user, or swift user. - -**swift-init** - Script that initializes the building of the ring file, takes daemon - names as parameter and offers commands. Documented in - http://docs.openstack.org/developer/swift/admin_guide.html#managing-services. - -**swift-recon** - A cli tool used to retrieve various metrics and telemetry information - about a cluster that has been collected by the swift-recon middleware. - -**swift-ring-builder** - Storage ring build and rebalance utility. Documented in - http://docs.openstack.org/developer/swift/admin_guide.html#managing-the-rings. - -Install and configure the controller node ------------------------------------------ - -This section describes how to install and configure the proxy service -that handles requests for the account, container, and object services -operating on the storage nodes. For simplicity, this guide installs and -configures the proxy service on the controller node. However, you can -run the proxy service on any node with network connectivity to the -storage nodes. Additionally, you can install and configure the proxy -service on multiple nodes to increase performance and redundancy. - -To configure prerequisites -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The proxy service relies on an authentication and authorization -mechanism such as the Identity service. However, unlike other services, -it also offers an internal mechanism that allows it to operate without -any other OpenStack* services. However, for simplicity, this guide -references the Identity service. Before you configure the Object Storage -service, you must create service credentials and an API endpoint. - -#. Source the ``admin`` credentials to gain access to admin-only CLI - commands:: - - $ source admin-openrc.sh - -#. To create the Identity service credentials, complete these steps: - - * Create the ``swift`` user:: - - $ openstack user create --domain default --password-prompt swift - User Password: - Repeat User Password: - +-----------+----------------------------------+ - | Field | Value | - +-----------+----------------------------------+ - | domain_id | default | - | enabled | True | - | id | d535e5cbd2b74ac7bfb97db9cced3ed6 | - | name | swift | - +-----------+----------------------------------+ - - * Add the admin role to the ``swift`` user:: - - $ openstack role add --project service --user swift admin - - * Create the ``swift`` service entity:: - - $ openstack service create --name swift \ - --description "OpenStack Object Storage" object-store - +-------------+----------------------------------+ - | Field | Value | - +-------------+----------------------------------+ - | description | OpenStack Object Storage | - | enabled | True | - | id | 75ef509da2c340499d454ae96a2c5c34 | - | name | swift | - | type | object-store | - +-------------+----------------------------------+ - -#. Create the Object Storage service API endpoint:: - - $ openstack endpoint create --region RegionOne \ - object-store public http://controller:8080/v1/AUTH_%\(tenant_id\)s - +--------------+----------------------------------------------+ - | Field | Value | - +--------------+----------------------------------------------+ - | enabled | True | - | id | 12bfd36f26694c97813f665707114e0d | - | interface | public | - | region | RegionOne | - | region_id | RegionOne | - | service_id | 75ef509da2c340499d454ae96a2c5c34 | - | service_name | swift | - | service_type | object-store | - | url | http://controller:8080/v1/AUTH_%(tenant_id)s | - +--------------+----------------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - object-store internal http://controller:8080/v1/AUTH_%\(tenant_id\)s - +--------------+----------------------------------------------+ - | Field | Value | - +--------------+----------------------------------------------+ - | enabled | True | - | id | 7a36bee6733a4b5590d74d3080ee6789 | - | interface | internal | - | region | RegionOne | - | region_id | RegionOne | - | service_id | 75ef509da2c340499d454ae96a2c5c34 | - | service_name | swift | - | service_type | object-store | - | url | http://controller:8080/v1/AUTH_%(tenant_id)s | - +--------------+----------------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - object-store admin http://controller:8080/v1 - +--------------+----------------------------------+ - | Field | Value | - +--------------+----------------------------------+ - | enabled | True | - | id | ebb72cd6851d4defabc0b9d71cdca69b | - | interface | admin | - | region | RegionOne | - | region_id | RegionOne | - | service_id | 75ef509da2c340499d454ae96a2c5c34 | - | service_name | swift | - | service_type | object-store | - | url | http://controller:8080/v1 | - +--------------+----------------------------------+ - -To install and configure the controller node components -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -#. Install OpenStack Object Storage bundle:: - - # swupd bundle-add openstack-object-storage - # swupd verify --fix - -#. Create the directory ``/etc/swift`` if does not exist:: - - # mkdir /etc/swift - -#. Copy the sample proxy-server config file to the configuration - directory:: - - # cp /usr/share/defaults/swift/proxy-server.conf /etc/swift - -#. Edit the ``/etc/swift/proxy-server.conf`` file and complete the - following actions: - - * In the ``[pipeline:main]`` section, enable the appropriate - modules:: - - [pipeline:main] - pipeline = catch_errors gatekeeper healthcheck proxy-logging cache container_sync bulk ratelimit authtoken keystoneauth container-quotas account-quotas slo dlo versioned_writes proxy-logging proxy-server - - * In the ``[app:proxy-server]`` section, enable automatic account - creation:: - - [app:proxy-server] - ... - account_autocreate = true - - * In the ``[filter:keystoneauth]`` section, configure the operator - roles:: - - [filter:keystoneauth] - use = egg:swift#keystoneauth - ... - operator_roles = admin,user - - * In the ``[filter:authtoken]`` section, configure Identity service - access. Replace *SWIFT_PASS* with the password you chose for the - ``swift`` user in the Identity service:: - - [filter:authtoken] - paste.filter_factory = keystonemiddleware.auth_token:filter_factory - ... - auth_uri = http://controller:5000 - auth_url = http://controller:35357 - auth_plugin = password - project_domain_id = default - user_domain_id = default - project_name = service - username = swift - password = SWIFT_PASS - delay_auth_decision = true - - * In the ``[filter:cache]`` section, configure the ``memcached`` - location:: - - [filter:cache] - ... - memcache_servers = 127.0.0.1:11211 - -Install and configure the storage nodes ---------------------------------------- - -This section describes how to install and configure storage nodes that -operate the account, container, and object services. For simplicity, -this configuration references two storage nodes, each containing two -empty local block storage devices. Each of the devices, ``/dev/sdb`` and -``/dev/sdc``, must contain a suitable partition table with one partition -occupying the entire device. - -Although the Object Storage service -supports any file system with extended attributes (xattr), testing and -benchmarking indicate the best performance and reliability on XFS. - -To configure prerequisites -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You must configure each storage node before you install and configure -the Object Storage service on it. Similar to the controller node, each -storage node contains one network interface on the management network. -Optionally, each storage node can contain a second network interface on -a separate network for replication. - -#. Configure unique items on the first storage node: - - * Configure the management interface:: - - IP address: 10.0.0.51 - Network mask: 255.255.255.0 (or /24) - Default gateway: 10.0.0.1 - - * Set the hostname of the node to ``object1``. - -#. Configure unique items on the second storage node: - - * Configure the management interface:: - - IP address: 10.0.0.52 - Network mask: 255.255.255.0 (or /24) - Default gateway: 10.0.0.1 - - * Set the hostname of the node to ``object2``. - -#. Configure shared items on both storage nodes: - - * Copy the contents of ``/etc/hosts`` file from ``controller`` node to ``storage`` nodes and add the - following :: - - # object1 - 10.0.0.51 object1 - # object2 - 10.0.0.52 object2 - -#. Install the OpenStack Object Storage bundle:: - - # swupd bundle-add openstack-object-storage - # swupd verify --fix - -#. Format the ``/dev/sdb1`` and ``/dev/sdc1`` partitions as XFS:: - - # mkfs.xfs /dev/sdb1 - # mkfs.xfs /dev/sdc1 - -#. Create the mount point directory structure:: - - # mkdir -p /srv/node/sdb1 - # mkdir -p /srv/node/sdc1 - -#. Edit the ``/etc/fstab`` file and add the following to it:: - - /dev/sdb1 /srv/node/sdb1 xfs noatime,nodiratime,nobarrier,logbufs=8 0 2 - /dev/sdc1 /srv/node/sdc1 xfs noatime,nodiratime,nobarrier,logbufs=8 0 2 - -#. Mount the devices:: - - # mount /srv/node/sdb1 - # mount /srv/node/sdc1 - -#. Edit the ``/etc/rsyncd.conf`` file and add the following to it:: - - uid = swift - gid = swift - log file = /var/log/rsyncd.log - pid file = /var/run/rsyncd.pid - address = MANAGEMENT_INTERFACE_IP_ADDRESS - - [account] - max connections = 2 - path = /srv/node/ - read only = false - lock file = /var/lock/account.lock - - [container] - max connections = 2 - path = /srv/node/ - read only = false - lock file = /var/lock/container.lock - - [object] - max connections = 2 - path = /srv/node/ - read only = false - lock file = /var/lock/object.lock - - Replace *MANAGEMENT_INTERFACE_IP_ADDRESS* with the IP address of - the management network on the storage node. - - Note: The ``rsync`` service requires no authentication, so consider - running it on a private network. - -#. Start the ``rsyncd`` service and configure it to start when the - system boots:: - - # systemctl enable rsyncd.service - # systemctl start rsyncd.service - -Install and configure storage node components -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -#. Copy the accounting, container, object, container-reconciler, and - object-expirer service configuration files to the configuration - directory:: - - # cp /usr/share/defaults/swift/account-server.conf /etc/swift - # cp /usr/share/defaults/swift/container-server.conf /etc/swift - # cp /usr/share/defaults/swift/object-server.conf /etc/swift - # cp /usr/share/defaults/swift/container-reconciler.conf /etc/swift - # cp /usr/share/defaults/swift/object-expirer.conf /etc/swift - -#. Edit the ``/etc/swift/account-server.conf`` file and complete the - following actions: - - * In the ``[DEFAULT]`` section, configure the bind IP address and - mount point directory:: - - [DEFAULT] - ... - bind_ip = MANAGEMENT_INTERFACE_IP_ADDRESS - devices = /srv/node - - Replace *MANAGEMENT_INTERFACE_IP_ADDRESS* with the IP - address of the management network on the storage node. - - * In the ``[pipeline:main]`` section, enable the appropriate - modules:: - - [pipeline:main] - pipeline = healthcheck recon account-server - - * In the ``[filter:recon]`` section, configure the ``recon`` (metrics) - cache directory:: - - [filter:recon] - ... - recon_cache_path = /var/cache/swift - -#. Edit the ``/etc/swift/container-server.conf`` file and complete the - following actions: - - * In the ``[DEFAULT]`` section, configure the bind IP address and - mount point directory:: - - [DEFAULT] - ... - bind_ip = MANAGEMENT_INTERFACE_IP_ADDRESS - devices = /srv/node - - Replace *MANAGEMENT_INTERFACE_IP_ADDRESS* with the IP - address of the management network on the storage node. - - * In the ``[pipeline:main]`` section, enable the appropriate modules:: - - [pipeline:main] - pipeline = healthcheck recon container-server - - * In the ``[filter:recon]`` section, configure the recon (metrics) - cache directory:: - - [filter:recon] - ... - recon_cache_path = /var/cache/swift - -#. Edit the ``/etc/swift/object-server.conf`` file and complete the - following actions: - - * In the ``[DEFAULT]`` section, configure the bind IP address and - mount point directory:: - - [DEFAULT] - ... - bind_ip = MANAGEMENT_INTERFACE_IP_ADDRESS - devices = /srv/node - - Replace *MANAGEMENT_INTERFACE_IP_ADDRESS* with the IP - address of the management network on the storage node. - - * In the ``[pipeline:main]`` section, enable the appropriate - modules:: - - [pipeline:main] - pipeline = healthcheck recon object-server - - * In the ``[filter:recon]`` section, configure the ``recon`` (metrics) - cache and lock directories:: - - [filter:recon] - ... - recon_cache_path = /var/cache/swift - recon_lock_path = /var/lock - -#. Ensure proper ownership of the mount point directory structure:: - - # systemctl restart update-triggers.target - -About creating initial rings ----------------------------- - -Before starting the Object Storage services, you must create the initial -account, container, and object rings. The ring builder creates -configuration files that each node uses to determine and deploy the -storage architecture. For simplicity, this guide uses one region and -zone with 2^10 (1024) maximum partitions, 3 replicas of each object, and -1 hour minimum time between moving a partition more than once. For -Object Storage, a partition indicates a directory on a storage device -rather than a conventional partition table. - -Create Account Ring -------------------- - -The account server uses the account ring to maintain lists of -containers. - -To create the ring -~~~~~~~~~~~~~~~~~~ - -#. Create the base ``account.builder`` file:: - - # swift-ring-builder account.builder create 10 3 1 - -#. Add each storage node to the ring:: - - # swift-ring-builder account.builder \ - add --region 1 --zone 1 --ip STORAGE_NODE_MANAGEMENT_INTERFACE_IP_ADDRESS --port 6002 \ - --device DEVICE_NAME --weight DEVICE_WEIGHT - - Replace *STORAGE_NODE_MANAGEMENT_INTERFACE_IP_ADDRESS* with the - IP address of the management network on the storage node. Replace - *DEVICE_NAME* with a storage device name on the same storage node. - For example, using the first storage node with the ``/dev/sdb1`` storage - device and weight of 100:: - - # swift-ring-builder account.builder add \ - --region 1 --zone 1 --ip 10.0.0.51 --port 6002 --device sdb --weight 100 - - Repeat this command for each storage device on each storage node. In - the example architecture, use the command in four variations:: - - # swift-ring-builder account.builder add \ - --region 1 --zone 1 --ip 10.0.0.51 --port 6002 --device sdb --weight 100 - Device d0r1z1-10.0.0.51:6002R10.0.0.51:6002/sdb_"" with 100.0 weight got id 0 - # swift-ring-builder account.builder add \ - --region 1 --zone 2 --ip 10.0.0.51 --port 6002 --device sdc --weight 100 - Device d1r1z2-10.0.0.51:6002R10.0.0.51:6002/sdc_"" with 100.0 weight got id 1 - # swift-ring-builder account.builder add \ - --region 1 --zone 3 --ip 10.0.0.52 --port 6002 --device sdb --weight 100 - Device d2r1z3-10.0.0.52:6002R10.0.0.52:6002/sdb_"" with 100.0 weight got id 2 - # swift-ring-builder account.builder add \ - --region 1 --zone 4 --ip 10.0.0.52 --port 6002 --device sdc --weight 100 - Device d3r1z4-10.0.0.52:6002R10.0.0.52:6002/sdc_"" with 100.0 weight got id 3 - -#. Verify the ring contents:: - - # swift-ring-builder account.builder - account.builder, build version 4 - 1024 partitions, 3.000000 replicas, 1 regions, 4 zones, 4 devices, 100.00 balance, 0.00 dispersion - The minimum number of hours before a partition can be reassigned is 1 - The overload factor is 0.00% (0.000000) - Devices: id region zone ip address port replication ip replication port name weight partitions balance meta - 0 1 1 10.0.0.51 6002 10.0.0.51 6002 sdb 100.00 0 -100.00 - 1 1 2 10.0.0.51 6002 10.0.0.51 6002 sdc 100.00 0 -100.00 - 2 1 3 10.0.0.52 6002 10.0.0.52 6002 sdb 100.00 0 -100.00 - 3 1 4 10.0.0.52 6002 10.0.0.52 6002 sdc 100.00 0 -100.00 - -#. Rebalance the ring:: - - # swift-ring-builder account.builder rebalance - Reassigned 1024 (100.00%) partitions. Balance is now 0.00. Dispersion is now 0.00 - -Create Container Ring ---------------------- - -The container server uses the container ring to maintain lists of -objects. However, it does not track object locations. - -To create the ring -~~~~~~~~~~~~~~~~~~ - -#. Create the base ``container.builder`` file:: - - # swift-ring-builder container.builder create 10 3 1 - -#. Add each storage node to the ring:: - - # swift-ring-builder container.builder \ - add --region 1 --zone 1 --ip STORAGE_NODE_MANAGEMENT_INTERFACE_IP_ADDRESS --port 6001 \ - --device DEVICE_NAME --weight DEVICE_WEIGHT - - Replace *STORAGE_NODE_MANAGEMENT_INTERFACE_IP_ADDRESS* with the - IP address of the management network on the storage node. Replace - *DEVICE_NAME* with a storage device name on the same storage node. - For example, using the first storage node with the ``/dev/sdb1`` storage - device and weight of 100:: - - # swift-ring-builder container.builder add \ - --region 1 --zone 1 --ip 10.0.0.51 --port 6001 --device sdb --weight 100 - - Repeat this command for each storage device on each storage node. In - the example architecture, use the command in four variations:: - - # swift-ring-builder container.builder add \ - --region 1 --zone 1 --ip 10.0.0.51 --port 6001 --device sdb --weight 100 - Device d0r1z1-10.0.0.51:6001R10.0.0.51:6001/sdb_"" with 100.0 weight got id 0 - # swift-ring-builder container.builder add \ - --region 1 --zone 2 --ip 10.0.0.51 --port 6001 --device sdc --weight 100 - Device d1r1z2-10.0.0.51:6001R10.0.0.51:6001/sdc_"" with 100.0 weight got id 1 - # swift-ring-builder container.builder add \ - --region 1 --zone 3 --ip 10.0.0.52 --port 6001 --device sdb --weight 100 - Device d2r1z3-10.0.0.52:6001R10.0.0.52:6001/sdb_"" with 100.0 weight got id 2 - # swift-ring-builder container.builder add \ - --region 1 --zone 4 --ip 10.0.0.52 --port 6001 --device sdc --weight 100 - Device d3r1z4-10.0.0.52:6001R10.0.0.52:6001/sdc_"" with 100.0 weight got id 3 - -#. Verify the ring contents:: - - # swift-ring-builder container.builder - container.builder, build version 4 - 1024 partitions, 3.000000 replicas, 1 regions, 4 zones, 4 devices, 100.00 balance, 0.00 dispersion - The minimum number of hours before a partition can be reassigned is 1 - The overload factor is 0.00% (0.000000) - Devices: id region zone ip address port replication ip replication port name weight partitions balance meta - 0 1 1 10.0.0.51 6001 10.0.0.51 6001 sdb 100.00 0 -100.00 - 1 1 2 10.0.0.51 6001 10.0.0.51 6001 sdc 100.00 0 -100.00 - 2 1 3 10.0.0.52 6001 10.0.0.52 6001 sdb 100.00 0 -100.00 - 3 1 4 10.0.0.52 6001 10.0.0.52 6001 sdc 100.00 0 -100.00 - -#. Rebalance the ring:: - - # swift-ring-builder container.builder rebalance - Reassigned 1024 (100.00%) partitions. Balance is now 0.00. Dispersion is now 0.00 - -Create Object Ring ------------------- - -The object server uses the object ring to maintain lists of object -locations on local devices. - -To create the ring -~~~~~~~~~~~~~~~~~~ - -#. Create the base ``object.builder`` file:: - - # swift-ring-builder object.builder create 10 3 1 - -#. Add each storage node to the ring:: - - # swift-ring-builder object.builder \ - add --region 1 --zone 1 --ip STORAGE_NODE_MANAGEMENT_INTERFACE_IP_ADDRESS --port 6000 \ - --device DEVICE_NAME --weight DEVICE_WEIGHT - - Replace *STORAGE_NODE_MANAGEMENT_INTERFACE_IP_ADDRESS* with the - IP address of the management network on the storage node. Replace - *DEVICE_NAME* with a storage device name on the same storage node. - For example, using the first storage node with the ``/dev/sdb1`` storage - device and weight of 100:: - - # swift-ring-builder object.builder add \ - --region 1 --zone 1 --ip 10.0.0.51 --port 6000 --device sdb --weight 100 - - Repeat this command for each storage device on each storage node. In - the example architecture, use the command in four variations:: - - # swift-ring-builder object.builder add \ - --region 1 --zone 1 --ip 10.0.0.51 --port 6000 --device sdb --weight 100 - Device d0r1z1-10.0.0.51:6000R10.0.0.51:6000/sdb_"" with 100.0 weight got id 0 - # swift-ring-builder object.builder add \ - --region 1 --zone 2 --ip 10.0.0.51 --port 6000 --device sdc --weight 100 - Device d1r1z2-10.0.0.51:6000R10.0.0.51:6000/sdc_"" with 100.0 weight got id 1 - # swift-ring-builder object.builder add \ - --region 1 --zone 3 --ip 10.0.0.52 --port 6000 --device sdb --weight 100 - Device d2r1z3-10.0.0.52:6000R10.0.0.52:6000/sdb_"" with 100.0 weight got id 2 - # swift-ring-builder object.builder add \ - --region 1 --zone 4 --ip 10.0.0.52 --port 6000 --device sdc --weight 100 - Device d3r1z4-10.0.0.52:6000R10.0.0.52:6000/sdc_"" with 100.0 weight got id 3 - -#. Verify the ring contents:: - - # swift-ring-builder object.builder - object.builder, build version 4 - 1024 partitions, 3.000000 replicas, 1 regions, 4 zones, 4 devices, 100.00 balance, 0.00 dispersion - The minimum number of hours before a partition can be reassigned is 1 - The overload factor is 0.00% (0.000000) - Devices: id region zone ip address port replication ip replication port name weight partitions balance meta - 0 1 1 10.0.0.51 6000 10.0.0.51 6000 sdb 100.00 0 -100.00 - 1 1 2 10.0.0.51 6000 10.0.0.51 6000 sdc 100.00 0 -100.00 - 2 1 3 10.0.0.52 6000 10.0.0.52 6000 sdb 100.00 0 -100.00 - 3 1 4 10.0.0.52 6000 10.0.0.52 6000 sdc 100.00 0 -100.00 - -#. Rebalance the ring:: - - # swift-ring-builder object.builder rebalance - Reassigned 1024 (100.00%) partitions. Balance is now 0.00. Dispersion is now 0.00 - -Distribute ring configuration files -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Copy the ``account.ring.gz``, ``container.ring.gz``, and ``object.ring.gz`` files to -the ``/etc/swift`` directory on each storage node and any additional nodes -running the proxy service:: - - # cp account.ring.gz container.ring.gz object.ring.gz /etc/swift/ - -Finalize installation ---------------------- - -Configure hashes and default storage policy -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -#. Copy the swift service configuration file to the configuration directory:: - - # cp /usr/share/defaults/swift/swift.conf /etc/swift - -#. Edit the ``/etc/swift/swift.conf`` file and complete the following - actions: - - * In the ``[swift-hash]`` section, configure the hash path prefix and - suffix for your environment. Replace *HASH_PATH_PREFIX* and - *HASH_PATH_SUFFIX* with unique values.:: - - [swift-hash] - ... - swift_hash_path_suffix = HASH_PATH_PREFIX - swift_hash_path_prefix = HASH_PATH_SUFFIX - - * In the ``[storage-policy:0]`` section, configure the default storage - policy:: - - [storage-policy:0] - ... - name = Policy-0 - default = yes - -#. Copy the ``swift.conf`` file to the ``/etc/swift`` directory on each storage - node and any additional nodes running the proxy service. -#. On all nodes, ensure proper ownership of the configuration directory:: - - # systemctl restart update-triggers.target - -#. On the controller node and any other nodes running the proxy service, - start the Object Storage proxy service including its dependencies and - configure them to start when the system boots:: - - # systemctl enable swift-proxy.service memcached.service - # systemctl start swift-proxy.service memcached.service - -#. On the storage nodes, start the Object Storage services and configure - them to start when the system boots:: - - # systemctl enable swift-account.service \ - swift-account-auditor.service \ - swift-account-reaper.service \ - swift-account-replicator.service \ - swift-container.service \ - swift-container-auditor.service \ - swift-container-replicator.service \ - swift-container-updater.service \ - swift-object.service \ - swift-object-auditor.service \ - swift-object-replicator.service \ - swift-object-updater.service - # systemctl start swift-account.service \ - swift-account-auditor.service \ - swift-account-reaper.service \ - swift-account-replicator.service \ - swift-container.service \ - swift-container-auditor.service \ - swift-container-replicator.service \ - swift-container-updater.service \ - swift-object.service \ - swift-object-auditor.service \ - swift-object-replicator.service \ - swift-object-updater.service - -Verify operation ----------------- - -Verify operation of the Object Storage service. - -#. In each client environment script, configure the Object Storage service client to use the Identity API version 3:: - - $ echo "export OS_AUTH_VERSION=3" \ - | tee -a admin-openrc.sh demo-openrc.sh - -#. Source the demo credentials:: - - $ source demo-openrc.sh - -#. Show the service status:: - - $ swift stat - Account: AUTH_ed0b60bf607743088218b0a533d5943f - Containers: 0 - Objects: 0 - Bytes: 0 - Containers in policy "policy-0": 0 - Objects in policy "policy-0": 0 - Bytes in policy "policy-0": 0 - X-Account-Project-Domain-Id: default - X-Timestamp: 1444143887.71539 - X-Trans-Id: tx1396aeaf17254e94beb34-0056143bde - Content-Type: text/plain; charset=utf-8 - Accept-Ranges: bytes - -#. Upload a test file:: - - $ swift upload container1 FILE - FILE - -Replace *FILE* with the name of a local file to upload to the ``container1`` container. - -#. List containers:: - - $ swift list - container1 - -#. Download a test file:: - - $ swift download container1 FILE - FILE [auth 0.295s, headers 0.339s, total 0.339s, 0.005 MB/s] - - Replace *FILE* with the name of the file uploaded to the ``container1`` container. diff --git a/source/openstack_orchestration.rst b/source/openstack_orchestration.rst deleted file mode 100644 index b047c2b0..00000000 --- a/source/openstack_orchestration.rst +++ /dev/null @@ -1,393 +0,0 @@ -.. _openstack_orchestration: - -Orchestration -############################################################ - -The OpenStack* Orchestration service provides a template-based orchestration for -describing a cloud application by running OpenStack API calls to generate -running cloud applications. The software integrates other core components of -OpenStack into a one-file template system. - -The templates allow you to create most OpenStack resource types, such as -instances, floating IPs, volumes, security groups and users. It also provides -advanced functionality, such as instance high availability, instance -auto-scaling, and nested stacks. This enables OpenStack core projects to -receive a larger user base. - -Installing and configuring controller node ------------------------------------------- - -This section describes how to install and configure the Orchestration -service, codenamed heat, on the controller node. - -Configuring prerequisites -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Before you install and configure Orchestration, 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:: - - $ mysql -u root -p - - * Create the ``heat`` database:: - - CREATE DATABASE heat; - - * Grant proper access to the ``heat`` database. Replace *HEAT_DBPASS*   - with a suitable password:: - - GRANT ALL PRIVILEGES ON heat.* TO 'heat'@'localhost' \ - IDENTIFIED BY 'HEAT_DBPASS'; - GRANT ALL PRIVILEGES ON heat.* TO 'heat'@'%' \ - IDENTIFIED BY 'HEAT_DBPASS'; - - * Exit the database access client. - -#. Source the ``admin`` credentials to gain access to admin-only CLI - commands:: - - $ source admin-openrc.sh - -#. To create the service credentials, complete these steps: - - * Create the ``heat`` user:: - - $ openstack user create --domain default --password-prompt heat - User Password: - Repeat User Password: - +-----------+----------------------------------+ - | Field | Value | - +-----------+----------------------------------+ - | domain_id | default | - | enabled | True | - | id | ca2e175b851943349be29a328cc5e360 | - | name | heat | - +-----------+----------------------------------+ - - * Add the ``admin`` role to the ``heat`` user:: - - $ openstack role add --project service --user heat admin - - * Create the ``heat`` and ``heat-cfn`` service entities:: - - $ openstack service create --name heat \ - --description "Orchestration" orchestration - +-------------+----------------------------------+ - | Field | Value | - +-------------+----------------------------------+ - | description | Orchestration | - | enabled | True | - | id | 727841c6f5df4773baa4e8a5ae7d72eb | - | name | heat | - | type | orchestration | - +-------------+----------------------------------+ - - $ openstack service create --name heat-cfn \ - --description "Orchestration" cloudformation - +-------------+----------------------------------+ - | Field | Value | - +-------------+----------------------------------+ - | description | Orchestration | - | enabled | True | - | id | c42cede91a4e47c3b10c8aedc8d890c6 | - | name | heat-cfn | - | type | cloudformation | - +-------------+----------------------------------+ - -#. Create the Orchestration service API endpoints:: - - $ openstack endpoint create --region RegionOne \ - orchestration public http://controller:8004/v1/%\(tenant_id\)s - +--------------+-----------------------------------------+ - | Field | Value | - +--------------+-----------------------------------------+ - | enabled | True | - | id | 3f4dab34624e4be7b000265f25049609 | - | interface | public | - | region | RegionOne | - | region_id | RegionOne | - | service_id | 727841c6f5df4773baa4e8a5ae7d72eb | - | service_name | heat | - | service_type | orchestration | - | url | http://controller:8004/v1/%(tenant_id)s | - +--------------+-----------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - orchestration internal http://controller:8004/v1/%\(tenant_id\)s - +--------------+-----------------------------------------+ - | Field | Value | - +--------------+-----------------------------------------+ - | enabled | True | - | id | 9489f78e958e45cc85570fec7e836d98 | - | interface | internal | - | region | RegionOne | - | region_id | RegionOne | - | service_id | 727841c6f5df4773baa4e8a5ae7d72eb | - | service_name | heat | - | service_type | orchestration | - | url | http://controller:8004/v1/%(tenant_id)s | - +--------------+-----------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - orchestration admin http://controller:8004/v1/%\(tenant_id\)s - +--------------+-----------------------------------------+ - | Field | Value | - +--------------+-----------------------------------------+ - | enabled | True | - | id | 76091559514b40c6b7b38dde790efe99 | - | interface | admin | - | region | RegionOne | - | region_id | RegionOne | - | service_id | 727841c6f5df4773baa4e8a5ae7d72eb | - | service_name | heat | - | service_type | orchestration | - | url | http://controller:8004/v1/%(tenant_id)s | - +--------------+-----------------------------------------+ - - $ openstack endpoint create --region RegionOne \ - cloudformation public http://controller:8000/v1 - +--------------+----------------------------------+ - | Field | Value | - +--------------+----------------------------------+ - | enabled | True | - | id | b3ea082e019c4024842bf0a80555052c | - | interface | public | - | region | RegionOne | - | region_id | RegionOne | - | service_id | c42cede91a4e47c3b10c8aedc8d890c6 | - | service_name | heat-cfn | - | service_type | cloudformation | - | url | http://controller:8000/v1 | - +--------------+----------------------------------+ - - $ openstack endpoint create --region RegionOne \ - cloudformation internal http://controller:8000/v1 - +--------------+----------------------------------+ - | Field | Value | - +--------------+----------------------------------+ - | enabled | True | - | id | 169df4368cdc435b8b115a9cb084044e | - | interface | internal | - | region | RegionOne | - | region_id | RegionOne | - | service_id | c42cede91a4e47c3b10c8aedc8d890c6 | - | service_name | heat-cfn | - | service_type | cloudformation | - | url | http://controller:8000/v1 | - +--------------+----------------------------------+ - - $ openstack endpoint create --region RegionOne \ - cloudformation admin http://controller:8000/v1 - +--------------+----------------------------------+ - | Field | Value | - +--------------+----------------------------------+ - | enabled | True | - | id | 3d3edcd61eb343c1bbd629aa041ff88b | - | interface | internal | - | region | RegionOne | - | region_id | RegionOne | - | service_id | c42cede91a4e47c3b10c8aedc8d890c6 | - | service_name | heat-cfn | - | service_type | cloudformation | - | url | http://controller:8000/v1 | - +--------------+----------------------------------+ - -#. Orchestration requires additional information in the Identity service to - manage stacks. To add this information, complete these steps: - - * Create the ``heat`` domain that contains projects and users for stacks:: - - $ openstack domain create --description "Stack projects and users" heat - +-------------+----------------------------------+ - | Field | Value | - +-------------+----------------------------------+ - | description | Stack projects and users | - | enabled | True | - | id | 0f4d1bd326f2454dacc72157ba328a47 | - | name | heat | - +-------------+----------------------------------+ - - * Create the ``heat_domain_admin`` user to manage projects and users in the - ``heat`` domain:: - - $ openstack user create --domain heat --password-prompt heat_domain_admin - User Password: - Repeat User Password: - +-----------+----------------------------------+ - | Field | Value | - +-----------+----------------------------------+ - | domain_id | 0f4d1bd326f2454dacc72157ba328a47 | - | enabled | True | - | id | b7bd1abfbcf64478b47a0f13cd4d970a | - | name | heat_domain_admin | - +-----------+----------------------------------+ - - * Add the ``admin`` role to the ``heat_domain_admin`` in the ``heat`` domain - to enable administrative stack management privileges by the - ``heat_domain_admin`` user:: - - $ openstack role add --domain heat --user heat_domain_admin admin - - * Create the ``heat_stack_owner`` role:: - - $ openstack role create heat_stack_owner - +-------+----------------------------------+ - | Field | Value | - +-------+----------------------------------+ - | id | 15e34f0c4fed4e68b3246275883c8630 | - | name | heat_stack_owner | - +-------+----------------------------------+ - - * Create the ``heat_stack_user`` role:: - - $ openstack role create heat_stack_user - +-------+----------------------------------+ - | Field | Value | - +-------+----------------------------------+ - | id | 88849d41a55d4d1d91e4f11bffd8fc5c | - | name | heat_stack_user | - +-------+----------------------------------+ - -Installing and configuring components -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To install and configure the Orchestration components: - -#. Install OpenStack Orchestration bundle:: - - # swupd bundle-add openstack-orchestration - -#. Custom configuration will be located at ``/etc/heat/heat.conf file``. - - * Create the ``/etc/heat`` directory:: - - # mkdir /etc/heat - - * Create empty heat configuration file ``/etc/heat/heat.conf``:: - - # touch /etc/heat/heat.conf - -#. Edit the ``/etc/heat/heat.conf`` file and complete the following - actions: - - * In the ``[database]`` section, configure database access. - Replace *HEAT_DBPASS*  with the password you chose for the - Orchestration database:: - - [database] - ... - connection = mysql://heat:HEAT_DBPASS@controller/heat - - * In the ``[DEFAULT]`` and ``[oslo_messaging_rabbit]`` sections, configure - RabbitMQ message queue access. Replace ``RABBIT_PASS``  with the password - you chose for the ``openstack`` account in RabbitMQ:: - - [DEFAULT] - ... - rpc_backend = rabbit - - [oslo_messaging_rabbit] - ... - rabbit_host = controller - rabbit_userid = openstack - rabbit_password = RABBIT_PASS - - * In the ``[keystone_authtoken]``, ``[trustee]``, ``[clients_keystone]``, - and ``[ec2authtoken]`` sections, configure Identity service access. Replace - ``HEAT_PASS`` with the password you chose for the heat user in the Identity - service.:: - - [keystone_authtoken] - ... - auth_uri = http://controller:5000 - auth_url = http://controller:35357 - auth_plugin = password - project_domain_id = default - user_domain_id = default - project_name = service - username = heat - password = HEAT_PASS - - [trustee] - ... - auth_uri = http://controller:5000 - auth_url = http://controller:35357 - auth_plugin = password - project_domain_id = default - user_domain_id = default - project_name = service - username = heat - password = HEAT_PASS - - [clients_keystone] - ... - auth_uri = http://controller:5000 - - [ec2authtoken] - ... - auth_uri = http://controller:5000 - - - * In the ``[DEFAULT]`` section, configure the metadata and wait - condition URLs:: - - [DEFAULT] - ... - heat_metadata_server_url = http://controller:8000 - heat_waitcondition_server_url = http://controller:8000/v1/waitcondition - - * In the ``[DEFAULT]`` section, configure the stack domain and administrative - credentials. Replace ``HEAT_DOMAIN_PASS`` with the password you chose for - the ``heat_domain_admin`` user in the Identity service.:: - - [DEFAULT] - ... - stack_domain_admin = heat_domain_admin - stack_domain_admin_password = HEAT_DOMAIN_PASS - stack_user_domain_name = heat - - -#. Ensure files have proper ownership by running the following command:: - - # systemctl restart update-triggers.target - -#. Populate the Orchestration database:: - - # su -s /bin/sh -c "heat-manage db_sync" heat - -Finalize installation -~~~~~~~~~~~~~~~~~~~~~~~~ - -Complete this step to finalize the installation: - -* Start the Orchestration services and configure them to start when the - system boots:: - - # systemctl enable heat-api.service heat-api-cfn.service heat-engine.service - # systemctl start heat-api.service heat-api-cfn.service heat-engine.service - -Verify operation ----------------- - -#. Source the ``admin`` tenant credentials:: - - $ source admin-openrc.sh - -#. List service components to verify successful launch and registration of each - process:: - - $ heat service-list - +------------+-------------+--------------------------------------+------------+--------+----------------------------+--------+ - | hostname | binary | engine_id | host | topic | updated_at | status | - +------------+-------------+--------------------------------------+------------+--------+----------------------------+--------+ - | controller | heat-engine | 3e85d1ab-a543-41aa-aa97-378c381fb958 | controller | engine | 2015-10-13T14:16:06.000000 | up | - | controller | heat-engine | 45dbdcf6-5660-4d5f-973a-c4fc819da678 | controller | engine | 2015-10-13T14:16:06.000000 | up | - | controller | heat-engine | 51162b63-ecb8-4c6c-98c6-993af899c4f7 | controller | engine | 2015-10-13T14:16:06.000000 | up | - | controller | heat-engine | 8d7edc6d-77a6-460d-bd2a-984d76954646 | controller | engine | 2015-10-13T14:16:06.000000 | up | - +------------+-------------+--------------------------------------+------------+--------+----------------------------+--------+ - -Next topic: :ref:`openstack_telemetry`. diff --git a/source/openstack_supporting-database.rst b/source/openstack_supporting-database.rst deleted file mode 100644 index 615e65c1..00000000 --- a/source/openstack_supporting-database.rst +++ /dev/null @@ -1,52 +0,0 @@ -.. _openstack_supporting-database: - -Database -######## - -Most OpenStack* services use an SQL database to store information. The -database typically runs on the controller node. The procedures in this -guide use MariaDB. - -Install and configure the database server ------------------------------------------ - -#. Install MariaDB bundle:: - - # swupd bundle-add database-mariadb - -#. Create the ``/etc/mariadb/`` folder and the ``/etc/mariadb/openstack.cnf`` - file:: - - # mkdir /etc/mariadb - # touch /etc/mariadb/openstack.cnf - -#. Add the ``[mysqld]`` section, set the bind-address key to the - management IP address of the controller node to enable access by - other nodes via the management network and enable useful options for - UTF-8 character set:: - - [mysqld] - bind-address = 10.0.0.11 - default-storage-engine = innodb - innodb_file_per_table - collation-server = utf8_general_ci - init-connect = 'SET NAMES utf8' - character-set-server = utf8 - -Finalizing database installation --------------------------------- - -Complete the following steps to finalize database installation: - -#. Start the database service and configure it to start when the system - boots:: - - # systemctl enable mariadb.service - # systemctl start mariadb.service - -#. Secure the database service including choosing a suitable password - for the root account:: - - # mysql_secure_installation - -Next topic: :ref:`openstack_supporting-messaging`. diff --git a/source/openstack_supporting-messaging.rst b/source/openstack_supporting-messaging.rst deleted file mode 100644 index aa0fe3f0..00000000 --- a/source/openstack_supporting-messaging.rst +++ /dev/null @@ -1,47 +0,0 @@ -.. _openstack_supporting-messaging: - -Message queue -############# - -OpenStack* uses a `message queue` to coordinate operations and -status information among services. The message queue service typically -runs on the controller node. OpenStack supports several message queue -services. This guide implements the RabbitMQ message queue service. - -Install the message queue service ---------------------------------- - -#. Install the message queue bundle.:: - - # swupd bundle-add message-broker-rabbitmq - -Configuring the message broker service --------------------------------------- - -Complete the following steps to configure the message broker service: - -#. Message broker service needs to be able to resolve to itself. Add the - following line to ``/etc/hosts``.:: - - 127.0.0.1 controller - -#. Start the message broker service and configure it to start when the - system boots.:: - - # systemctl enable rabbitmq-server.service - # systemctl start rabbitmq-server.service - -#. Add the OpenStack user. Replace ``RABBIT_PASS`` with a suitable password.:: - - # rabbitmqctl add_user openstack RABBIT_PASS - Creating user openstack ... - ...done. - - -#. Permit configuration, write, and read access for the OpenStack user.:: - - # rabbitmqctl set_permissions openstack ".*" ".*" ".*" - Setting permissions for user "openstack" in vhost "/" ... - ...done. - -Next topic: :ref:`openstack_identity`. diff --git a/source/openstack_sys_req_and_pw_summary.rst b/source/openstack_sys_req_and_pw_summary.rst deleted file mode 100644 index 6dfaea4f..00000000 --- a/source/openstack_sys_req_and_pw_summary.rst +++ /dev/null @@ -1,68 +0,0 @@ -.. _openstack_sys_req_and_pw_summary: - -System requirements and password summary -######################################## - -System requirements -------------------- - -For best performance, we recommend that your environment meets or -exceeds the following hardware requirements: - -- Controller Node: 1 processor, 2 GB memory, and 5 GB storage. -- Compute Node: 1 processor, 2 GB memory, and 10 GB storage. - -For OpenStack* services, this guide uses \ ``SERVICE_PASS``\ to reference -service account passwords and ``SERVICE_DBPASS`` to reference database -passwords. - -Prerequisites -------------- - -All nodes require Internet access to install OpenStack bundles and -perform maintenance tasks such as periodic updates. - -OpenStack and supporting services require administrative privileges -during installation and operation. - -You must also configure networking so that each node can resolve the -other nodes by name in addition to IP address. For example, the -``controller`` name must resolve to ``10.0.0.11``, the IP address of the -management interface on the controller node. - -To configure name resolution: - -#. Set the hostname of the node to ``controller``:: - - # hostnamectl set-hostname controller - -#. Edit the ``/etc/hosts`` file to contain the following:: - - # controller 10.0.0.11 controller - # compute1 10.0.0.31 compute1 - -Password summary ----------------- - -The following table provides a list of services that require passwords, -as well as their associated references in the guide: - -.. csv-table:: Password Services - :header: "Password name", "Description" - :widths: 100, 100 - - "Database password (no variable used)", "Root password for the database." - "RABBIT_PASS", "Password of user ``guest`` of RabbitMQ." - "KEYSTONE_DBPASS", "Database password of Identity service." - "DEMO_PASS", "Password of user ``demo``." - "ADMIN_PASS", "Password of user ``admin``." - "GLANCE_DBPASS", "Database password for Image Service." - "GLANCE_PASS", "Password of Image Service user ``glance``." - "NOVA_DBPASS", "Database password for Compute service." - "NOVA_PASS", "Password of Compute service user ``nova``." - "DASH_DBPASS", "Database password for the dashboard." - "CINDER_DBPASS", "Database password for the Block Storage service." - "CINDER_PASS", "Password of Block Storage service user ``cinder``." - - -Next topic: :ref:`openstack_installing_bundles`. \ No newline at end of file diff --git a/source/openstack_telemetry.rst b/source/openstack_telemetry.rst deleted file mode 100644 index 4ab51917..00000000 --- a/source/openstack_telemetry.rst +++ /dev/null @@ -1,260 +0,0 @@ -.. _openstack_telemetry: - -Telemetry -############################################################ - -Overview ---------- - -The OpenStack* Telemetry service performs the following functions: - -- Efficiently polls metering data related to OpenStack services -- Collects event and metering data by monitoring notifications sent - from services -- Publishes collected data to various targets, including data stores - and message queues -- Creates alarms when collected data breaks defined rules - -Installing and configuring ---------------------------- - -This section describes how to install and configure the Telemetry -service, code-named ceilometer, on the controller node. The Telemetry -service collects measurements from most OpenStack services and optionally -triggers alarms. - - -Prerequisites -~~~~~~~~~~~~~~~ - -Before installing and configuring the ``telemetry`` service, install -MongoDB* and create a MongoDB database, service credentials, and API -endpoint. - -#. Install the MongoDB bundle:: - - # swupd bundle-add database-mongodb - -#. Create the ``/etc/mongodb/`` folder and the - ``/etc/mongodb/openstack.cnf`` file.:: - - # mkdir /etc/mongodb - # touch /etc/mongodb/openstack.cnf - -#. Configure the ``bind_ip`` key to use the management interface IP - address of the controller node by editing the ``/etc/mongodb/openstack.cnf`` file:: - - bind_ip = 10.0.0.11 - -#. Start the database service and configure it to start when the system - boots with the following commands:: - - # systemctl enable mongodb.service - # systemctl start mongodb.service - -#. Create the ``ceilometer`` database. Replace *CEILOMETER_DBPASS* - with a suitable password:: - - # mongo --host controller --eval ' - db = db.getSiblingDB("ceilometer"); - db.createUser({user: "ceilometer", - pwd: "CEILOMETER_DBPASS", - roles: [ "readWrite", "dbAdmin" ]})' - - MongoDB shell version: 3.1.7 - connecting to: controller:27017/test - Successfully added user: { "user" : "ceilometer", "roles" : [ "readWrite", "dbAdmin" ] } - -#. Source the ``admin`` credentials to gain access to admin-only CLI - commands:: - - $ source admin-openrc.sh - -#. To create the service credentials, complete these steps: - - * Create the ``ceilometer`` user:: - - $ openstack user create --domain default --password-prompt ceilometer - User Password: - Repeat User Password: - +-----------+----------------------------------+ - | Field | Value | - +-----------+----------------------------------+ - | domain_id | default | - | enabled | True | - | id | c859c96f57bd4989a8ea1a0b1d8ff7cd | - | name | ceilometer | - +-----------+----------------------------------+ - - * Add the ``admin`` role to the ``ceilometer`` user:: - - $ openstack role add --project service --user ceilometer admin - - * Create the ``ceilometer`` service entity:: - - $ openstack service create --name ceilometer \ - --description "Telemetry" metering - +-------------+----------------------------------+ - | Field | Value | - +-------------+----------------------------------+ - | description | Telemetry | - | enabled | True | - | id | 3405453b14da441ebb258edfeba96d83 | - | name | ceilometer | - | type | metering | - +-------------+----------------------------------+ - -#. Create the Telemetry service API endpoints:: - - $ openstack endpoint create --region RegionOne \ - metering public http://controller:8777 - +--------------+----------------------------------+ - | Field | Value | - +--------------+----------------------------------+ - | enabled | True | - | id | 340be3625e9b4239a6415d034e98aace | - | interface | public | - | region | RegionOne | - | region_id | RegionOne | - | service_id | 8c2c7f1b9b5049ea9e63757b5533e6d2 | - | service_name | celiometer | - | service_type | metering | - | url | http://controller:8777 | - +--------------+----------------------------------+ - - $ openstack endpoint create --region RegionOne \ - metering internal http://controller:8777 - +--------------+----------------------------------+ - | Field | Value | - +--------------+----------------------------------+ - | enabled | True | - | id | 340be3625e9b4239a6415d034e98aace | - | interface | internal | - | region | RegionOne | - | region_id | RegionOne | - | service_id | 8c2c7f1b9b5049ea9e63757b5533e6d2 | - | service_name | celiometer | - | service_type | metering | - | url | http://controller:8777 | - +--------------+----------------------------------+ - - $ openstack endpoint create --region RegionOne \ - metering admin http://controller:8777 - +--------------+----------------------------------+ - | Field | Value | - +--------------+----------------------------------+ - | enabled | True | - | id | 340be3625e9b4239a6415d034e98aace | - | interface | admin | - | region | RegionOne | - | region_id | RegionOne | - | service_id | 8c2c7f1b9b5049ea9e63757b5533e6d2 | - | service_name | celiometer | - | service_type | metering | - | url | http://controller:8777 | - +--------------+----------------------------------+ - - -Install and configure components -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -#. Install the OpenStack Telemetry Controller bundle:: - - # swupd bundle-add openstack-telemetry - -#. Custom configurations will be located at ``/etc/ceilometer``. - - * Create ``/etc/ceilometer`` directory:: - - # mkdir /etc/ceilometer - - * Create the empty ceilometer configuration file:: - - # touch /etc/ceilometer/ceilometer.conf - -#. Edit the ``/etc/ceilometer/ceilometer.conf`` file and - complete the following actions: - - * In the ``[database]`` section, configure database access. Replace - *CEILOMETER_DBPASS* with the password you chose for the - Telemetry module database. You must escape special characters such - as ':', '/', '+', and '@' in the connection string in accordance - with RFC2396:: - - [database] - ... - connection = mongodb://ceilometer:CEILOMETER_DBPASS@controller:27017/ceilometer - - * In the ``[DEFAULT]`` and ``[oslo_messaging_rabbit]`` sections, - configure RabbitMQ message queue access. Replace *RABBIT_PASS* - with the password you chose for the ``openstack`` account in - RabbitMQ:: - - [DEFAULT] - ... - rpc_backend = rabbit - - [oslo_messaging_rabbit] - ... - rabbit_host = controller - rabbit_userid = openstack - rabbit_password = RABBIT_PASS - - * In the ``[DEFAULT]`` and ``[keystone_authtoken]`` sections, - configure Identity service access. Replace *CEILOMETER_PASS* - with the password you chose for the ``celiometer`` user in the - Identity service:: - - [DEFAULT] - ... - auth_strategy = keystone - - [keystone_authtoken] - ... - auth_uri = http://controller:5000 - auth_url = http://controller:35357 - auth_plugin = password - project_domain_id = default - user_domain_id = default - project_name = service - username = ceilometer - password = CEILOMETER_PASS - - * In the ``[service_credentials]`` section, configure service - credentials. Replace *CEILOMETER_PASS* with the password you - chose for the ``ceilometer`` user in the Identity service:: - - [service_credentials] - ... - os_auth_url = http://controller:5000/v2.0 - os_username = ceilometer - os_tenant_name = service - os_password = CEILOMETER_PASS - os_endpoint_type = internalURL - os_region_name = RegionOne - - * Ensure files have proper ownership by running the following command:: - - # systemctl restart update-triggers.target - - -Finalizing installation -~~~~~~~~~~~~~~~~~~~~~~~~ - -#. Start the Telemetry services and configure them to start when the system boots:: - - # systemctl enable ceilometer-agent-central.service \ - ceilometer-agent-notification.service \ - ceilometer-api.service \ - ceilometer-collector.service \ - ceilometer-alarm-evaluator.service \ - ceilometer-alarm-notifier.service - - # systemctl start ceilometer-agent-central.service \ - ceilometer-agent-notification.service \ - ceilometer-api.service \ - ceilometer-collector.service \ - ceilometer-alarm-evaluator.service \ - ceilometer-alarm-notifier.service - -Next topic: :ref:`openstack_object_storage`. From 71e60d06e4a26740b4da5ab0900954858b210c7f Mon Sep 17 00:00:00 2001 From: Leoswaldo Macias Date: Thu, 31 Mar 2016 12:41:47 -0600 Subject: [PATCH 02/25] Add new documentation for openstack deployment with ansible Signed-off-by: Leoswaldo Macias --- source/configure_openstack_environment.rst | 44 +++++++++++++ source/index-openstack.rst | 19 ++---- source/installing_openstack.rst | 63 +++++++++++++++++++ .../openstack_bundle_and_service_summary.rst | 2 +- source/openstack_conf_vars_about.rst | 14 +++++ source/openstack_conf_vars_list.rst | 63 +++++++++++++++++++ source/openstack_env_inventory_file.rst | 59 +++++++++++++++++ 7 files changed, 249 insertions(+), 15 deletions(-) create mode 100644 source/configure_openstack_environment.rst create mode 100644 source/installing_openstack.rst create mode 100644 source/openstack_conf_vars_about.rst create mode 100644 source/openstack_conf_vars_list.rst create mode 100644 source/openstack_env_inventory_file.rst diff --git a/source/configure_openstack_environment.rst b/source/configure_openstack_environment.rst new file mode 100644 index 00000000..85b223c2 --- /dev/null +++ b/source/configure_openstack_environment.rst @@ -0,0 +1,44 @@ +.. _configure_openstack_environment: + + +Configure your environment +========================== + +Before continuing with the installation process, is important to understand: + +* The :file:`hosts` file; this file defines the roles your machines play in the + overall scheme of your network mapping. + **Note**: For more in-depth information, see :ref:`openstack_env_inventory_file` + +* The ``group_vars/all`` structuring can be used to override variable + values. **Note**: For more in-depth information, see :ref:`openstack_conf_vars_about` + +Once you understand these components and are comfortable modifying them to affect +the network configuration, you can proceed as follows: + +#. Copy ``/usr/share/ansible/examples/openstack`` to your working directory. + +#. Move into the copied directory. + +#. Edit the :file:`hosts` file to specify node roles. + +#. Edit the contents under ``group_vars/all`` to set passwords and other needed + variables. **Note**: Default variables exist for every role in the + :file:`roles//defaults/main.yml` file. To override a default, define + it with specifications under ``group_vars/all``. + + +Run the installer +================= + +Finally, you can run the installer. + +#. Run the installer as follows, replacing ```` with the key you've + previously set up:: + + $ ansible-playbook -i hosts openstack_deployment.yml --private-key= + +After running the previous command you should see the output of the tasks +that are running. + +At the end of the execution Ansible* will display a summary of the results. diff --git a/source/index-openstack.rst b/source/index-openstack.rst index 4a1787be..12856ae4 100644 --- a/source/index-openstack.rst +++ b/source/index-openstack.rst @@ -6,17 +6,8 @@ OpenStack* implementation openstack_use_cases openstack_bundle_and_service_summary - openstack_sys_req_and_pw_summary - openstack_installing_bundles - openstack_supporting-database - openstack_supporting-messaging - openstack_identity - openstack_identity-openrc - openstack_image - openstack_compute - openstack_block_storage - openstack_dashboard - openstack_networking - openstack_orchestration - openstack_telemetry - openstack_object_storage + installing_openstack + configure_openstack_environment + openstack_env_inventory_file + openstack_conf_vars_about + openstack_conf_vars_list diff --git a/source/installing_openstack.rst b/source/installing_openstack.rst new file mode 100644 index 00000000..8e5ba276 --- /dev/null +++ b/source/installing_openstack.rst @@ -0,0 +1,63 @@ +.. _installing_openstack: + +Installing OpenStack +#################### + +This section details an OpenStack* installation that uses +bundles available for Clear Linux* OS for Intel® Architecture. + +The sample configuration files that are included will likely +require modification for your specific environment. + +This installer will be using Ansible* as configuration management tool. + + +Components supported by this installer +====================================== + +At the moment, this installer can deploy any or all of the following +components: + + - MariaDB + - RabbitMQ + - Keystone + - Glance + - Nova + - Neutron + - Dashboard (An identity node) + - Heat + +Prerequisites +============= + +Before the installer can set up your cloud environment, these requirements +should be completed (if they aren't already): + +#. Create a pair of SSH keys. + +#. Copy your public key to each node. + +#. Create the :file:`sshd_config` in ``/etc/ssh`` if it doesn't exist:: + + # mkdir -p /etc/ssh && touch /etc/ssh/sshd_config + +#. Allow ssh root access by adding "PermitRootLogin yes" to the ssh + configuration.:: + + # echo "PermitRootLogin yes" >> /etc/ssh/sshd_config + + +Using the Installer +=================== + +This step presumes a Clear Linux* machine as the ansible host. + + +Install the bundle +------------------ + +#. Install the `sysadmin-hostmgmt` bundle:: + + # swupd bundle-add sysadmin-hostmgmt + +**Next**: :ref:`configure_openstack_environment` diff --git a/source/openstack_bundle_and_service_summary.rst b/source/openstack_bundle_and_service_summary.rst index d34b2210..d9713b7c 100644 --- a/source/openstack_bundle_and_service_summary.rst +++ b/source/openstack_bundle_and_service_summary.rst @@ -63,4 +63,4 @@ uses a two-node architecture. using overlay segmentation methods. Additionally, this option provides the foundation for advanced services such as LBaaS and FWaaS. -Next topic: :ref:``. +Next topic: :ref:`installing_openstack`. diff --git a/source/openstack_conf_vars_about.rst b/source/openstack_conf_vars_about.rst new file mode 100644 index 00000000..d5ad8ce4 --- /dev/null +++ b/source/openstack_conf_vars_about.rst @@ -0,0 +1,14 @@ +.. _openstack_conf_vars_about: + +About "group_vars/all" +###################### + +The ``group_vars/all`` section is where you will specify the +values for your passwords and other required or optional parameters. + +Variables in this section are built with yaml format. + +For a more detailed reference of the numerous variables and parameters +that can be set, see the :ref:`openstack_conf_vars_list`. + +**Back to Configuration Section** :ref:`configure_openstack_environment` diff --git a/source/openstack_conf_vars_list.rst b/source/openstack_conf_vars_list.rst new file mode 100644 index 00000000..7a55796b --- /dev/null +++ b/source/openstack_conf_vars_list.rst @@ -0,0 +1,63 @@ +.. _openstack_conf_vars_list: + +Variables for OpenStack Deployment +################################## + +This installer provides a variety of configurations you can set through +variables; below you will find a reference of the components supported +with Clear Linux* OS for Intel® Architecture. + +.. csv-table:: "Required Parameters Per Component" + :header: "Variable", "Components Impacted", "Description" + :widths: 90, 90, 150 + + "rabbitmq_password", "RabbitMQ, Neutron, Nova, Heat", "Password of + RabbitMQ user " + "database_root_password", "ALL", "Password for root database user" + "keystone_database_password", "Keystone", "Password for 'keystone' + database" + "keystone_admin_password", "ALL", "Password for 'admin' user" + "keystone_admin_token", "Keystone", "Used only for installation + process of keystone" + "glance_user_password", "Glance", "Password for 'glance' user" + "glance_database_password", "Glance", "Password for 'glance' database" + "nova_user_password", "Nova, Neutron", "Password for 'nova' user" + "nova_database_password", "Nova", "Password for 'nova' database" + "neutron_database_password", "Neutron", "Password for 'neutron' + database" + "neutron_user_password", "Neutron, Nova", "Password for 'neutron' + user" + "metadata_proxy_shared_secret", "Neutron, Nova", "Proxy" + "heat_domain_admin_password", "Heat", "Password for heat domain admin + user" + "heat_user_password", "Heat", "Password for heat user" + "heat_database_password", "Heat", "Password for heat database" + "heat_domain", "Heat", "The heat domain that contains projects and + users for stacks" + + +.. csv-table:: "Optional Parameters Per Component" + :header: "Variable", "Default Value", "Components Impacted", "Description" + :widths: 90, 40, 90, 150 + + "swupd_args", "", "ALL", "Optional arguments for swupd" + "log_debug", "False", "ALL", "Set to True to enable debug log level on all + services" + "rabbitmq_username", "openstack", "RabbitMQ, Neutron, Nova, Heat", "User ID for + RabbitMQ" + "neutron_public_interface_name", "First default iface", "Neutron, Nova", "Public interface of + Neutron machines, if not define it will make autodiscovery for each machine" + "nova_public_interface_name", "First default iface", "Nova", "Public + interface of Nova machines, if not define it will make autodiscovery for each + machine" + "nova_virt_type", "qemu", "Nova", "Virtualization type (qemu | kvm), if + this is not set, then the playbook will try to guess it" + "os_tuning_params", "net.ipv4.ip_forward: 1, net.ipv4.conf.default.rp_filter: 0, net.ipv4.conf.all.rp_filter: 0, net.bridge.bridge-nf-call-iptables: 1, net.bridge.bridge-nf-call-ip6tables: 1", "Neutron", "syctl values needed by neutron when + using openvswitch deployment scenario" + +Note: +----- +If you would like to override a default, you can define it in the +:ref:`openstack_conf_vars_about`. + +**Back to Configuration Section** :ref:`configure_openstack_environment` diff --git a/source/openstack_env_inventory_file.rst b/source/openstack_env_inventory_file.rst new file mode 100644 index 00000000..a51c1954 --- /dev/null +++ b/source/openstack_env_inventory_file.rst @@ -0,0 +1,59 @@ +.. _openstack_env_inventory_file: + +The "hosts" file +################ + +The :file:`hosts` file is an inventory file where you specify, via +``ini`` format, the roles your machine plays. + +The hosts file can be structured with different groups, where each +group plays a specific role in your environment and network mapping. + +Consider the following example:: + + [openstack_identity] + 192.168.50.13 + +Here the :role:`[openstack_identity]` syntax defines the group, and +``192.168.50.13`` specifies the machines that possess that role. You +may define multiple machines in the same group; this is a standard +configuration for :role:`[openstack_compute]` nodes:: + + [openstack_compute] + 192.168.50.16 + 192.168.50.17 + + +Inventory file groups +--------------------- + +Below you will find the description of each group in the `hosts` file. + +.. csv-table:: "Inventory File Groups" + :header: "Group", "Components", "Comments" + :widths: 40, 40, 300 + + "[dbservers]", "MariaDB", "" + "[messaging_servers]", "RabbitMQ", "" + "[openstack_identity]", "Keystone, Horizon", "" + "[openstack_image]", "Glance", "" + "[openstack_compute_controller]", "Nova", "" + "[openstack_compute]", "Nova", "Accepts multiple entries to have multiple compute nodes. You can add more entries and re-run the installer to add them to your environment." + "[openstack_networking]", "Neutron", "" + "[openstack_orchestration]", "Heat", "" + + +Important Notes +--------------- + +* To omit any role, do not add an entry under its group section. + +* To create an ``All In One`` scenario, specify the same machine name or IPv4 + Address under all of the groups. + +For further reference, check out the `Ansible`_ documentation. + + +**Back to Configuration Section** :ref:`configure_openstack_environment` + +.. _Ansible: http://docs.ansible.com/ansible/intro_inventory.html From daadf061b4734f435f90595e28bc9badb956d09b Mon Sep 17 00:00:00 2001 From: Leoswaldo Macias Date: Thu, 31 Mar 2016 12:44:56 -0600 Subject: [PATCH 03/25] Fix grammar syntax to present Signed-off-by: Leoswaldo Macias --- source/installing_openstack.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/installing_openstack.rst b/source/installing_openstack.rst index 8e5ba276..5d92f56b 100644 --- a/source/installing_openstack.rst +++ b/source/installing_openstack.rst @@ -9,7 +9,7 @@ bundles available for Clear Linux* OS for Intel® Architecture. The sample configuration files that are included will likely require modification for your specific environment. -This installer will be using Ansible* as configuration management tool. +This installer uses Ansible* as configuration management tool. Components supported by this installer From b3c57cb383dc9c349de01f3173d6e67ce77adb5e Mon Sep 17 00:00:00 2001 From: Leoswaldo Macias Date: Thu, 31 Mar 2016 12:53:13 -0600 Subject: [PATCH 04/25] fix typo --- source/installing_openstack.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/installing_openstack.rst b/source/installing_openstack.rst index 5d92f56b..863b3911 100644 --- a/source/installing_openstack.rst +++ b/source/installing_openstack.rst @@ -24,7 +24,7 @@ components: - Glance - Nova - Neutron - - Dashboard (An identity node) + - Dashboard (In identity node) - Heat Prerequisites From 2eb3d7aab1093f90b8ee1c068bf2560e071266d6 Mon Sep 17 00:00:00 2001 From: Leoswaldo Macias Date: Thu, 31 Mar 2016 15:34:11 -0600 Subject: [PATCH 05/25] fix table and remove MVP word Signed-off-by: Leoswaldo Macias --- source/openstack_bundle_and_service_summary.rst | 5 ++--- source/openstack_env_inventory_file.rst | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/source/openstack_bundle_and_service_summary.rst b/source/openstack_bundle_and_service_summary.rst index d9713b7c..362285ff 100644 --- a/source/openstack_bundle_and_service_summary.rst +++ b/source/openstack_bundle_and_service_summary.rst @@ -6,10 +6,9 @@ OpenStack* bundle and service summary OpenStack provides an Infrastructure-as-a-Service (IaaS) solution through a variety of complementary services. Each service offers an application programming interface (API) that facilitates this -integration. The following table provides a list of OpenStack MVP -services: +integration. The following table provides a list of OpenStack services: -.. csv-table:: OpenStack MVP services +.. csv-table:: OpenStack services :header: "Bundle Name (service)", "Project Name", "Description" :widths: 90, 90, 300 diff --git a/source/openstack_env_inventory_file.rst b/source/openstack_env_inventory_file.rst index a51c1954..e295e8ca 100644 --- a/source/openstack_env_inventory_file.rst +++ b/source/openstack_env_inventory_file.rst @@ -30,7 +30,7 @@ Inventory file groups Below you will find the description of each group in the `hosts` file. .. csv-table:: "Inventory File Groups" - :header: "Group", "Components", "Comments" + :header: "Group", "Components", "Comments" :widths: 40, 40, 300 "[dbservers]", "MariaDB", "" From a6953126606f70a50f6f59954bd7efa3a18c58de Mon Sep 17 00:00:00 2001 From: Leoswaldo Macias Date: Fri, 1 Apr 2016 12:29:49 -0600 Subject: [PATCH 06/25] Add unsupported components table Signed-off-by: Leoswaldo Macias --- source/installing_openstack.rst | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/source/installing_openstack.rst b/source/installing_openstack.rst index 863b3911..30388556 100644 --- a/source/installing_openstack.rst +++ b/source/installing_openstack.rst @@ -9,11 +9,11 @@ bundles available for Clear Linux* OS for Intel® Architecture. The sample configuration files that are included will likely require modification for your specific environment. -This installer uses Ansible* as configuration management tool. +This Clear Config Management uses Ansible* as configuration management tool. -Components supported by this installer -====================================== +Components supported by Clear Config Management +=============================================== At the moment, this installer can deploy any or all of the following components: @@ -27,6 +27,21 @@ components: - Dashboard (In identity node) - Heat +Note: +----- + +Below you will find the reference to componets supported on ClearLinux* but +its support in Clear Config Management is still pending of development: + +.. csv-table:: "Supported Components on ClearLinux*, but unsupported by Clear Config Management" + :header: "Component", "Bundles", "OpenStack* official documentation" + :widths: 20, 70, 300 + + "Swift", "openstack-object-storage and openstack-block-storage-controller", "http://docs.openstack.org/developer/swift/" + "Cinder", "openstack-block-storage and openstack-block-storage-controller", "http://docs.openstack.org/developer/cinder/" + "Ceilometer", "openstack-telemetry", "http://docs.openstack.org/developer/ceilometer/" + + Prerequisites ============= From 8ad3a1a817eecf869e8530fe56cc1a1cf15098bc Mon Sep 17 00:00:00 2001 From: Leoswaldo Macias Date: Fri, 1 Apr 2016 12:31:12 -0600 Subject: [PATCH 07/25] Fix table spacing Signed-off-by: Leoswaldo Macias --- source/installing_openstack.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/installing_openstack.rst b/source/installing_openstack.rst index 30388556..83f9a0b3 100644 --- a/source/installing_openstack.rst +++ b/source/installing_openstack.rst @@ -35,7 +35,7 @@ its support in Clear Config Management is still pending of development: .. csv-table:: "Supported Components on ClearLinux*, but unsupported by Clear Config Management" :header: "Component", "Bundles", "OpenStack* official documentation" - :widths: 20, 70, 300 + :widths: 20, 70, 100 "Swift", "openstack-object-storage and openstack-block-storage-controller", "http://docs.openstack.org/developer/swift/" "Cinder", "openstack-block-storage and openstack-block-storage-controller", "http://docs.openstack.org/developer/cinder/" From f036705c40961f4983991aead9e70beb33be3c1f Mon Sep 17 00:00:00 2001 From: "Munoz, Obed N" Date: Thu, 7 Apr 2016 14:44:08 -0500 Subject: [PATCH 08/25] Fix a couple of singular/plural words Signed-off-by: Munoz, Obed N --- source/configure_openstack_environment.rst | 2 +- source/openstack_env_inventory_file.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/configure_openstack_environment.rst b/source/configure_openstack_environment.rst index 85b223c2..65a8d69f 100644 --- a/source/configure_openstack_environment.rst +++ b/source/configure_openstack_environment.rst @@ -4,7 +4,7 @@ Configure your environment ========================== -Before continuing with the installation process, is important to understand: +Before continuing with the installation process, it's important to understand: * The :file:`hosts` file; this file defines the roles your machines play in the overall scheme of your network mapping. diff --git a/source/openstack_env_inventory_file.rst b/source/openstack_env_inventory_file.rst index e295e8ca..69505ad2 100644 --- a/source/openstack_env_inventory_file.rst +++ b/source/openstack_env_inventory_file.rst @@ -6,7 +6,7 @@ The "hosts" file The :file:`hosts` file is an inventory file where you specify, via ``ini`` format, the roles your machine plays. -The hosts file can be structured with different groups, where each +The :file:`hosts` file can be structured with different groups, where each group plays a specific role in your environment and network mapping. Consider the following example:: @@ -15,7 +15,7 @@ Consider the following example:: 192.168.50.13 Here the :role:`[openstack_identity]` syntax defines the group, and -``192.168.50.13`` specifies the machines that possess that role. You +``192.168.50.13`` specifies the machine(s) that possess that role. You may define multiple machines in the same group; this is a standard configuration for :role:`[openstack_compute]` nodes:: From 4836b8ef6c2d25f989ed8a1a56c318d335281531 Mon Sep 17 00:00:00 2001 From: "Simental Magana, Marcos" Date: Thu, 7 Apr 2016 14:58:14 -0500 Subject: [PATCH 09/25] openstack_conf_vars_list.rst: fix table headers --- source/openstack_conf_vars_list.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/openstack_conf_vars_list.rst b/source/openstack_conf_vars_list.rst index 7a55796b..dc521da8 100644 --- a/source/openstack_conf_vars_list.rst +++ b/source/openstack_conf_vars_list.rst @@ -8,7 +8,7 @@ variables; below you will find a reference of the components supported with Clear Linux* OS for Intel® Architecture. .. csv-table:: "Required Parameters Per Component" - :header: "Variable", "Components Impacted", "Description" + :header: "Variable", "Components Impacted", "Description" :widths: 90, 90, 150 "rabbitmq_password", "RabbitMQ, Neutron, Nova, Heat", "Password of @@ -37,7 +37,7 @@ with Clear Linux* OS for Intel® Architecture. .. csv-table:: "Optional Parameters Per Component" - :header: "Variable", "Default Value", "Components Impacted", "Description" + :header: "Variable", "Default Value", "Components Impacted", "Description" :widths: 90, 40, 90, 150 "swupd_args", "", "ALL", "Optional arguments for swupd" From 9bef8f4da3e9cfd73e79d93f497dc016a14516a7 Mon Sep 17 00:00:00 2001 From: "Munoz, Obed N" Date: Thu, 7 Apr 2016 15:12:42 -0500 Subject: [PATCH 10/25] Fix roles inline code syntax Signed-off-by: Munoz, Obed N --- source/openstack_env_inventory_file.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/openstack_env_inventory_file.rst b/source/openstack_env_inventory_file.rst index 69505ad2..2a3353b9 100644 --- a/source/openstack_env_inventory_file.rst +++ b/source/openstack_env_inventory_file.rst @@ -14,10 +14,10 @@ Consider the following example:: [openstack_identity] 192.168.50.13 -Here the :role:`[openstack_identity]` syntax defines the group, and +Here, the role ``[openstack_identity]`` syntax defines the group, and ``192.168.50.13`` specifies the machine(s) that possess that role. You may define multiple machines in the same group; this is a standard -configuration for :role:`[openstack_compute]` nodes:: +configuration for role ``[openstack_compute]`` nodes:: [openstack_compute] 192.168.50.16 From 04bf65c149551328a091c5bf413f7b7d1b220878 Mon Sep 17 00:00:00 2001 From: "Simental Magana, Marcos" Date: Fri, 8 Apr 2016 13:56:16 -0500 Subject: [PATCH 11/25] remove keystone_admin_token variable from documentation. The installation process for mitaka does not use admin token for keystone, so remove it from the documentation. --- source/openstack_conf_vars_list.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/openstack_conf_vars_list.rst b/source/openstack_conf_vars_list.rst index dc521da8..4704bdab 100644 --- a/source/openstack_conf_vars_list.rst +++ b/source/openstack_conf_vars_list.rst @@ -17,8 +17,6 @@ with Clear Linux* OS for Intel® Architecture. "keystone_database_password", "Keystone", "Password for 'keystone' database" "keystone_admin_password", "ALL", "Password for 'admin' user" - "keystone_admin_token", "Keystone", "Used only for installation - process of keystone" "glance_user_password", "Glance", "Password for 'glance' user" "glance_database_password", "Glance", "Password for 'glance' database" "nova_user_password", "Nova, Neutron", "Password for 'nova' user" From d371e82e622d81a9040efc27d1c08cd7a2904f1f Mon Sep 17 00:00:00 2001 From: "Simental Magana, Marcos" Date: Fri, 8 Apr 2016 14:34:25 -0500 Subject: [PATCH 12/25] Fix "Optional Parameters Per Component" table. Having 4 rows makes the table hard to read so change it to only have 2 rows. --- source/openstack_conf_vars_list.rst | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/source/openstack_conf_vars_list.rst b/source/openstack_conf_vars_list.rst index 4704bdab..1e513de7 100644 --- a/source/openstack_conf_vars_list.rst +++ b/source/openstack_conf_vars_list.rst @@ -35,23 +35,16 @@ with Clear Linux* OS for Intel® Architecture. .. csv-table:: "Optional Parameters Per Component" - :header: "Variable", "Default Value", "Components Impacted", "Description" - :widths: 90, 40, 90, 150 + :header: "*(Component)* `Variable` : **Value**", "Description" + :widths: 90, 150 - "swupd_args", "", "ALL", "Optional arguments for swupd" - "log_debug", "False", "ALL", "Set to True to enable debug log level on all - services" - "rabbitmq_username", "openstack", "RabbitMQ, Neutron, Nova, Heat", "User ID for - RabbitMQ" - "neutron_public_interface_name", "First default iface", "Neutron, Nova", "Public interface of - Neutron machines, if not define it will make autodiscovery for each machine" - "nova_public_interface_name", "First default iface", "Nova", "Public - interface of Nova machines, if not define it will make autodiscovery for each - machine" - "nova_virt_type", "qemu", "Nova", "Virtualization type (qemu | kvm), if - this is not set, then the playbook will try to guess it" - "os_tuning_params", "net.ipv4.ip_forward: 1, net.ipv4.conf.default.rp_filter: 0, net.ipv4.conf.all.rp_filter: 0, net.bridge.bridge-nf-call-iptables: 1, net.bridge.bridge-nf-call-ip6tables: 1", "Neutron", "syctl values needed by neutron when - using openvswitch deployment scenario" + "*(ALL)* `swupd_args` : **unset**", "Optional arguments for swupd" + "*(ALL)* `log_debug` : **False**", "Set to True to enable debug log level on all services" + "*(Heat, Neutron, Nova, RabbitMQ)* `rabbitmq_username` : **openstack**", "User ID for RabbitMQ" + "*(Neutron, Nova)* `neutron_public_interface_name`: **unset**", "Public interface of Neutron machines, if is not set, it will take the default interface reported by `ip route`" + "*(Nova)* `nova_public_interface_name` : **unset**", "Public interface of Neutron machines, if is not set, it will take the default interface reported by `ip route`" + "*(Nova)* `nova_virt_type`: **qemu**", "Virtualization type (qemu | kvm), if this is not set, then the playbook will try to guess it" + "*(Neutron)* `os_tuning_params`: **net.ipv4.ip_forward: 1, net.ipv4.conf.default.rp_filter: 0, net.ipv4.conf.all.rp_filter: 0, net.bridge.bridge-nf-call-iptables: 1, net.bridge.bridge-nf-call-ip6tables: 1**", "syctl values needed by neutron when using openvswitch deployment scenario" Note: ----- From 952485ee678119dcea26de2f88fa97bcacfb986e Mon Sep 17 00:00:00 2001 From: "Simental Magana, Marcos" Date: Fri, 8 Apr 2016 15:05:55 -0500 Subject: [PATCH 13/25] Fix "Required Parameters Per Component" table --- source/openstack_conf_vars_list.rst | 51 ++++++++++++++--------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/source/openstack_conf_vars_list.rst b/source/openstack_conf_vars_list.rst index 1e513de7..30c4a1c0 100644 --- a/source/openstack_conf_vars_list.rst +++ b/source/openstack_conf_vars_list.rst @@ -7,35 +7,34 @@ This installer provides a variety of configurations you can set through variables; below you will find a reference of the components supported with Clear Linux* OS for Intel® Architecture. -.. csv-table:: "Required Parameters Per Component" - :header: "Variable", "Components Impacted", "Description" - :widths: 90, 90, 150 +Required Variables +================== - "rabbitmq_password", "RabbitMQ, Neutron, Nova, Heat", "Password of - RabbitMQ user " - "database_root_password", "ALL", "Password for root database user" - "keystone_database_password", "Keystone", "Password for 'keystone' - database" - "keystone_admin_password", "ALL", "Password for 'admin' user" - "glance_user_password", "Glance", "Password for 'glance' user" - "glance_database_password", "Glance", "Password for 'glance' database" - "nova_user_password", "Nova, Neutron", "Password for 'nova' user" - "nova_database_password", "Nova", "Password for 'nova' database" - "neutron_database_password", "Neutron", "Password for 'neutron' - database" - "neutron_user_password", "Neutron, Nova", "Password for 'neutron' - user" - "metadata_proxy_shared_secret", "Neutron, Nova", "Proxy" - "heat_domain_admin_password", "Heat", "Password for heat domain admin - user" - "heat_user_password", "Heat", "Password for heat user" - "heat_database_password", "Heat", "Password for heat database" - "heat_domain", "Heat", "The heat domain that contains projects and - users for stacks" +.. csv-table:: + :header: "*(Component)* `Variable`", "Description" + :widths: 90, 150 + "*(Heat, Neutron, Nova, RabbitMQ)* `rabbitmq_password`", "Password of RabbitMQ user " + "*(ALL)* `database_root_password`","Password for root database user" + "*(Keystone)* `keystone_database_password`", "Password for 'keystone' database" + "*(ALL)* `keystone_admin_password`", "Password for 'admin' user" + "*(Glance)* `glance_user_password`", "Password for 'glance' user" + "*(Glance)* `glance_database_password`", "Password for 'glance' database" + "*(Neutron, Nova)* `nova_user_password`", "Password for 'nova' user" + "*(Nova)* `nova_database_password`", "Password for 'nova' database" + "*(Neutron)* `neutron_database_password`", "Password for 'neutron' database" + "*(Neutron, Nova)* `neutron_user_password`", "Password for 'neutron' user" + "*(Neutron, Nova)* `metadata_proxy_shared_secret`", "Secret for the metadata proxy" + "*(Heat)* `heat_domain_admin_password`", "Password for heat domain admin user" + "*(Heat)* `heat_user_password`", "Password for heat user" + "*(Heat)* `heat_database_password`", "Password for heat database" + "*(Heat)* `heat_domain`", "The heat domain that contains projects and users for stacks" -.. csv-table:: "Optional Parameters Per Component" - :header: "*(Component)* `Variable` : **Value**", "Description" +Optional Variables +================== + +.. csv-table:: + :header: "*(Component)* `Variable` : **Default value**", "Description" :widths: 90, 150 "*(ALL)* `swupd_args` : **unset**", "Optional arguments for swupd" From 5b7f79281ab9899fb75d8c2c86af1e21f1ce00db Mon Sep 17 00:00:00 2001 From: "Simental Magana, Marcos" Date: Fri, 8 Apr 2016 15:15:24 -0500 Subject: [PATCH 14/25] Use **bold** for the variables --- source/openstack_conf_vars_list.rst | 46 ++++++++++++++--------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/source/openstack_conf_vars_list.rst b/source/openstack_conf_vars_list.rst index 30c4a1c0..fe054757 100644 --- a/source/openstack_conf_vars_list.rst +++ b/source/openstack_conf_vars_list.rst @@ -14,36 +14,36 @@ Required Variables :header: "*(Component)* `Variable`", "Description" :widths: 90, 150 - "*(Heat, Neutron, Nova, RabbitMQ)* `rabbitmq_password`", "Password of RabbitMQ user " - "*(ALL)* `database_root_password`","Password for root database user" - "*(Keystone)* `keystone_database_password`", "Password for 'keystone' database" - "*(ALL)* `keystone_admin_password`", "Password for 'admin' user" - "*(Glance)* `glance_user_password`", "Password for 'glance' user" - "*(Glance)* `glance_database_password`", "Password for 'glance' database" - "*(Neutron, Nova)* `nova_user_password`", "Password for 'nova' user" - "*(Nova)* `nova_database_password`", "Password for 'nova' database" - "*(Neutron)* `neutron_database_password`", "Password for 'neutron' database" - "*(Neutron, Nova)* `neutron_user_password`", "Password for 'neutron' user" - "*(Neutron, Nova)* `metadata_proxy_shared_secret`", "Secret for the metadata proxy" - "*(Heat)* `heat_domain_admin_password`", "Password for heat domain admin user" - "*(Heat)* `heat_user_password`", "Password for heat user" - "*(Heat)* `heat_database_password`", "Password for heat database" - "*(Heat)* `heat_domain`", "The heat domain that contains projects and users for stacks" + "*(Heat, Neutron, Nova, RabbitMQ)* **rabbitmq_password**", "Password of RabbitMQ user " + "*(ALL)* **database_root_password**","Password for root database user" + "*(Keystone)* **keystone_database_password**", "Password for 'keystone' database" + "*(ALL)* **keystone_admin_password**", "Password for 'admin' user" + "*(Glance)* **glance_user_password**", "Password for 'glance' user" + "*(Glance)* **glance_database_password**", "Password for 'glance' database" + "*(Neutron, Nova)* **nova_user_password**", "Password for 'nova' user" + "*(Nova)* **nova_database_password**", "Password for 'nova' database" + "*(Neutron)* **neutron_database_password**", "Password for 'neutron' database" + "*(Neutron, Nova)* **neutron_user_password**", "Password for 'neutron' user" + "*(Neutron, Nova)* **metadata_proxy_shared_secret**", "Secret for the metadata proxy" + "*(Heat)* **heat_domain_admin_password**", "Password for heat domain admin user" + "*(Heat)* **heat_user_password**", "Password for heat user" + "*(Heat)* **heat_database_password**", "Password for heat database" + "*(Heat)* **heat_domain**", "The heat domain that contains projects and users for stacks" Optional Variables ================== .. csv-table:: - :header: "*(Component)* `Variable` : **Default value**", "Description" + :header: "*(Component)* **Variable** : Default value", "Description" :widths: 90, 150 - "*(ALL)* `swupd_args` : **unset**", "Optional arguments for swupd" - "*(ALL)* `log_debug` : **False**", "Set to True to enable debug log level on all services" - "*(Heat, Neutron, Nova, RabbitMQ)* `rabbitmq_username` : **openstack**", "User ID for RabbitMQ" - "*(Neutron, Nova)* `neutron_public_interface_name`: **unset**", "Public interface of Neutron machines, if is not set, it will take the default interface reported by `ip route`" - "*(Nova)* `nova_public_interface_name` : **unset**", "Public interface of Neutron machines, if is not set, it will take the default interface reported by `ip route`" - "*(Nova)* `nova_virt_type`: **qemu**", "Virtualization type (qemu | kvm), if this is not set, then the playbook will try to guess it" - "*(Neutron)* `os_tuning_params`: **net.ipv4.ip_forward: 1, net.ipv4.conf.default.rp_filter: 0, net.ipv4.conf.all.rp_filter: 0, net.bridge.bridge-nf-call-iptables: 1, net.bridge.bridge-nf-call-ip6tables: 1**", "syctl values needed by neutron when using openvswitch deployment scenario" + "*(ALL)* **swupd_args**: unset", "Optional arguments for swupd" + "*(ALL)* **log_debug**: False", "Set to True to enable debug log level on all services" + "*(Heat, Neutron, Nova, RabbitMQ)* **rabbitmq_username**: openstack", "User ID for RabbitMQ" + "*(Neutron, Nova)* **neutron_public_interface_name**: unset", "Public interface of Neutron machines, if is not set, it will take the default interface reported by **ip route**" + "*(Nova)* **nova_public_interface_name**: unset", "Public interface of Neutron machines, if is not set, it will take the default interface reported by **ip route**" + "*(Nova)* **nova_virt_type**: qemu", "Virtualization type (qemu | kvm), if this is not set, then the playbook will try to guess it" + "*(Neutron)* **os_tuning_params**: net.ipv4.ip_forward: 1, net.ipv4.conf.default.rp_filter: 0, net.ipv4.conf.all.rp_filter: 0, net.bridge.bridge-nf-call-iptables: 1, net.bridge.bridge-nf-call-ip6tables: 1", "syctl values needed by neutron when using openvswitch deployment scenario" Note: ----- From 4cf62418d48439e53afe0aadea5934abaff041cd Mon Sep 17 00:00:00 2001 From: "Tullis, Michael L" Date: Mon, 11 Apr 2016 10:52:12 -0600 Subject: [PATCH 15/25] Fix two hyperlinks in bundles_overview.rst. --- source/bundles_overview.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/bundles_overview.rst b/source/bundles_overview.rst index 7a27d37a..e99b88ef 100644 --- a/source/bundles_overview.rst +++ b/source/bundles_overview.rst @@ -194,7 +194,7 @@ Current list of available bundles: - Games + games ACTIVE

A colossal, but entertaining waste of time

@@ -419,7 +419,7 @@ Current list of available bundles: - openstack-common + openstack-common WIP

common components for OpenStack functionalit

From 860ca51432415db4e6205f0dcb9a48878af8dd75 Mon Sep 17 00:00:00 2001 From: "Tullis, Michael L" Date: Mon, 11 Apr 2016 16:03:39 -0600 Subject: [PATCH 16/25] Fixed and verified in local build two broken hyperlinks in bundles_overview.rst --- source/bundles_overview.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/bundles_overview.rst b/source/bundles_overview.rst index e99b88ef..3d4a2451 100644 --- a/source/bundles_overview.rst +++ b/source/bundles_overview.rst @@ -194,7 +194,7 @@ Current list of available bundles: - games + games ACTIVE

A colossal, but entertaining waste of time

@@ -419,7 +419,7 @@ Current list of available bundles: - openstack-common + openstack-common WIP

common components for OpenStack functionalit

From ad873384eb6a8ac960fbe2fbd69274e17dece636 Mon Sep 17 00:00:00 2001 From: Mario Alfredo Carrillo Arevalo Date: Tue, 12 Apr 2016 14:30:25 -0500 Subject: [PATCH 17/25] add DPDK and OVS-DPDK documentation Signed-off-by: Mario Alfredo Carrillo Arevalo --- source/_static/images/pktgen_lw3fd.png | Bin 0 -> 32343 bytes source/_static/images/pyshical_net.png | Bin 0 -> 16772 bytes source/_static/images/use_case.png | Bin 0 -> 28030 bytes source/ac-dpdk.rst | 332 ++++++++++++++++++++++++ source/ac-ovs-dpdk.rst | 289 +++++++++++++++++++++ source/index_advanced_configuration.rst | 5 +- 6 files changed, 625 insertions(+), 1 deletion(-) create mode 100644 source/_static/images/pktgen_lw3fd.png create mode 100644 source/_static/images/pyshical_net.png create mode 100644 source/_static/images/use_case.png create mode 100644 source/ac-dpdk.rst create mode 100644 source/ac-ovs-dpdk.rst diff --git a/source/_static/images/pktgen_lw3fd.png b/source/_static/images/pktgen_lw3fd.png new file mode 100644 index 0000000000000000000000000000000000000000..6c67de906f1a365ba6fb045410014a923a1d6952 GIT binary patch literal 32343 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 literal 0 HcmV?d00001 diff --git a/source/_static/images/use_case.png b/source/_static/images/use_case.png new file mode 100644 index 0000000000000000000000000000000000000000..0d9be8bb942ea9dff5a9ca0ae1b046310064bbe3 GIT binary patch literal 28030 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 X8zfzwki;)gBe`-}MJD;uJ=gyOGwWRV literal 0 HcmV?d00001 diff --git a/source/ac-dpdk.rst b/source/ac-dpdk.rst new file mode 100644 index 00000000..159a5c2f --- /dev/null +++ b/source/ac-dpdk.rst @@ -0,0 +1,332 @@ +.. _ac-dpdk: + +Clear Linux & DPDK +################## + +Introduction +============ + +This document describes HOWTO run a basic use case that involves to l3fwd DPDK example, the objective is to send +packages between 2 platforms using a traffic generator called pktgen where l3fwd example application will forward +those packages (figure 1.0). + +.. figure:: _static/images/pktgen_lw3fd.png + + figure 1.0 environment for l3fwd DPDK application. + + +**Requirements:** + +* 2 platform using Clear Linux (recommended release 7160). +* both Clear Linux images have to use kernel-native +* Install "dpdk-dev", "os-core-dev" and "sysadmin-basic" bundles + + .. code-block:: bash + + $ swupd bundle-add dpdk-dev os-core-dev sysadmin-basic + +* The Platforms must have 2 NICs at least each one, check Network cards compatibility, it's very important to verify if your NIC is compatible with DPDK project, you can check it in this site http://dpdk.org/doc/nics. +* 2 Network cables. + + +1. Disable iommu on Clear Linux (platform A and B). +=================================================== + +1. mount sda1 partition + + .. code-block:: bash + + $ mkdir mnt + $ mount /dev/sda1 mnt + +2. move to entries directory + + .. code-block:: bash + + $ cd mnt/loader/entries/ + + edit **Clear-linux-native-.conf** and add **intel_iommu=off** in the end of the last line. + +3. Umount partition and reboot + + .. code-block:: bash + + cd ../../../ + umount mnt + reboot + + +2. Installing dpdk bundle on Clear Linux and build l3fwd example (platform B). +============================================================================== + +1. Install dpdk bundle you can use the following command: + + .. code-block:: bash + + $ swupd bundle-add dpdk-dev + +2. Move to l3fwd example + + .. code-block:: bash + + $ cd /usr/share/dpdk/examples/l3fwd + +3. Assign RTE_SDK var the path where makefiles are + + .. code-block:: bash + + $ export RTE_SDK=/usr/share/dpdk/ + +4. Assign RTE_TARGET var the value where config file is + + .. code-block:: bash + + $ export RTE_TARGET=x86_64-native-linuxapp-gcc + +5. Build the l3fwd application and add the configuration header to CFLAGS var + + .. code-block:: bash + + $ make CFLAGS+="-include /usr/include/rte_config.h" + + +3. Building pktgen (platform A). +================================ + +Currently pktgen project is not included in Clear Linux, for that reason it is necessary to download it from upstream and build it: + +1. Install dpdk bundle + + .. code-block:: bash + + $ swupd bundle-add dpdk-dev + +2. Download pktgen tar package 2.9.12 version from this site: http://dpdk.org/browse/apps/pktgen-dpdk/refs/ + +3. Decompress packages and move to uncompressed source directory. + +4. Assign RTE_SDK var the path where makefiles are + + .. code-block:: bash + + $ export RTE_SDK=/usr/share/dpdk/ + +5. Assign RTE_TARGET var the value where config file is + + .. code-block:: bash + + $ export RTE_TARGET=x86_64-native-linuxapp-gcc + +6. Build Pktgen project setting CONFIG_RTE_BUILD_SHARED_LIB variable with "n" + + .. code-block:: bash + + $ make CONFIG_RTE_BUILD_SHARED_LIB=n + + +4. Binding NIC's to dpdk kernel drivers (platform A and B). +============================================================= + +l3fwd application will use 2 NIC's, DPDK has useful tools in order for binding NICs to DPDK modules in order to run DPDK applications. + +1. Load dpdk I/O kernel module + + .. code-block:: bash + + $ modprobe igb_uio + +2. Check your status of your NIC's, this in order to know which network cards are not busy, in case that another application is using them, the status will be “Active” and those NICs could not be bound. + + .. code-block:: bash + + $ dpdk_nic_bind.py --status + +3. Binding 2 available NICs using the syntax: **dpdk_nic_bind.py --bind=igb_uio ** , example: + + .. code-block:: bash + + $ dpdk_nic_bind.py --bind=igb_uio 01:00.0 + +4. Be sure that your NIC's was binding correctly checking the status (point 2), drv should has igb_uio value, at this point the NIC's are using the DPDK modules. + + +5. Setting hugepages (platform A and B). +========================================== + +Clear Linux supports hugepages for the large memory pool allocation used for packet buffers. + +1. Set number of hugepages. + + .. code-block:: bash + + $ echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages + +2. Allocate pages on NUMA machines. + + .. code-block:: bash + + $ echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages + $ echo 1024 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages + +3. Making memory available for DPDK. + + .. code-block:: bash + + $ mkdir -p /mnt/huge $ mount -t hugetlbfs nodev /mnt/huge + + If you would like to know more about this, you can check this site: http://dpdk.org/doc/guides/linux_gsg/sys_reqs.html + + +6. Setting a physical environment (platform A and B). +===================================================== + +In order to achieve the model proposed in the introduction of this document (figure 1.0), we need to connect the first grantley’s NICs to the second grantley’s NICs using the network cables (Figure 2.0). + +.. figure:: _static/images/pyshical_net.png + + figure 2.0 Physical network environment. + + +7. Running l3fwd application (platform B). +========================================== + +l3fwd application is one of the DPDK examples available when you install dpdk-dev bundle, this application is going to forward packages for one NIC to another. + +1. Move to l3fwd example + + .. code-block:: bash + + $ cd /usr/share/dpdk/examples/l3fwd + +2. The next step is very important, DPDK needs poll drivers for working, these poll drivers are shared objects and they are in /usr/lib64, dpdk just support some NICs, you can see which in the next link: , you need to know which kernel module the NIC is using and choose poll driver according to your NICs. + +3. At this point the system must have hugepages requirements and the NICs bound and the configuration for running pktgen depends to the network use case and the available system resources, use “-d” flag for setting the pull driver, example, the NICs’ are using e1000 network driver, this means that they are going to use e1000 poll driver (librte_pmd_e1000.so), it should be in /usr/lib64 in clear linux and it should be enough to add the name, e.g + + .. code-block:: bash + + $ ./build/l3fwd -c 0x3 -n 2 -d librte_pmd_e1000.so -- -p 0x3 --config="(0,0,0),(1,0,1)" + +4. When the application start to run, it will show a lot information about the steps that l3fwd is doing, pay attention when the application in the step when it is Initializing ports, after port 0 initialization it will show a mac address and the same for port 1, save this information in order to set configuration to Pktgen project. + + +8. Running pktgen application (platform A). +=========================================== + +Pktgen is network traffic generator, it will be used to measure the network packaging performance in a forwarding use case. + +1. At this point the system must have hugepages requirements and the NICs bound, and the configuration for running pktgen depends to the network use case and the available system resources, this is just a basic configuration. + + .. code-block:: bash + + $ ./app/app/x86_64-native-linuxapp-gcc/pktgen -c 0xf -n 4 -- -p 0xf -P -m "1.0, 2.1" + +2. Active colorful output (this step is optional). + + .. code-block:: bash + + Pktgen> theme enable + +3. l3fwd application showed a mac address per port initialized, this mac addresses must have set in pktgen environment (Pktgen prompt): set mac example: + + .. code-block:: bash + + Pktgen> set mac 0 00:1E:67:CB:E8:C9 + Pktgen> set mac 1 00:1E:67:CB:E8:C9 + +4. Start to send packages using the next command: + + .. code-block:: bash + + Pktgen> start 0-1 + +5. If you have done the steps of this document correctly, you should see that pktgen is sending and receiving packages. + +For more information about Pktgen: https://media.readthedocs.org/pdf/pktgen/latest/pktgen.pdf + + +Annex A: Using pass-through for running on virtual machines. +============================================================ + +This section will explain how to do in order to work in a virtual environment where virtual machines will take the control of host's NIC's. + +1. Create a new directory and move to it. + +2. Download "start_qemu.sh" script in order to run a kvm virtual machine: + + .. code-block:: bash + + $ curl -O https://download.clearlinux.org/image/start_qemu.sh + +3. Download a bare-metal Clear Linux image and rename it as "clear.img". + +4. Look for entry for device and vendor & device ID: + + .. code-block:: bash + + $ lspci -nn | grep Ethernet + + This is an output example from last step: **03:00.0 Ethernet controller [0200]: Intel Corporation I350 Gigabit Network Connection [8086:1521]** + where 8086:1521 is vendor:device ID and 03:00.0 is the entry for device this information is necessary for unbinding host's NICs. + +5. Unbind NICs from host, this in order to do passthrough with virtual machines, currently Clear Linux support this action, you can use the following commands: + + * echo "vendor device_ID" > /sys/bus/pci/drivers/pci-stub/new_id + * echo "entry for device" > /sys/bus/pci/drivers/igb/unbind + * echo "entry for device" > /sys/bus/pci/drivers/pci-stub/bind + * echo "vendor device_ID" > /sys/bus/pci/drivers/pci-stub/remove_id + + e.g + + .. code-block:: bash + + $ echo "8086 1521" > /sys/bus/pci/drivers/pci-stub/new_id + $ echo "0000:03:00.0" > /sys/bus/pci/drivers/igb/unbind + $ echo "0000:03:00.0" > /sys/bus/pci/drivers/pci-stub/bind + $ echo "8086 1521" > /sys/bus/pci/drivers/pci-stub/remove_id + +6. Assign to kvm virtual machine (guest) the unbound NICs previously. Modify the "start_qemu.sh" script in qemu-system-x86_64 arguments, and add the lines with the host's NICs information. + + **-device pci-assign,host="",id=passnic0,addr=03.0** + **-device pci-assign,host="",id=passnic1,addr=04.0** + + e.g + + .. code-block:: bash + + -device pci-assign,host=03:00.0,id=passnic0,addr=03.0 \ + -device pci-assign,host=03:00.3,id=passnic1,addr=04.0 \ + +5. Assign to kvm virtual machine (guest) the unbound NICs previously. Modify the "start_qemu.sh" script in qemu-system-x86_64 arguments, and add the lines with the host's NICs information. + + **-device pci-assign,host="",id=passnic0,addr=03.0** + **-device pci-assign,host="",id=passnic1,addr=04.0** + + e.g + + .. code-block:: bash + + -device pci-assign,host=03:00.0,id=passnic0,addr=03.0 \ + -device pci-assign,host=03:00.3,id=passnic1,addr=04.0 \ + + +6. If you would like to add more NUMA machines to the virtual machine, you can add the next line in Makefile boot target: + + **-numa node,mem=,cpus=** + + e.g. + + you have a virtual machine with 4096 of memory and 4 cpus the configuration should be next: + + .. code-block:: bash + + -numa node,mem=2048,cpus=0-1 \ + -numa node,mem=2048,cpus=2-3 \ + + this means that each NUMA machine have to use the same quantity of memory. + +7. Run "start_qemu.sh" script. + + + + + diff --git a/source/ac-ovs-dpdk.rst b/source/ac-ovs-dpdk.rst new file mode 100644 index 00000000..df46048a --- /dev/null +++ b/source/ac-ovs-dpdk.rst @@ -0,0 +1,289 @@ +.. _ac-ovs-dpdk: + +OpenvSwitch and DPDK use case +############################# + +Introduction +============ + +OpenvSwitch project using DPDK support gets an important network performance, an easy way for +understanding the magnitude of this increment is to compare to another software solution and +even compare with itself without using DPDK support, this document describes the "HOWTO" about +a simple use case (figure 1.0) where one virtual machine sends 1 million of HTTP requests to +another virtual machine using Linux bridges, OpenvSwitch bridges and of course +OpenvSwitch-DPDK bridges as a network link. + +.. figure:: _static/images/use_case.png + + figure 1.0 Basic virtual network environment. + +**Requirements:** + +* 1 platform using Clear Linux (recommended release 7160) for host +* The Clear Linux image for host has to use kernel-native +* Install "network-advanced" and "os-clr-on-clr" bundles + + .. code-block:: bash + + $ swupd bundle-add network-advanced os-clr-on-clr + +* Get 2 Clear Linux kvm images (recommended release 7160), these images will be the guest virtual machines, you can download them https://download.clearlinux.org/releases/. The virtual machines must have installed "network-basic" and "lamp-basic" bundles. + + .. code-block:: bash + + $ swupd bundle-add network-basic lamp-basic + + +Using Linux Bridges +=================== + +1. Create an UP script for linux bridge in a virtual machine **(qemu-ifup)**. + + .. code-block:: bash + + #!/bin/bash + set -x + switch=br0 + if [ -n "$1" ];then + tunctl -u whoami -t $1 + ip link set $1 up + sleep 0.5s + brctl addif $switch $1 + exit 0 + else + echo "Error: no interface specified" + exit 1 + fi + +2. Change permissions to up script. + + .. code-block:: bash + + $ chmod a+x qemu-ifup + +3. Create a bridge using the openvswitch tool, you can verify if the bridge was created using ip tool. + + .. code-block:: bash + + $ brctl addbr br0 + + Note: At this point as an option is possible to add a NIC with the next command: **brctl addif br0 ** e.g: + + .. code-block:: bash + + $ brctl addif br0 enp3s0f0 + + If the last option is used, and the NIC is connected to DHCP server, the 1 and 2 steps should be omitted in "Setting ip address" section. + +4. Setup the linux bridge + + .. code-block:: bash + + $ ip link set dev br0 up + +5. Run guest virtual machine A using the next configuration as reference, where **$IMAGE** var is the clear linux image name. + + .. code-block:: bash + + qemu-system-x86_64 \ + -enable-kvm -m 1024 \ + -bios OVMF.fd \ + -smp cpus=2,cores=1 -cpu host \ + -vga none -nographic \ + -drive file="$IMAGE",if=virtio,aio=threads \ + -net nic,macaddr=00:11:22:33:44:55,model=virtio -net tap,script=qemu-ifup \ + -debugcon file:debug.log -global isa-debugcon.iobase=0x402 + + +6. Run guest virtual machine B using the configuration from step 4, only it's necessary to change the mac address, example: 00:11:22:33:44:56 + +7. Follow instructions from "Setting ip address" section. + +8. In order to clean the previous environment, turn off the virtual machines and delete the bridge. + + .. code-block:: bash + + $ ip link set dev br0 down + $ brctl delbr br0 + + +Using OpenvSwitch +================= + +1. Start OpenvSwitch service. + + .. code-block:: bash + + $ systemctl start openvswitch.service + +2. Create a bridge using the openvswitch tool, you can verify if the bridge was created using ip tool. + + .. code-block:: bash + + $ ovs-vsctl add-br br0 + $ ip a + +3. Create **UP-DOWN** scripts, this is in order to bring up the tap devices into the bridge created in the step 2 for **ovs-ifdown** script: + + .. code-block:: bash + + #!/bin/sh + switch="br0" + /usr/bin/ifconfig $1 0.0.0.0 down + ovs-vsctl del-port ${switch} $1 + + and for **ovs-ifup script**: + + .. code-block:: bash + + #!/bin/sh + switch="br0" + /usr/bin/ifconfig $1 0.0.0.0 up + ovs-vsctl add-port ${switch} $1 + +4. Change permissions to up-down scripts + + .. code-block:: bash + + $ chmod a+x ovs-ifdown + $ chmod a+x ovs-ifup + +5. Run guest virtual machine A using the next configuration as reference, where **$IMAGE** var is the clear linux image name, notice that network configuration use the up-down scripts (step ). + + .. code-block:: bash + + qemu-system-x86_64 \ + -enable-kvm -m 1024 \ + -bios OVMF.fd \ + -smp cpus=2,cores=1 -cpu host \ + -vga none -nographic \ + -drive file="$IMAGE",if=virtio,aio=threads \ + -net nic,model=virtio,macaddr=00:11:22:33:44:55 -net tap,script=ovs-ifup,downscript=ovs-ifdown \ + -debugcon file:debug.log -global isa-debugcon.iobase=0x402 + +6. Run guest virtual machine B using the configuration from step 5, only it's necessary to change the mac address, you could use this: *00:11:22:33:44:56* + +7. Follow instructions from "Setting ip address" section. + + +Using Linux OpenvSwitch-DPDK +============================ + +1. Use a new environment and add **iommu=pt intel_iommu=on** to kernel command line. + + .. code-block:: bash + + $mkdir mnt + $ mount /dev/sda1 mnt + $ cd mnt/loader/entries/ + + Edit Clear-linux-native-.conf and add **iommu=pt intel_iommu=on** in the end of the line, umount and reboot. + + .. code-block:: bash + + $ cd ../../../ + $ umount mnt + $ reboot + + +2. Set number of hugepages + + .. code-block:: bash + + $ echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages + +3. Allocate pages on NUMA machines + + .. code-block:: bash + + $ echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages + $ echo 1024 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages + +4. Making memory available for DPDK. + + .. code-block:: bash + + $ mkdir -p /mnt/huge + $ mount -t hugetlbfs nodev /mnt/huge + +5. Add cores and memory configuration to OpenvSwitch example, the file **/usr/share/openvswitch/scripts/ovs-ctl** can be edited in the line 256 and add DPDK configuration it should look like this: **set ovs-vswitchd --dpdk -c 0x2 -n 4 --socket-mem 2048 -- unix:"$DB_SOCK"** or the next regular expression could be helpful: + + .. code-block:: bash + + $ sed -i s/"set ovs-vswitchd unix:"/"set ovs-vswitchd --dpdk -c 0x2 -n 4 --socket-mem 2048 -- unix:"/g /usr/share/openvswitch/scripts/ovs-ctl + +6. Start OpenvSwitch service + + .. code-block:: bash + + $ systemctl start openvswitch.service + +7. Create a virtual bridge using openvswitch + + .. code-block:: bash + + $ ovs-vsctl add-br br0 -- set bridge br0 datapath_type=netdev + +8. Add dpdk ports to the bridge + + .. code-block:: bash + + $ ovs-vsctl add-port br0 vhost-user1 -- set Interface vhost-user1 type=dpdkvhostuser + $ ovs-vsctl add-port br0 vhost-user2 -- set Interface vhost-user2 type=dpdkvhostuser + + +9. Run guest virtual machine A using the next configuration as reference, where **$IMAGE** var is the clear linux image name. + + .. code-block:: bash + + qemu-system-x86_64 \ + -enable-kvm -m 1024 \ + -bios OVMF.fd \ + -smp 4 -cpu host \ + -vga none -nographic \ + -drive file="$IMAGE",if=virtio,aio=threads \ + -chardev socket,id=char1,path=/run/openvswitch/vhost-user1 \ + -netdev type=vhost-user,id=mynet1,chardev=char1,vhostforce \ + -device virtio-net-pci,mac=00:00:00:00:00:01,netdev=mynet1 \ + -object memory-backend-file,id=mem,size=1024M,mem-path=/dev/hugepages,share=on \ + -numa node,memdev=mem -mem-prealloc \ + -debugcon file:debug.log -global isa-debugcon.iobase=0x402 + + +10. Run guest virtual machine B, use the configuration from step 6, only it's necessary change the mac address and the port socket, you can use 00:00:00:00:00:02 as a mac address and vhost-user2 as a socket. + +11. Follow instructions from "Setting ip address" section. + + +Setting ip address +====================== + +1. Set ip address to virtual machine for virtual machine A: + + .. code-block:: bash + + $ ip addr add dev enp0s2 10.0.0.5/24 + + for virtual machine B: + + .. code-block:: bash + + $ ip addr add dev enp0s2 10.0.0.6/24 + +2. Check if there is communication between both virtual machines using ping tool. + +3. Verify if apache service is running: + + .. code-block:: bash + + $ systemctl status httpd.service + $ systemctl start httpd.service + + (start httpd service only if it is inactive). + Use apache benchmark in order to get information about the network performance between both virtual machines. + + .. code-block:: bash + + $ ab -n 1000000 -c 100 http://10.0.0.6/ + + diff --git a/source/index_advanced_configuration.rst b/source/index_advanced_configuration.rst index 85e98e83..3de0284c 100644 --- a/source/index_advanced_configuration.rst +++ b/source/index_advanced_configuration.rst @@ -5,4 +5,7 @@ Advanced configuration :maxdepth: 2 network_boot - mixer \ No newline at end of file + mixer + ac-dpdk + ac-ovs-dpdk + From 6735fa36f295e93c0aebe1e89838b03a94a68392 Mon Sep 17 00:00:00 2001 From: Mario Alfredo Carrillo Arevalo Date: Tue, 12 Apr 2016 15:55:38 -0500 Subject: [PATCH 18/25] fix symbols on ac-dpdk --- source/ac-dpdk.rst | 95 ++++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 42 deletions(-) diff --git a/source/ac-dpdk.rst b/source/ac-dpdk.rst index 159a5c2f..c6f5f989 100644 --- a/source/ac-dpdk.rst +++ b/source/ac-dpdk.rst @@ -6,24 +6,29 @@ Clear Linux & DPDK Introduction ============ -This document describes HOWTO run a basic use case that involves to l3fwd DPDK example, the objective is to send -packages between 2 platforms using a traffic generator called pktgen where l3fwd example application will forward -those packages (figure 1.0). +This document describes *how to* run a basic use case that involves **l3fwd +DPDK example**, the objective is to *send packages between 2 platforms* using a +traffic generator called :ref:`pktgen ` where l3fwd example +application will forward those packages (:ref:`f1`). + +.. _f1: .. figure:: _static/images/pktgen_lw3fd.png + :align: center + :alt: platform A and B - figure 1.0 environment for l3fwd DPDK application. + Figure 1: environment for l3fwd DPDK application. **Requirements:** -* 2 platform using Clear Linux (recommended release 7160). -* both Clear Linux images have to use kernel-native +* 2 platform using Clear Linux (recommended release 7160 or higher). +* both Clear Linux images have to use **kernel-native boundle** * Install "dpdk-dev", "os-core-dev" and "sysadmin-basic" bundles - .. code-block:: bash - - $ swupd bundle-add dpdk-dev os-core-dev sysadmin-basic + .. code-block:: bash + + # swupd bundle-add dpdk-dev os-core-dev sysadmin-basic * The Platforms must have 2 NICs at least each one, check Network cards compatibility, it's very important to verify if your NIC is compatible with DPDK project, you can check it in this site http://dpdk.org/doc/nics. * 2 Network cables. @@ -32,28 +37,26 @@ those packages (figure 1.0). 1. Disable iommu on Clear Linux (platform A and B). =================================================== -1. mount sda1 partition +1. mount the :abbr:`ESP (EFI system partition)` - .. code-block:: bash + .. code-block:: bash - $ mkdir mnt - $ mount /dev/sda1 mnt + # systemctl start boot.mount 2. move to entries directory - .. code-block:: bash + .. code-block:: bash - $ cd mnt/loader/entries/ + # cd /boot/loader/entries/ edit **Clear-linux-native-.conf** and add **intel_iommu=off** in the end of the last line. -3. Umount partition and reboot +3. Umount *ESP* and reboot - .. code-block:: bash + .. code-block:: bash - cd ../../../ - umount mnt - reboot + # systemctl start boot.mount + # reboot 2. Installing dpdk bundle on Clear Linux and build l3fwd example (platform B). @@ -63,43 +66,47 @@ those packages (figure 1.0). .. code-block:: bash - $ swupd bundle-add dpdk-dev + # swupd bundle-add dpdk-dev 2. Move to l3fwd example .. code-block:: bash - $ cd /usr/share/dpdk/examples/l3fwd + # cd /usr/share/dpdk/examples/l3fwd 3. Assign RTE_SDK var the path where makefiles are .. code-block:: bash - $ export RTE_SDK=/usr/share/dpdk/ + # export RTE_SDK=/usr/share/dpdk/ 4. Assign RTE_TARGET var the value where config file is .. code-block:: bash - $ export RTE_TARGET=x86_64-native-linuxapp-gcc + # export RTE_TARGET=x86_64-native-linuxapp-gcc 5. Build the l3fwd application and add the configuration header to CFLAGS var .. code-block:: bash - $ make CFLAGS+="-include /usr/include/rte_config.h" + # make CFLAGS+="-include /usr/include/rte_config.h" + +.. _sec_pktgen: + 3. Building pktgen (platform A). ================================ -Currently pktgen project is not included in Clear Linux, for that reason it is necessary to download it from upstream and build it: +Currently **pktgen project** is not included in Clear Linux, for that reason +it is necessary to download it from upstream and build it: 1. Install dpdk bundle .. code-block:: bash - $ swupd bundle-add dpdk-dev + # swupd bundle-add dpdk-dev 2. Download pktgen tar package 2.9.12 version from this site: http://dpdk.org/browse/apps/pktgen-dpdk/refs/ @@ -109,19 +116,19 @@ Currently pktgen project is not included in Clear Linux, for that reason it is n .. code-block:: bash - $ export RTE_SDK=/usr/share/dpdk/ + # export RTE_SDK=/usr/share/dpdk/ 5. Assign RTE_TARGET var the value where config file is .. code-block:: bash - $ export RTE_TARGET=x86_64-native-linuxapp-gcc + # export RTE_TARGET=x86_64-native-linuxapp-gcc 6. Build Pktgen project setting CONFIG_RTE_BUILD_SHARED_LIB variable with "n" .. code-block:: bash - $ make CONFIG_RTE_BUILD_SHARED_LIB=n + # make CONFIG_RTE_BUILD_SHARED_LIB=n 4. Binding NIC's to dpdk kernel drivers (platform A and B). @@ -133,19 +140,19 @@ l3fwd application will use 2 NIC's, DPDK has useful tools in order for binding N .. code-block:: bash - $ modprobe igb_uio + # modprobe igb_uio 2. Check your status of your NIC's, this in order to know which network cards are not busy, in case that another application is using them, the status will be “Active” and those NICs could not be bound. .. code-block:: bash - $ dpdk_nic_bind.py --status + # dpdk_nic_bind.py --status 3. Binding 2 available NICs using the syntax: **dpdk_nic_bind.py --bind=igb_uio ** , example: .. code-block:: bash - $ dpdk_nic_bind.py --bind=igb_uio 01:00.0 + # dpdk_nic_bind.py --bind=igb_uio 01:00.0 4. Be sure that your NIC's was binding correctly checking the status (point 2), drv should has igb_uio value, at this point the NIC's are using the DPDK modules. @@ -159,20 +166,20 @@ Clear Linux supports hugepages for the large memory pool allocation used for pac .. code-block:: bash - $ echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages + # echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages 2. Allocate pages on NUMA machines. .. code-block:: bash - $ echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages - $ echo 1024 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages + # echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages + # echo 1024 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages 3. Making memory available for DPDK. .. code-block:: bash - $ mkdir -p /mnt/huge $ mount -t hugetlbfs nodev /mnt/huge + # mkdir -p /mnt/huge $ mount -t hugetlbfs nodev /mnt/huge If you would like to know more about this, you can check this site: http://dpdk.org/doc/guides/linux_gsg/sys_reqs.html @@ -180,11 +187,15 @@ Clear Linux supports hugepages for the large memory pool allocation used for pac 6. Setting a physical environment (platform A and B). ===================================================== -In order to achieve the model proposed in the introduction of this document (figure 1.0), we need to connect the first grantley’s NICs to the second grantley’s NICs using the network cables (Figure 2.0). +In order to achieve the model proposed in the introduction of this document +(:ref:`f1`), we need to connect the first grantley’s NICs to the second +grantley’s NICs using the network cables (:ref:`f2`). + +.. _f2: .. figure:: _static/images/pyshical_net.png - figure 2.0 Physical network environment. + Figure 2: Physical network environment. 7. Running l3fwd application (platform B). @@ -196,7 +207,7 @@ l3fwd application is one of the DPDK examples available when you install dpdk-de .. code-block:: bash - $ cd /usr/share/dpdk/examples/l3fwd + # cd /usr/share/dpdk/examples/l3fwd 2. The next step is very important, DPDK needs poll drivers for working, these poll drivers are shared objects and they are in /usr/lib64, dpdk just support some NICs, you can see which in the next link: , you need to know which kernel module the NIC is using and choose poll driver according to your NICs. @@ -204,7 +215,7 @@ l3fwd application is one of the DPDK examples available when you install dpdk-de .. code-block:: bash - $ ./build/l3fwd -c 0x3 -n 2 -d librte_pmd_e1000.so -- -p 0x3 --config="(0,0,0),(1,0,1)" + # ./build/l3fwd -c 0x3 -n 2 -d librte_pmd_e1000.so -- -p 0x3 --config="(0,0,0),(1,0,1)" 4. When the application start to run, it will show a lot information about the steps that l3fwd is doing, pay attention when the application in the step when it is Initializing ports, after port 0 initialization it will show a mac address and the same for port 1, save this information in order to set configuration to Pktgen project. @@ -218,7 +229,7 @@ Pktgen is network traffic generator, it will be used to measure the network pack .. code-block:: bash - $ ./app/app/x86_64-native-linuxapp-gcc/pktgen -c 0xf -n 4 -- -p 0xf -P -m "1.0, 2.1" + # ./app/app/x86_64-native-linuxapp-gcc/pktgen -c 0xf -n 4 -- -p 0xf -P -m "1.0, 2.1" 2. Active colorful output (this step is optional). From d7b99c1bd0ef9bd199088be93ab2ece119724662 Mon Sep 17 00:00:00 2001 From: Mario Alfredo Carrillo Arevalo Date: Tue, 12 Apr 2016 16:14:25 -0500 Subject: [PATCH 19/25] fix ac-dpdk umount doc --- source/ac-dpdk.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/ac-dpdk.rst b/source/ac-dpdk.rst index c6f5f989..5b748d45 100644 --- a/source/ac-dpdk.rst +++ b/source/ac-dpdk.rst @@ -55,7 +55,8 @@ application will forward those packages (:ref:`f1`). .. code-block:: bash - # systemctl start boot.mount + # cd / + # systemctl stop boot.mount # reboot From 8380fabf38a3f0d8489c4ccb81d53f8fbdfc758f Mon Sep 17 00:00:00 2001 From: Mario Alfredo Carrillo Arevalo Date: Tue, 12 Apr 2016 16:14:54 -0500 Subject: [PATCH 20/25] fix sign on ac-ovs-dpdk --- source/ac-ovs-dpdk.rst | 92 +++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 45 deletions(-) diff --git a/source/ac-ovs-dpdk.rst b/source/ac-ovs-dpdk.rst index df46048a..2fc3f583 100644 --- a/source/ac-ovs-dpdk.rst +++ b/source/ac-ovs-dpdk.rst @@ -6,16 +6,18 @@ OpenvSwitch and DPDK use case Introduction ============ -OpenvSwitch project using DPDK support gets an important network performance, an easy way for +Using *DPDK* support on **OpenvSwitch project**, gets an important network performance, an easy way for understanding the magnitude of this increment is to compare to another software solution and even compare with itself without using DPDK support, this document describes the "HOWTO" about -a simple use case (figure 1.0) where one virtual machine sends 1 million of HTTP requests to +a simple use case (:ref:`f1ovs`) where one virtual machine sends 1 million of HTTP requests to another virtual machine using Linux bridges, OpenvSwitch bridges and of course OpenvSwitch-DPDK bridges as a network link. +.. _f1ovs: + .. figure:: _static/images/use_case.png - figure 1.0 Basic virtual network environment. + Figure 1: Basic virtual network environment. **Requirements:** @@ -25,13 +27,13 @@ OpenvSwitch-DPDK bridges as a network link. .. code-block:: bash - $ swupd bundle-add network-advanced os-clr-on-clr + # swupd bundle-add network-advanced os-clr-on-clr * Get 2 Clear Linux kvm images (recommended release 7160), these images will be the guest virtual machines, you can download them https://download.clearlinux.org/releases/. The virtual machines must have installed "network-basic" and "lamp-basic" bundles. .. code-block:: bash - $ swupd bundle-add network-basic lamp-basic + # swupd bundle-add network-basic lamp-basic Using Linux Bridges @@ -59,19 +61,19 @@ Using Linux Bridges .. code-block:: bash - $ chmod a+x qemu-ifup + # chmod a+x qemu-ifup 3. Create a bridge using the openvswitch tool, you can verify if the bridge was created using ip tool. .. code-block:: bash - $ brctl addbr br0 + # brctl addbr br0 Note: At this point as an option is possible to add a NIC with the next command: **brctl addif br0 ** e.g: .. code-block:: bash - $ brctl addif br0 enp3s0f0 + # brctl addif br0 enp3s0f0 If the last option is used, and the NIC is connected to DHCP server, the 1 and 2 steps should be omitted in "Setting ip address" section. @@ -79,7 +81,7 @@ Using Linux Bridges .. code-block:: bash - $ ip link set dev br0 up + # ip link set dev br0 up 5. Run guest virtual machine A using the next configuration as reference, where **$IMAGE** var is the clear linux image name. @@ -103,8 +105,8 @@ Using Linux Bridges .. code-block:: bash - $ ip link set dev br0 down - $ brctl delbr br0 + # ip link set dev br0 down + # brctl delbr br0 Using OpenvSwitch @@ -114,14 +116,14 @@ Using OpenvSwitch .. code-block:: bash - $ systemctl start openvswitch.service + # systemctl start openvswitch.service 2. Create a bridge using the openvswitch tool, you can verify if the bridge was created using ip tool. .. code-block:: bash - $ ovs-vsctl add-br br0 - $ ip a + # ovs-vsctl add-br br0 + # ip a 3. Create **UP-DOWN** scripts, this is in order to bring up the tap devices into the bridge created in the step 2 for **ovs-ifdown** script: @@ -145,8 +147,8 @@ Using OpenvSwitch .. code-block:: bash - $ chmod a+x ovs-ifdown - $ chmod a+x ovs-ifup + # chmod a+x ovs-ifdown + # chmod a+x ovs-ifup 5. Run guest virtual machine A using the next configuration as reference, where **$IMAGE** var is the clear linux image name, notice that network configuration use the up-down scripts (step ). @@ -173,63 +175,62 @@ Using Linux OpenvSwitch-DPDK .. code-block:: bash - $mkdir mnt - $ mount /dev/sda1 mnt - $ cd mnt/loader/entries/ + # systemctl start boot.mount + # cd /boot/loader/entries/ Edit Clear-linux-native-.conf and add **iommu=pt intel_iommu=on** in the end of the line, umount and reboot. .. code-block:: bash - - $ cd ../../../ - $ umount mnt - $ reboot + + # cd / + # systemctl stop boot.mount + # reboot 2. Set number of hugepages .. code-block:: bash - $ echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages + # echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages 3. Allocate pages on NUMA machines .. code-block:: bash - $ echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages - $ echo 1024 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages + # echo 1024 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages + # echo 1024 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages 4. Making memory available for DPDK. .. code-block:: bash - $ mkdir -p /mnt/huge - $ mount -t hugetlbfs nodev /mnt/huge + # mkdir -p /mnt/huge + # mount -t hugetlbfs nodev /mnt/huge 5. Add cores and memory configuration to OpenvSwitch example, the file **/usr/share/openvswitch/scripts/ovs-ctl** can be edited in the line 256 and add DPDK configuration it should look like this: **set ovs-vswitchd --dpdk -c 0x2 -n 4 --socket-mem 2048 -- unix:"$DB_SOCK"** or the next regular expression could be helpful: .. code-block:: bash - $ sed -i s/"set ovs-vswitchd unix:"/"set ovs-vswitchd --dpdk -c 0x2 -n 4 --socket-mem 2048 -- unix:"/g /usr/share/openvswitch/scripts/ovs-ctl + # sed -i s/"set ovs-vswitchd unix:"/"set ovs-vswitchd --dpdk -c 0x2 -n 4 --socket-mem 2048 -- unix:"/g /usr/share/openvswitch/scripts/ovs-ctl 6. Start OpenvSwitch service .. code-block:: bash - $ systemctl start openvswitch.service + # systemctl start openvswitch.service 7. Create a virtual bridge using openvswitch .. code-block:: bash - $ ovs-vsctl add-br br0 -- set bridge br0 datapath_type=netdev + # ovs-vsctl add-br br0 -- set bridge br0 datapath_type=netdev 8. Add dpdk ports to the bridge .. code-block:: bash - $ ovs-vsctl add-port br0 vhost-user1 -- set Interface vhost-user1 type=dpdkvhostuser - $ ovs-vsctl add-port br0 vhost-user2 -- set Interface vhost-user2 type=dpdkvhostuser + # ovs-vsctl add-port br0 vhost-user1 -- set Interface vhost-user1 type=dpdkvhostuser + # ovs-vsctl add-port br0 vhost-user2 -- set Interface vhost-user2 type=dpdkvhostuser 9. Run guest virtual machine A using the next configuration as reference, where **$IMAGE** var is the clear linux image name. @@ -260,30 +261,31 @@ Setting ip address 1. Set ip address to virtual machine for virtual machine A: - .. code-block:: bash + .. code-block:: bash - $ ip addr add dev enp0s2 10.0.0.5/24 + # ip addr add dev enp0s2 10.0.0.5/24 - for virtual machine B: + for virtual machine B: - .. code-block:: bash + .. code-block:: bash - $ ip addr add dev enp0s2 10.0.0.6/24 + # ip addr add dev enp0s2 10.0.0.6/24 2. Check if there is communication between both virtual machines using ping tool. 3. Verify if apache service is running: - .. code-block:: bash + .. code-block:: bash - $ systemctl status httpd.service - $ systemctl start httpd.service + # systemctl status httpd.service + # systemctl start httpd.service - (start httpd service only if it is inactive). - Use apache benchmark in order to get information about the network performance between both virtual machines. + (start httpd service only if it is inactive). + Use apache benchmark in order to get information about the + network performance between both virtual machines. - .. code-block:: bash + .. code-block:: bash - $ ab -n 1000000 -c 100 http://10.0.0.6/ + # ab -n 1000000 -c 100 http://10.0.0.6/ From 1bab6bdf8d0996f282ac3894ad3a80a6e8a0bd91 Mon Sep 17 00:00:00 2001 From: Miguel Bernal Marin Date: Tue, 12 Apr 2016 16:19:37 -0500 Subject: [PATCH 21/25] fix path in hyper-v --- source/vm-hyper-v.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/vm-hyper-v.rst b/source/vm-hyper-v.rst index 04757dcc..99baacd4 100644 --- a/source/vm-hyper-v.rst +++ b/source/vm-hyper-v.rst @@ -50,7 +50,7 @@ Create a virtual machine PS C:\> Convert-VHD -Path c:\path\to\clear-XXXX-live.vhd -DestinationPath c:\path\to\clear-XXXX-live.vhdx - You can save the new *VHDX* virtual hard disk in :file:`C:\Users\Public\Documents\Hyper-V\Virtual Hard Disks`. + You can save the new *VHDX* virtual hard disk in :file:`C:\\Users\\Public\\Documents\\Hyper-V\\Virtual Hard Disks`. 4. Create virtual machine using the **Hyper-V Manager**: From 7c8763ca9e8c4010d59fa6ec2ba142ca09ee3c51 Mon Sep 17 00:00:00 2001 From: Miguel Bernal Marin Date: Tue, 12 Apr 2016 16:25:21 -0500 Subject: [PATCH 22/25] Renaming titles to short --- source/ac-dpdk.rst | 4 ++-- source/ac-ovs-dpdk.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/ac-dpdk.rst b/source/ac-dpdk.rst index 5b748d45..1d8b98e1 100644 --- a/source/ac-dpdk.rst +++ b/source/ac-dpdk.rst @@ -1,7 +1,7 @@ .. _ac-dpdk: -Clear Linux & DPDK -################## +DPDK +#### Introduction ============ diff --git a/source/ac-ovs-dpdk.rst b/source/ac-ovs-dpdk.rst index 2fc3f583..243bb3c5 100644 --- a/source/ac-ovs-dpdk.rst +++ b/source/ac-ovs-dpdk.rst @@ -1,7 +1,7 @@ .. _ac-ovs-dpdk: -OpenvSwitch and DPDK use case -############################# +OpenvSwitch and DPDK +#################### Introduction ============ From b9a88d7e0308c9eea1b693eea5298f53550b2cf2 Mon Sep 17 00:00:00 2001 From: Miguel Bernal Marin Date: Tue, 12 Apr 2016 16:31:49 -0500 Subject: [PATCH 23/25] add dpdk url --- source/ac-dpdk.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/ac-dpdk.rst b/source/ac-dpdk.rst index 1d8b98e1..2248d818 100644 --- a/source/ac-dpdk.rst +++ b/source/ac-dpdk.rst @@ -6,6 +6,7 @@ DPDK Introduction ============ +DPDK_ is a set of libraries and drivers for fast packet processing. This document describes *how to* run a basic use case that involves **l3fwd DPDK example**, the objective is to *send packages between 2 platforms* using a traffic generator called :ref:`pktgen ` where l3fwd example @@ -339,6 +340,5 @@ This section will explain how to do in order to work in a virtual environment wh 7. Run "start_qemu.sh" script. - - +.. _DPDK: http://dpdk.org From d0d7a1364490471e3680fa3a0273300aa01f6d3a Mon Sep 17 00:00:00 2001 From: Miguel Bernal Marin Date: Tue, 12 Apr 2016 16:35:46 -0500 Subject: [PATCH 24/25] fix ipxe script --- source/network_boot.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/network_boot.rst b/source/network_boot.rst index fc6eeba4..f00c4ee4 100644 --- a/source/network_boot.rst +++ b/source/network_boot.rst @@ -214,8 +214,8 @@ The iPXE script used is #!ipxe - kernel linux quiet rdinit=/usr/lib/systemd/systemd-bootchart initcall_debug - tsc=reliable no_timer_check noreplace-smp rw initrd=initrd initrd initrd + kernel linux quiet rdinit=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp rw initrd=initrd + initrd initrd boot This should be located in ``/var/www/pxe`` with the kernel and initrd. From 919b2e4efafe5b016a415e87cf37387465fb1721 Mon Sep 17 00:00:00 2001 From: Juan Esteban Castano Ramirez Date: Wed, 13 Apr 2016 14:02:46 -0500 Subject: [PATCH 25/25] Fixes current doc, and adds a new 'step - description' format Signed-off-by: Juan Esteban Castano Ramirez --- source/network_boot.rst | 253 ++++++++++++++++++++++++---------------- 1 file changed, 151 insertions(+), 102 deletions(-) diff --git a/source/network_boot.rst b/source/network_boot.rst index f00c4ee4..0c1bcffe 100644 --- a/source/network_boot.rst +++ b/source/network_boot.rst @@ -26,34 +26,144 @@ computers that lack built-in PXE support. Clear Linux Project for Intel Architecture can be configured to do network booting via HTTP with the help of iPXE. The following sets up an iPXE -environment using Clear Linux OS for Intel Architecture, but the configuration -options may apply elsewhere. First, add the ``pxe-server`` bundle to your -system with: +environment using Clear Linux OS for Intel Architecture, but the configuration +options may apply elsewhere. + +Step 1 +------- + +Add the pxe-server bundle to your system which has all the bits to run a PXE +server for Clear Linux. .. code-block:: console # swupd bundle-add pxe-server +Step 2 +------- -DHCP configuration -------------------- +Configure the tftpd service using ``dnsmasq``. To do this, create the +:file:`/etc/dnsmasq.conf` file with the following entries: -To use PXE chainloading, set up ISC DHCPD to hand out ``undionly.kpxe`` to legacy -PXE clients and then hand out boot configuration only to iPXE clients. Do -this by telling ISC DHCPD to use different configurations based on the DHCP user class. -Here's one way to do this: +.. code-block:: console + + # cat << EOF > /etc/dnsmasq.conf + enable-tftp + tftp-root=/srv/tftp/ + EOF + +Step 3 +------- + +Download the ``undionly.kpxe`` (legacy) and ``ipxe.efi`` (EFI) files from `the +iPXE website `_, and place them in your TFTP directory. + +.. code-block:: console + + # mkdir /srv/tftp/ + # curl -o /srv/tftp/undionly.kpxe http://boot.ipxe.org/undionly.kpxe + # curl -o /srv/tftp/ipxe.efi http://boot.ipxe.org/ipxe.efi + +Step 4 +------- + +Start the dnsmasq service with: + +.. code-block:: console + + # systemctl start dnsmasq.service + +Step 5 +------- + +The kernel (linux), initramfs (initrd) and the iPXE scripts are transported via +HTTP. Download the Linux kernel and initrdfiles, and place them into the http +server root ``/var/www/pxe/``. + +.. code-block:: console + + # mkdir -p /var/www/pxe/ + # version=$(cat /usr/share/clear/version) + # curl -o /var/www/pxe/clear-${version}-pxe.tar.xz https://download.clearlinux.org/image/clear-${version}-pxe.tar.xz + # tar -xJf /var/www/pxe/clear-${version}-pxe.tar.xz -C /var/www/pxe/ && rm /var/www/pxe/clear-${version}-pxe.tar.xz + # unset version + +Step 6 +------- + +Create an iPXE script, and place it into the http server root +:file:`/var/www/pxe/ipxe_boot_script.txt`. + +.. code-block:: console + + # cat << EOF > /var/www/pxe/ipxe_boot_script.txt + #!ipxe + + kernel linux quiet rdinit=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp rw initrd=initrd + initrd initrd + boot + EOF + +If your kernel is not named linux, either rename the kernel or create a symlink. + +.. code-block:: console + + # kernel=$(find /var/www/pxe/ -name 'org.clearlinux.*') + # ln -s ${kernel} /var/www/pxe/linux + # unset kernel + +Step 7 +------- + +Create a configuration file for the http service (nginx in this example) to +serve the kernel, initramfs, and ipxe_boot_script in +:file:`/etc/nginx/nginx.conf` with the following: + +.. code-block:: console + + # mkdir /etc/nginx/ + # cat << EOF > /etc/nginx/nginx.conf + server { + listen 80; + server_name hostname; + server_name_in_redirect off; + location / { + root /var/www/pxe; + autoindex on; + index index.html index.htm; + } + } + EOF + +Step 8 +------- + +Start the nginx service with: + +.. code-block:: console + + # systemctl start nginx.service + +Step 9 +------- + +To use PXE chainloading, set up ISC DHCPD to hand out ``undionly.kpxe`` to +legacy PXE clients and then hand out boot configuration only to iPXE clients. +Do this by telling ISC DHCPD to use different configurations based on the DHCP +user class. Here’s one way to do this using the :file:`/etc/dhcpd.conf` file: .. code-block:: console allow booting; allow bootp; - + DHCPDARGS="interface"; + # Set up a class to assign an IP only to devices is attempting network boot. class "pxeclients" { match if substring(option vendor-class-identifier, 0, 9) = "PXEClient"; next-server 192.168.1.1; if exists user-class and option user-class = "iPXE" { - filename "http://my.web.server/real_boot_script.txt"; + filename "http://my.web.server/ipxe_boot_script.txt"; } elsif exists client-arch and option client-arch = 9 { # client-arch = 9 (64-bit EFI) filename "ipxe.efi"; @@ -62,6 +172,7 @@ Here's one way to do this: filename "undionly.kpxe"; } } + # Private subnet, in case you aren't able to run your own network wide DHCP service. # Works when the machine you are network booting has two network interfaces, # one connected to the private PXE boot network and the other connected to an external @@ -73,23 +184,23 @@ Here's one way to do this: } } -This ensures that either iPXE image (``undionly.kpxe`` for BIOS or ``ipxe.efi`` for EFI) is handed -out only when the DHCP request comes from a legacy PXE client or from a UEFI client. Once -iPXE loads, the DHCP server will direct it to boot from options configured in your -``http://my.web.server/real_boot_script.txt`` file, where ``my.web.server`` and the filename -are replaced with your actual location. +This ensures that either iPXE image (``undionly.kpxe`` for BIOS or ``ipxe.efi`` +for EFI) is handed out only when the DHCP request comes from a legacy PXE client +or from a UEFI client. Once iPXE loads, the DHCP server will direct it to boot +from options configured in your ``http://my.web.server/real_boot_script.txt`` +file. -The address ``192.168.1.1`` should be set to the address your TFTP server is using. +Note. +``192.168.1.1`` is set to the address your TFTP server is using. +``my.web.server`` is set to the address your web server is using. +``DHCPDARGS`` is set to the interface you are using. -The subnet being used in this example is private; if the DHCPD service you use applies to your -entire network, modify the configuration as needed. +Step 10 +------- -iPXE-specific options ------------------------ - -There are several DHCP options specific to `iPXE `_ which are not recognized by the standard ISC -dhcpd installation. To add support for these options, place the following at the start of your -:file:`/etc/dhcpd.conf`: +There are several DHCP options specific to `iPXE `_ which are +not recognized by the standard ISC dhcpd installation. To add suport for these +options, place the following at the start of your :file:`/etc/dhcpd.conf`: .. code-block:: console @@ -98,6 +209,7 @@ dhcpd installation. To add support for these options, place the following at the # Source: http://www.ipxe.org/howto/dhcpd # ################################################### option space ipxe; + option client-arch code 93 = unsigned integer 16; option ipxe-encap-opts code 175 = encapsulate ipxe; option ipxe.priority code 1 = signed integer 8; option ipxe.keep-san code 8 = unsigned integer 8; @@ -139,88 +251,25 @@ dhcpd installation. To add support for these options, place the following at the option ipxe.sdi code 40 = unsigned integer 8; option ipxe.nfs code 41 = unsigned integer 8; -Next, create an empty :file:`/var/db/dhcp.leases` file and start the dhcpd service with: +Step 11 +------- + +Create an empty :file:`/var/db/dhcpd.leases` file. + +.. code-block:: console + + # mkdir /var/db/ + # touch /var/db/dhcpd.leases + +Step 12 +------- + +Start the dhcp service with: .. code-block:: console - # mkdir -p /var/db - # touch /var/db/dhcp.leases # systemctl start dhcp4.service -TFTP configuration ------------------------ - -Clear Linux uses ``dnsmasq`` to provide the tftpd service. Modify -:file:`/etc/dnsmasq.conf` with the following required entries: - -.. code-block:: console - - enable-tftp - tftp-root=/srv/tftp/ - -Download the ``undionly.kpxe`` (legacy) and ``ipxe.efi`` (EFI) files from -`the iPXE website `_ and place them in your TFTP -directory. Then you can start the service with - -.. code-block:: console - - # systemctl start dnsmasq.service - - -HTTP configuration ------------------------ - -The kernel (linux), initramfs (initrd) and the iPXE scripts are transported -via HTTP. The Linux kernel and initrd files can be downloaded from -https://download.clearlinux.org/image/ where ``clear-$version-pxe.tar.xz`` is a -compressed tar file containing two clearly-labeled files that should be moved -to the http server root ``/var/www/pxe/``. - -Create a configuration file for the http service (nginx in this example) to -serve the kernel and initramfs in :file:`/etc/nginx/nginx.conf` with the -following: - -.. code-block:: console - - worker_processes 1; - http { - sendfile on; - keepalive_timeout 65; - server { - listen 80; - server_name hostname; - server_name_in_redirect off; - location / { - root /var/www/pxe; - autoindex on; - index index.html index.htm; - } - } - } - - And start the service with: - -.. code-block:: console - - # systemctl start nginx.service - - -iPXE script ------------------------ - -The iPXE script used is - -.. code-block:: console - - #!ipxe - - kernel linux quiet rdinit=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp rw initrd=initrd - initrd initrd - boot - -This should be located in ``/var/www/pxe`` with the kernel and initrd. - - PXE + grub =======================