---
title: "Install Calico on an OpenShift HCP cluster"
description: "Install Calico Open Source on an OpenShift Hosted Control Planes (HCP) cluster, where the control plane is managed and the data plane runs on user-owned nodes."
product: "Calico Open Source"
version: "3.32 (latest)"
section: "Installing and upgrading"
canonical_url: "https://docs.tigera.io/calico/latest/getting-started/kubernetes/openshift/hostedcontrolplanes"
---

# Install Calico on an OpenShift HCP cluster

## Big picture

Install Calico on an OpenShift Hosted Control Planes (HCP) cluster.

## Value

Provides steps to install Calico in [OpenShift Hosted Control Planes (HCP)](https://docs.openshift.com/container-platform/latest/hosted_control_planes/index.html) clusters using the [HyperShift](https://github.com/openshift/hypershift) middleware, augmenting the steps in the [HyperShift documentation](https://hypershift-docs.netlify.app) where appropriate.

## How to

### Before you begin

- Ensure that your environment meets the Calico [system requirements](https://docs.tigera.io/calico/latest/getting-started/kubernetes/openshift/requirements.md).

- Ensure that you have a [RedHat account](https://cloud.redhat.com/). A RedHat account is required to get the pull secret necessary to provision an OpenShift cluster. Note that the OpenShift installer supports a subset of AWS regions.

- If installing on AWS, ensure that you have:

  - Configured an AWS account appropriate for OpenShift 4
  - [Set up your AWS credentials](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html)
  - Generated a local SSH private key and added it to your ssh-agent

- Install the HyperShift CLI and fulfill all the other [Prerequisites from the HyperShift documentation](https://hypershift-docs.netlify.app/getting-started/#prerequisites).

### Create the hosting cluster

Deploy an [OpenShift cluster](https://docs.tigera.io/calico/latest/getting-started/kubernetes/openshift/installation.md) with Calico. This will be the hosting cluster with control-plane nodes for all hosted clusters you deploy with the steps below. Set up your `KUBECONFIG` environment variable to your hosting cluster's kubeconfig file:

```text
export KUBECONFIG=/path/to/kubeconfig
```

### Install the HyperShift operator in the hosting cluster

Follow the steps from the HyperShift documentation to [Install the HyperShift Operator](https://hypershift-docs.netlify.app/getting-started/#install-hypershift-operator).

### Create a hosted cluster

Create a hosted cluster with Calico by going through the following steps (slightly modified from the [HyperShift docs](https://hypershift-docs.netlify.app/how-to/aws/other-sdn-providers/#calico)).

1. Create a HostedCluster and set its HostedCluster.spec.networking.networkType to Other:

> **SECONDARY:** Make sure to adjust the variables for the command below to the correct values for your cluster, credentials and environment.

```text
HOSTED_CLUSTER_NAME=my-os-hosted-cluster
REGION=us-west-2
BASE_DOMAIN=www.example.com
AWS_CREDS="$HOME/.aws/credentials"
PULL_SECRET="$HOME/.secrets/redhat-pull-secret.txt"

hypershift create cluster aws \
  --name $HOSTED_CLUSTER_NAME \
  --node-pool-replicas=3 \
  --base-domain $BASE_DOMAIN \
  --pull-secret $PULL_SECRET \
  --aws-creds $AWS_CREDS \
  --region $REGION \
  --generate-ssh \
  --network-type Other
```

> **SECONDARY:** If your hosted cluster is having authorization problems with your Red Hat pull secret (`unauthorized: authentication required` in the HyperShift operator pod logs), make sure it is using a stable release image for the OpenShift Container Platform (OCP). You can find them in \[[https://amd64.ocp.releases.ci.openshift.org](https://amd64.ocp.releases.ci.openshift.org)], for example `--release-image quay.io/openshift-release-dev/ocp-release:4.16.4-x86_64`

> **SECONDARY:** If you face an [issue](https://github.com/openshift/hypershift/issues/3927) with the HyperShift middleware that results in the hosted cluster installation not progressing due to a missing `OVNSbDb` service, patch the hosted cluster resource in order to add it:
>
> ```text
> HOSTED_CLUSTER_NAME=my-os-hosted-cluster
> CLUSTER_NS="clusters"
> oc patch -n ${CLUSTER_NS} hostedcluster ${HOSTED_CLUSTER_NAME} --type='json' -p '[{"op": "add", "path": "/spec/services/-", "value": {"service":"OVNSbDb","servicePublishingStrategy": {"type": "Route"}}}]'
> ```

Once the hosted cluster is up, use the `hypershift` CLI tool to generate the `kubeconfig` file. We strongly recommend you create a separate directory for the hosted cluster, it is very important to not mix up configuration and manifests from the hosting and hosted clusters:

```text
mkdir my_hosted_cluster && cd my_hosted_cluster
hypershift create kubeconfig > hosted_kubeconfig && export KUBECONFIG=$(pwd)/hosted_kubeconfig
```

Then, copy the `aws-creds` secret from the hosting cluster to the hosted cluster. Run this using the hosting cluster kubeconfig to extract the secret to a `yaml` file:

```text
oc get secrets --kubeconfig /path/to/hosting/kubeconfig -n kube-system aws-creds -o yaml > aws-creds.yaml
```

Then import it in the hosted cluster:

```text
oc apply --kubeconfig /path/to/hosted/kubeconfig -f aws-creds.yaml
```

> **SECONDARY:** There is no need to specify the `--kubeconfig` CLI argument if the hosted cluster's kubeconfig file is configured as the `KUBECONFIG` environment variable in your shell.

### Download the Calico install manifests

Download the Calico manifests for OpenShift:

```bash
mkdir calico
wget -qO- https://github.com/projectcalico/calico/releases/download/v3.32.1/ocp.tgz | \
tar xvz --strip-components=1 -C calico
```

### Select and configure a data plane

Calico manifests for OpenShift are ready to configure and install the **eBPF** data plane. The steps in the **eBPF (recommended)** tab below will guide you through the process. You can also select a different tab to follow the steps for configuring another data plane.

<!-- tabs -->

**Tab: eBPF (recommended)**

To configure the eBPF data plane, you need to:

1. Set the `KUBERNETES_SERVICE_HOST` attribute in the `calico/01-configmap-kubernetes-services-endpoint.yaml` file. You can use the `oc config view` command to look at the `server` attribute for the cluster. The following extracts the URL from the `oc config view` command and sets it.

   ```bash
   API_SERVER_URL=$(oc config view | sed -n 's/.*server: https:\/\/\([^:]*\).*/\1/p') && \
   sed -i "s|^\([^:]*KUBERNETES_SERVICE_HOST: \).*\$|\1\"$API_SERVER_URL\"|" calico/01-configmap-kubernetes-services-endpoint.yaml
   ```

2. Include the following `spec.template.spec.dnsConfig.nameservers` block to resolve the apiserver DNS in the `calico/02-tigera-operator.yaml` file. For clusters in AWS, the DNS server address is 169.254.169.253.

   ```yaml
   spec:
     template:
       spec:
         (...)
         dnsConfig:
           nameservers:
           - 169.254.169.253 # AWS DNS server
   ```

3. Disable kube-proxy in the OpenShift Cluster Network Operator:

   ```bash
   oc patch network.operator.openshift.io cluster --type merge --patch '{"spec":{"deployKubeProxy":false}}'
   ```

**Tab: Iptables**

To install Calico with iptables, you need to:

1. Set `linuxDataplane` to `Iptables` in the `calico/03-cr-installation.yaml` file.

2. Remove the `calico/cluster-network-operator.yaml` and `calico/01-configmap-kubernetes-services-endpoint.yaml` files.

You can do it by running the following command:

```bash
sed -i 's/^\(\s*linuxDataplane:\s*\)BPF/\1Iptables/' calico/03-cr-installation.yaml && \
rm -f calico/cluster-network-operator.yaml && \
rm -f calico/01-configmap-kubernetes-services-endpoint.yaml
```

<!-- /tabs -->

### Optionally provide additional configuration

You may want to provide Calico with additional configuration at install-time. For example, BGP configuration or peers. You can use a Kubernetes ConfigMap with your desired Calico resources to set configuration as part of the installation. If you do not need to provide additional configuration, you can skip this section.

To include [Calico resources](https://docs.tigera.io/calico/latest/reference/resources.md) during installation, edit `calico/02-configmap-calico-resources.yaml` to add your own configuration.

> **SECONDARY:** If you have a directory with the Calico resources, you can create the file with the command:
>
> ```text
> oc create configmap -n tigera-operator calico-resources \
> --from-file=<resource-directory> --dry-run -o yaml \
> calico/02-configmap-calico-resources.yaml
> ```
>
> With recent versions of oc it is necessary to have a kubeconfig configured or add `--server='127.0.0.1:443'` even though it is not used.

> **SECONDARY:** If you have provided a `calico-resources` configmap and the tigera-operator pod fails to come up with `Init:CrashLoopBackOff`, check the output of the init-container with `oc logs -n tigera-operator -l k8s-app=tigera-operator -c create-initial-resources`.

### Apply the Calico install manifests

Apply the install manifests paying attention to the required order. First apply all necessary manifests to install the Tigera Operator:

```text
cd calico/
ls 00* | xargs -n1 oc apply -f
ls 01* | xargs -n1 oc apply -f
ls 02* | xargs -n1 oc apply -f
```

Then wait until the Tigera Operator creates the necessary CustomResourceDefinitions (CRDs) before applying the CustomResources to install Calico on your cluster:

```text
timeout --foreground 600 bash -c "while ! kubectl get crd installations.operator.tigera.io; do sleep 5; done" # wait until CRDs are created by the operator
ls 03* | xargs -n1 oc apply -f
```

> **SECONDARY:** You can safely ignore any `ls: cannot access '0X*': No such file or directory` errors if there's no yaml files with that prefix to be applied.

Once the above commands are complete, you can verify Calico is installed by verifying the components are available with the following command.

```text
oc get tigerastatus
```

> **SECONDARY:** To get more information, add `-o yaml` to the above command.

## Next steps

**Recommended - Networking**

- If you are using the default BGP networking with full-mesh node-to-node peering with no encapsulation, go to [Configure BGP peering](https://docs.tigera.io/calico/latest/networking/configuring/bgp.md) to get traffic flowing between pods.
- If you are unsure about networking options, or want to implement encapsulation (overlay networking), see [Determine best networking option](https://docs.tigera.io/calico/latest/networking/determine-best-networking.md).

**Recommended - Security**

- [Secure Calico component communications](https://docs.tigera.io/calico/latest/network-policy/comms/crypto-auth.md)
- [Secure hosts by installing Calico on hosts](https://docs.tigera.io/calico/latest/getting-started/bare-metal/about.md)
- [Secure pods with Calico network policy](https://docs.tigera.io/calico/latest/network-policy/get-started/calico-policy/calico-network-policy.md)
- If you are using Calico with Istio service mesh, get started here: [Enable application layer policy](https://docs.tigera.io/calico/latest/network-policy/istio/app-layer-policy.md)
