This is an automated email from the ASF dual-hosted git repository.

mwalch pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/fluo-muchos.git


The following commit(s) were added to refs/heads/master by this push:
     new 3f82587  Muchos can optionally set up Docker & Swarm (#237)
3f82587 is described below

commit 3f825878450d481b519bfabdd626341fde8781e1
Author: Mike Walch <[email protected]>
AuthorDate: Wed Nov 21 16:40:12 2018 -0500

    Muchos can optionally set up Docker & Swarm (#237)
    
    * Set up occurs if user specifies 'swarmmanager' in configuration
---
 README.md                              |  7 +++++++
 ansible/docker.yml                     | 35 ++++++++++++++++++++++++++++++++
 ansible/kill.yml                       |  5 +++++
 ansible/roles/docker/defaults/main.yml |  1 +
 ansible/roles/docker/tasks/main.yml    | 37 ++++++++++++++++++++++++++++++++++
 conf/muchos.props.example              |  4 ++--
 lib/muchos/config.py                   |  6 ++++--
 lib/muchos/main.py                     |  4 ++++
 lib/tests/test_config.py               |  4 ++--
 9 files changed, 97 insertions(+), 6 deletions(-)

diff --git a/README.md b/README.md
index d64b07c..cd7544a 100644
--- a/README.md
+++ b/README.md
@@ -101,6 +101,11 @@ at `http://<MESOS_MASTER_NODE>:8080/`.
 5. `client` - Used to specify a client node where no services are run but 
libraries are installed to
 run Accumulo/Hadoop clients.
 
+6. `swarmmanager` - Sets up [Docker swarm] with the manager on this node and 
joins all worker nodes
+to this swarm. When this is set, docker will be installed on all nodes of the 
cluster. It is
+recommended that the swarm manager is specified on a worker node as it runs 
docker containers. Check
+out [Portainer] if you want to run a management UI for your swarm cluster.
+
 If you run the `muchos setup` command and a failure occurs, you can repeat the 
command until setup
 completes. Any work that was successfully completed will not be repeated. 
While some setup steps can
 take over a minute, use `ctrl-c` to stop setup if it hangs for a long time. 
Just remember to run
@@ -236,3 +241,5 @@ The following command runs the unit tests:
 [hadoop]: http://hadoop.apache.org/
 [Uno]: https://github.com/apache/fluo-uno
 [muchos.props]: conf/muchos.props.example
+[Docker swarm]: https://docs.docker.com/engine/swarm/
+[Portainer]: https://github.com/portainer/portainer
diff --git a/ansible/docker.yml b/ansible/docker.yml
new file mode 100644
index 0000000..10afd1a
--- /dev/null
+++ b/ansible/docker.yml
@@ -0,0 +1,35 @@
+- hosts: all
+  become: yes
+  roles:
+    - docker
+- hosts: swarmmanager
+  become: yes
+  tasks:
+    - name: get swarm status
+      shell: >
+        docker info | egrep '^Swarm: ' | cut -d ' ' -f 2
+      register: swarm_status
+      changed_when: "'active' not in swarm_status.stdout_lines"
+    - name: initialize swarm
+      shell: >
+        docker swarm init --advertise-addr={{ ansible_default_ipv4.address 
}}:2377
+      when: "'active' not in swarm_status.stdout_lines"
+    - name: get swarm token
+      shell: docker swarm join-token -q worker
+      register: swarm_token
+      changed_when: "'active' not in swarm_status.stdout_lines"
+- hosts: workers
+  become: yes
+  vars:
+    swarm_token: "{{ 
hostvars[groups['swarmmanager'][0]]['swarm_token']['stdout'] }}"
+    manager_ip: "{{ 
hostvars[groups['swarmmanager'][0]]['ansible_default_ipv4']['address'] }}"
+  tasks:
+    - name: get swarm status
+      shell: >
+        docker info | egrep '^Swarm: ' | cut -d ' ' -f 2
+      register: swarm_status
+      changed_when: "'active' not in swarm_status.stdout_lines"
+    - name: join worker to swarm
+      shell: >
+        docker swarm join --token={{ swarm_token }} {{ manager_ip }}:2377
+      when: "'active' not in swarm_status.stdout_lines"
diff --git a/ansible/kill.yml b/ansible/kill.yml
index 0294436..fa5757d 100644
--- a/ansible/kill.yml
+++ b/ansible/kill.yml
@@ -16,5 +16,10 @@
 - hosts: all
   become: yes
   tasks:
