Tuesday, July 31, 2018

Azure Container Instance (6): Socket Connections in ACI


This article is going to summarize how to have socket connections within ACI. The containers for socket server and client are in the same container group, so the server and client locate in the same virtual machine. The sample code, for both socket server and client, is in Node.js.

Define Socket Server

The following Node.js code creates a socket server, which listens on port 1337 of localhost:

var net = require('net');

function getTimePrefix() {
    return (new Date()).toString() + ' ';
}

var server = net.createServer(function(socket) {
    socket.on('data', function(data){
        textChunk = data.toString('utf8');
        console.log(getTimePrefix() + textChunk);
        socket.write(textChunk);
    });
   
    socket.on('error', function(err) {
       console.log(getTimePrefix() + err)
    })
});

server.listen(1337, 'localhost');

Define Socket Client

The following Node.js code creates 200 socket clients, which try to connect to the socket server concurrently:

var connections = 200;
const cp = require('child_process');
var net = require('net');

function getTimePrefix() {
    return (new Date()).toString() + ' ';
}

var onConnected = function(client, connection) {
    return function() {
        client.write(connection + ': Hello, server! Love, Client.');
    };
};

var onData = function(client, connection) {
    return function(data) {
        console.log(getTimePrefix() + 'Connection ' + connection + ' received: ' + data);
        client.destroy();
    };
}
   
var onClosed = function(connection) {
    return function() {
        console.log(getTimePrefix() + 'Connection ' + connection + ' closed');
    };
};

var onError = function(connection) {
    return function(err) {
        console.log(getTimePrefix() + 'Connection ' + connection + ' has error: ' + err);
    };
};

var startClient = function () {
    for (var i = 0; i < connections; ++i) {
        var client = new net.Socket();
        client.connect(1337, 'localhost', onConnected(client, i));
        client.on('data', onData(client, i));
        client.on('close', onClosed(i));
        client.on('error', onError(i));
    }
};

setInterval(startClient, 10000);

Build Docker Image

We can build both server and client applications into docker images. I’ve published the server image as containerinstance/socket-server, and client image as containerinstance/socket-client in Docker Hub.

Create Azure Container Instance

If we include the socket server and client into an Azure container instance, they can talk to each other. The following is a sample of Azure container instance definition to deploy both the socket server and client:

{
  "properties": {
    "containers": [
      {
        "name": "socket-server",
        "properties": {
          "command": [],
          "image": "containerinstance/socket-server:20180731",
          "ports": [
            {
              "port": 1337
            }
          ],
          "resources": {
            "requests": {
              "cpu": 1,
              "memoryInGb": 1.5
            }
          }
        }
      },
      {
        "name": "socket-client",
        "properties": {
          "command": [],
          "image": "containerinstance/socket-client:20180731",
          "ports": [],
          "resources": {
            "requests": {
              "cpu": 1,
              "memoryInGb": 1.5
            }
          }
        }
      }
    ],
    "osType": "Linux",
    "ipAddress": {
      "ports": [
        {
          "protocol": "TCP",
          "port": 1337
        }
      ],
      "type": "Public"
    }
  },
  "location": "westus"
}

The ACI logs API can demonstrate that these two containers talk smoothly.

Notes



No comments:

Post a Comment

AKS (1) - Five seconds latency when resolving DNS

We intermittently meet 5s latencies in an AKS clusters with CNI when it’s resolving DNS. This article is to summarize what we have learned...