Examples¶
Here we describe some example usage scenarios for AppSwitch. There is a repository on GitHub, please clone it to follow along with these examples.
$ git clone https://github.com/appswitch/examples/
$ cd examples
All examples require use of Vagrant to bring up the virtual machines used to form an AppSwitch cluster. Instructions on installing Vagrant can be found on the HashiCorp website
We will be progressively working up to an advanced AppSwitch configuration using all four nodes. The node naming convention is based on the requirements of those use cases. To start with the naming convention is not important but for the interested, the nodes are named hostXY
where X
is the cluster number and Y
is the node number.
Bring up the first node and ssh into it:
$ vagrant up host00
$ vagrant ssh host00
The AppSwitch binary (ax
) is distributed as an image via Docker Hub. The latest image is already pulled as part of provisioning the Vagrant VM.
Single Node Cluster - Basic AppSwitch Usage¶
First step is to bring up AppSwitch daemon with the docker-compose file. It includes basic configuration:
$ cd appswitch
$ docker-compose -f docker-compose-host00.yaml up -d appswitch
Let’s start a simple Python based HTTP server using the supplied docker-compose file.
version: '2.3'
services:
http:
image: python:alpine
entrypoint: /usr/bin/ax run --name test
command: python -m http.server
networks: []
volumes:
- /usr/bin:/usr/bin
- /var/run/appswitch:/var/run/appswitch
$ docker-compose -f docker-compose-httpserver.yaml up -d httpserver
That brings up the server on the specified ip (1.1.1.1
). Note that the container in which the server runs has no networks. All network connectivity is handled by AppSwitch. Also note that it is an unprivileged container.
Let’s check it with curl
.
$ sudo ax run -- curl -I 1.1.1.1:8000
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.6.5
Date: Wed, 06 Jun 2018 01:37:55 GMT
Content-type: text/html; charset=utf-8
Content-Length: 882
The above command is run as root because ax creates a new network namespace to isolate the application. sudo
won’t be needed with --new-netns=false
option:
$ ax run --new-netns=false curl -I 1.1.1.1:8000
Run the server without Docker¶
Let’s start another web server. This time natively without a container. We will assign it an IP address of 1.1.1.1 and give it a DNS resolvable name ‘webserver’.
$ sudo ax run --ip 1.1.1.1 --name webserver python -m SimpleHTTPServer 8000 &
Again we can curl the webserver using either the IP address or the name that we have assigned. Since the previous server and this one are assigned the same IP address, incoming requests would get load balanced across the two.
$ sudo ax run -- curl -I webserver:8000
or:
$ sudo ax run -- curl -I 1.1.1.1:8000
Connecting to services without AppSwitch AKA ‘Ingress Gateway’¶
Services run by AppSwitch can be exposed externally with the --expose
option.
$ sudo ax run --ip 1.1.1.1 --name webserver --expose 8000:192.168.0.10:10000 python -m SimpleHTTPServer 8000 &
We can now connect to the web server using curl without wrapping the command in ax
$ curl -I 192.168.0.10:10000
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/2.7.5
Date: Wed, 06 Jun 2018 03:18:02 GMT
Content-type: text/html; charset=UTF-8
Content-Length: 274
When starting the web server you can see we have explicitly specified the IP address of the node we wish to expose the service. We could also have used the wildcard address 0.0.0.0
to expose the service on all nodes in the cluster.
If you start two web server processes both with the same name and IP then AppSwitch will load balance when a connection to that name/IP is made.
Virtual Services¶
If we start the web server without an IP
$ sudo ax run -- python -m SimpleHTTPServer 8000
And view the app
$ ax get apps
NAME APPID NODEID CLUSTER APPIP DRIVER LABELS ZONES
-----------------------------------------------------------------------------------------------------------------------
<9142a421-00e8-483e-83d0-eea9716c849a> f000015d host appswitch 10.0.2.15 user zone=default [zone==default]
We can associate an IP address with this app by creating a virtual service.
$ ax create vservice --ip 1.1.1.1 --backends 10.0.2.15 --expose 8000:10000 myvsvc
Service 'myvsvc' created successfully with IP '1.1.1.1'.
$ ax get vservices
VSNAME VSTYPE VSIP VSPORTS VSBACKENDIPS
-------------------------------------------------------
myvsvc Random 1.1.1.1 [{8000 10000}] [10.0.2.15]
Now we can curl to the virtual IP or the virtual name. This feature enables multiple IPs for the same server since the server is still available at the IP assigned it by ax. Furthermore, if we start more than one server we can add them all as backends for the virtual service and AppSwitch will load balance when connecting to the virtual name or IP. Currently round-robin and random load balancing strategies are supported.
$ sudo ax run -- curl -I myvsvc:8000
$ sudo ax run -- curl -I 1.1.1.1:8000
Multi-Node AppSwitch Cluster¶
Bring up a second VM so that we can build a 2 node AppSwitch cluster:
$ vagrant up host01
ssh in and start the AppSwitch daemon
$ vagrant ssh host01
host01 $ docker-compose --file docker-compose-host01.yaml up -d
Now we can have a play with these two nodes. We can then try curl’ing the server we brought up earlier on host00 from host01.
host01 $ sudo ax run -- curl -I webserver:8000
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/2.7.5
Date: Wed, 06 Jun 2018 03:18:02 GMT
Content-type: text/html; charset=UTF-8
Content-Length: 274
Let’s restart the webserver on host00, this time passing it the ingress gateway wildcard address
host00 $ sudo ax run --ip 1.1.1.1 --name webserver --expose 8000:0.0.0.0:10000 python -m SimpleHTTPServer 8000 &
From either host we can now directly curl the web server
$ curl -I 192.168.0.11:10000
$ curl -I 192.168.0.10:10000
Multi-Node Multi-Cluster AKA AppSwitch Federation¶
Let us now configure two AppSwitch clusters each consisting of two nodes. As documented in the Vagrant file, the topology looks as follows:
# cluster0 cluster1
# host01 host00 host10 host11
#
# 10.0.0.10 ----------------- 10.0.0.11
# 192.168.0.11 ----- 192.168.0.10 192.168.1.10 ----- 192.168.1.11
Bring up the other two VMs:
$ vagrant up host10
$ vagrant up host11
Configure and Start the Daemon¶
To configure the nodes for federation connectivity we must configure two of
the nodes as federation gateways, we use host00
and host10
as the
gateways. Also each node must be configured with a cluster name,
cluster0
or cluster1
.
Start the AppSwitch daemon on each node
$ docker-compose --file docker-compose-$(hostname).yaml up -d
Now we can have a play with these four nodes. First let’s start a web
server on host11
$ sudo ax run --ip 2.2.2.2 python -m SimpleHTTPServer 8000 &
We can then try curl’ing this server from host01:
$ sudo ax run -- curl -I 2.2.2.2:8000
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/2.7.5
Date: Wed, 06 Jun 2018 03:18:02 GMT
Content-type: text/html; charset=UTF-8
Content-Length: 274
In this case, the client is able to reach the server on the specified IP address (2.2.2.2
) even though it is in a completely different network, which could have been somewhere in the cloud. AppSwitch is able to flatten the network even across hybrid environments without complex tunneling etc.