From e287ad3c3b0219b8fabf9ce46928014a559d7927 Mon Sep 17 00:00:00 2001 From: asettle Date: Wed, 8 Jul 2015 11:47:11 +1000 Subject: [PATCH] [cloud-admin-guide] Converting networking files to RST Converted the following files: 1. networking.xml 2. section_networking-adv-config.xml 3. section_networking_adv_operational_features.xml 4. section_networking_arch.xml 5. section_networking_config-plugins.xml 6. section_networking-use.xml 7. section_networking_auth.xml Change-Id: I2502951a9bf17511defc07efc03bc6676529342a Implements: blueprint reorganise-user-guides --- doc/admin-guide-cloud-rst/source/index.rst | 1 + .../source/networking.rst | 24 ++ .../source/networking_adv-config.rst | 77 ++++ .../networking_adv-operational-features.rst | 160 +++++++++ .../source/networking_arch.rst | 92 +++++ .../source/networking_auth.rst | 256 ++++++++++++++ .../source/networking_config-plugins.rst | 252 ++++++++++++++ .../source/networking_use.rst | 329 ++++++++++++++++++ .../figures/demo_multiple_dhcp_agents.png | Bin 0 -> 32813 bytes 9 files changed, 1191 insertions(+) create mode 100644 doc/admin-guide-cloud-rst/source/networking.rst create mode 100644 doc/admin-guide-cloud-rst/source/networking_adv-config.rst create mode 100644 doc/admin-guide-cloud-rst/source/networking_adv-operational-features.rst create mode 100644 doc/admin-guide-cloud-rst/source/networking_arch.rst create mode 100644 doc/admin-guide-cloud-rst/source/networking_auth.rst create mode 100644 doc/admin-guide-cloud-rst/source/networking_config-plugins.rst create mode 100644 doc/admin-guide-cloud-rst/source/networking_use.rst create mode 100644 doc/common-rst/figures/demo_multiple_dhcp_agents.png diff --git a/doc/admin-guide-cloud-rst/source/index.rst b/doc/admin-guide-cloud-rst/source/index.rst index ee6cefb51a..9c8c36352c 100644 --- a/doc/admin-guide-cloud-rst/source/index.rst +++ b/doc/admin-guide-cloud-rst/source/index.rst @@ -24,6 +24,7 @@ Contents database.rst orchestration.rst blockstorage.rst + networking.rst telemetry.rst common/app_support.rst common/glossary.rst diff --git a/doc/admin-guide-cloud-rst/source/networking.rst b/doc/admin-guide-cloud-rst/source/networking.rst new file mode 100644 index 0000000000..fc29f6463e --- /dev/null +++ b/doc/admin-guide-cloud-rst/source/networking.rst @@ -0,0 +1,24 @@ +========== +Networking +========== + +Learn OpenStack Networking concepts, architecture, and basic and +advanced ``neutron`` and ``nova`` command-line interface (CLI) commands. + +.. toctree:: + :maxdepth: 2 + + networking_config-plugins.rst + networking_arch.rst + networking_adv-config.rst + networking_use.rst + networking_adv-operational-features.rst + networking_auth.rst + +.. TODO (asettle) + + networking_adv-features.rst + networking_multi-dhcp-agents.rst + networking_introduction.rst + networking_config-agents.rst + networking_config-identity.rst diff --git a/doc/admin-guide-cloud-rst/source/networking_adv-config.rst b/doc/admin-guide-cloud-rst/source/networking_adv-config.rst new file mode 100644 index 0000000000..4622e25a27 --- /dev/null +++ b/doc/admin-guide-cloud-rst/source/networking_adv-config.rst @@ -0,0 +1,77 @@ +============================== +Advanced configuration options +============================== + +This section describes advanced configuration options for various system +components. For example, configuration options where the default works +but that the user wants to customize options. After installing from +packages, ``$NEUTRON_CONF_DIR`` is :file:`/etc/neutron`. + +L3 metering agent +~~~~~~~~~~~~~~~~~ + +You can run an L3 metering agent that enables layer-3 traffic metering. +In general, you should launch the metering agent on all nodes that run +the L3 agent: + +:: + + neutron-metering-agent --config-file NEUTRON_CONFIG_FILE + --config-file L3_METERING_CONFIG_FILE + +You must configure a driver that matches the plug-in that runs on the +service. The driver adds metering to the routing interface. + ++------------------------------------------+---------------------------------+ +| Option | Value | ++==========================================+=================================+ +| **Open vSwitch** | | ++------------------------------------------+---------------------------------+ +| interface\_driver | | +| ($NEUTRON\_CONF\_DIR/metering\_agent.ini)| neutron.agent.linux.interface. | +| | OVSInterfaceDriver | ++------------------------------------------+---------------------------------+ +| **Linux Bridge** | | ++------------------------------------------+---------------------------------+ +| interface\_driver | | +| ($NEUTRON\_CONF\_DIR/metering\_agent.ini)| neutron.agent.linux.interface. | +| | BridgeInterfaceDriver | ++------------------------------------------+---------------------------------+ + +Namespace +--------- + +The metering agent and the L3 agent must have the same network +namespaces configuration. + +.. note:: + + If the Linux installation does not support network namespaces, you + must disable network namespaces in the L3 metering configuration + file. The default value of the ``use_namespaces`` option is + ``True``. + +.. code:: ini + + use_namespaces = False + +L3 metering driver +------------------ + +You must configure any driver that implements the metering abstraction. +Currently the only available implementation uses iptables for metering. + +.. code:: ini + + driver = neutron.services.metering.drivers. + iptables.iptables_driver.IptablesMeteringDriver + +L3 metering service driver +-------------------------- + +To enable L3 metering, you must set the following option in the +:file:`neutron.conf` file on the host that runs neutron-server: + +.. code:: ini + + service_plugins = metering diff --git a/doc/admin-guide-cloud-rst/source/networking_adv-operational-features.rst b/doc/admin-guide-cloud-rst/source/networking_adv-operational-features.rst new file mode 100644 index 0000000000..61e00f5e0a --- /dev/null +++ b/doc/admin-guide-cloud-rst/source/networking_adv-operational-features.rst @@ -0,0 +1,160 @@ +============================= +Advanced operational features +============================= + +Logging settings +~~~~~~~~~~~~~~~~ + +Networking components use Python logging module to do logging. Logging +configuration can be provided in :file:`neutron.conf` or as command-line +options. Command options override ones in :file:`neutron.conf`. + +To configure logging for Networking components, use one of these +methods: + +- Provide logging settings in a logging configuration file. + + See `Python logging + how-to `__ to learn more + about logging. + +- Provide logging setting in :file:`neutron.conf`. + + .. code-block:: ini + :linenos: + + [DEFAULT] + # Default log level is WARNING + # Show debugging output in logs (sets DEBUG log level output) + # debug = False + + # Show more verbose log output (sets INFO log level output) if debug + is False + # verbose = False + + # log_format = %(asctime)s %(levelname)8s [%(name)s] %(message)s + # log_date_format = %Y-%m-%d %H:%M:%S + + # use_syslog = False + # syslog_log_facility = LOG_USER + + # if use_syslog is False, we can set log_file and log_dir. + # if use_syslog is False and we do not set log_file, + # the log will be printed to stdout. + # log_file = + # log_dir = + +Notifications +~~~~~~~~~~~~~ + +Notifications can be sent when Networking resources such as network, +subnet and port are created, updated or deleted. + +Notification options +-------------------- + +To support DHCP agent, rpc\_notifier driver must be set. To set up the +notification, edit notification options in :file:`neutron.conf`: + +.. code-block:: ini + :linenos: + + # Driver or drivers to handle sending notifications. (multi + # valued) + #notification_driver= + + # AMQP topic used for OpenStack notifications. (list value) + # Deprecated group/name - [rpc_notifier2]/topics + notification_topics = notifications + +Setting cases +------------- + +Logging and RPC +^^^^^^^^^^^^^^^ + +These options configure the Networking server to send notifications +through logging and RPC. The logging options are described in OpenStack +Configuration Reference . RPC notifications go to ``notifications.info`` +queue bound to a topic exchange defined by ``control_exchange`` in +:file:`neutron.conf`. + +.. code-block:: ini + :linenos: + + # ============ Notification System Options ==================== + + # Notifications can be sent when network/subnet/port are create, + updated or deleted. + # There are three methods of sending notifications: logging + (via the log_file directive), rpc (via a message queue) and + # noop (no notifications sent, the default) + + # Notification_driver can be defined multiple times + # Do nothing driver + # notification_driver = neutron.openstack.common.notifier. + no_op_notifier + # Logging driver + notification_driver = neutron.openstack.common.notifier. + log_notifier + # RPC driver + notification_driver = neutron.openstack.common.notifier. + rpc_notifier + + # default_notification_level is used to form actual topic + names or to set logging level + default_notification_level = INFO + + # default_publisher_id is a part of the notification payload + # host = myhost.com + # default_publisher_id = $host + + # Defined in rpc_notifier for rpc way, can be comma-separated values. + # The actual topic names will be %s.%(default_notification_level)s + notification_topics = notifications + + # Options defined in oslo.messaging + + # The default exchange under which topics are scoped. May be + # overridden by an exchange name specified in the + # transport_url option. (string value) + #control_exchange=openstack + +Multiple RPC topics +^^^^^^^^^^^^^^^^^^^ + +These options configure the Networking server to send notifications to +multiple RPC topics. RPC notifications go to ``notifications_one.info`` +and ``notifications_two.info`` queues bound to a topic exchange defined +by ``control_exchange`` in :file:`neutron.conf`. + +.. code-block:: ini + :linenos: + + # ============ Notification System Options ===================== + + # Notifications can be sent when network/subnet/port are create, + updated or deleted. + # There are three methods of sending notifications: logging (via the + # log_file directive), rpc (via a message queue) and + # noop (no notifications sent, the default) + + # Notification_driver can be defined multiple times + # Do nothing driver + # notification_driver = neutron.openstack.common.notifier.no_op_notifier + # Logging driver + # notification_driver = neutron.openstack.common.notifier.log_notifier + # RPC driver + notification_driver = neutron.openstack.common.notifier.rpc_notifier + + # default_notification_level is used to form actual topic names or to set + logging level + default_notification_level = INFO + + # default_publisher_id is a part of the notification payload + # host = myhost.com + # default_publisher_id = $host + + # Defined in rpc_notifier for rpc way, can be comma-separated values. + # The actual topic names will be %s.%(default_notification_level)s + notification_topics = notifications_one,notifications_two diff --git a/doc/admin-guide-cloud-rst/source/networking_arch.rst b/doc/admin-guide-cloud-rst/source/networking_arch.rst new file mode 100644 index 0000000000..16acfb5462 --- /dev/null +++ b/doc/admin-guide-cloud-rst/source/networking_arch.rst @@ -0,0 +1,92 @@ +======================= +Networking architecture +======================= + +Before you deploy Networking, it is useful to understand the Networking +services and how they interact with the OpenStack components. + +Overview +~~~~~~~~ + +Networking is a standalone component in the OpenStack modular +architecture. It's positioned alongside OpenStack components such as +Compute, Image service, Identity, or the Dashboard. Like those +components, a deployment of Networking often involves deploying several +services to a variety of hosts. + +The Networking server uses the neutron-server daemon to expose the +Networking API and enable administration of the configured Networking +plug-in. Typically, the plug-in requires access to a database for +persistent storage (also similar to other OpenStack services). + +If your deployment uses a controller host to run centralized Compute +components, you can deploy the Networking server to that same host. +However, Networking is entirely standalone and can be deployed to a +dedicated host. Depending on your configuration, Networking can also +include the following agents: + ++----------------------------+---------------------------------------------+ +| Agent | Description | ++============================+=============================================+ +|**plug-in agent** | | +|(``neutron-*-agent``) | Runs on each hypervisor to perform | +| | local vSwitch configuration. The agent that | +| | runs, depends on the plug-in that you use. | +| | Certain plug-ins do not require an agent. | ++----------------------------+---------------------------------------------+ +|**dhcp agent** | | +|(``neutron-dhcp-agent``) | Provides DHCP services to tenant networks. | +| | Required by certain plug-ins. | ++----------------------------+---------------------------------------------+ +|**l3 agent** | | +|(``neutron-l3-agent``) | Provides L3/NAT forwarding to provide | +| | external network access for VMs on tenant | +| | networks. Required by certain plug-ins. | ++----------------------------+---------------------------------------------+ +|**metering agent** | | +|(``neutron-metering-agent``)| Provides L3 traffic metering for tenant | +| | networks. | ++----------------------------+---------------------------------------------+ + +These agents interact with the main neutron process through RPC (for +example, RabbitMQ or Qpid) or through the standard Networking API. In +addition, Networking integrates with OpenStack components in a number of +ways: + +- Networking relies on the Identity service (keystone) for the + authentication and authorization of all API requests. + +- Compute (nova) interacts with Networking through calls to its + standard API. As part of creating a VM, the nova-compute service + communicates with the Networking API to plug each virtual NIC on the + VM into a particular network. + +- The dashboard (horizon) integrates with the Networking API, enabling + administrators and tenant users to create and manage network services + through a web-based GUI. + +VMware NSX integration +~~~~~~~~~~~~~~~~~~~~~~ + +OpenStack Networking uses the NSX plug-in to integrate with an existing +VMware vCenter deployment. When installed on the network nodes, the NSX +plug-in enables a NSX controller to centrally manage configuration +settings and push them to managed network nodes. Network nodes are +considered managed when they're added as hypervisors to the NSX +controller. + +The diagrams below depict some VMware NSX deployment examples. The first +diagram illustrates the traffic flow between VMs on separate Compute +nodes, and the second diagram between two VMs on a single Compute node. +Note the placement of the VMware NSX plug-in and the neutron-server +service on the network node. The green arrow indicates the management +relationship between the NSX controller and the network node. + +|VMware NSX deployment example - two Compute nodes| + +|VMware NSX deployment example - single Compute node| + +.. |VMware NSX deployment example - two Compute nodes| + image:: ../../common/figures/vmware_nsx_ex1.png +.. |VMware NSX deployment example - single Compute node| + image:: ../../common/figures/vmware_nsx_ex2.png diff --git a/doc/admin-guide-cloud-rst/source/networking_auth.rst b/doc/admin-guide-cloud-rst/source/networking_auth.rst new file mode 100644 index 0000000000..734d42c59b --- /dev/null +++ b/doc/admin-guide-cloud-rst/source/networking_auth.rst @@ -0,0 +1,256 @@ +================================ +Authentication and authorization +================================ + +Networking uses the Identity Service as the default authentication +service. When the Identity Service is enabled, users who submit requests +to the Networking service must provide an authentication token in +``X-Auth-Token`` request header. Users obtain this token by +authenticating with the Identity Service endpoint. For more information +about authentication with the Identity Service, see `OpenStack Identity +Service API v2.0 +Reference `__. +When the Identity Service is enabled, it is not mandatory to specify the +tenant ID for resources in create requests because the tenant ID is +derived from the authentication token. + +The default authorization settings only allow administrative users +to create resources on behalf of a different tenant. Networking uses +information received from Identity to authorize user requests. +Networking handles two kind of authorization policies: + +- **Operation-based** policies specify access criteria for specific + operations, possibly with fine-grained control over specific + attributes. + +- **Resource-based** policies specify whether access to specific + resource is granted or not according to the permissions configured + for the resource (currently available only for the network resource). + The actual authorization policies enforced in Networking might vary + from deployment to deployment. + +The policy engine reads entries from the :file:`policy.json` file. The +actual location of this file might vary from distribution to +distribution. Entries can be updated while the system is running, and no +service restart is required. Every time the policy file is updated, the +policies are automatically reloaded. Currently the only way of updating +such policies is to edit the policy file. In this section, the terms +*policy* and *rule* refer to objects that are specified in the same way +in the policy file. There are no syntax differences between a rule and a +policy. A policy is something that is matched directly from the +Networking policy engine. A rule is an element in a policy, which is +evaluated. For instance in ``create_subnet: +[["admin_or_network_owner"]]``, *create_subnet* is a +policy, and *admin_or_network_owner* is a rule. + +Policies are triggered by the Networking policy engine whenever one of +them matches a Networking API operation or a specific attribute being +used in a given operation. For instance the ``create_subnet`` policy is +triggered every time a ``POST /v2.0/subnets`` request is sent to the +Networking server; on the other hand ``create_network:shared`` is +triggered every time the *shared* attribute is explicitly specified (and +set to a value different from its default) in a ``POST /v2.0/networks`` +request. It is also worth mentioning that policies can also be related +to specific API extensions; for instance +``extension:provider_network:set`` is triggered if the attributes +defined by the Provider Network extensions are specified in an API +request. + +An authorization policy can be composed by one or more rules. If more +rules are specified then the evaluation policy succeeds if any of the +rules evaluates successfully; if an API operation matches multiple +policies, then all the policies must evaluate successfully. Also, +authorization rules are recursive. Once a rule is matched, the rule(s) +can be resolved to another rule, until a terminal rule is reached. + +The Networking policy engine currently defines the following kinds of +terminal rules: + +- **Role-based rules** evaluate successfully if the user who submits + the request has the specified role. For instance ``"role:admin"`` is + successful if the user who submits the request is an administrator. + +- **Field-based rules** evaluate successfully if a field of the + resource specified in the current request matches a specific value. + For instance ``"field:networks:shared=True"`` is successful if the + ``shared`` attribute of the ``network`` resource is set to true. + +- **Generic rules** compare an attribute in the resource with an + attribute extracted from the user's security credentials and + evaluates successfully if the comparison is successful. For instance + ``"tenant_id:%(tenant_id)s"`` is successful if the tenant identifier + in the resource is equal to the tenant identifier of the user + submitting the request. + +This extract is from the default :file:`policy.json` file: + +- A rule that evaluates successfully if the current user is an + administrator or the owner of the resource specified in the request + (tenant identifier is equal). + + .. code-block:: json + :linenos: + + { + "admin_or_owner": [ + [ + "role:admin" + ], + [ + "tenant_id:%(tenant_id)s" + ] + ], + "admin_or_network_owner": [ + [ + "role:admin" + ], + [ + "tenant_id:%(network_tenant_id)s" + ] + ], + "admin_only": [ + [ + "role:admin" + ] + ], + "regular_user": [], + "shared": [ + [ + "field:networks:shared=True" + ] + ], + "default": [ + [ + +- The default policy that is always evaluated if an API operation does + not match any of the policies in ``policy.json``. + + .. code-block:: json + :linenos: + + "rule:admin_or_owner" + ] + ], + "create_subnet": [ + [ + "rule:admin_or_network_owner" + ] + ], + "get_subnet": [ + [ + "rule:admin_or_owner" + ], + [ + "rule:shared" + ] + ], + "update_subnet": [ + [ + "rule:admin_or_network_owner" + ] + ], + "delete_subnet": [ + [ + "rule:admin_or_network_owner" + ] + ], + "create_network": [], + "get_network": [ + [ + "rule:admin_or_owner" + ], + +- This policy evaluates successfully if either *admin\_or\_owner*, or + *shared* evaluates successfully. + + .. code-block:: json + :linenos: + + [ + "rule:shared" + ] + ], + "create_network:shared": [ + [ + "rule:admin_only" + ] + +- This policy restricts the ability to manipulate the *shared* + attribute for a network to administrators only. + + .. code-block:: json + :linenos: + + ], + "update_network": [ + [ + "rule:admin_or_owner" + ] + ], + "delete_network": [ + [ + "rule:admin_or_owner" + ] + ], + "create_port": [], + "create_port:mac_address": [ + [ + "rule:admin_or_network_owner" + ] + ], + "create_port:fixed_ips": [ + +- This policy restricts the ability to manipulate the *mac\_address* + attribute for a port only to administrators and the owner of the + network where the port is attached. + + .. code-block:: json + :linenos: + + [ + "rule:admin_or_network_owner" + ] + ], + "get_port": [ + [ + "rule:admin_or_owner" + ] + ], + "update_port": [ + [ + "rule:admin_or_owner" + ] + ], + "delete_port": [ + [ + "rule:admin_or_owner" + ] + ] + } + +In some cases, some operations are restricted to administrators only. +This example shows you how to modify a policy file to permit tenants to +define networks, see their resources, and permit administrative users to +perform all other operations: + +.. code-block:: ini + :linenos: + + { + "admin_or_owner": [["role:admin"], ["tenant_id:%(tenant_id)s"]], + "admin_only": [["role:admin"]], "regular_user": [], + "default": [["rule:admin_only"]], + "create_subnet": [["rule:admin_only"]], + "get_subnet": [["rule:admin_or_owner"]], + "update_subnet": [["rule:admin_only"]], + "delete_subnet": [["rule:admin_only"]], + "create_network": [], + "get_network": [["rule:admin_or_owner"]], + "create_network:shared": [["rule:admin_only"]], + "update_network": [["rule:admin_or_owner"]], + "delete_network": [["rule:admin_or_owner"]], + "create_port": [["rule:admin_only"]], + "get_port": [["rule:admin_or_owner"]], + "update_port": [["rule:admin_only"]], + "delete_port": [["rule:admin_only"]] + } diff --git a/doc/admin-guide-cloud-rst/source/networking_config-plugins.rst b/doc/admin-guide-cloud-rst/source/networking_config-plugins.rst new file mode 100644 index 0000000000..6012e68d50 --- /dev/null +++ b/doc/admin-guide-cloud-rst/source/networking_config-plugins.rst @@ -0,0 +1,252 @@ +====================== +Plug-in configurations +====================== + +For configurations options, see `Networking configuration +options `__ +in Configuration Reference. These sections explain how to configure +specific plug-ins. + +Configure Big Switch (Floodlight REST Proxy) plug-in +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +#. Edit the :file:`/etc/neutron/neutron.conf` file and add this line: + + .. code:: ini + + core_plugin = bigswitch + +#. In the :file:`/etc/neutron/neutron.conf` file, set the ``service_plugins`` + option: + + :: + + service_plugins = neutron.plugins.bigswitch.l3_router_plugin.L3RestProxy + +#. Edit the :file:`/etc/neutron/plugins/bigswitch/restproxy.ini` file for the + plug-in and specify a comma-separated list of controller\_ip:port pairs: + + .. code:: ini + + server = CONTROLLER_IP:PORT + + For database configuration, see `Install Networking + Services `__ + in the Installation Guide in the `OpenStack Documentation + index `__. (The link defaults to the Ubuntu + version.) + +#. Restart neutron-server to apply the settings: + + .. code:: console + + # service neutron-server restart + +Configure Brocade plug-in +~~~~~~~~~~~~~~~~~~~~~~~~~ + +#. Install the Brocade-modified Python netconf client (ncclient) library, + which is available at https://github.com/brocade/ncclient: + + .. code:: console + + $ git clone https://github.com/brocade/ncclient + +#. As root, run this command: + + .. code:: console + + # cd ncclient;python setup.py install + +#. Edit the :file:`/etc/neutron/neutron.conf` file and set the following + option: + + .. code:: ini + + core_plugin = brocade + +#. Edit the :file:`/etc/neutron/plugins/brocade/brocade.ini` file for the + Brocade plug-in and specify the admin user name, password, and IP + address of the Brocade switch: + + .. code:: ini + + [SWITCH] + username = ADMIN + password = PASSWORD + address = SWITCH_MGMT_IP_ADDRESS + ostype = NOS + + For database configuration, see `Install Networking + Services `__ + in any of the Installation Guides in the `OpenStack Documentation + index `__. (The link defaults to the Ubuntu + version.) + +#. Restart the neutron-server service to apply the settings: + + .. code:: console + + # service neutron-server restart + +Configure NSX-mh plug-in +~~~~~~~~~~~~~~~~~~~~~~~~ + +The instructions in this section refer to the VMware NSX-mh platform, +formerly known as Nicira NVP. + +#. Install the NSX plug-in: + + .. code:: console + + # apt-get install neutron-plugin-vmware + +#. Edit the :file:`/etc/neutron/neutron.conf` file and set this line: + + .. code:: ini + + core_plugin = vmware + + Example :file:`neutron.conf`: file for NSX-mh integration: + + .. code:: ini + + core_plugin = vmware + rabbit_host = 192.168.203.10 + allow_overlapping_ips = True + +#. To configure the NSX-mh controller cluster for OpenStack Networking, + locate the ``[default]`` section in the + :file:`/etc/neutron/plugins/vmware/nsx.ini` file and add the following + entries: + + - To establish and configure the connection with the controller cluster + you must set some parameters, including NSX-mh API endpoints, access + credentials, and optionally specify settings for HTTP timeouts, + redirects and retries in case of connection failures: + + .. code:: ini + + nsx_user = ADMIN_USER_NAME + nsx_password = NSX_USER_PASSWORD + http_timeout = HTTP_REQUEST_TIMEOUT # (seconds) default 75 seconds + retries = HTTP_REQUEST_RETRIES # default 2 + redirects = HTTP_REQUEST_MAX_REDIRECTS # default 2 + nsx_controllers = API_ENDPOINT_LIST # comma-separated list + + To ensure correct operations, the ``nsx_user`` user must have + administrator credentials on the NSX-mh platform. + + A controller API endpoint consists of the IP address and port for the + controller; if you omit the port, port 443 is used. If multiple API + endpoints are specified, it is up to the user to ensure that all + these endpoints belong to the same controller cluster. The OpenStack + Networking VMware NSX-mh plug-in does not perform this check, and + results might be unpredictable. + + When you specify multiple API endpoints, the plug-in takes care of + load balancing requests on the various API endpoints. + + - The UUID of the NSX-mh transport zone that should be used by default + when a tenant creates a network. You can get this value from the + Transport Zones page for the NSX-mh manager: + + Alternatively the transport zone identfier can be retrieved by query + the NSX-mh API: ``/ws.v1/transport-zone`` + + .. code:: ini + + default_tz_uuid = TRANSPORT_ZONE_UUID + + - .. code:: ini + + default_l3_gw_service_uuid = GATEWAY_SERVICE_UUID + + .. Warning:: + + Ubuntu packaging currently does not update the neutron init + script to point to the NSX-mh configuration file. Instead, you + must manually update :file:`/etc/default/neutron-server` to add this + line: + + .. code:: ini + + NEUTRON_PLUGIN_CONFIG = /etc/neutron/plugins/vmware/nsx.ini + + For database configuration, see `Install Networking + Services `__ + in the Installation Guide. + +#. Restart neutron-server to apply settings: + + .. code:: console + + # service neutron-server restart + + .. Warning:: + + The neutron NSX-mh plug-in does not implement initial + re-synchronization of Neutron resources. Therefore resources that + might already exist in the database when Neutron is switched to the + NSX-mh plug-in will not be created on the NSX-mh backend upon + restart. + +Example :file:`nsx.ini` file: + +.. code:: ini + + [DEFAULT] + default_tz_uuid = d3afb164-b263-4aaa-a3e4-48e0e09bb33c + default_l3_gw_service_uuid=5c8622cc-240a-40a1-9693-e6a5fca4e3cf + nsx_user=admin + nsx_password=changeme + nsx_controllers=10.127.0.100,10.127.0.200:8888 + + .. Note:: + + To debug :file:`nsx.ini` configuration issues, run this command from the + host that runs neutron-server: + + ..code:: console + + # neutron-check-nsx-config PATH_TO_NSX.INI + + This command tests whether neutron-server can log into all of the + NSX-mh controllers and the SQL server, and whether all UUID values + are correct. + +Configure PLUMgrid plug-in +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +#. Edit the :file:`/etc/neutron/neutron.conf` file and set this line: + + .. code:: ini + + core_plugin = plumgrid + +#. Edit the [PLUMgridDirector] section in the + :file:`/etc/neutron/plugins/plumgrid/plumgrid.ini` file and specify the IP + address, port, admin user name, and password of the PLUMgrid Director: + + .. code:: ini + + [PLUMgridDirector] + director_server = "PLUMgrid-director-ip-address" + director_server_port = "PLUMgrid-director-port" + username = "PLUMgrid-director-admin-username" + password = "PLUMgrid-director-admin-password" + + For database configuration, see `Install Networking + Services `__ + in the Installation Guide. + +#. Restart the neutron-server service to apply the settings: + + .. code:: console + + # service neutron-server restart diff --git a/doc/admin-guide-cloud-rst/source/networking_use.rst b/doc/admin-guide-cloud-rst/source/networking_use.rst new file mode 100644 index 0000000000..b198d6cc60 --- /dev/null +++ b/doc/admin-guide-cloud-rst/source/networking_use.rst @@ -0,0 +1,329 @@ +============== +Use Networking +============== + +You can manage OpenStack Networking services by using the service +command. For example: + +.. code:: console + + # service neutron-server stop + # service neutron-server status + # service neutron-server start + # service neutron-server restart + +Log files are in the :file:`/var/log/neutron` directory. + +Configuration files are in the :file:`/etc/neutron` directory. + +Cloud administrators and tenants can use OpenStack Networking to build +rich network topologies. Cloud administrators can create network +connectivity on behalf of tenants. + +Core Networking API features +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +After you install and configure Networking, tenants and administrators +can perform create-read-update-delete (CRUD) API networking operations +by using the Networking API directly or neutron command-line interface +(CLI). The neutron CLI is a wrapper around the Networking API. Every +Networking API call has a corresponding neutron command. + +The CLI includes a number of options. For details, see the `OpenStack +End User Guide `__. + +Basic Networking operations +--------------------------- + +To learn about advanced capabilities available through the neutron +command-line interface (CLI), read the networking section in the +`OpenStack End User +Guide `__. + +This table shows example neutron commands that enable you to complete +basic network operations: + ++-------------------------+-------------------------------------------------+ +| Operation | Command | ++=========================+=================================================+ +|Creates a network. | | +| | | +| | ``$ neutron net-create net1`` | ++-------------------------+-------------------------------------------------+ +|Creates a subnet that is | | +|associated with net1. | | +| | | +| | ``$ neutron subnet-create`` | +| | ``net1 10.0.0.0/24`` | ++-------------------------+-------------------------------------------------+ +|Lists ports for a | | +|specified tenant. | | +| | | +| | ``$ neutron port-list`` | ++-------------------------+-------------------------------------------------+ +|Lists ports for a | | +|specified tenant | | +|and displays the ``id``, | | +|``fixed_ips``, | | +|and ``device_owner`` | | +|columns. | | +| | | +| | ``$ neutron port-list -c id`` | +| | ``-c fixed_ips -c device_owner`` | ++-------------------------+-------------------------------------------------+ +|Shows information for a | | +|specified port. | | +| | ``$ neutron port-show PORT_ID`` | ++-------------------------+-------------------------------------------------+ + +**Basic Networking operations** + +.. Note:: + + The ``device_owner`` field describes who owns the port. A port whose + ``device_owner`` begins with: + + - ``network`` is created by Networking. + + - ``compute`` is created by Compute. + +Administrative operations +------------------------- + +The cloud administrator can run any ``neutron`` command on behalf of +tenants by specifying an Identity ``tenant_id`` in the command, as +follows: + +.. code:: console + + $ neutron net-create --tenant-id TENANT_ID NETWORK_NAME + +For example: + +.. code:: console + + $ neutron net-create --tenant-id 5e4bbe24b67a4410bc4d9fae29ec394e net1 + +.. Note:: + + To view all tenant IDs in Identity, run the following command as an + Identity service admin user: + + .. code:: console + + $ keystone tenant-list + +Advanced Networking operations +------------------------------ + +This table shows example Networking commands that enable you to complete +advanced network operations: + ++-------------------------------+--------------------------------------------+ +| Operation | Command | ++===============================+============================================+ +|Creates a network that | | +|all tenants can use. | | +| | | +| | ``$ neutron net-create`` | +| | ``--shared public-net`` | ++-------------------------------+--------------------------------------------+ +|Creates a subnet with a | | +|specified gateway IP address. | | +| | | +| | ``$ neutron subnet-create`` | +| | ``--gateway 10.0.0.254 net1 10.0.0.0/24``| ++-------------------------------+--------------------------------------------+ +|Creates a subnet that has | | +|no gateway IP address. | | +| | | +| | ``$ neutron subnet-create`` | +| | ``--no-gateway net1 10.0.0.0/24`` | ++-------------------------------+--------------------------------------------+ +|Creates a subnet with DHCP | | +|disabled. | | +| | | +| | ``$ neutron subnet-create`` | +| | ``net1 10.0.0.0/24 --enable-dhcp False`` | ++-------------------------------+--------------------------------------------+ +|Specified set of host routes. | | +| | | +| | ``$ neutron subnet-create`` | +| | ``test-net1 40.0.0.0/24 --host-routes``| +| | ``type=dict list=true`` | +| | ``destination=40.0.1.0/24,`` | +| | ``nexthop=40.0.0.2`` | ++-------------------------------+--------------------------------------------+ +|Creates a subnet with a | | +|specified set of dns name | | +|servers. | | +| | | +| | ``$ neutron subnet-create test-net1`` | +| | ``40.0.0.0/24 --dns-nameservers`` | +| | ``list=true 8.8.4.4 8.8.8.8`` | ++-------------------------------+--------------------------------------------+ +|Displays all ports and | | +|IPs allocated on a network. | | +| | | +| | ``$ neutron port-list --network_id NET_ID``| ++-------------------------------+--------------------------------------------+ + +**Advanced Networking operations** + +Use Compute with Networking +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Basic Compute and Networking operations +--------------------------------------- + +This table shows example neutron and nova commands that enable you to +complete basic VM networking operations: + ++----------------------------------+-----------------------------------------+ +| Action | Command | ++==================================+=========================================+ +|Checks available networks. | | +| | | +| | ``$ neutron net-list`` | ++----------------------------------+-----------------------------------------+ +|Boots a VM with a single NIC on | | +|a selected Networking network. | | +| | | +| | ``$ nova boot --image IMAGE --flavor`` | +| | ``FLAVOR --nic net-id=NET_ID VM_NAME`` | ++----------------------------------+-----------------------------------------+ +|Searches for ports with a | | +|``device_id`` that matches the | | +|Compute instance UUID. See :ref: | | +|`Create and delete VMs` | | +| | | +| |``$ neutron port-list --device_id VM_ID``| ++----------------------------------+-----------------------------------------+ +|Searches for ports, but shows | | +|onlythe ``mac_address`` of | | +|the port. | | +| | | +| | ``$ neutron port-list --field`` | +| | ``mac_address --device_id VM_ID`` | ++----------------------------------+-----------------------------------------+ +|Temporarily disables a port from | | +|sending traffic. | | +| | | +| | ``$ neutron port-update PORT_ID`` | +| | ``--admin_state_up False`` | ++----------------------------------+-----------------------------------------+ + +**Basic Compute and Networking operations** + +.. Note:: + + The ``device_id`` can also be a logical router ID. + +.. Note:: + + - When you boot a Compute VM, a port on the network that + corresponds to the VM NIC is automatically created and associated + with the default security group. You can configure `security + group rules <#enabling_ping_and_ssh>`__ to enable users to access + the VM. + +.. _Create and delete VMs: + - When you delete a Compute VM, the underlying Networking port is + automatically deleted. + +Advanced VM creation operations +------------------------------- + +This table shows example nova and neutron commands that enable you to +complete advanced VM creation operations: + ++-------------------------------------+--------------------------------------+ +| Operation | Command | ++=====================================+======================================+ +|Boots a VM with multiple | | +|NICs. | | +| | | +| |``$ nova boot --image IMAGE --flavor``| +| |``FLAVOR --nic net-id=NET1-ID --nic`` | +| |``net-id=NET2-ID VM_NAME`` | ++-------------------------------------+--------------------------------------+ +|Boots a VM with a specific IP | | +|address. Note that you cannot | | +|use the ``--num-instances`` | | +|parameter in this case. | | +| | | +| |``$ nova boot --image IMAGE --flavor``| +| | ``FLAVOR --nic net-id=NET-ID,`` | +| | ``v4-fixed-ip=IP-ADDR VM_NAME`` | ++-------------------------------------+--------------------------------------+ +|Boots a VM that connects to all | | +|networks that are accessible to the | | +|tenant who submits the request | | +|(without the ``--nic`` option). | | +| | | +| |``$ nova boot --image IMAGE --flavor``| +| |``FLAVOR VM_NAME`` | ++-------------------------------------+--------------------------------------+ + +**Advanced VM creation operations** + +.. Note:: + + Cloud images that distribution vendors offer usually have only one + active NIC configured. When you boot with multiple NICs, you must + configure additional interfaces on the image or the NICS are not + reachable. + + The following Debian/Ubuntu-based example shows how to set up the + interfaces within the instance in the ``/etc/network/interfaces`` + file. You must apply this configuration to the image. + + .. code:: bash + + # The loopback network interface + auto lo + iface lo inet loopback + + auto eth0 + iface eth0 inet dhcp + + auto eth1 + iface eth1 inet dhcp + +Enable ping and SSH on VMs (security groups) +-------------------------------------------- + +You must configure security group rules depending on the type of plug-in +you are using. If you are using a plug-in that: + +- Implements Networking security groups, you can configure security + group rules directly by using the ``neutron security-group-rule-create`` + command. This example enables ``ping`` and ``ssh`` access to your VMs. + + .. code:: console + + $ neutron security-group-rule-create --protocol icmp \ + --direction ingress default + + .. code:: console + + $ neutron security-group-rule-create --protocol tcp --port-range-min 22 \ + --port-range-max 22 --direction ingress default + +- Does not implement Networking security groups, you can configure + security group rules by using the ``nova secgroup-add-rule`` or + ``euca-authorize`` command. These ``nova`` commands enable ``ping`` + and ``ssh`` access to your VMs. + + .. code:: console + + $ nova secgroup-add-rule default icmp -1 -1 0.0.0.0/0 + $ nova secgroup-add-rule default tcp 22 22 0.0.0.0/0 + +.. Note:: + + If your plug-in implements Networking security groups, you can also + leverage Compute security groups by setting + ``security_group_api = neutron`` in the :file:`nova.conf` file. After + you set this option, all Compute security group commands are proxied + to Networking. diff --git a/doc/common-rst/figures/demo_multiple_dhcp_agents.png b/doc/common-rst/figures/demo_multiple_dhcp_agents.png new file mode 100644 index 0000000000000000000000000000000000000000..1014b6610579cc7e8b1fcb8dc74b352123d00335 GIT binary patch literal 32813 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 literal 0 HcmV?d00001