github.com/openshift/installer@v1.4.17/docs/user/openstack/README.md (about)

     1  # OpenStack Platform Support
     2  
     3  This document discusses the requirements, current expected behavior, and how to try out what exists so far.
     4  It covers the installation with the default CNI (OVNKubernetes).
     5  
     6  ## Table of Contents
     7  
     8  - [OpenStack Platform Support](#openstack-platform-support)
     9    - [Table of Contents](#table-of-contents)
    10    - [Reference Documents](#reference-documents)
    11    - [OpenStack Requirements](#openstack-requirements)
    12      - [Master Nodes](#master-nodes)
    13      - [Worker Nodes](#worker-nodes)
    14      - [Bootstrap Node](#bootstrap-node)
    15      - [Image Registry Requirements](#image-registry-requirements)
    16      - [Disk Requirements](#disk-requirements)
    17      - [Neutron Public Network](#neutron-public-network)
    18      - [Nova Metadata Service](#nova-metadata-service)
    19      - [Glance Service](#glance-service)
    20    - [OpenStack Credentials](#openstack-credentials)
    21      - [OpenStack credentials update](#openstack-credentials-update)
    22      - [Self Signed OpenStack CA certificates](#self-signed-openstack-ca-certificates)
    23    - [Standalone Single-Node Development Environment](#standalone-single-node-development-environment)
    24    - [Running The Installer](#running-the-installer)
    25      - [Known Issues](#known-issues)
    26      - [Initial Setup](#initial-setup)
    27      - [API Access](#api-access)
    28        - [Using Floating IPs](#using-floating-ips)
    29          - [Create API and Ingress Floating IP Addresses](#create-api-and-ingress-floating-ip-addresses)
    30          - [Create API and Ingress DNS Records](#create-api-and-ingress-dns-records)
    31          - [External API Access](#external-api-access)
    32          - [External Ingress (apps) Access](#external-ingress-apps-access)
    33        - [Without Floating IPs](#without-floating-ips)
    34      - [Running a Deployment](#running-a-deployment)
    35      - [Current Expected Behavior](#current-expected-behavior)
    36      - [Checking Cluster Status](#checking-cluster-status)
    37      - [Destroying The Cluster](#destroying-the-cluster)
    38    - [Post Install Operations](#post-install-operations)
    39      - [Adding a MachineSet](#adding-a-machineset)
    40        - [Defining a MachineSet That Uses Multiple Networks](#defining-a-machineset-that-uses-multiple-networks)
    41        - [Using a Server Group](#using-a-server-group)
    42        - [Setting Nova Availability Zones](#setting-nova-availability-zones)
    43      - [Using a Custom External Load Balancer](#using-a-custom-external-load-balancer)
    44        - [External Facing OpenShift Services](#external-facing-openshift-services)
    45        - [HAProxy Example Load Balancer Config](#haproxy-example-load-balancer-config)
    46        - [DNS Lookups](#dns-lookups)
    47        - [Verifying that the API is Reachable](#verifying-that-the-api-is-reachable)
    48        - [Verifying that Apps Reachable](#verifying-that-apps-reachable)
    49      - [Reconfiguring cloud provider](#reconfiguring-cloud-provider)
    50        - [Modifying cloud provider options](#modifying-cloud-provider-options)
    51        - [Refreshing a CA Certificate](#refreshing-a-ca-certificate)
    52      - [Control Plane node migration](#control-plane-node-migration)
    53    - [Reporting Issues](#reporting-issues)
    54  
    55  ## Reference Documents
    56  
    57  - [Privileges](privileges.md)
    58  - [Control plane machine set](control-plane-machine-set.md)
    59  - [Known Issues and Workarounds](known-issues.md)
    60  - [Troubleshooting your cluster](troubleshooting.md)
    61  - [Customizing your install](customization.md)
    62  - [Installing OpenShift on OpenStack User-Provisioned Infrastructure](install_upi.md)
    63  - [Deploying OpenShift bare-metal workers](deploy_baremetal_workers.md)
    64  - [Deploying OpenShift single root I/O virtualization (SRIOV) workers](deploy_sriov_workers.md)
    65  - [Deploying OpenShift with OVS-DPDK](ovs-dpdk.md)
    66  - [Deploying OpenShift with an external load balancer](external_load_balancer.md)
    67  - [Provider Networks](provider_networks.md)
    68  - [Migrate the Image Registry from Cinder to Swift](image-registry-storage-swift.md)
    69  - [Image Registry With A Custom PVC Backend](image_registry_with_custom_pvc_backends.md)
    70  - [Adding Worker Nodes By Hand](add_worker_nodes_by_hand.md)
    71  - [Connecting workers nodes and pods to an IPv6 network](connect_nodes_to_ipv6_network.md)
    72  - [Connecting worker nodes to a dedicated Manila network](connect_nodes_to_manila_network.md)
    73  - [Learn about the OpenShift on OpenStack networking infrastructure design](../../design/openstack/networking-infrastructure.md)
    74  - [Deploying OpenShift vGPU workers](vgpu.md)
    75  
    76  ## OpenStack Requirements
    77  
    78  The OpenShift installation on OpenStack platform relies on a number of core
    79  services being available:
    80  
    81  - Keystone
    82  - Neutron
    83  - Nova
    84    - with Metadata service enabled
    85  - Glance
    86  - Storage solution for the image registry, one of:
    87    - Swift
    88    - Cinder
    89  
    90  In order to run the latest version of the installer in OpenStack, at a bare minimum you need the following quota to run a *default* cluster. While it is possible to run the cluster with fewer resources than this, it is not recommended. Certain cases, such as deploying [without FIPs](#without-floating-ips), or deploying with an [external load balancer](#using-an-external-load-balancer) are documented below, and are not included in the scope of this recommendation.
    91  
    92  For a successful installation it is required:
    93  
    94  - Floating IPs: 2 (plus one that will be created and destroyed by the Installer during the installation process)
    95  - Security Groups: 3
    96  - Security Group Rules: 60
    97  - Routers: 1
    98  - Subnets: 1
    99  - Server Groups: 2, plus one per additional Availability zone in each machine-pool
   100  - RAM: 112 GB
   101  - vCPUs: 28
   102  - Volume Storage: 700 GB
   103  - Instances: 7
   104  - Depending on the type of [image registry backend](#image-registry-requirements) either 1 Swift container or an additional 100 GB volume.
   105  - OpenStack resource tagging
   106  
   107  > **Note**
   108  > The installer will check OpenStack quota limits to make sure that the requested resources can be created.
   109  > Note that it won't check for resource availability in the cloud, but only on the quotas.
   110  
   111  You may need to increase the security group related quotas from their default values. For example (as an OpenStack administrator):
   112  
   113  ```sh
   114  openstack quota set --secgroups 8 --secgroup-rules 100 <project>`
   115  ```
   116  
   117  Once you configure the quota for your project, please ensure that the user for the installer has the proper [privileges](privileges.md).
   118  
   119  ### Master Nodes
   120  
   121  The default deployment stands up 3 master nodes, which is the minimum amount required for a cluster. For each master node you stand up, you will need 1 instance, and 1 port available in your quota. They should be assigned a flavor with at least 16 GB RAM, 4 vCPUs, and 100 GB Disk (or Root Volume). It is theoretically possible to run with a smaller flavor, but be aware that if it takes too long to stand up services, or certain essential services crash, the installer could time out, leading to a failed install.
   122  
   123  The master nodes are placed in a single Server group with "soft anti-affinity" policy by default; the machines will therefore be created on separate hosts when possible. Note that this is also the case when the master nodes are deployed across multiple availability zones that were specified by their failure domain.
   124  
   125  ### Worker Nodes
   126  
   127  The default deployment stands up 3 worker nodes. Worker nodes host the applications you run on OpenShift. The flavor assigned to the worker nodes should have at least 2 vCPUs, 8 GB RAM and 100 GB Disk (or Root Volume). However, if you are experiencing `Out Of Memory` issues, or your installs are timing out, try increasing the size of your flavor to match the master nodes: 4 vCPUs and 16 GB RAM.
   128  
   129  The worker nodes are placed in a single Server group with "soft anti-affinity" policy by default; the machines will therefore be created on separate hosts when possible.
   130  
   131  See the [OpenShift documentation](https://docs.openshift.com/container-platform/4.4/architecture/control-plane.html#defining-workers_control-plane) for more information on the worker nodes.
   132  
   133  ### Bootstrap Node
   134  
   135  The bootstrap node is a temporary node that is responsible for standing up the control plane on the masters. Only one bootstrap node will be stood up and it will be deprovisioned once the production control plane is ready. To do so, you need 1 instance, and 1 port. We recommend a flavor with a minimum of 16 GB RAM, 4 vCPUs, and 100 GB Disk (or Root Volume), it can be created using below command:
   136  
   137  ```sh
   138  openstack flavor create --ram 16384 --disk 128 --vcpu 4 okd-cluster
   139  ```
   140  
   141  ### Image Registry Requirements
   142  
   143  If Swift is available in the cloud where the installation is being performed, it is used as the default backend for the OpenShift image registry. At the time of installation only an empty container is created without loading any data. Later on, for the system to work properly, you need to have enough free space to store the container images.
   144  
   145  In this case the user must have `swiftoperator` permissions. As an OpenStack administrator:
   146  
   147  ```sh
   148  openstack role add --user <user> --project <project> swiftoperator
   149  ```
   150  
   151  If Swift is not available, the [PVC](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims) storage is used as the backend. For this purpose, a persistent volume of 100 GB will be created in Cinder and mounted to the image registry pod during the installation.
   152  
   153  > **Note**
   154  > If you are deploying a cluster in an Availability Zone where Swift isn't available but where Cinder is,
   155  > it is recommended to deploy the Image Registry with Cinder backend.
   156  > It will try to schedule the volume into the same AZ as the Nova zone where the PVC is located;
   157  > otherwise it'll pick the default availability zone.
   158  > If needed, the Image registry can be moved to another availability zone by a day 2 operation.
   159  
   160  If you want to force Cinder to be used as a backend for the Image Registry, you need to remove the `swiftoperator` permissions. As an OpenStack administrator:
   161  
   162  ```sh
   163  openstack role remove --user <user> --project <project> swiftoperator
   164  ```
   165  
   166  > **Note**
   167  > Since Cinder supports only [ReadWriteOnce](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes) access mode,
   168  > it's not possible to have more than one replica of the image registry pod.
   169  
   170  ### Disk Requirements
   171  
   172  Etcd, which runs on the control plane nodes, has [disk requirements](https://github.com/etcd-io/etcd/blob/master/Documentation/op-guide/hardware.md#disks) that need to be met to ensure the stability of the cluster.
   173  
   174  Generally speaking, it is advised to choose for the control plane nodes a flavour that is backed by SSD in order to reduce latency.
   175  
   176  If the ephemeral disk that gets attached to instances of the chosen flavor does not meet etcd requirements, check if the cloud has a more performant volume type and use a [custom `install-config.yaml`](customization.md) to deploy the control plane with root volumes. However, please note that Ceph RBD (and any other network-attached storage) can result in unpredictable network latencies. Prefer PCI passthrough of an NVM device instead.
   177  
   178  In order to **measure the performance of your disk**, you can use [fio](https://github.com/axboe/fio):
   179  
   180  ```shell
   181  sudo podman run \
   182  	--volume "/var/lib/etcd:/mount:z" \
   183  	docker.io/ljishen/fio \
   184  		--directory=/mount \
   185  		--name=iotest \
   186  		--size=22m \
   187  		--bs=2300 \
   188  		--fdatasync=1 \
   189  		--ioengine=sync \
   190  		--rw=write
   191  ```
   192  
   193  The command must be run as superuser.
   194  
   195  In the command output, look for the the 99th percentile of [fdatasync](https://linux.die.net/man/2/fdatasync) durations (`fsync/fdatasync/sync_file_range` -> `sync percentiles`). The number must be less than 10ms (or 10000µs: fio fluidly adjusts the scale between ms/µs/ns depending on the numbers).
   196  
   197  **Look for spikes.** Even if the baseline latency looks good, there may be spikes where it comes up, triggering issues that result in API being unavailable.
   198  
   199  **Prometheus collects etcd-specific metrics.**
   200  
   201  Once the cluster is up, Prometheus provides useful metrics here:
   202  
   203  ```
   204  https://prometheus-k8s-openshift-monitoring.apps.<cluster name>.<domain name>/graph?g0.range_input=2h&g0.stacked=0&g0.expr=histogram_quantile(0.99%2C%20rate(etcd_disk_wal_fsync_duration_seconds_bucket%5B5m%5D))&g0.tab=0&g1.range_input=2h&g1.expr=histogram_quantile(0.99%2C%20rate(etcd_disk_backend_commit_duration_seconds_bucket%5B5m%5D))&g1.tab=0&g2.range_input=2h&g2.expr=etcd_server_health_failures&g2.tab=0
   205  ```
   206  
   207  Click "Login with OpenShift", enter `kubeadmin` and the password printed out by the installer.
   208  
   209  The units are in seconds and should stay under 10ms (0.01s) at all times. The `etcd_health` graph should remain at 0.
   210  
   211  In order to collect relevant information interactively, **run the conformance tests**:
   212  
   213  ```
   214  git clone https://github.com/openshift/origin/
   215  make WHAT=cmd/openshift-tests
   216  export KUBECONFIG=<path/to/kubeconfig>
   217  _output/local/bin/linux/amd64/openshift-tests run openshift/conformance/parallel
   218  ```
   219  
   220  The entire test suite takes over an hour to complete. Run it and check the Prometheus logs afterwards.
   221  
   222  ### Neutron Public Network
   223  
   224  The public network should be created by the OpenStack administrator. Verify the name/ID of the 'External' network:
   225  
   226  ```sh
   227  openstack network list --long -c ID -c Name -c "Router Type"
   228  +--------------------------------------+----------------+-------------+
   229  | ID                                   | Name           | Router Type |
   230  +--------------------------------------+----------------+-------------+
   231  | 148a8023-62a7-4672-b018-003462f8d7dc | public_network | External    |
   232  +--------------------------------------+----------------+-------------+
   233  ```
   234  
   235  > **Note**
   236  > If the Neutron `trunk` service plug-in is enabled, trunk port will be created by default.
   237  > For more information, please refer to [neutron trunk port](https://wiki.openstack.org/wiki/Neutron/TrunkPort).
   238  
   239  ### Nova Metadata Service
   240  
   241  Nova [metadata service](https://docs.openstack.org/nova/latest/user/metadata.html#metadata-service) must be enabled and available at `http://169.254.169.254`. Currently the service is used to deliver Ignition config files to Nova instances and provide information about the machine to `kubelet`.
   242  
   243  ### Glance Service
   244  
   245  The creation of images in Glance should be available to the user. Now Glance is used for two things:
   246  
   247  - Right after the installation starts, the installer automatically uploads the actual `RHCOS` binary image to Glance with the name `<clusterID>-rhcos`. The image exists throughout the life of the cluster and is removed along with it.
   248  
   249  - The installer stores bootstrap ignition configs in a temporary image called `<clusterID>-ignition`. This is not a canonical use of the service, but this solution allows us to unify the installation process, since Glance is available on all OpenStack clouds, unlike Swift. The image exists for a limited period of time while the bootstrap process is running (normally 10-30 minutes), and then is automatically deleted.
   250  
   251  ## OpenStack Credentials
   252  
   253  You must have a `clouds.yaml` file in order to run the installer. The installer will look for a `clouds.yaml` file in the following locations in order:
   254  
   255  1. Value of `OS_CLIENT_CONFIG_FILE` environment variable
   256  2. Current directory
   257  3. unix-specific user config directory (`~/.config/openstack/clouds.yaml`)
   258  4. unix-specific site config directory (`/etc/openstack/clouds.yaml`)
   259  
   260  In many OpenStack distributions, you can generate a `clouds.yaml` file through Horizon. Otherwise, you can make a `clouds.yaml` file yourself.
   261  Information on this file can be found [here](https://docs.openstack.org/openstacksdk/latest/user/config/configuration.html#config-files) and it looks like:
   262  
   263  ```yaml
   264  clouds:
   265    shiftstack:
   266      auth:
   267        auth_url: http://10.10.14.42:5000/v3
   268        project_name: shiftstack
   269        username: shiftstack_user
   270        password: XXX
   271        user_domain_name: Default
   272        project_domain_name: Default
   273    dev-evn:
   274      region_name: RegionOne
   275      auth:
   276        username: 'devuser'
   277        password: XXX
   278        project_name: 'devonly'
   279        auth_url: 'https://10.10.14.22:5001/v2.0'
   280  ```
   281  
   282  The file can contain information about several clouds. For instance, the example above describes two clouds: `shiftstack` and `dev-evn`.
   283  In order to determine which cloud to use, the user can either specify it in the `install-config.yaml` file under `platform.openstack.cloud` or with `OS_CLOUD` environment variable. If both are omitted, then the cloud name defaults to `openstack`.
   284  
   285  ### OpenStack credentials update
   286  
   287  To update the OpenStack credentials on a running OpenShift cluster, upload the new `clouds.yaml` to the `openstack-credentials` secret in the `kube-system` namespace.
   288  
   289  For example:
   290  
   291  ```
   292  oc set data -n kube-system secret/openstack-credentials clouds.yaml="$(<path/to/clouds.yaml)"
   293  ```
   294  
   295  Please note that the credentials MUST be in the `openstack` stanza of `clouds`.
   296  
   297  ### Self Signed OpenStack CA certificates
   298  
   299  If your OpenStack cluster uses self signed CA certificates for endpoint authentication, add the `cacert` key to your `clouds.yaml`. Its value should be a valid path to your CA cert, and the file should be readable by the user who runs the installer. The path can be either absolute, or relative to the current working directory while running the installer.
   300  
   301  For example:
   302  
   303  ```yaml
   304  clouds:
   305    shiftstack:
   306      auth: ...
   307      cacert: "/etc/pki/ca-trust/source/anchors/ca.crt.pem"
   308  ```
   309  
   310  ## Standalone Single-Node Development Environment
   311  
   312  If you would like to set up an isolated development environment, you may use a bare metal host running CentOS 7. The following repository includes some instructions and scripts to help with creating a single-node OpenStack development environment for running the installer. Please refer to [this documentation](https://github.com/shiftstack-dev-tools/ocp-doit) for further details.
   313  
   314  ## Running The Installer
   315  
   316  ### Known Issues
   317  
   318  OpenStack support has [known issues](known-issues.md). We will be documenting workarounds until we are able to resolve these bugs in the upcoming releases. To see the latest status of any bug, read through bugzilla or github link provided in that bug's description. If you know of a possible workaround that hasn't been documented yet, please comment in that bug's tracking link so we can address it as soon as possible. Also note that any bug listed in these documents is already a top priority issue for the dev team, and will be resolved as soon as possible. If you find more bugs during your runs, please read the section on [issue reporting](#reporting-issues).
   319  
   320  ### Initial Setup
   321  
   322  Please head to [openshift.com/try](https://www.openshift.com/try) to get the latest versions of the installer, and instructions to run it.
   323  
   324  Before running the installer, we recommend you create a directory for each cluster you plan to deploy. See the documents on the [recommended workflow](../overview.md#multiple-invocations) for more information about why you should do it this way.
   325  
   326  ```sh
   327  mkdir ostest
   328  cp install-config.yaml ostest/install-config.yaml
   329  ```
   330  
   331  ### API Access
   332  
   333  All the OpenShift nodes get created in an OpenStack tenant network and as such, can't be accessed directly in most OpenStack deployments. We will briefly explain how to set up access to the OpenShift API with and without floating IP addresses.
   334  
   335  #### Using Floating IPs
   336  
   337  This method allows you to attach two floating IP (FIP) addresses to endpoints in OpenShift.
   338  
   339  A standard deployment uses three floating IP addresses in total:
   340  
   341  1. External access to the OpenShift API
   342  2. External access to the workloads (apps) running on the OpenShift cluster
   343  3. Temporary IP address for bootstrap log collection
   344  
   345  The first two addresses (API and Ingress) are generally created up-front and have the corresponding DNS records resolve to them.
   346  
   347  The third floating IP is created automatically by the installer and will be destroyed along with all the other bootstrap resources. If the bootstrapping process fails, the installer will try to SSH into the bootstrap node and collect the logs.
   348  
   349  ##### Create API and Ingress Floating IP Addresses
   350  
   351  The deployed OpenShift cluster will need two floating IP addresses: one to attach to the API load balancer (`apiFloatingIP`) and one for the OpenShift applications (`ingressFloatingIP`). Note that `apiFloatingIP` is the IP address you will add to your `install-config.yaml` or select in the interactive installer prompt.
   352  
   353  You can create them like so:
   354  
   355  ```sh
   356  openstack floating ip create --description "API <cluster name>.<base domain>" <external network>
   357  # => <apiFloatingIP>
   358  openstack floating ip create --description "Ingress <cluster name>.<base domain>" <external network>
   359  # => <ingressFloatingIP>
   360  ```
   361  
   362  > **Note**
   363  > These IP addresses will **not** show up attached to any particular server (e.g. when running `openstack server list`).
   364  > Similarly, the API and Ingress ports will always be in the `DOWN` state.
   365  > This is because the ports are not attached to the servers directly.
   366  > Instead, their fixed IP addresses are managed by keepalived.
   367  > This has no record in Neutron's database and as such, is not visible to OpenStack.
   368  
   369  *The network traffic will flow through even though the IPs and ports do not show up in the servers*.
   370  
   371  For more details, read the [OpenShift on OpenStack networking infrastructure design document](../../design/openstack/networking-infrastructure.md).
   372  
   373  ##### Create API and Ingress DNS Records
   374  
   375  You will also need to add the following records to your DNS:
   376  
   377  ```dns
   378  api.<cluster name>.<base domain>.  IN  A  <apiFloatingIP>
   379  *.apps.<cluster name>.<base domain>.  IN  A  <ingressFloatingIP>
   380  ```
   381  
   382  If you're unable to create and publish these DNS records, you can add them to your `/etc/hosts` file.
   383  
   384  ```dns
   385  <apiFloatingIP> api.<cluster name>.<base domain>
   386  <ingressFloatingIP> console-openshift-console.apps.<cluster name>.<base domain>
   387  <ingressFloatingIP> integrated-oauth-server-openshift-authentication.apps.<cluster name>.<base domain>
   388  <ingressFloatingIP> oauth-openshift.apps.<cluster name>.<base domain>
   389  <ingressFloatingIP> prometheus-k8s-openshift-monitoring.apps.<cluster name>.<base domain>
   390  <ingressFloatingIP> grafana-openshift-monitoring.apps.<cluster name>.<base domain>
   391  <ingressFloatingIP> <app name>.apps.<cluster name>.<base domain>
   392  ```
   393  
   394  > **WARNING:**
   395  > *This workaround will make the API accessible only to the computer with these `/etc/hosts` entries. This is fine for your own testing (and it is enough for the installation to succeed), but it is not enough for a production deployment. In addition, if you create new OpenShift apps or routes, you will have to add their entries too, because `/etc/hosts` does not support wildcard entries.*
   396  
   397  ##### External API Access
   398  
   399  If you have specified the API floating IP (either via the installer prompt or by adding the `apiFloatingIP` entry in your `install-config.yaml`) the installer will attach the Floating IP address to the `api-port` automatically.
   400  
   401  If you have created the API DNS record, you should be able access the OpenShift API.
   402  
   403  ##### External Ingress (apps) Access
   404  
   405  In the same manner, you may have specified an Ingress floating IP by adding the `ingressFloatingIP` entry in your `install-config.yaml`, in which case the installer attaches the Floating IP address to the `ingress-port` automatically.
   406  
   407  If `ingressFloatingIP` is empty or absent in `install-config.yaml`, the Ingress port will be created but not attached to any floating IP. You can manually attach the Ingress floating IP to the ingress-port after the cluster is created.
   408  
   409  That can be done in the following steps:
   410  
   411  ```sh
   412  openstack port show <cluster name>-<clusterID>-ingress-port
   413  ```
   414  
   415  Then attach the FIP to it:
   416  
   417  ```sh
   418  openstack floating ip set --port <cluster name>-<clusterID>-ingress-port <ingressFloatingIP>
   419  ```
   420  
   421  This assumes the floating IP and corresponding `*.apps` DNS record exists.
   422  
   423  
   424  #### Without Floating IPs
   425  
   426  If you cannot or don't want to pre-create a floating IP address, the installation should still succeed, however the installer will fail waiting for the API.
   427  
   428  > **WARNING:**
   429  > The installer will fail if it can't reach the bootstrap OpenShift API in 20 minutes.
   430  
   431  Even if the installer times out, the OpenShift cluster should still come up. Once the bootstrapping process is in place, it should all run to completion. So you should be able to deploy OpenShift without any floating IP addresses and DNS records and create everything yourself after the cluster is up.
   432  
   433  ### Running a Deployment
   434  
   435  To run the installer, you have the option of using the interactive wizard, or providing your own `install-config.yaml` file for it. The wizard is the easier way to run the installer, but passing your own `install-config.yaml` enables you to use more fine grained customizations. If you are going to create your own `install-config.yaml`, read through the available [OpenStack customizations](customization.md).
   436  
   437  ```sh
   438  ./openshift-install create cluster --dir ostest
   439  ```
   440  
   441  If you want to create an install config without deploying a cluster, you can use the command:
   442  
   443  ```sh
   444  ./openshift-install create install-config --dir ostest
   445  ```
   446  
   447  ### Current Expected Behavior
   448  
   449  Currently:
   450  
   451  - Deploys an isolated tenant network
   452  - Deploys a bootstrap instance to bootstrap the OpenShift cluster
   453  - Deploys 3 master nodes
   454  - Once the masters are deployed, the bootstrap instance is destroyed
   455  - Deploys 3 worker nodes
   456  
   457  Look for a message like this to verify that your install succeeded:
   458  
   459  ```txt
   460  INFO Install complete!
   461  INFO To access the cluster as the system:admin user when using 'oc', run
   462      export KUBECONFIG=/home/stack/ostest/auth/kubeconfig
   463  INFO Access the OpenShift web-console here: https://console-openshift-console.apps.ostest.shiftstack.com
   464  INFO Login to the console with user: kubeadmin, password: xxx
   465  ```
   466  
   467  ### Checking Cluster Status
   468  
   469  If you want to see the status of the apps and services in your cluster during, or after a deployment, first export your administrator's kubeconfig:
   470  
   471  ```sh
   472  export KUBECONFIG=ostest/auth/kubeconfig
   473  ```
   474  
   475  After a finished deployment, there should be a node for each master and worker server created. You can check this with the command:
   476  
   477  ```sh
   478  oc get nodes
   479  ```
   480  
   481  To see the version of your OpenShift cluster, do:
   482  
   483  ```sh
   484  oc get clusterversion
   485  ```
   486  
   487  To see the status of you operators, do:
   488  
   489  ```sh
   490  oc get clusteroperator
   491  ```
   492  
   493  Finally, to see all the running pods in your cluster, you can do:
   494  
   495  ```sh
   496  oc get pods -A
   497  ```
   498  ### Destroying The Cluster
   499  
   500  To destroy the cluster, point it to your cluster with this command:
   501  
   502  ```sh
   503  ./openshift-install --log-level debug destroy cluster --dir ostest
   504  ```
   505  
   506  Then, you can delete the folder containing the cluster metadata:
   507  
   508  ```sh
   509  rm -rf ostest/
   510  ```
   511  ## Post Install Operations
   512  
   513  ### Adding a MachineSet
   514  
   515  Groups of Compute nodes are managed using the MachineSet resource. It is possible to create additional MachineSets post-install, for example to assign workloads to specific machines.
   516  
   517  When running on OpenStack, the MachineSet has platform-specific fields under `spec.template.spec.providerSpec.value`. For more information about the values that you can set in the `providerSpec`, see [the API definition][provider-spec-definition].
   518  
   519  ```yaml
   520  apiVersion: machine.openshift.io/v1beta1
   521  kind: MachineSet
   522  metadata:
   523    labels:
   524      machine.openshift.io/cluster-api-cluster: <infrastructure_ID>
   525      machine.openshift.io/cluster-api-machine-role: <node_role>
   526      machine.openshift.io/cluster-api-machine-type: <node_role>
   527    name: <infrastructure_ID>-<node_role>
   528    namespace: openshift-machine-api
   529  spec:
   530    replicas: <number_of_replicas>
   531    selector:
   532      matchLabels:
   533        machine.openshift.io/cluster-api-cluster: <infrastructure_ID>
   534        machine.openshift.io/cluster-api-machineset: <infrastructure_ID>-<node_role>
   535    template:
   536      metadata:
   537        labels:
   538          machine.openshift.io/cluster-api-cluster: <infrastructure_ID>
   539          machine.openshift.io/cluster-api-machine-role: <node_role>
   540          machine.openshift.io/cluster-api-machine-type: <node_role>
   541          machine.openshift.io/cluster-api-machineset: <infrastructure_ID>-<node_role>
   542      spec:
   543        providerSpec:
   544          value:
   545            apiVersion: openstackproviderconfig.openshift.io/v1alpha1
   546            cloudName: openstack
   547            cloudsSecret:
   548              name: openstack-cloud-credentials
   549              namespace: openshift-machine-api
   550            flavor: <nova_flavor>
   551            image: <glance_image_name_or_location>
   552            serverGroupID: <UUID of the pre-created Nova server group (optional)>
   553            kind: OpenstackProviderSpec
   554            networks:
   555            - filter: {}
   556              subnets:
   557              - filter:
   558                  name: <subnet_name>
   559                  tags: openshiftClusterID=<infrastructure_ID>
   560            securityGroups:
   561            - filter: {}
   562              name: <infrastructure_ID>-<node_role>
   563            serverMetadata:
   564              Name: <infrastructure_ID>-<node_role>
   565              openshiftClusterID: <infrastructure_ID>
   566            tags:
   567            - openshiftClusterID=<infrastructure_ID>
   568            trunk: true
   569            userDataSecret:
   570              name: <node_role>-user-data
   571            availabilityZone: <optional_openstack_availability_zone>
   572  ```
   573  
   574  [provider-spec-definition]: https://github.com/openshift/api/blob/master/machine/v1alpha1/types_openstack.go
   575  
   576  #### Defining a MachineSet That Uses Multiple Networks
   577  
   578  To define a MachineSet with multiple networks, the `primarySubnet` value in the `providerSpec` must be set to the OpenStack subnet that you want the Kubernetes endpoints of the nodes to be published on. For most use cases, this is the same subnet(s) as the subnets listed in [controlPlanePort](./customization.md#cluster-scoped-properties) in the `install-config.yaml`.
   579  
   580   After you set the subnet, add all of the networks that you want to attach to your machines to the `Networks` list in `providerSpec`. You must also add the network that the primary subnet is part of to this list.
   581  
   582  #### Using a Server Group
   583  
   584  The `serverGroupID` property of the `MachineSet` resource is used to create machines in that OpenStack server group. The server group must exist in OpenStack before you can apply the new `MachineSet` resource.
   585  
   586  In order to hint the Nova scheduler to spread the Machines across different
   587  hosts, first create a Server Group with the [desired
   588  policy][server-group-docs]:
   589  
   590  ```shell
   591  openstack server group create --policy=anti-affinity <server-group-name>
   592  ## OR ##
   593  openstack --os-compute-api-version=2.15 server group create --policy=soft-anti-affinity <server-group-name>
   594  ```
   595  
   596  If the command is successful, the OpenStack CLI will return the ID of the newly
   597  created Server Group. Paste it in the optional `serverGroupID` property of the
   598  MachineSet.
   599  
   600  #### Setting Nova Availability Zones
   601  
   602  In order to use Availability Zones, create one MachineSet per target
   603  Availability Zone, and set the Availability Zone in the `availabilityZone`
   604  property of the MachineSet.
   605  
   606  [server-group-docs]: https://docs.openstack.org/api-ref/compute/?expanded=create-server-group-detail#create-server-group
   607  
   608  ### Using a Custom External Load Balancer
   609  
   610  You can shift ingress/egress traffic from the default OpenShift on OpenStack load balancer to a load balancer that you provide. To do so, the instance that it runs from must be able to access every machine in your cluster. You might ensure this access by creating the instance on a subnet that is within your cluster's network, and then attaching a router interface to that subnet from the `OpenShift-external-router` [object/instance/whatever]. This can also be accomplished by attaching floating ips to the machines you want to add to your load balancer.
   611  
   612  #### External Facing OpenShift Services
   613  
   614  Add the following external facing services to your new load balancer:
   615  
   616  - The master nodes serve the OpenShift API on port 6443 using TCP.
   617  - The apps hosted on the worker nodes are served on ports 80, and 443. They are both served using TCP.
   618  
   619  > **Note**
   620  > Make sure the instance that your new load balancer is running on has security group rules that allow TCP traffic over these ports.
   621  
   622  #### HAProxy Example Load Balancer Config
   623  
   624  The following `HAProxy` config file demonstrates a basic configuration for an external load balancer:
   625  
   626  ```haproxy
   627  listen <cluster-name>-api-6443
   628          bind 0.0.0.0:6443
   629          mode tcp
   630          balance roundrobin
   631          server <cluster-name>-master-0 192.168.0.154:6443 check
   632          server <cluster-name>-master-1 192.168.0.15:6443 check
   633          server <cluster-name>-master-2 192.168.3.128:6443 check
   634  listen <cluster-name>-apps-443
   635          bind 0.0.0.0:443
   636          mode tcp
   637          balance roundrobin
   638          server <cluster-name>-worker-0 192.168.3.18:443 check
   639          server <cluster-name>-worker-1 192.168.2.228:443 check
   640          server <cluster-name>-worker-2 192.168.1.253:443 check
   641  listen <cluster-name>-apps-80
   642          bind 0.0.0.0:80
   643          mode tcp
   644          balance roundrobin
   645          server <cluster-name>-worker-0 192.168.3.18:80 check
   646          server <cluster-name>-worker-1 192.168.2.228:80 check
   647          server <cluster-name>-worker-2 192.168.1.253:80 check
   648  ```
   649  
   650  #### DNS Lookups
   651  
   652  To ensure that your API and apps are accessible through your load balancer, [create or update your DNS entries](#create-api-and-ingress-dns-records) for those endpoints. To use your new load balancing service for external traffic, make sure the IP address for these DNS entries is the IP address your load balancer is reachable at.
   653  
   654  ```dns
   655  <load balancer ip> api.<cluster-name>.<base domain>
   656  <load balancer ip> apps.<cluster-name>.base domain>
   657  ```
   658  
   659  #### Verifying that the API is Reachable
   660  
   661  One good way to test whether or not you can reach the API is to run the `oc` command. If you can't do that easily, you can use this curl command:
   662  
   663  ```sh
   664  curl https://api.<cluster-name>.<base domain>:6443/version --insecure
   665  ```
   666  
   667  Result:
   668  
   669  ```json
   670  {
   671    "major": "1",
   672    "minor": "19",
   673    "gitVersion": "v1.19.2+4abb4a7",
   674    "gitCommit": "4abb4a77838037b8dbb8e4ca34e63c4a129654c8",
   675    "gitTreeState": "clean",
   676    "buildDate": "2020-11-12T05:46:36Z",
   677    "goVersion": "go1.15.2",
   678    "compiler": "gc",
   679    "platform": "linux/amd64"
   680  }
   681  ```
   682  
   683  > **Note**
   684  > The versions in the sample output may differ from your own. As long as you get a JSON payload response, the API is accessible.
   685  
   686  #### Verifying that Apps Reachable
   687  
   688  The simplest way to verify that apps are reachable is to open the OpenShift console in a web browser. If you don't have access to a web browser, query the console with the following curl command:
   689  
   690  ```sh
   691  curl http://console-openshift-console.apps.<cluster-name>.<base domain> -I -L --insecure
   692  ```
   693  
   694  
   695  Result:
   696  
   697  ```http
   698  HTTP/1.1 302 Found
   699  content-length: 0
   700  location: https://console-openshift-console.apps.<cluster-name>.<base domain>/
   701  cache-control: no-cacheHTTP/1.1 200 OK
   702  referrer-policy: strict-origin-when-cross-origin
   703  set-cookie: csrf-token=39HoZgztDnzjJkq/JuLJMeoKNXlfiVv2YgZc09c3TBOBU4NI6kDXaJH1LdicNhN1UsQWzon4Dor9GWGfopaTEQ==; Path=/; Secure
   704  x-content-type-options: nosniff
   705  x-dns-prefetch-control: off
   706  x-frame-options: DENY
   707  x-xss-protection: 1; mode=block
   708  date: Tue, 17 Nov 2020 08:42:10 GMT
   709  content-type: text/html; charset=utf-8
   710  set-cookie: 1e2670d92730b515ce3a1bb65da45062=9b714eb87e93cf34853e87a92d6894be; path=/; HttpOnly; Secure; SameSite=None
   711  cache-control: private
   712  ```
   713  
   714  ### Reconfiguring cloud provider
   715  
   716  If you need to update the OpenStack cloud provider configuration you can edit the ConfigMap containing it:
   717  
   718  ```sh
   719  oc edit configmap -n openshift-config cloud-provider-config
   720  ```
   721  
   722  > **Note**
   723  > It can take a while to reconfigure the cluster depending on the size of it.
   724  > The reconfiguration is completed once no node is getting `SchedulingDisabled` taint anymore.
   725  
   726  There are several things you can change:
   727  
   728  #### Modifying cloud provider options
   729  
   730  If you need to modify the direct cloud provider options, then edit the `config` key in the ConfigMap. A brief list of possible options is shown in [Cloud Provider configuration](./customization.md#cloud-provider-configuration) section.
   731  
   732  
   733  #### Refreshing a CA Certificate
   734  
   735  If you ran the installer with a [custom CA certificate](#self-signed-openstack-ca-certificates), then this certificate can be changed while the cluster is running. To change your certificate, edit the value of the `ca-cert.pem` key in the `cloud-provider-config` configmap with a valid PEM certificate.
   736  
   737  ## Control Plane node migration
   738  
   739  This script moves one node from its host to a different host.
   740  
   741  Requirements:
   742  * environment variable `OS_CLOUD` pointing to a `clouds` entry with admin credentials in `clouds.yaml`
   743  * environment variable `KUBECONFIG` pointing to admin OpenShift credentials
   744  
   745  ```
   746  #!/usr/bin/env bash
   747  
   748  set -Eeuo pipefail
   749  
   750  if [ $# -lt 1 ]; then
   751  	echo "Usage: '$0 node_name'"
   752  	exit 64
   753  fi
   754  
   755  # Check for admin OpenStack credentials
   756  openstack server list --all-projects >/dev/null || { >&2 echo "The script needs OpenStack admin credentials. Exiting"; exit 77; }
   757  
   758  # Check for admin OpenShift credentials
   759  oc adm top node >/dev/null || { >&2 echo "The script needs OpenShift admin credentials. Exiting"; exit 77; }
   760  
   761  set -x
   762  
   763  declare -r node_name="$1"
   764  declare server_id
   765  server_id="$(openstack server list --all-projects -f value -c ID -c Name | grep "$node_name" | cut -d' ' -f1)"
   766  readonly server_id
   767  
   768  # Drain the node
   769  oc adm cordon "$node_name"
   770  oc adm drain "$node_name" --delete-emptydir-data --ignore-daemonsets --force
   771  
   772  # Power off the server
   773  oc debug "node/${node_name}" -- chroot /host shutdown -h 1
   774  
   775  # Verify the server is shutoff
   776  until openstack server show "$server_id" -f value -c status | grep -q 'SHUTOFF'; do sleep 5; done
   777  
   778  # Migrate the node
   779  openstack server migrate --wait "$server_id"
   780  
   781  # Resize VM
   782  openstack server resize confirm "$server_id"
   783  
   784  # Wait for the resize confirm to finish
   785  until openstack server show "$server_id" -f value -c status | grep -q 'SHUTOFF'; do sleep 5; done
   786  
   787  # Restart VM
   788  openstack server start "$server_id"
   789  
   790  # Wait for the node to show up as Ready:
   791  until oc get node "$node_name" | grep -q "^${node_name}[[:space:]]\+Ready"; do sleep 5; done
   792  
   793  # Uncordon the node
   794  oc adm uncordon "$node_name"
   795  
   796  # Wait for cluster operators to stabilize
   797  until oc get co -o go-template='statuses: {{ range .items }}{{ range .status.conditions }}{{ if eq .type "Degraded" }}{{ if ne .status "False" }}DEGRADED{{ end }}{{ else if eq .type "Progressing"}}{{ if ne .status "False" }}PROGRESSING{{ end }}{{ else if eq .type "Available"}}{{ if ne .status "True" }}NOTAVAILABLE{{ end }}{{ end }}{{ end }}{{ end }}' | grep -qv '\(DEGRADED\|PROGRESSING\|NOTAVAILABLE\)'; do sleep 5; done
   798  ```
   799  
   800  ## Reporting Issues
   801  
   802  Please see the [Issue Tracker][issues_openstack] for current known issues.
   803  Please report a new issue if you do not find an issue related to any trouble you’re having.
   804  
   805  [issues_openstack]: https://github.com/openshift/installer/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+openstack