Other SDN providers
This document explains how to create a HostedCluster that runs an SDN provider different from OVNKubernetes. The document assumes that you already have the required infrastructure in place to create HostedClusters.
Important
The work described here is not supported. SDN providers must certify their software on HyperShift before it becomes a supported solution. The steps described here are just a technical reference for people who wants to try different SDN providers in HyperShift.
Versions used while writing this doc:
- Management cluster running OpenShift
v4.14.5
and HyperShift Operator versione87182ca75da37c74b371aa0f17aeaa41437561a
. - HostedCluster release set to OpenShift
v4.14.10
.
Important
To configure a different CNI provider for the Hosted Cluster, you must adjust the hostedcluster.spec.networking.networkType
to Other
. By doing so, the Control Plane Operator will skip the deployment of the default CNI provider.
Calico
Deployment
In this scenario we are using the Calico version v3.27.0 which is the last one at the time of this writing. The steps followed rely on the docs by Tigera to deploy Calico on OpenShift.
-
Create a
HostedCluster
and set itsHostedCluster.spec.networking.networkType
toOther
. -
Wait for the HostedCluster's API to be ready. Once it's ready, get the admin kubeconfig.
-
Eventually the compute nodes will show up in the cluster. Keep in mind since the SDN is not deployed yet, they will remain in
NotReady
state.export KUBECONFIG=/path/to/hostedcluster/admin/kubeconfig oc get nodes
NAME STATUS ROLES AGE VERSION hosted-worker1 NotReady worker 2m51s v1.27.8+4fab27b hosted-worker2 NotReady worker 2m52s v1.27.8+4fab27b
-
Apply the yaml manifests provided by
Tigera
in the HostedCluster:mkdir calico wget -qO- https://github.com/projectcalico/calico/releases/download/v3.27.0/ocp.tgz | tar xvz --strip-components=1 -C calico cd calico/ ls *crd*.yaml | xargs -n1 oc apply -f ls 00* | xargs -n1 oc apply -f ls 01* | xargs -n1 oc apply -f ls 02* | xargs -n1 oc apply -f
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgpfilters.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/apiservers.operator.tigera.io created customresourcedefinition.apiextensions.k8s.io/imagesets.operator.tigera.io created customresourcedefinition.apiextensions.k8s.io/installations.operator.tigera.io created customresourcedefinition.apiextensions.k8s.io/tigerastatuses.operator.tigera.io created namespace/calico-apiserver created namespace/calico-system created namespace/tigera-operator created apiserver.operator.tigera.io/default created installation.operator.tigera.io/default created configmap/calico-resources created clusterrolebinding.rbac.authorization.k8s.io/tigera-operator created clusterrole.rbac.authorization.k8s.io/tigera-operator created serviceaccount/tigera-operator created deployment.apps/tigera-operator created
Checks
We should see the following pods running in the tigera-operator
namespace:
oc -n tigera-operator get pods
NAME READY STATUS RESTARTS AGE
tigera-operator-dc7c9647f-fvcvd 1/1 Running 0 2m1s
We should see the following pods running in the calico-system
namespace:
oc -n calico-system get pods
NAME READY STATUS RESTARTS AGE
calico-kube-controllers-69d6d5ff89-5ftcn 1/1 Running 0 2m1s
calico-node-6bzth 1/1 Running 0 2m2s
calico-node-bl4b6 1/1 Running 0 2m2s
calico-typha-6558c4c89d-mq2hw 1/1 Running 0 2m2s
csi-node-driver-l948w 2/2 Running 0 2m1s
csi-node-driver-r6rgw 2/2 Running 0 2m2s
We should see the following pods running in the calico-apiserver
namespace:
oc -n calico-apiserver get pods
NAME READY STATUS RESTARTS AGE
calico-apiserver-7bfbf8fd7c-d75fw 1/1 Running 0 84s
calico-apiserver-7bfbf8fd7c-fqxjm 1/1 Running 0 84s
The nodes should've moved to Ready
state:
oc get nodes
NAME STATUS ROLES AGE VERSION
hosted-worker1 Ready worker 10m v1.27.8+4fab27b
hosted-worker2 Ready worker 10m v1.27.8+4fab27b
The HostedCluster deployment will continue, at this point the SDN is running.
Cilium
Deployment
In this scenario we are using the Cilium version v1.14.5 which is the last one at the time of this writing. The steps followed rely on the docs by Cilium project to deploy Cilium on OpenShift.
-
Create a
HostedCluster
and set itsHostedCluster.spec.networking.networkType
toOther
. -
Wait for the HostedCluster's API to be ready. Once it's ready, get the admin kubeconfig.
-
Eventually the compute nodes will show up in the cluster. Keep in mind since the SDN is not deployed yet, they will remain in
NotReady
state.export KUBECONFIG=/path/to/hostedcluster/admin/kubeconfig oc get nodes
NAME STATUS ROLES AGE VERSION hosted-worker1 NotReady worker 2m30s v1.27.8+4fab27b hosted-worker2 NotReady worker 2m33s v1.27.8+4fab27b
-
Apply the yaml manifests provided by
Isovalent
in the HostedCluster:#!/bin/bash version="1.14.5" oc apply -f https://raw.githubusercontent.com/isovalent/olm-for-cilium/main/manifests/cilium.v${version}/cluster-network-03-cilium-ciliumconfigs-crd.yaml oc apply -f https://raw.githubusercontent.com/isovalent/olm-for-cilium/main/manifests/cilium.v${version}/cluster-network-06-cilium-00000-cilium-namespace.yaml oc apply -f https://raw.githubusercontent.com/isovalent/olm-for-cilium/main/manifests/cilium.v${version}/cluster-network-06-cilium-00001-cilium-olm-serviceaccount.yaml oc apply -f https://raw.githubusercontent.com/isovalent/olm-for-cilium/main/manifests/cilium.v${version}/cluster-network-06-cilium-00002-cilium-olm-deployment.yaml oc apply -f https://raw.githubusercontent.com/isovalent/olm-for-cilium/main/manifests/cilium.v${version}/cluster-network-06-cilium-00003-cilium-olm-service.yaml oc apply -f https://raw.githubusercontent.com/isovalent/olm-for-cilium/main/manifests/cilium.v${version}/cluster-network-06-cilium-00004-cilium-olm-leader-election-role.yaml oc apply -f https://raw.githubusercontent.com/isovalent/olm-for-cilium/main/manifests/cilium.v${version}/cluster-network-06-cilium-00005-cilium-olm-role.yaml oc apply -f https://raw.githubusercontent.com/isovalent/olm-for-cilium/main/manifests/cilium.v${version}/cluster-network-06-cilium-00006-leader-election-rolebinding.yaml oc apply -f https://raw.githubusercontent.com/isovalent/olm-for-cilium/main/manifests/cilium.v${version}/cluster-network-06-cilium-00007-cilium-olm-rolebinding.yaml oc apply -f https://raw.githubusercontent.com/isovalent/olm-for-cilium/main/manifests/cilium.v${version}/cluster-network-06-cilium-00008-cilium-cilium-olm-clusterrole.yaml oc apply -f https://raw.githubusercontent.com/isovalent/olm-for-cilium/main/manifests/cilium.v${version}/cluster-network-06-cilium-00009-cilium-cilium-clusterrole.yaml oc apply -f https://raw.githubusercontent.com/isovalent/olm-for-cilium/main/manifests/cilium.v${version}/cluster-network-06-cilium-00010-cilium-cilium-olm-clusterrolebinding.yaml oc apply -f https://raw.githubusercontent.com/isovalent/olm-for-cilium/main/manifests/cilium.v${version}/cluster-network-06-cilium-00011-cilium-cilium-clusterrolebinding.yaml
-
Use the right configuration for each network stack
apiVersion: cilium.io/v1alpha1
kind: CiliumConfig
metadata:
name: cilium
namespace: cilium
spec:
debug:
enabled: true
k8s:
requireIPv4PodCIDR: true
logSystemLoad: true
bpf:
preallocateMaps: true
etcd:
leaseTTL: 30s
ipv4:
enabled: true
ipv6:
enabled: false
identityChangeGracePeriod: 0s
ipam:
mode: "cluster-pool"
operator:
clusterPoolIPv4PodCIDRList:
- "10.128.0.0/14"
clusterPoolIPv4MaskSize: "23"
nativeRoutingCIDR: "10.128.0.0/14"
endpointRoutes: {enabled: true}
clusterHealthPort: 9940
tunnelPort: 4789
cni:
binPath: "/var/lib/cni/bin"
confPath: "/var/run/multus/cni/net.d"
chainingMode: portmap
prometheus:
serviceMonitor: {enabled: false}
hubble:
tls: {enabled: false}
sessionAffinity: true
oc apply -f ciliumconfig.yaml
apiVersion: cilium.io/v1alpha1
kind: CiliumConfig
metadata:
name: cilium
namespace: cilium
spec:
debug:
enabled: true
k8s:
requireIPv6PodCIDR: true
logSystemLoad: true
bpf:
preallocateMaps: true
etcd:
leaseTTL: 30s
ipv4:
enabled: false
ipv6:
enabled: true
identityChangeGracePeriod: 0s
ipam:
mode: "cluster-pool"
operator:
clusterPoolIPv6PodCIDRList:
- "fd01::/48"
clusterPoolIPv6MaskSize: "48"
nativeRoutingCIDR: "fd01::/48"
endpointRoutes: {enabled: true}
clusterHealthPort: 9940
tunnelPort: 4789
cni:
binPath: "/var/lib/cni/bin"
confPath: "/var/run/multus/cni/net.d"
chainingMode: portmap
prometheus:
serviceMonitor: {enabled: false}
hubble:
tls: {enabled: false}
sessionAffinity: true
oc apply -f ciliumconfig.yaml
apiVersion: cilium.io/v1alpha1
kind: CiliumConfig
metadata:
name: cilium
namespace: cilium
spec:
debug:
enabled: true
k8s:
requireIPv4PodCIDR: true
logSystemLoad: true
bpf:
preallocateMaps: true
etcd:
leaseTTL: 30s
ipv4:
enabled: true
ipv6:
enabled: true
identityChangeGracePeriod: 0s
ipam:
mode: "cluster-pool"
operator:
clusterPoolIPv4PodCIDRList:
- "10.128.0.0/14"
clusterPoolIPv4MaskSize: "23"
nativeRoutingCIDR: "10.128.0.0/14"
endpointRoutes: {enabled: true}
clusterHealthPort: 9940
tunnelPort: 4789
cni:
binPath: "/var/lib/cni/bin"
confPath: "/var/run/multus/cni/net.d"
chainingMode: portmap
prometheus:
serviceMonitor: {enabled: false}
hubble:
tls: {enabled: false}
sessionAffinity: true
oc apply -f ciliumconfig.yaml
Important
Make sure you've changed the networking values according to your platform details spec.ipam.operator.clusterPoolIPv4PodCIDRList
, spec.ipam.operator.clusterPoolIPv4MaskSize
and nativeRoutingCIDR
in IPv4 and spec.ipam.operator.clusterPoolIPv6PodCIDRList
, spec.ipam.operator.clusterPoolIPv6MaskSize
and nativeRoutingCIDR
in IPv6 case.
Checks
This will be the output:
customresourcedefinition.apiextensions.k8s.io/ciliumconfigs.cilium.io created
namespace/cilium created
serviceaccount/cilium-olm created
Warning: would violate PodSecurity "restricted:v1.24": host namespaces (hostNetwork=true), hostPort (container "operator" uses hostPort 9443), allowPrivilegeEscalation != false (container "operator" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "operator" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "operator" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "operator" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
deployment.apps/cilium-olm created
service/cilium-olm created
role.rbac.authorization.k8s.io/cilium-olm-leader-election created
role.rbac.authorization.k8s.io/cilium-olm created
rolebinding.rbac.authorization.k8s.io/leader-election created
rolebinding.rbac.authorization.k8s.io/cilium-olm created
clusterrole.rbac.authorization.k8s.io/cilium-cilium-olm created
clusterrole.rbac.authorization.k8s.io/cilium-cilium created
clusterrolebinding.rbac.authorization.k8s.io/cilium-cilium-olm created
clusterrolebinding.rbac.authorization.k8s.io/cilium-cilium created
ciliumconfig.cilium.io/cilium created
We should see the following pods running in the cilium
namespace:
oc -n cilium get pods
NAME READY STATUS RESTARTS AGE
cilium-ds5tr 1/1 Running 0 106s
cilium-olm-7c9cf7c948-txkvt 1/1 Running 0 2m36s
cilium-operator-595594bf7d-gbnns 1/1 Running 0 106s
cilium-operator-595594bf7d-mn5wc 1/1 Running 0 106s
cilium-wzhdk 1/1 Running 0 106s
The nodes should've moved to Ready
state:
oc get nodes
NAME STATUS ROLES AGE VERSION
hosted-worker1 Ready worker 8m v1.27.8+4fab27b
hosted-worker2 Ready worker 8m v1.27.8+4fab27b
The HostedCluster deployment will continue, at this point the SDN is running.
Validation
Additionally you have some conformance tests that could be deployed into the HostedCluster in order to validate if the Cilium SDN was deployed and working properly.
In order for Cilium connectivity test pods to run on OpenShift, a simple custom SecurityContextConstraints object is required to allow hostPort/hostNetwork which the connectivity test pods relies on. it should only set allowHostPorts and allowHostNetwork without any other privileges.
oc apply -f - <<EOF
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
name: cilium-test
allowHostPorts: true
allowHostNetwork: true
users:
- system:serviceaccount:cilium-test:default
priority: null
readOnlyRootFilesystem: false
runAsUser:
type: MustRunAsRange
seLinuxContext:
type: MustRunAs
volumes: null
allowHostDirVolumePlugin: false
allowHostIPC: false
allowHostPID: false
allowPrivilegeEscalation: false
allowPrivilegedContainer: false
allowedCapabilities: null
defaultAddCapabilities: null
requiredDropCapabilities: null
groups: null
EOF
version="1.14.5"
oc apply -n cilium-test -f https://raw.githubusercontent.com/cilium/cilium/${version}/examples/kubernetes/connectivity-check/connectivity-check.yaml
oc get pod -n cilium-test
NAME READY STATUS RESTARTS AGE
echo-a-846dcb4-kq7zh 1/1 Running 0 23h
echo-b-58f67d5b86-5mrtx 1/1 Running 0 23h
echo-b-host-84d7468c8d-nf4vk 1/1 Running 0 23h
host-to-b-multi-node-clusterip-b98ff785c-b9vgf 1/1 Running 0 23h
host-to-b-multi-node-headless-5c55d85dfc-5xjbc 1/1 Running 0 23h
pod-to-a-6b996b7675-46kkf 1/1 Running 0 23h
pod-to-a-allowed-cnp-c958b55bf-6vskb 1/1 Running 0 23h
pod-to-a-denied-cnp-6d9b8cbff5-lbrgp 1/1 Running 0 23h
pod-to-b-intra-node-nodeport-5f9c4c866f-mhfs4 1/1 Running 0 23h
pod-to-b-multi-node-clusterip-7cb4bf5495-hmmtg 1/1 Running 0 23h
pod-to-b-multi-node-headless-68975fc557-sqbgq 1/1 Running 0 23h
pod-to-b-multi-node-nodeport-559c54c6fc-2rhvv 1/1 Running 0 23h
pod-to-external-1111-5c4cfd9497-6slss 1/1 Running 0 23h
pod-to-external-fqdn-allow-google-cnp-7d65d9b747-w4cx5 1/1 Running 0 23h