Accessing OpenStack Resources from CloudFerro Cloud Managed Kubernetes Using Shared Networks

CloudFerro Cloud relies on OpenStack to manage cloud infrastructure, meaning:

  • you can create and control OpenStack resources, e.g., Virtual Machines using its

  • two main interfaces: Horizon GUI and the OpenStack CLI.

In CloudFerro Cloud Managed Kubernetes, the node pools are managed separately and provisioned outside the scope of your OpenStack project. Still, these node pools can access your OpenStack project resources via a private network connection — without routing the traffic over the public Internet. This enhances security, reduces latency, and avoids unnecessary bandwidth costs.

This article explains how such a connection can be set up from CloudFerro Cloud Managed Kubernetes node pools utilizing the Shared Networks feature.

Note

To use the Shared Networks feature, both the CloudFerro Cloud Managed Kubernetes cluster and your OpenStack project with the accessed resource must be in the same region (currently only WAW4-1).

What We Are Going To Cover

Prerequisites

No. 1 Hosting account on CloudFerro Cloud

To use CloudFerro Cloud Managed Kubernetes, you need your

No. 2 – Created a managed Kubernetes cluster

Follow the guide How to create a Kubernetes cluster using the CloudFerro Cloud Managed Kubernetes launcher GUI to create a cluster.

By the end of that guide, you should have a working Kubernetes cluster called networktest, and both the openstack and kubectl commands should be available. We also assume you know how to create node pools for a given managed Kubernetes cluster.

No. 3 – Launch a new VM

You will need a VM in your OpenStack project. This VM will be used to test the incoming connection from a pod on your CloudFerro Cloud Managed Kubernetes cluster’s node pool. Use the guide How to create a VM using the OpenStack CLI client on CloudFerro Cloud cloud.

No. 4 – OpenStack networks

This article builds upon basic OpenStack networking concepts. For a primer, see:

How to create a network with router in Horizon Dashboard on CloudFerro Cloud

For brevity, in this article we will use OpenStack CLI commands to create the network.

Step 1: Create network

Create the network:

openstack network create networktest_shared_network

Create its subnet:

openstack subnet create \
  --network networktest_shared_network \
  --subnet-range 192.168.168.0/24 \
  --gateway 192.168.168.1 \
  --dns-nameserver 8.8.8.8 \
  networktest_shared_subnet_168

Get the network ID:

openstack network show networktest_shared_network -f value -c id

Example output (your value will differ):

d2a6efc8-9994-41d9-bbc9-9b26bce47461
Example of retrieving a network ID. The network name and ID in this capture differ from the command examples; use the ID returned for your own network.

Example of retrieving a network ID. The network name and ID in this capture differ from the command examples; use the ID returned for your own network.

Store this value in an environment variable for use in later steps:

export NETWORK_ID=d2a6efc8-9994-41d9-bbc9-9b26bce47461

Warning

The NETWORK_ID and SOURCE_ID shown in this guide are example values. You must retrieve and use your own IDs throughout the steps.

Create a Security Group for Testing

We need to ensure that the VM allows incoming traffic such as ping, SSH, and optionally RDP for remote desktop testing. We need a security group that will allow at least ping.

  1. Check whether there already is a security group allowing ping traffic, and if there is, just use it in the rest of the article.

  2. Otherwise, create a new security group called allow_ping_ssh_icmp_rdp. Execute the following commands to create it:

openstack security group create allow_ping_ssh_icmp_rdp \
  --description "Allow ping, SSH, ICMP, and RDP"

openstack security group rule create --protocol tcp --dst-port 22 allow_ping_ssh_icmp_rdp

openstack security group rule create --protocol tcp --dst-port 3389 allow_ping_ssh_icmp_rdp

openstack security group rule create --protocol icmp allow_ping_ssh_icmp_rdp

Note

You need to create a new security group such as allow_ping_ssh_icmp_rdp only once.

This security group is now ready to be used with any VM to allow basic testing and remote access capabilities. We will use it in the next step when creating the test VM.

Step 2: Create a VM, associating that network

Create the VM using the saved network. It is important that this VM accepts incoming ICMP traffic so it can respond to ping requests:

openstack server create \
  --image "Ubuntu 22.04 LTS" \
  --flavor eo1a.small \
  --key-name sshkey \
  --network $NETWORK_ID \
  --security-group default \
  --security-group allow_ping_ssh_icmp_rdp \
  test-shared-vm

In Horizon, the VM’s Security Groups tab lets you check the assigned groups:

Example VM with the testing security group assigned alongside the default group.

Example VM with the testing security group assigned alongside the default group.

To retrieve the internal IP address of the VM (which will be used for testing later), run:

