volvox
volvox

Reputation: 3060

Set up swarm mode Docker Swarm using Vagrant

I'm using Vagrant and ansible local to provision a bunch of DEV minimal centos VMs. The VMs all run Docker 1.12.x and I'm now looking at automatically creating a swarm mode cluster. The aim is to do vagrant up and when the cli returns, I have a cluster up and running.

Trouble I have is I can run a docker swarm init --advertise-addr <my init swarm mgr> on one of the boxes, but then I need to get the token for the managers and worker nodes out of this box and inject them into the subsequently set up VMs.

I cannot program Ruby, and I would really rather not start with the Docker Remote API if I can avoid it.

I've tried soliciting the hostid from a test VM setup to try and assign a guest cmd output to a variable in the Vagrantfile, but my Ruby is not up to scratch.

Irrespective, the question is how best to create a swarm mode cluster using Vagrant when provisioning VMs with ansible local.

EDIT: I've just seen vagrant scp which I could at least use to extract token in the form of a file and copy it into the relevant machines. I was hoping to keep things pure rather than plugged in, and avoid shelling out of Ruby to run more vagrant commands (is there a better way to do that?), but at least that gives use of vagrant and ansible local.

Upvotes: 2

Views: 885

Answers (2)

volvox
volvox

Reputation: 3060

OK in case someone (including me) finds this, as mentioned in @abronan's post, I needed to get the token out in some way. I did it this way.

Ansible local playbook code on Vagrant host used to extract the token:

## docker swarm mgr
  #
  - name: docker swarm join-token -q manager
    shell: docker swarm join-token -q manager
    register: dockerswarmjointokenmgr

  - name: copy content={{ dockerswarmjointokenmgr.stdout.split() }} dest=/vagrant/myswarmwkr.token
    local_action: copy content={{ dockerswarmjointokenmgr.stdout.split() }} dest=/vagrant/myswarmwkr.token

  - name: make swarm wkr token readable
    file: path=/vagrant/myswarmwkr.token owner=vagrant group=vagrant recurse=no

Vagrantfile code specific to my docker swarm worker node using vagrant scp:

## now handle docker swarm tokens
#
config.vm.provision :host_shell do |host_shell|
  host_shell.inline = 'vagrant scp dockerwkr:/vagrant/myswarmwkr.token .'
end
config.vm.provision :host_shell do |host_shell|
  host_shell.inline = 'vagrant scp dockerwkr:/vagrant/myswarmwkr.token .'
end

This causes the outputting of tokens to a file on the guest, scp'd to the vagrant host and then when vagrant handles the docker swarm worker setup, if the tokens were written to the same dir as the Vagrantfile, they will automatically rock up in the worker guest /vagrant where your ansible local code can read them into the docker swarm join command. Fiddly and sellotaped together, but fine for learning on one's own laptop.

Upvotes: 1

abronan
abronan

Reputation: 3449

As of Docker 1.12.3, there is no easy way to do this. You'll have to get the token out in some way.

You can:

  • Inspect the Swarm using the Docker Remote API with the \swarm endpoint and extract the relevant JoinTokens after the first machine init:

    [...]
    "JoinTokens" : {
        "Worker" : "SWMTKN-1-1h8aps2yszaiqmz2l3oc5392pgk8e49qhx2aj3nyv0ui0hez2a-6qmn92w6bu3jdvnglku58u11a",
        "Manager" : "SWMTKN-1-1h8aps2yszaiqmz2l3oc5392pgk8e49qhx2aj3nyv0ui0hez2a-8llk83c4wm9lwioey2s316r9l"
    }
    [...]
    
  • As you mentioned, using vagrant scp after writing the token to a file.

  • Using a synced folder and mounting it on all your VMs. Thus the first VM writes the token to a file and the others are reading the token from it.

But in any case, you need to synchronize the bootstrap process manually.

Relevant Docker issue: https://github.com/docker/docker/issues/26743

Upvotes: 1

Related Questions