+  - name: "stop docker"
+    service:
+      name: docker
+      state: stopped
+    when: "'swarmmanager' in groups"
   - name: "ensure all processes started by Muchos are killed"
     script: roles/common/files/kill.sh
diff --git a/ansible/roles/docker/defaults/main.yml 
b/ansible/roles/docker/defaults/main.yml
new file mode 100644
index 0000000..f4941a0
--- /dev/null
+++ b/ansible/roles/docker/defaults/main.yml
@@ -0,0 +1 @@
+docker_repo_baseurl: 
https://download.docker.com/linux/centos/7/$basearch/stable
diff --git a/ansible/roles/docker/tasks/main.yml 
b/ansible/roles/docker/tasks/main.yml
new file mode 100644
index 0000000..c13a85c
--- /dev/null
+++ b/ansible/roles/docker/tasks/main.yml
@@ -0,0 +1,37 @@
+- name: install required packages for docker
+  yum:
+    name: "{{ packages }}"
+  vars:
+    packages:
+    - yum-utils
+    - device-mapper-persistent-data
+    - lvm2
+- name: add docker repo
+  yum_repository:
+    name: docker-ce-stable
+    description: "Docker CE Stable - $basearch"
+    baseurl: "{{ docker_repo_baseurl }}"
+    gpgcheck: yes
+    gpgkey: https://download.docker.com/linux/centos/gpg
+- name: install docker
+  yum:
+    name: docker-ce
+- name: create docker directory in data dir
+  file:
+    path: "{{ default_data_dirs[0] }}/docker"
+    state: directory
+    mode: 0755
+- name: link /var/lib/docker
+  file:
+    src: "{{ default_data_dirs[0] }}/docker"
+    dest: /var/lib/docker
+    state: link
+- name: "add {{ cluster_user }} to docker group"
+  user:
+    name: "{{ cluster_user }}"
+    groups: docker
+    append: yes
+- name: "start docker service"
+  service:
+    name: docker
+    state: started
diff --git a/conf/muchos.props.example b/conf/muchos.props.example
index c797155..b999eaa 100644
--- a/conf/muchos.props.example
+++ b/conf/muchos.props.example
@@ -148,12 +148,12 @@ yarn_nm_mem_mb=16384
 # <Hostname> = <Service1>[,<Service2>,<Service3>]
 # Where:
 #   Hostname = Must be unique.  Will be used for hostname in EC2 or should 
match hostname on your own cluster
-#   Service = Service to run on node (possible values: zookeeper, namenode, 
resourcemanager, accumulomaster, client,
+#   Service = Service to run on node (possible values: zookeeper, namenode, 
resourcemanager, accumulomaster, client, swarmmanager,
 #             mesosmaster, worker, fluo, metrics, spark). The following 
services are required: namenode, resourcemanager,
 #             accumulomaster, zookeeper & worker
 leader1 = namenode,resourcemanager,accumulomaster,zookeeper
 leader2 = metrics
-worker1 = worker
+worker1 = worker,swarmmanager
 worker2 = worker
 worker3 = worker
 worker4 = worker
diff --git a/lib/muchos/config.py b/lib/muchos/config.py
index 5f8a399..ad03164 100644
--- a/lib/muchos/config.py
+++ b/lib/muchos/config.py
@@ -17,7 +17,9 @@ from sys import exit
 from util import get_ephemeral_devices, get_arch
 import os
 