openstack server show test-shared-vm -c addresses -f value

This will output the IP address assigned to your VM on the shared network, for example:

networktest_shared_network=192.168.168.126

Take note of this IP address — you will need it in Step 5 to test connectivity from the pod.

Step 3: Create node pool

Open the details of your CloudFerro Cloud Managed Kubernetes cluster and copy Source ID from Cluster Details. Use Source ID, not Cluster ID, for the network-sharing policy.

The networktest cluster details show the Source ID used as the target OpenStack project.

The networktest cluster details show the Source ID used as the target OpenStack project.

Save your source ID to an environment variable. Replace the example value with the ID of your own cluster:

export SOURCE_ID=114e29b7f2a64ac2b706b933366d70eb

We will use both NETWORK_ID and SOURCE_ID to create an RBAC connection between the nodes and the stand-alone VM from above.

Open the node pool creation form and set the name, machine specification, autoscaling mode, and size. The example uses small-nodepool with one worker node.

Advanced Settings includes the Shared networks field and an Add control for each network ID.

Advanced Settings includes the Shared networks field and an Add control for each network ID.

Enable Advanced Settings, enter your NETWORK_ID in Shared networks, and select Add. Repeat this for each network you want to share.

Select Add Node Pool to submit the form. The node pool can appear as CREATING while it waits for the selected networks to be shared. Continue with the RBAC policy in Step 4.

Step 4: Share network via RBAC

RBAC (Role-Based Access Control) in OpenStack allows you to grant fine-grained access to specific resources, such as networks, between different projects. In our case, the node pool associated with your CloudFerro Cloud Managed Kubernetes cluster is deployed under a separate OpenStack project. To allow the node pool to access a private network created under your main project, we must explicitly grant it access. This is achieved by sharing the network via an RBAC policy targeted at the node pool’s project ID (SOURCE_ID).

Use the OpenStack CLI to share the network:

openstack --os-region WAW4-1 network rbac create \
  --type network \
  --action access_as_shared \
  --target-project $SOURCE_ID \
  $NETWORK_ID

Example output:

+-------------------+--------------------------------------+
| Field             | Value                                |
+-------------------+--------------------------------------+
| action            | access_as_shared                     |
| id                | 4a9f9c38-8c0c-4620-bfe6-733328c427a4 |
| object_id         | d2a6efc8-9994-41d9-bbc9-9b26bce47461 |
| object_type       | network                              |
| project_id        | 673cfda60d7147688057d6de74e85ef4     |
| target_project_id | 114e29b7f2a64ac2b706b933366d70eb     |
+-------------------+--------------------------------------+

You may get a 409 Conflict if it was already shared. This is safe to ignore.

After sharing the network, check the node pool’s Status in the Node pools list. Provisioning can take a long time, and the node pool can remain CREATING while its worker nodes are being prepared.

The small-nodepool entry is still CREATING; this is not the completed state.

The small-nodepool entry is still CREATING; this is not the completed state.

Refresh the node pool list periodically. Continue to Step 5 only when the Status of the new node pool is RUNNING. Check the node pool row itself: the cluster’s RUNNING status does not mean that a newly added node pool is ready.

If provisioning does not complete, confirm that the RBAC policy uses your network ID and your cluster’s Source ID. If it still does not progress, contact support with the cluster ID, node pool name, region, and current status.

Step 5: Test the connection

Now we will verify that your pod can reach the VM over the shared private network.

The command below creates a simple pod named alpine-sleeper using the lightweight Alpine Linux image. It instructs the pod to sleep indefinitely so that we can interact with it afterward.

kubectl run alpine-sleeper --image=alpine --restart=Never -- sleep infinity

Attach to the running pod using an interactive shell:

kubectl exec -it alpine-sleeper -- /bin/sh

From inside the pod, ping the internal IP address of your VM retrieved earlier in Step 2:

PING 192.168.168.126 (192.168.168.126): 56 data bytes
5 packets transmitted, 5 received, 0% packet loss

Clean Up the Test Pod

Once you’ve confirmed that the pod can reach the VM, you should remove the temporary pod used for testing.

Leaving unused pods running consumes resources on the node pool and can interfere with future tests. It’s a good practice to keep your cluster clean and free of artifacts after diagnostic checks.

Run the following command to delete the pod:

kubectl delete pod alpine-sleeper

What To Do Next

Use shared connectivity to:

  • Connect pods to VM-hosted databases or APIs

  • Monitor infrastructure from Kubernetes (e.g., Prometheus)

  • Deploy hybrid apps across VM and K8s

Still need help?
If this article doesn’t answer all of your questions, our support team will do their best to help you.
Contact support