Help us improve your experience.

Let us know what you think.

Do you have time for a two-minute survey?


Create a Kubernetes Cluster

Use this example procedure to create an upstream Kubernetes cluster.

We provide this example procedure purely for informational purposes. There are multiple ways you can create a cluster, such as with kubeadm, kOps, or kubespray, among others.

In this example, we'll use kubespray and Ansible to create the cluster. Kubespray uses Ansible playbooks, which makes cluster creation fairly straightforward. To make the steps easier to follow, we'll use a separate installer machine to perform the installation and to run kubectl and other tools.

For more information on creating a cluster, see the official Kubernetes documentation (


The command line examples below don't always show absolute directory paths. We leave it to you to apply these commands within your directory structure.

  1. Install a fresh OS on the installer machine, configuring the OS minimally for the following:
    • static IP address and mask (for example, for our single cluster) and gateway
    • access to one or more DNS servers
    • SSH connectivity including root SSH access
    • NTP
    The installer machine used in our examples is a Ubuntu host attached to the cluster network.
  2. From your local computer, SSH into the installer machine as the sudo user.
  3. Install ansible.
  4. Install kubectl. In this example, we run kubectl on the installer machine. If you want to run kubectl on another machine (for example, your local computer), download and install kubectl on that machine instead.
    • Set up and update the Kubernetes repository.
    • Install kubectl.
  5. If you want to install Contrail Analytics, then install Helm 3.0 or later.
    • Set up and update the Helm repository.

    • Install Helm.

  6. Configure SSH password-less root access from the installer machine to the control plane and worker nodes. This allows ansible to log in to these nodes when you run the playbook later.
    1. Create an SSH key.

      In this example, we store the SSH key in its default location ~/.ssh/

    2. Copy the key to the root user on the control plane and worker nodes. For example:
  7. Clone the kubespray directory.
    For example:

    This creates a clone of the kubespray directory at the present location (in ~/contrail in this example).

  8. Configure the pod and service subnets if desired.
    The default subnets used by kubespray are defined in the kubespray/roles/kubespray-defaults/defaults/main.yaml file. Look for the following parameters in that file and change accordingly.

    If you're creating a multi-cluster Contrail setup, you must configure different pod and service subnets on each cluster. These subnets must be unique within the entire multi-cluster.

    If you're following the multi-cluster example in this document, then leave the subnets on the central cluster at their defaults and configure the subnets on the workload cluster as follows:

  9. Disable Node Local DNS.
    In the kubespray/roles/kubespray-defaults/defaults/main.yaml file, set enable_nodelocaldns: false.
  10. If you're running DPDK in your cluster, then configure multus.
    Multus is required when running DPDK.
    1. Enable multus.
      In kubespray/roles/kubespray-defaults/defaults/main.yaml, enable multus:
    2. Set the multus version to 0.3.1, which is the version required for running DPDK. You set the version in two files.
      In kubespray/roles/network_plugin/multus/defaults/main.yml, configure the multus version:
      In kubespray/extra_playbooks/roles/network_plugin/multus/defaults/main.yml, configure the multus version:
  11. Create the inventory file for ansible to use. For example:

    The host names (k8s-cp0, k8s-worker0, k8s-worker1) that you specify in the file are automatically configured on the node when the override_system_hostname parameter is set to true.


    If you're creating a multi-cluster Contrail setup, you must configure different node names for each node in the multi-cluster. Node names must be unique across the entire multi-cluster.


    If you're running DPDK, set kube_network_plugin_multus: true.

    If you want to run with a different container runtime, change the container_manager value above.

    Ensure enable_nodelocaldns is set to false.

    If you want to run with a different number of control plane and worker nodes, adjust the inventory accordingly.

  12. Check that ansible can SSH into the control plane and worker nodes based on the contents of the inventory.yaml file. In this example, the inventory.yaml file is in the ~/contrail directory.
  13. To create the cluster, run the playbook from the kubespray directory. Adjust the command below to reference the inventory.yaml within your directory structure.
    This step can take a an hour or more to complete, depending on the size of your cluster.

    You can safely ignore network and CNI warnings and errors because you haven't configured a CNI yet. If a fatal error occurs, ansible will stop the playbook.

  14. Copy the cluster's secure token to the default ~/.kube/config location. The kubeconfig must be at that default location for Contrail tools to work.
    You can find the secure token location from the inventory.yaml file. If you use the inventory file in this example, the token is in /tmp/mycluster.

    If you have a kubeconfig that already holds tokens for existing clusters, then you'll need to merge rather than overwrite the ~/.kube/config file.

  15. Use standard kubectl commands to check on the health of the cluster.
    1. Show the status of the nodes.
      You can see that the nodes are not ready because there is no CNI plug-in. This is expected because you haven't installed Contrail yet.
    2. Show the status of the pods.
      All pods should have a STATUS of Running except for the DNS pods. The DNS pods do not come up because there is no networking. This is what we expect.
You have successfully installed a new cluster. You can now proceed to install Contrail on this cluster.