-SERVICES = ['zookeeper', 'namenode', 'resourcemanager', 'accumulomaster', 
'mesosmaster', 'worker', 'fluo', 'fluo_yarn', 'metrics', 'spark', 'client']
+SERVICES = ['zookeeper', 'namenode', 'resourcemanager', 'accumulomaster', 
'mesosmaster', 'worker', 'fluo', 'fluo_yarn', 'metrics', 'spark', 'client', 
'swarmmanager']
+
+OPTIONAL_SERVICES = ['fluo', 'fluo_yarn', 'metrics', 'mesosmaster', 'spark', 
'client', 'swarmmanager']
 
 
 class DeployConfig(ConfigParser):
@@ -50,7 +52,7 @@ class DeployConfig(ConfigParser):
 
         if action in ['launch', 'setup']:
             for service in SERVICES:
-                if service not in ['fluo', 'fluo_yarn', 'metrics', 
'mesosmaster', 'spark', 'client']:
+                if service not in OPTIONAL_SERVICES:
                     if not self.has_service(service):
                         exit("ERROR - Missing '{0}' service from [nodes] 
section of muchos.props".format(service))
 
diff --git a/lib/muchos/main.py b/lib/muchos/main.py
index a7824f5..930030c 100644
--- a/lib/muchos/main.py
+++ b/lib/muchos/main.py
@@ -243,6 +243,8 @@ class MuchosCluster:
                 print >>site_file, "- import_playbook: fluo_yarn.yml"
             if config.has_service("mesosmaster"):
                 print >>site_file, "- import_playbook: mesos.yml"
+            if config.has_service("swarmmanager"):
+                print >>site_file, "- import_playbook: docker.yml"
 
         ansible_conf = join(config.deploy_path, "ansible/conf")
         with open(join(ansible_conf, "hosts"), 'w') as hosts_file:
@@ -256,6 +258,8 @@ class MuchosCluster:
                 print >>hosts_file, 
"\n[mesosmaster]\n{0}".format(config.get_service_hostnames("mesosmaster")[0])
             if config.has_service("metrics"):
                 print >>hosts_file, 
"\n[metrics]\n{0}".format(config.get_service_hostnames("metrics")[0])
+            if config.has_service("swarmmanager"):
+                print >>hosts_file, 
"\n[swarmmanager]\n{0}".format(config.get_service_hostnames("swarmmanager")[0])
 
             print >>hosts_file, "\n[zookeepers]"
             for (index, zk_host) in 
enumerate(config.get_service_hostnames("zookeeper"), start=1):
diff --git a/lib/tests/test_config.py b/lib/tests/test_config.py
index f708162..288a04b 100644
--- a/lib/tests/test_config.py
+++ b/lib/tests/test_config.py
@@ -35,7 +35,7 @@ def test_defaults():
     assert c.instance_tags() == {}
     assert len(c.nodes()) == 6
     assert c.get_node('leader1') == ['namenode', 'resourcemanager', 
'accumulomaster', 'zookeeper']
-    assert c.get_node('worker1') == ['worker']
+    assert c.get_node('worker1') == ['worker', 'swarmmanager']
     assert c.get_node('worker2') == ['worker']
     assert c.get_node('worker3') == ['worker']
     assert c.has_service('accumulomaster')
@@ -59,7 +59,7 @@ def test_defaults():
     assert c.get_non_proxy() == [('10.0.0.1', 'leader2'), ('10.0.0.2', 
'worker1'), ('10.0.0.3', 'worker2'),
                                  ('10.0.0.4', 'worker3'), ('10.0.0.5', 
'worker4')]
     assert c.get_host_services() == [('leader1', 'namenode resourcemanager 
accumulomaster zookeeper'), ('leader2', 'metrics'),
-            ('worker1', 'worker'), ('worker2', 'worker'), ('worker3', 
'worker'), ('worker4', 'worker')]
+            ('worker1', 'worker swarmmanager'), ('worker2', 'worker'), 
('worker3', 'worker'), ('worker4', 'worker')]
 
 def test_case_sensitive():
     c = DeployConfig("muchos", '../conf/muchos.props.example', 
'../conf/hosts/example/example_cluster',

Reply via email to