Scaling Docker Across EC2

TODO: collapasable, copyable, download, etc

I have a single ec2 instance and am using docker compose to startup 6 services on it. I need to move one of the services jvb onto it's own ec2 host to scale horizontally. Right now my docker-compose.yml uses

networks:
    meet.jitsi:

How do I open op the networking across two ec2 hosts? What changes are made to my docker-compose.yml?To open up networking across two EC2 instances, you can use Docker Swarm or an overlay network. Docker Swarm is a better option if you plan to scale your services in the future. Here, I'll explain how to use Docker Swarm to achieve this.

  1. Initialize Docker Swarm:

On the first EC2 instance, where you currently run your Docker Compose services, initialize a Docker Swarm by running:

docker swarm init --advertise-addr <EC2_INSTANCE_1_IP>

Replace <EC2_INSTANCE_1_IP> with the private IP address of your first EC2 instance.

  1. Join the second EC2 instance to the Swarm:

On the second EC2 instance, where you want to move the jvb service, run the following command to join the swarm:

docker swarm join --token <SWMTKN> <EC2_INSTANCE_1_IP>:2377

Replace <SWMTKN> with the Swarm token obtained in the previous step and <EC2_INSTANCE_1_IP> with the private IP address of the first EC2 instance.

  1. Create an overlay network:

On the first EC2 instance, create an overlay network for your services:

docker network create -d overlay meet.jitsi
  1. Modify your docker-compose.yml file:

Change the version to 3.8 and add deploy configuration to your services, specifying the placement constraints for the jvb service to run on the second EC2 instance. Also, remove the networks definition at the bottom.

Here's an example docker-compose.yml:

version: '3.8'

services:
  web:
    image: ...
    networks:
      - meet.jitsi
    deploy:
      replicas: 1

  prosody:
    image: ...
    networks:
      - meet.jitsi
    deploy:
      replicas: 1

  # other services ...

  jvb:
    image: ...
    networks:
      - meet.jitsi
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.hostname == <EC2_INSTANCE_2_HOSTNAME>

networks:
  meet.jitsi:
    external: true

Replace <EC2_INSTANCE_2_HOSTNAME> with the hostname of the second EC2 instance.

  1. Deploy the stack:

On the first EC2 instance, deploy the stack using the following command:

docker stack deploy -c docker-compose.yml my-stack

Replace my-stack with the desired stack name. This command will deploy the services across the nodes in the swarm, and the jvb service should now run on the second EC2 instance.

Note: Make sure the necessary ports are opened in the security group of both instances to allow communication between the instances and with clients.What is the difference between swarm and overlay?Docker Swarm and overlay networks are related concepts in Docker, but they serve different purposes. Here's a brief explanation of each:

  1. Docker Swarm:

Docker Swarm is a container orchestration platform built into Docker Engine. It allows you to create, deploy, and manage a cluster of Docker nodes (called a swarm) and services running across the nodes. Docker Swarm provides features such as scaling, rolling updates, load balancing, and service discovery. It helps you manage a group of Docker nodes as a single entity, making it easier to deploy and manage distributed applications.

  1. Overlay network:

An overlay network is a type of network in Docker that allows containers running on different Docker nodes (which could be on different hosts or virtual machines) to communicate with each other as if they were on the same host. Overlay networks are created using network drivers that operate at the level above the physical network, encapsulating the underlying network packets and routing them between hosts.

In the context of Docker Swarm, overlay networks are used to enable communication between services running on different nodes in the swarm. When you create a service in Docker Swarm, you can attach it to an overlay network, and the containers for that service will be able to communicate with containers from other services on the same overlay network, regardless of which node they are running on.

In summary:

  • Docker Swarm is an orchestration platform for managing clusters of Docker nodes and the services running on them.
  • An overlay network is a type of Docker network that enables communication between containers running on different nodes.

Docker Swarm uses overlay networks to facilitate communication between services running on different nodes in the swarm.In your response you said "you can use Docker Swarm or an overlay network". Why did you say or?Apologies for the confusion, and thank you for pointing that out. You're right; my response was not clear. To clarify, Docker Swarm and overlay networks are not alternatives but rather complementary technologies. Docker Swarm uses overlay networks to enable communication between containers running on different nodes.

When you want to scale your services across multiple nodes or hosts, you need to use Docker Swarm as an orchestration platform to manage the distributed deployment. In this process, Docker Swarm utilizes overlay networks to ensure seamless communication betweenI had a docker-compose file with version 3.5. Why do I need to change that to 3.8?Apologies for the confusion, you don't necessarily need to change your docker-compose.yml version from 3.5 to 3.8 for the Docker Swarm setup. You can use version 3.5 with Docker Swarm as well. I recommended version 3.8 because it's a more recent version with support for additional features and improvements, but it's not required for this use case.

You can continue to use version 3.5 and modify your docker-compose.yml file as described in the previous steps, adding the deploy configuration for your services and removing the networks definition at the bottom.

Here'sdocker network create -d overlay meet.jitsi has the error Error response from daemon: rpc error: code = InvalidArgument desc = name must be valid as a DNS name componentI apologize for the oversight. It seems that the network name meet.jitsi does not comply with the DNS name requirements. To fix this error, you can change the network name to a valid DNS name component. DNS name components should consist of lowercase alphanumeric characters, hyphens, and periods.

