Quickstart¶
This guide will walk you through an example of how to use Paraglider to ping two VMs within a single cloud.
Installation¶
$ git clone https://github.com/paraglider-project/paraglider
$ cd paraglider
$ make build install
Cloud Authentication¶
Paraglider currently supports Azure, GCP and IBM. To use Paraglider with a cloud provider, you must have an account with that provider and have the necessary credentials set up.
Authenticate to your Azure account.
$ az login
Retrieve the subscription ID and resource group name you would like to use.
$ az group list
Take note of the
id
field for the subscription ID and resource group name (referred to as${AZURE_SUBSCRIPTION_ID}
and${AZURE_RESOURCE_GROUP_NAME}
throughout this document).
Set up your application default credentials.
$ gcloud auth application-default login $ gcloud auth login
Note
For using Paraglider, you only need to setup application default credentials (i.e., first command). However, throughout this example, we will be using some
gcloud
commands that require authentication.Retrieve the project ID you would like to use.
$ gcloud projects list
Take note of the
GCP_PROJECT_ID
column for the project ID (referred to as${GCP_PROJECT_ID}
throughout this document).
Set up your application default credentials.
$ ibmcloud login --sso
Retrieve the resource group ID you would like to use.
$ ibmcloud resource groups
Take note of the
ID
column for the resource ID (referred to as${IBM_RESOURCE_GROUP_ID}
throughout this document).Create a new API key.
$ mkdir -p ~/.ibm $ ibmcloud iam api-key-create glide_apikey | grep "API Key" | { echo -n "iam_api_key: " & grep -o '[^ ]\+$'; } > ~/.ibm/credentials.yaml
Note
An existing API key could also be used by the IBM plugin. Copy the API Key to
~/.ibm/credentials.yaml
.iam_api_key: ${API_KEY}
Configuration¶
Copy paste the following configuration into a new file called paraglider_config.yaml
. Make sure to substitute the necessary parameters for your cloud provider.
server:
host: "localhost"
port: 8080
rpcPort: 8081
cloudPlugins:
- name: "azure"
host: "localhost"
port: 8082
tagService:
host: "localhost"
port: 8083
namespaces:
default:
- name: "azure"
deployment: "/subscriptions/${AZURE_SUBSCRIPTION_ID}/resourceGroups/${AZURE_RESOURCE_GROUP_NAME}"
server:
host: "localhost"
port: 8080
rpcPort: 8081
cloudPlugins:
- name: "gcp"
host: "localhost"
port: 8082
tagService:
host: "localhost"
port: 8083
namespaces:
default:
- name: "gcp"
deployment: "projects/${GCP_PROJECT_ID}"
server:
host: "localhost"
port: 8080
rpcPort: 8081
cloudPlugins:
- name: "ibm"
host: "localhost"
port: 8082
tagService:
host: "localhost"
port: 8083
kvStore:
host: "localhost"
port: 8084
namespaces:
default:
- name: "ibm"
deployment: "/resourcegroup/${IBM_RESOURCE_GROUP_ID}"
Note
IBM plugin leverages KV-store provided by paraglider orchestrator to store permit-list to security group rule IDs.
Here is a breakdown of the configuration file:
server
defines the orchestrator’s host and ports. The orchestrator has two ports:port
for an HTTP server for users andrpcPort
for an RPC server for cloud plugins.cloudPlugins
lists the cloud plugins that Paraglider will use. In this example, we only specify one cloud but you can specify multiple clouds.tagService
defines the host and port for the tag service.kvStore
defines the host and port for the KV-store service, which can optionally be used by cloud plugins to store states.namespaces
lists the namespaces that Paraglider will reference. Each namespace consists of a list of clouds that specifies the cloud name and deployment URI.
Startup Services¶
This command will start up all services specified in the configuration. In this case, that would be the orchestrator and the cloud plugin.
$ glided startup paraglider_config.yaml
Create VMs¶
To create VMs in clouds, Paraglider requires a JSON file that describes the VM. This is the same as what you would provide in the body of the REST API request to the cloud.
Copy the following into a file called
azure_vm.json
. Make sure to fill in theadminUsername
andadminPassword
fields!{ "location": "eastus", "properties": { "hardwareProfile": { "vmSize": "Standard_B1s" }, "osProfile": { "computerName": "sample-compute", "adminUsername": "<your-username>", "adminPassword": "<your-password>" }, "storageProfile": { "imageReference": { "offer": "0001-com-ubuntu-minimal-jammy", "publisher": "canonical", "sku": "minimal-22_04-lts-gen2", "version": "latest" } } } }
Create two VMs called
vm-1
andvm-2
.$ glide resource create azure vm-1 azure_vm.json $ glide resource create azure vm-2 azure_vm.json
Copy the following into a file called
gcp_vm.json
.{ "instance_resource": { "disks": [{ "auto_delete": true, "boot": true, "initialize_params": { "disk_size_gb": 10, "source_image": "projects/ubuntu-os-cloud/global/images/family/ubuntu-2204-lts" }, "type": "PERSISTENT" }], "machine_type": "zones/us-west1-a/machineTypes/f1-micro" }, "zone": "us-west1-a" }
Create two VMs called
vm-1
andvm-2
.$ glide resource create gcp vm-1 gcp_vm.json $ glide resource create gcp vm-2 gcp_vm.json
Copy the following into a file called
ibm_vm.json
.{ "InstancePrototype": { "profile": { "name": "bx2-2x8" }, "image": { "id": "r014-0acbdcb5-a68f-4a52-98ea-4da4fe89bacb" }, "zone": { "name": "us-east-1" } } }
Create two VMs called
vm-1
andvm-2
.$ glide resource create ibm vm-1 ibm_vm.json $ glide resource create ibm vm-2 ibm_vm.json
Ping VMs¶
Now that your VMs are created, you can try pinging between the two VMs. Since Paraglider denies all traffic by default, the ping should fail.
Since Paraglider creates VMs without public IPs, you will need to use cloud specific connectivity checks instead of SSH-ing into the VMs which may require some setup.
Configure Azure Network Watcher.
$ az network watcher configure -g ${AZURE_RESOURCE_GROUP_NAME} -l eastus --enabled true
Install the Network Watcher Agent extension on both VMs.
$ az vm extension set -g ${AZURE_RESOURCE_GROUP_NAME} --vm-name vm-1 --name NetworkWatcherAgentLinux --publisher Microsoft.Azure.NetworkWatcher --version 1.4 $ az vm extension set -g ${AZURE_RESOURCE_GROUP_NAME} --vm-name vm-2 --name NetworkWatcherAgentLinux --publisher Microsoft.Azure.NetworkWatcher --version 1.4
Check connectivity between vm-1 and vm-2.
$ az network watcher test-connectivity -g ${AZURE_RESOURCE_GROUP_NAME} --source-resource vm-1 --dest-resource vm-2 --protocol Icmp
You should see the
connectionStatus
beUnreachable
. If you look at theissues
fields closely, you’ll notice that the issue is due to network security rules called deny-all-outbound (for source) and deny-all-inbound (for destination).
Run connectivity test between vm-1 and vm-2.
$ gcloud network-management connectivity-tests create vm-1-to-vm-2 \ --source-instance=projects/${GCP_PROJECT_ID}/zones/us-west1-a/instances/vm-1 \ --destination-instance=projects/${GCP_PROJECT_ID}/zones/us-west1-a/instances/vm-2 \ --project=${GCP_PROJECT_ID} \ --protocol=ICMP $ gcloud network-management connectivity-tests describe vm-1-to-vm-2 --project=${GCP_PROJECT_ID}
You should see the
result
field beUNREACHABLE
. If you look at thesteps
fields closely, you’ll notice that the default-deny-all-egress rule is blocking the traffic.
Login to the VM vm-1 using serial console/ssh.
Ping the IP address of vm-2.
Note
IP address of vm-2 can be obtained using tag command.
$ glide tag get default.ibm.vm-2
The ping should not work.
Add Permit List Rules¶
To get the VMs to talk to each other, you will need to add permit list rules to both VMs.
Add permit list rules to both VMs.
$ glide rule add azure vm-1 --ping default.azure.vm-2 $ glide rule add azure vm-2 --ping default.azure.vm-1
Check connectivity again between vm-1 and vm-2.
$ az network watcher test-connectivity -g ${AZURE_RESOURCE_GROUP_NAME} --source-resource vm-1 --dest-resource vm-2 --protocol Icmp
You should see the
connectionStatus
beReachable
.
Add permit list rules to both VMs.
$ glide rule add gcp vm-1 --ping default.gcp.vm-2 $ glide rule add gcp vm-2 --ping default.gcp.vm-1
Check connectivity again between vm-1 and vm-2.
$ gcloud network-management connectivity-tests rerun vm-1-to-vm-2 --project=${GCP_PROJECT_ID}
You should see the
result
field beREACHABLE
.
Add permit list rules to both VMs.
$ glide rule add ibm vm-1 --ping default.ibm.vm-2 $ glide rule add ibm vm-2 --ping default.ibm.vm-1
Check connectivity again between vm-1 and vm-2.
Login to the VM vm-1 using serial console/ssh.
Ping the IP address of vm-2.
Note
IP address of vm-2 can be obtained using tag command.
$ glide tag get default.ibm.vm-2
The ping should now work.