For example, you can change the network name to meet-jitsi:

  1. Create the overlay network with the new name:
docker network create -d overlay meet-jitsi
  1. Update your docker-compose.yml file to use the new network name:
version: '3.5'

services:
  web:
    image: ...
    networks:
      - meet-jitsi
    deploy:
      replicas: 1

  prosody:
    image: ...
    networks:
      - meet-jitsi
    deploy:
      replicas: 1

  # other services ...

  jvb:
    image: ...
    networks:
      - meet-jitsi
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.hostname == <EC2_INSTANCE_2_HOSTNAME>

networks:
  meet-jitsi:
    external: true

Make sure to replace <EC2_INSTANCE_2_HOSTNAME> with the hostname of the second EC2 instance.

Now, you should be able to create the overlay network without encountering the error.Can I start a service from a worker node? In Docker Swarm, you cannot directly start a service from a worker node. Service management and deployment are performed by the manager nodes in the swarm. Manager nodes are responsible for maintaining the desired state of the swarm, including creatingHow do I start my jvb service on the with ip 172.31.15.136?To start your jvb service on a specific node with IP address 172.31.15.136, you need to use placement constraints in your docker-compose.yml file. First, obtain the ID or hostname of the node with the desired IP address.

  1. On a manager node, list all the nodes in the swarm:
docker node ls
  1. Find the node with the IP address 172.31.15.136 in the list, and note its ID or hostname.

  2. Update your docker-compose.yml file to include the deploy configuration with a placement constraint for the jvb service:

version: '3.5'

services:
  # ... other services ...

  jvb:
    image: ...
    networks:
      - meet-jitsi
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.id == <NODE_ID>
        # OR if you want to use hostname:
        # constraints:
        #   - node.hostname == <NODE_HOSTNAME>

networks:
  meet-jitsi:
    external: true

Replace <NODE_ID> or <NODE_HOSTNAME> with the ID or hostname of the node with the IP address 172.31.15.136 that you obtained in step 2.

  1. Deploy the stack using the modified docker-compose.yml file:
docker stackIs it possible to do this from the CLI without editing docker-compose.yml? Like if I just want to test this out and spin up one instance?Yes, you can create a service with a placement constraint directly from the command line without editing the `docker-compose.yml` file. To do this, use the `docker service create` command with the `--constraint` option.

First, obtain the ID or hostname of the node with the desired IP address (172.31.15.136).

1. On a manager node, list all the nodes in the swarm:

```bash
docker node ls
  1. Find the node with the IP address 172.31.15.136 in the list, and note its ID or hostname.

  2. Create the jvb service with the placement constraint:

docker service create \
  --name jvb \
  --network meet-jitsi \
  --constraint 'node.id == <NODE_ID>' \
  <JVB_IMAGE>

Replace <NODE_ID> with the ID of the node with the IP address 172.31.15.136 that you obtained in step 2. Replace <JVB_IMAGE> with the Docker image for your jvb service.

Alternatively, if you want to use the hostname:

docker service create \
  --name jvb \
  --network meet-jitsi \
  --constraint 'node.hostname == <NODE_HOSTNAME>' \
  <JVB_IMAGE>

Replace <NODE_HOSTNAME> with the hostname of the node with the IP address 172.31.15.136 that you obtained in step 2. Replace <JVB_IMAGE> with the Docker image for your jvb service.

This command will create a single instance of the jvb service on the specified node.I see there is already an ingress network, can I use that one? Please answer breiflyYes, you can use the built-in ingress network for your services. However, the ingress network is mainly designed for load balancing incoming traffic to your services. If your use case doesn't require external access or load balancing, it's better to create a custom overlay network.And how would I clean up that test service?To clean up the test service you created, use the docker service rm command:

docker service rm jvb

This command will remove the jvb service and any associated containers running on the nodes in the swarm.What is an alternative way to share a network across two hosts with docker but not using swarm?An alternative way to share a network across two hosts with Docker without using Swarm is to use a third-party network plugin that supports multi-host networking. One such plugin is Weave Net.

Here's a brief guide on how to set up Weave Net to connect containers across two hosts:

  1. Install Weave Net on both hosts:
sudo curl -L git.io/weave -oany other ideas/Another approach to share a network across two hosts with Docker without using Swarm is by using a Virtual Private Cloud (VPC) and configuring host networking for your containers. This method requires manual management of container networking, but it allows your containers to communicate over a shared network.

Here's an outline of the process:

1. Create a Virtual Private Cloud (V

Scaling Docker Across EC2 created at Tue Jan 20 1970 11:05:05 GMT+0000 (Coordinated Universal Time)

Related Chats

Switch to EKS: Steps 0.579

Deploying Docker Compose EC2 0.556

Fargate Requirement for ECS 0.481

EC2 ELB Troubleshoot Setup 0.381

Troubleshooting Docker UDP Traffic 0.375

Update Docker Compose Envvars 0.350

Shutdown Docker Compose with 'docker-compose down' 0.342

Env File for Docker 0.342

Jitsi Multi-Bridge Conferences 0.339