<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3207985</id><updated>2026-05-18T02:37:14.024-04:00</updated><category term="accumulo"/><category term="java"/><category term="docker"/><category term="oracle"/><category term="ruby"/><category term="vagrant"/><category term="xml"/><category term="agile"/><category term="capistrano"/><category term="fedora"/><category term="gem"/><category term="javascript"/><category term="picocluster"/><category term="raspberry pi"/><category term="ruby rspec rails"/><category term="sql"/><category term="twitter"/><category term="ActiveRecord"/><category term="Amazon EC2"/><category term="Cardinality Estimation"/><category term="D4M"/><category term="ant"/><category term="bash"/><category term="cfmx"/><category term="consul"/><category term="distributed proofreading"/><category term="dynamic languages"/><category term="eclipse"/><category term="entity attribute value"/><category term="gnome"/><category term="go"/><category term="gora"/><category term="gutenberg"/><category term="jboss portal"/><category term="jboss seam"/><category term="jdbc"/><category term="judoscript"/><category term="junit"/><category term="linode"/><category term="linux"/><category term="locallucene"/><category term="localsolr"/><category term="lucene"/><category term="metadata"/><category term="metaprograming"/><category term="module_eval"/><category term="networking"/><category term="nodejs"/><category term="open cursors"/><category term="parsing"/><category term="plsql"/><category term="ruby rails gem"/><category term="scp"/><category term="servlet"/><category term="solr"/><category term="ssh"/><category term="stored procedure"/><category term="terminal"/><category term="timing study"/><category term="ubuntu"/><category term="ubuntu dv9000 sound"/><category term="validator"/><category term="wireless"/><category term="zookeeper"/><title type='text'>CodeBits - Tested Complex Code!</title><subtitle type='html'>&lt;a href=&quot;http://www.codebits.com&quot;&gt;Home&lt;/a&gt; - &#xa;&lt;a href=&quot;http://www.linkedin.com/in/affyadvice&quot;&gt;LinkedIn Profile&lt;/a&gt; - &#xa;&lt;a href=&quot;mailto:david.medinets@gmail.com&quot;&gt;Email&lt;/a&gt;</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://affy.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>303</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3207985.post-4053158554290852436</id><published>2016-07-17T12:40:00.003-04:00</published><updated>2016-07-17T12:40:33.744-04:00</updated><title type='text'>Docker Swarm 1.12 on PicoCluster</title><content type='html'>I followed the directions at https://medium.com/@bossjones/how-i-setup-a-raspberry-pi-3-cluster-using-the-new-docker-swarm-mode-in-29-minutes-aa0e4f3b1768#.ma06iyonf but tweaked them a bit.&lt;br /&gt;
&lt;br /&gt;
First off, I wanted to have my cluster using eth0 to connect to my laptop and then share its WiFi connection. Using this technique means that my WiFi network name and password are not on the cluster. So the cluster should be able to plug into any laptop or server without changes. Follow instructions at https://t.co/2jRbNAOiCU to share your eth0 connection.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use lsblk to umount any directories on the SD cards you&#39;ll be using. See http://affy.blogspot.com/2016/06/how-did-i-prepare-my-picocluster-for.html for a bit of information about lsblk.&lt;br /&gt;
&lt;br /&gt;
Now flash the SD cards using the flash tool from hypriot. Notice that *no* network information is provided.&lt;br /&gt;
&lt;br /&gt;
I used piX naming convention so that I can easily loop over all five RPI in the PicoCluster.&lt;br /&gt;
&lt;br /&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;flash --hostname pi1 --device /dev/mmcblk0 https://github.com/hypriot/image-builder-rpi/releases/download/v0.8.1/hypriotos-rpi-v0.8.1.img.zip&lt;br /&gt;flash --hostname pi2 --device /dev/mmcblk0 https://github.com/hypriot/image-builder-rpi/releases/download/v0.8.1/hypriotos-rpi-v0.8.1.img.zip&lt;br /&gt;flash --hostname pi3 --device /dev/mmcblk0 https://github.com/hypriot/image-builder-rpi/releases/download/v0.8.1/hypriotos-rpi-v0.8.1.img.zip&lt;br /&gt;flash --hostname pi4 --device /dev/mmcblk0 https://github.com/hypriot/image-builder-rpi/releases/download/v0.8.1/hypriotos-rpi-v0.8.1.img.zip&lt;br /&gt;flash --hostname pi5 --device /dev/mmcblk0 https://github.com/hypriot/image-builder-rpi/releases/download/v0.8.1/hypriotos-rpi-v0.8.1.img.zip&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;Using this function, you can find the IP addresses for the RPI.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;function getip() { (traceroute $1 2&amp;gt;&amp;amp;1 | head -n 1 | cut -d\( -f 2 | cut -d\) -f 1) }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;List the IP addresses.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;for i in `seq 1 5`; do echo &quot;HOST: pi$i&amp;nbsp; IP: $(getip pi$i.local)&quot;; done&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Remove any fingerprints for the RPI. &lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;for i in `seq 1 5`; do ssh-keygen -R pi${i}.local 2&amp;gt;/dev/null; done&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Copy your PKI identity to the RPI.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;for i in `seq 1 5`; do ssh-copy-id -oStrictHostKeyChecking=no -oCheckHostIP=no pirate@pi${i}.local; done&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Download the deb file for Docker v1.12&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;curl -O https://jenkins.hypriot.com/job/armhf-docker/17/artifact/bundles/latest/build-deb/raspbian-jessie/docker-engine_1.12.0%7Erc4-0%7Ejessie_armhf.deb&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Copy the deb file to the RPI&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;for i in `seq 1 5`; do scp -oStrictHostKeyChecking=no -oCheckHostIP=no docker-engine_1.12.0%7Erc4-0%7Ejessie_armhf.deb pirate@pi$i.local:.; done&lt;/span&gt;&lt;br /&gt;Remove older Docker version from the RPI&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;for i in `seq 1 5`; do ssh -oStrictHostKeyChecking=no -oCheckHostIP=no pirate@pi$i.local sudo apt-get purge -y docker-hypriot; done&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Install Docker&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;for i in `seq 1 5`; do ssh -oStrictHostKeyChecking=no -oCheckHostIP=no pirate@pi$i.local sudo dpkg -i docker-engine_1.12.0%7Erc4-0%7Ejessie_armhf.deb; done&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Initialize the Swarm&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;ssh -oStrictHostKeyChecking=no -oCheckHostIP=no pirate@pi1.local docker swarm init&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Join slaves to Swarm - replace the join command below with the specific one displayed by the init command.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;for i in `seq 2 5`; do &lt;br /&gt;&amp;nbsp; ssh -oStrictHostKeyChecking=no -oCheckHostIP=no pirate@pi$i.local docker swarm join --secret ceuok9jso0klube8m3ih9gcsv --ca-hash sha256:f0864eb57963e3f9cd1756e691d0b609903e3a0bb48785272ea53155809025ee 10.42.0.49:2377;&lt;br /&gt;done&lt;/span&gt;&lt;br /&gt;Exercise the Swarm&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;ssh -oStrictHostKeyChecking=no -oCheckHostIP=no pirate@pi1.local&lt;br /&gt;docker service create --name ping hypriot/rpi-alpine-scratch ping 8.8.8.8&lt;br /&gt;docker service tasks ping&lt;br /&gt;docker service update --replicas 10 ping&lt;br /&gt;docker service tasks ping&lt;br /&gt;docker service rm ping&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/4053158554290852436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/4053158554290852436' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/4053158554290852436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/4053158554290852436'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2016/07/docker-swarm-112-on-picocluster.html' title='Docker Swarm 1.12 on PicoCluster'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-4726785065850136962</id><published>2016-07-05T19:50:00.002-04:00</published><updated>2016-07-05T19:50:32.670-04:00</updated><title type='text'>How I Got Apache Spark to Sort Of (Not Really) Work on my PicoCluster of 5 Raspberry PI</title><content type='html'>I&#39;ve read several blog posts about people running Apache Spark on a Raspberry PI. It didn&#39;t seem too hard so I thought I&#39;ve have a go at it. But the results were disappointing. Bear in mind that I am a Spark novice so some setting is probably. I ran into two issues - memory and heartbeats.&lt;br /&gt;
&lt;br /&gt;
So, this what I did.&lt;br /&gt;
&lt;br /&gt;
I based my work on these pages:&lt;br /&gt;
&lt;br /&gt;
* https://darrenjw2.wordpress.com/2015/04/17/installing-apache-spark-on-a-raspberry-pi-2/&lt;br /&gt;
* https://darrenjw2.wordpress.com/2015/04/18/setting-up-a-standalone-apache-spark-cluster-of-raspberry-pi-2/&lt;br /&gt;
* http://www.openkb.info/2014/11/memory-settings-for-spark-standalone_27.html&lt;br /&gt;
&lt;br /&gt;
I created five SD cards according to my previous blog post (see&amp;nbsp;http://affy.blogspot.com/2016/06/how-did-i-prepare-my-picocluster-for.html).&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Installation of Apache Spark&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* install Oracle Java and Python&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;for i in `seq 1 5`; do (ssh -oStrictHostKeyChecking=no -oCheckHostIP=no pirate@pi0${i}.local sudo apt-get install -y oracle-java8-jdk python2.7 &amp;amp;); done&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* download Spark&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;wget http://d3kbcqa49mib13.cloudfront.net/spark-1.6.2-bin-hadoop2.6.tgz&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Copy Spark to all RPI&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;for i in `seq 1 5`; do (scp -q -oStrictHostKeyChecking=no -oCheckHostIP=no spark-1.6.2-bin-hadoop2.6.tgz pirate@pi0${i}.local:. &amp;amp;&amp;amp; echo &quot;Copy complete to pi0${i}&quot; &amp;amp;); done&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Uncompress Spark&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;for i in `seq 1 5`; do (ssh -oStrictHostKeyChecking=no -oCheckHostIP=no pirate@pi0${i}.local tar xfz spark-1.6.2-bin-hadoop2.6.tgz &amp;amp;&amp;amp; echo &quot;Uncompress complete to pi0${i}&quot; &amp;amp;); done&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Remove tgz file&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;for i in `seq 1 5`; do (ssh -oStrictHostKeyChecking=no -oCheckHostIP=no pirate@pi0${i}.local rm spark-1.6.2-bin-hadoop2.6.tgz); done&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Add the following to your .bashrc file on each RPI. I can&#39;t figure out how to put this into a loop.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;export SPARK_LOCAL_IP=&quot;$(ip route get 1 | awk &#39;{print $NF;exit}&#39;)&quot;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Run Standalone Spark Shell&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;ssh -oStrictHostKeyChecking=no -oCheckHostIP=no pirate@pi01.local&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;cd spark-1.6.2-bin-hadoop2.6&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;bin/run-example SparkPi 10&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;bin/spark-shell --master local[4]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;# This takes several minutes to display a prompt.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;# While the shell is running, visit http://pi01.local:4040/&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;scala&amp;gt; sc.textFile(&quot;README.md&quot;).count&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;# After the job is complete, visit the monitor page.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;scala&amp;gt; exit&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
* Run PyShark Shell&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;bin/pyspark --master local[4]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;gt;&amp;gt;&amp;gt; sc.textFile(&quot;README.md&quot;).count()&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;gt;&amp;gt;&amp;gt; exit()&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;CLUSTER&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now for the clustering...&lt;br /&gt;
&lt;br /&gt;
* Enable password-less SSH between nodes&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;ssh -oStrictHostKeyChecking=no -oCheckHostIP=no pirate@pi01.local&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;for i in `seq 1 5`; do avahi-resolve --name pi0${i}.local -4 | awk &#39; { t = $1; $1 = $2; $2 = t; print; } &#39; | sudo tee --append /etc/hosts; done&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;echo &quot;$(ip route get 1 | awk &#39;{print $NF;exit}&#39;) $(hostname).local&quot; | sudo tee --append /etc/hosts&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;ssh-keygen&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;for i in `seq 1 5`; do ssh-copy-id pirate@pi0${i}.local; done&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Configure Spark for Cluster&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;cd spark-1.6.2-bin-hadoop2.6/conf&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;create a slaves file with the following contents&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;pi01.local&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;pi02.local&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;pi03.local&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;pi04.local&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;pi05.local&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;cp spark-env.sh.template spark-env.sh&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;In spark-env.sh&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; Set SPARK_MASTER_IP the results of &quot;ip route get 1 | awk &#39;{print $NF;exit}&#39;&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; SPARK_WORKER_MEMORY=512m&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Copy the spark environment script to the other RPI&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;for i in `seq 2 5`; do scp spark-env.sh pirate@pi0${i}.local:spark-1.6.2-bin-hadoop2.6/conf/; done&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Start the cluster&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;cd ..&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;sbin/start-all.sh&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
* Visit the monitor page&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;http://192.168.1.8:8080&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
And everything is working so far! But ...&lt;br /&gt;
&lt;br /&gt;
* Start a Spark Shell&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;bin/spark-shell --executor-memory 500m --driver-memory 500m --master spark://pi01.local:7077 --conf spark.executor.heartbeatInterval=45s&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
And this fails...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/4726785065850136962/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/4726785065850136962' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/4726785065850136962'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/4726785065850136962'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2016/07/how-i-got-apache-spark-to-sort-of-not.html' title='How I Got Apache Spark to Sort Of (Not Really) Work on my PicoCluster of 5 Raspberry PI'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-6297884032591687875</id><published>2016-06-25T13:05:00.000-04:00</published><updated>2016-06-25T13:05:04.055-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="consul"/><category scheme="http://www.blogger.com/atom/ns#" term="docker"/><category scheme="http://www.blogger.com/atom/ns#" term="picocluster"/><title type='text'>How I got Docker Swarm to Run on a Raspberry PI PicoCluster with Consul</title><content type='html'>At the end of this article, I have a working Docker Swarm running on a five-node PicoCluster. Please flash your SD cards according to&amp;nbsp;http://affy.blogspot.com/2016/06/how-did-i-prepare-my-picocluster-for.html. Stop following that article after copying the SSH ids to the RPI.&lt;br /&gt;
&lt;br /&gt;
I am controlling the PicoCluster using my laptop. Therefore, my laptop is the HOST in the steps below.&lt;br /&gt;
&lt;br /&gt;
There is no guarantee this commands are correct. They just seem to work for me. And please don&#39;t ever, ever depend on this information for anything non-prototype without doing your own research.&lt;br /&gt;
&lt;br /&gt;
* On the HOST, create the Docker Machine to hold the consul service.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;docker-machine create \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; -d generic \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-storage-driver=overlay \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ip-address=$(getip pi01.local) \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ssh-user &quot;pirate&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; consul-machine&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Connect to the consul-machine Docker Machine&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;eval $(docker-machine env consul-machine)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Start Consul.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;docker run \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; -d \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; -p 8500:8500 \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; hypriot/rpi-consul \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; agent -dev -client 0.0.0.0&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Reset docker environment to talk with host docker.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;unset DOCKER_TLS_VERIFY DOCKER_HOST DOCKER_CERT_PATH DOCKER_MACHINE_NAME&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Visit the consul dashboard to provide it is working and accessible.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;firefox http://$(getip pi01.local):8500&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Create the swarm-master machine. &lt;b&gt;Note that eth0 is being used instead of eth1.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;docker-machine create \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; -d generic \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-storage-driver=overlay \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-master \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-image hypriot/rpi-swarm:latest \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-discovery=&quot;consul://$(docker-machine ip consul-machine):8500&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ip-address=$(getip pi02.local) \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ssh-user &quot;pirate&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-opt=&quot;cluster-store=consul://$(docker-machine ip consul-machine):8500&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-opt=&quot;cluster-advertise=eth0:2376&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; swarm-master&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Create the first slave node.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;docker-machine create \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; -d generic \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-storage-driver=overlay \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-image hypriot/rpi-swarm:latest \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-discovery=&quot;consul://$(docker-machine ip consul-machine):8500&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ip-address=$(getip pi03.local) \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ssh-user &quot;pirate&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-opt=&quot;cluster-store=consul://$(docker-machine ip consul-machine):8500&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-opt=&quot;cluster-advertise=eth0:2376&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; swarm-slave01&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* List nodes in the swarm. I don&#39;t know why, but this command must be run from one of the RPI. Otherwise, I see a &quot;malformed HTTP response&quot; message.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;eval $(docker-machine env swarm-master)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;docker -H $(docker-machine ip swarm-master):3376 run \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --rm \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; hypriot/rpi-swarm:latest \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; list consul://$(docker-machine ip consul-machine):8500&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Create the second slave node.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;docker-machine create \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; -d generic \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-storage-driver=overlay \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-image hypriot/rpi-swarm:latest \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-discovery=&quot;consul://$(docker-machine ip consul-machine):8500&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ip-address=$(getip pi04.local) \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ssh-user &quot;pirate&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-opt=&quot;cluster-store=consul://$(docker-machine ip consul-machine):8500&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-opt=&quot;cluster-advertise=eth0:2376&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; swarm-slave02&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Create the first third node.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;docker-machine create \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; -d generic \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-storage-driver=overlay \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-image hypriot/rpi-swarm:latest \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-discovery=&quot;consul://$(docker-machine ip consul-machine):8500&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ip-address=$(getip pi05.local) \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ssh-user &quot;pirate&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-opt=&quot;cluster-store=consul://$(docker-machine ip consul-machine):8500&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-opt=&quot;cluster-advertise=eth0:2376&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; swarm-slave03&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Check that docker machine sees all of the nodes&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ docker-machine ls&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;NAME &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ACTIVE &amp;nbsp; DRIVER &amp;nbsp; &amp;nbsp;STATE &amp;nbsp; &amp;nbsp; URL &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;SWARM &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DOCKER &amp;nbsp; &amp;nbsp;ERRORS&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;consul-machine &amp;nbsp; - &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;generic &amp;nbsp; Running &amp;nbsp; tcp://192.168.1.8:2376 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; v1.11.1 &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;swarm-master &amp;nbsp; &amp;nbsp; - &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;generic &amp;nbsp; Running &amp;nbsp; tcp://192.168.1.7:2376 &amp;nbsp; swarm-master (master) &amp;nbsp; v1.11.1 &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;swarm-slave01 &amp;nbsp; &amp;nbsp;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;generic &amp;nbsp; Running &amp;nbsp; tcp://192.168.1.2:2376 &amp;nbsp; swarm-master &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;v1.11.1 &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;swarm-slave02 &amp;nbsp; &amp;nbsp;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;generic &amp;nbsp; Running &amp;nbsp; tcp://192.168.1.5:2376 &amp;nbsp; swarm-master &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;v1.11.1 &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;swarm-slave03 &amp;nbsp; &amp;nbsp;- &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;generic &amp;nbsp; Running &amp;nbsp; tcp://192.168.1.4:2376 &amp;nbsp; swarm-master &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;v1.11.1 &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* List the swarm nodes in Firefox using Consul.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;firefox http://$(docker-machine ip consul-machine):8500/ui/#/dc1/kv/docker/swarm/nodes/&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Is my cluster working? First, switch to the swarm-master environment. Then view it&#39;s information. You should see the slaves listed. Next run the hello-world container. And finally, list the containers.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;eval $(docker-machine env swarm-master)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;docker -H $(docker-machine ip swarm-master):3376 info&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;docker -H $(docker-machine ip swarm-master):3376 run hypriot/armhf-hello-world&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;docker -H $(docker-machine ip swarm-master):3376 ps -a&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;CONTAINER ID &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;IMAGE &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; COMMAND &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;CREATED &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; STATUS &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; PORTS &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;NAMES&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;456fa23b8c52 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;hypriot/armhf-hello-world &amp;nbsp; &quot;/hello&quot; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 8 seconds ago &amp;nbsp; &amp;nbsp; &amp;nbsp; Exited (0) 5 seconds ago &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;swarm-slave01/nauseous_swartz&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;e1eb8a790e3f &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;hypriot/rpi-swarm:latest &amp;nbsp; &amp;nbsp;&quot;/swarm join --advert&quot; &amp;nbsp; 3 hours ago &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Up 3 hours &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 2375/tcp &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; swarm-slave03/swarm-agent&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;122b89a2ae5d &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;hypriot/rpi-swarm:latest &amp;nbsp; &amp;nbsp;&quot;/swarm join --advert&quot; &amp;nbsp; 3 hours ago &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Up 3 hours &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 2375/tcp &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; swarm-slave02/swarm-agent&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;449aa7087ecc &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;hypriot/rpi-swarm:latest &amp;nbsp; &amp;nbsp;&quot;/swarm join --advert&quot; &amp;nbsp; 3 hours ago &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Up 3 hours &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 2375/tcp &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; swarm-slave01/swarm-agent&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;6355f31de952 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;hypriot/rpi-swarm:latest &amp;nbsp; &amp;nbsp;&quot;/swarm join --advert&quot; &amp;nbsp; 3 hours ago &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Up 3 hours &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 2375/tcp &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; swarm-master/swarm-agent&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;05ee666e8662 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;hypriot/rpi-swarm:latest &amp;nbsp; &amp;nbsp;&quot;/swarm manage --tlsv&quot; &amp;nbsp; 3 hours ago &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Up 3 hours &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 2375/tcp, 192.168.1.7:3376-&amp;gt;3376/tcp &amp;nbsp; swarm-master/swarm-agent-master&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
Jump up and down when you see that the hello-world container was run from swarm-master but run on swarm-slave01!&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/6297884032591687875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/6297884032591687875' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/6297884032591687875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/6297884032591687875'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2016/06/how-i-got-docker-swarm-to-run-on.html' title='How I got Docker Swarm to Run on a Raspberry PI PicoCluster with Consul'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-5073925967198413356</id><published>2016-06-22T23:52:00.007-04:00</published><updated>2016-06-22T23:55:50.371-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="docker"/><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><title type='text'>How I attached a USB Thumb drive to my Raspberry PI and used it to hold Docker&#39;s Root Directory!</title><content type='html'>This post tells how I attached a USB Thumb drive to my Raspberry PI and used it to hold Docker&#39;s Root Directory.&lt;br /&gt;
&lt;br /&gt;
The first step is to connect to the RPI.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ ssh -o &#39;StrictHostKeyChecking=no&#39; -o &#39;CheckHostIP=no&#39; &#39;pirate@pi02.local&#39;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now create a mount point. This is just a directory, nothing fancy. It should be owned by root because Docker runs as root. Don&#39;t try to use &quot;pirate&quot; as the owner. I tried that. It failed. Leave the owner as root.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ sudo mkdir /media/usb&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Then look at the attached USB devices.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ sudo blkid&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;/dev/mmcblk0: PTTYPE=&quot;dos&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;/dev/mmcblk0p1: SEC_TYPE=&quot;msdos&quot; LABEL=&quot;HypriotOS&quot; UUID=&quot;D6D9-1D76&quot; TYPE=&quot;vfat&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;/dev/mmcblk0p2: LABEL=&quot;root&quot; UUID=&quot;81e5bfc7-0701-4a09-80aa-fe5bc3eecbcf&quot; TYPE=&quot;ext4&quot;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;/dev/sda1: LABEL=&quot;STORE N GO&quot; UUID=&quot;F171-FAE6&quot; TYPE=&quot;vfat&quot; PARTUUID=&quot;f11d6f2b-01&quot;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Note that the USB thumb drive is /dev/sda1. The information above is for the original formatting of the drive. After formatting the drive to use &quot;ext3&quot; the information looks like:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;/dev/sda1: LABEL=&quot;PI02&quot; UUID=&quot;801b666c-ea47-4f6f-ab6b-b88acceff08f&quot; TYPE=&quot;ext3&quot; PARTUUID=&quot;f11d6f2b-01&quot;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
This is the command that I used to format the drive to use ext3. Notiice that I named the drive the same as the hostname. I have no particular reason to do this. It just seemed right. Only run this formatting command once.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ sudo mkfs.ext3 -L &quot;PI02&quot; /dev/sda1&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now it&#39;s time to mount the thumb drive. Here we connect the device (/dev/sda1) to the mount point. After this command is run you&#39;ll be able to use /media/usb as a normal directory.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ sudo mount /dev/sda1 /media/usb&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Next we setup the thumb drive to be available whenever the RPI is rebooted. First, find the UUID. It&#39;s whatever UUID is associated with sda1.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ sudo ls -l /dev/disk/by-uuid&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;total 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;lrwxrwxrwx 1 root root 10 Jul &amp;nbsp;3 &amp;nbsp;2014 801b666c-ea47-4f6f-ab6b-b88acceff08f -&amp;gt; ../../sda1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;lrwxrwxrwx 1 root root 15 Jul &amp;nbsp;3 &amp;nbsp;2014 81e5bfc7-0701-4a09-80aa-fe5bc3eecbcf -&amp;gt; ../../mmcblk0p2&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;lrwxrwxrwx 1 root root 15 Jul &amp;nbsp;3 &amp;nbsp;2014 D6D9-1D76 -&amp;gt; ../../mmcblk0p1&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now add that UUID to the /etc/fstab file so it will be recognized across reboots. If you re-flash your SD card, you&#39;ll need to execute this step again.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ echo &quot;UUID=801b666c-ea47-4f6f-ab6b-b88acceff08f /media/usb nofail 0 0&quot; | sudo tee -a /etc/fstab&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Some images already on the Hypriot SD card. We&#39;ll make sure they are available after we move the Docker Root directory.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ docker images&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;REPOSITORY &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; TAG &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; IMAGE ID &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;CREATED &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SIZE&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;hypriot/rpi-swarm &amp;nbsp; &amp;nbsp;1.2.2 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; f13b7205f2db &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;5 weeks ago &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 13.97 MB&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;hypriot/rpi-consul &amp;nbsp; 0.6.4 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 879ac05d5353 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;6 weeks ago &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 19.71 MB&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Stop Docker to ensure that the Docker root directory does not change.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ sudo systemctl stop docker&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Copy files to the new location. Don&#39;t bother deleting the original files.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ sudo cp --no-preserve=mode --recursive /var/lib/docker /media/usb/docker&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
If you are paranoid, you can compare the two directory trees.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ sudo diff /var/lib/docker /media/usb/docker&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Common subdirectories: /var/lib/docker/containers and /media/usb/docker/containers&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Common subdirectories: /var/lib/docker/image and /media/usb/docker/image&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Common subdirectories: /var/lib/docker/network and /media/usb/docker/network&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Common subdirectories: /var/lib/docker/overlay and /media/usb/docker/overlay&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Common subdirectories: /var/lib/docker/tmp and /media/usb/docker/tmp&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Common subdirectories: /var/lib/docker/trust and /media/usb/docker/trust&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;Common subdirectories: /var/lib/docker/volumes and /media/usb/docker/volumes&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
Edit the docker service file to add --graph &quot;/media/usb/docker&quot; to the end of the ExecStart line.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ sudo vi /etc/systemd/system/docker.service&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now reload the systemctl daemon and start docker.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;sudo systemctl daemon-reload&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;sudo systemctl start docker&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Confirm that the ExecStart is correct - that is has the graph parameter.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ sudo systemctl show docker | grep ExecStart&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Confirm that the Docker Root Directory has changed.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ docker info | grep &quot;Root Dir&quot;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
And finally, confirm that you can see docker images.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &amp;quot;courier new&amp;quot; , &amp;quot;courier&amp;quot; , monospace;&quot;&gt;$ docker images&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/5073925967198413356/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/5073925967198413356' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/5073925967198413356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/5073925967198413356'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2016/06/how-i-attached-usb-thumb-drive-to-my.html' title='How I attached a USB Thumb drive to my Raspberry PI and used it to hold Docker&#39;s Root Directory!'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-4282831715555198095</id><published>2016-06-21T21:48:00.004-04:00</published><updated>2016-06-21T21:48:56.035-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="docker"/><category scheme="http://www.blogger.com/atom/ns#" term="picocluster"/><category scheme="http://www.blogger.com/atom/ns#" term="raspberry pi"/><title type='text'>How Did I prepare My PicoCluster For Docker Swarm?</title><content type='html'>How Did I prepare my PicoCluster?&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;DOCKER VERSION: &amp;nbsp;1.11.1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;HYPRIOT VERSION: 0.8&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;RASPBERRY PI: &amp;nbsp; &amp;nbsp;3&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
From my Linux laptop, I created five SD cards using the flash utility from Hypriot.&lt;br /&gt;
&lt;br /&gt;
As I plugged each SD card into my laptop, I ran &#39;lsblk&#39;. Then I used &#39;umount&#39; for anything mounted to the SD card. For example.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ lsblk&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;NAME &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;MAJ:MIN RM &amp;nbsp; SIZE RO TYPE MOUNTPOINT&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;sda &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 8:0 &amp;nbsp; &amp;nbsp;0 111.8G &amp;nbsp;0 disk&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;├─sda1 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;8:1 &amp;nbsp; &amp;nbsp;0 &amp;nbsp;79.9G &amp;nbsp;0 part /&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;├─sda2 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;8:2 &amp;nbsp; &amp;nbsp;0 &amp;nbsp; &amp;nbsp; 1K &amp;nbsp;0 part&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;└─sda5 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;8:5 &amp;nbsp; &amp;nbsp;0 &amp;nbsp;31.9G &amp;nbsp;0 part [SWAP]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;sdb &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 8:16 &amp;nbsp; 0 894.3G &amp;nbsp;0 disk&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;└─sdb1 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;8:17 &amp;nbsp; 0 894.3G &amp;nbsp;0 part /data&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;sr0 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;11:0 &amp;nbsp; &amp;nbsp;1 &amp;nbsp;1024M &amp;nbsp;0 rom &amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;mmcblk0 &amp;nbsp; &amp;nbsp; 179:0 &amp;nbsp; &amp;nbsp;0 &amp;nbsp; &amp;nbsp;15G &amp;nbsp;0 disk&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;├─mmcblk0p1 179:1 &amp;nbsp; &amp;nbsp;0 &amp;nbsp; &amp;nbsp;64M &amp;nbsp;0 part /media/medined/3ABE-55E4&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;└─mmcblk0p2 179:2 &amp;nbsp; &amp;nbsp;0 &amp;nbsp;14.9G &amp;nbsp;0 part /media/medined/root&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: inherit;&quot;&gt;umount any mount points for mmcblk0 (or your SD card). For example,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;umount /media/medined/3ABE-55E4&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;umount /media/medined/root&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
If the SD cards were flashed in the past then you&#39;ll need to run&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;umount /media/medined/HypriotOS&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;umount /media/medined/root&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Here are the five flash commands that I used. Of course, I used my real SSID and PASSWORD. Note that this command leaves your password in your shell history. If this is a concern, please research alternatives.&lt;br /&gt;
&lt;br /&gt;
As you flash the SD cards, use a gold sharpie to indicate the hostname of the SD card. This will make it much easier to make sure they are in the right RPI.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;flash --hostname pi01 --ssid NETWORK --password PASSWORD --device /dev/mmcblk0 https://downloads.hypriot.com/hypriotos-rpi-v0.8.0.img.zip&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;flash --hostname pi02 --ssid NETWORK --password PASSWORD --device /dev/mmcblk0 https://downloads.hypriot.com/hypriotos-rpi-v0.8.0.img.zip&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;flash --hostname pi03 --ssid NETWORK --password PASSWORD --device /dev/mmcblk0 https://downloads.hypriot.com/hypriotos-rpi-v0.8.0.img.zip&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;flash --hostname pi04 --ssid NETWORK --password PASSWORD --device /dev/mmcblk0 https://downloads.hypriot.com/hypriotos-rpi-v0.8.0.img.zip&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;flash --hostname pi05 --ssid NETWORK --password PASSWORD --device /dev/mmcblk0 https://downloads.hypriot.com/hypriotos-rpi-v0.8.0.img.zip&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
Next after the SD cards are plaeced into the PicoCluster, I plugged it into power.&lt;br /&gt;
&lt;br /&gt;
As a sidenote, each time you restart the RPIs, their SSH fingerprint changes. You&#39;ll need to remove the old fingerprint. One technique is the following:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;for i in `seq 1 5`; do ssh-keygen -R pi0${i}.local 2&amp;gt;/dev/null; done&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I dislike questions about server fingerprint&#39;s when connecting. Therefore, you&#39;ll see me using the &quot;StrictHostKeyChecking=no&quot; option with SSH. I take no stance on the security ramifications of this choice. I&#39;m connecting to my local PicoCluster not some public server. Make your own security decisions.&lt;br /&gt;
&lt;br /&gt;
Ensure that you have a SSH key set. Look for &quot;~/.ssh/id_rsa&quot;. If you don&#39;t have that file, use ssh-keygen to make one.&lt;br /&gt;
&lt;br /&gt;
Now copy your PKI credential to the five PRI to enable password-less SSH. You be asked for the password, which should be &quot;hypriot&quot;, five times.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;for i in `seq 1 5`; do ssh-copy-id -oStrictHostKeyChecking=no -oCheckHostIP=no pirate@pi0${i}.local; done&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Next you can check that password-less SSH is working. After each SSH, you&#39;ll see a prompt like &quot;HypriotOS/armv7: pirate@pi01 in ~&quot;. Just check the hostname is correct and then type exit to move onto the next RPI.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;for i in `seq 1 5`; do ssh -oStrictHostKeyChecking=no -oCheckHostIP=no pirate@pi0${i}.local; done&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
You can use the following shell function to determine the IP address of an RPI. I also found it happy to log into my router to see the list of attached devices. By the way, if you haven&#39;t changed the default password for the admin user of your router, do it. This article will wait...&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;function getip() { (traceroute $1 2&amp;gt;&amp;amp;1 | head -n 1 | cut -d\( -f 2 | cut -d\) -f 1) }&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
It&#39;s probably a good idea to place that function in your .bashrc file so that you&#39;ll always have it handy.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;for i in `seq 1 5`; do echo &quot;PI0${i}.local: $(getip pi0${i}.local)&quot;; done&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now comes the fun part, setting up the Docker Swarm. Fair warning. I don&#39;t know if these steps are correct.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;docker-machine create \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; -d generic \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-storage-driver=overlay \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-master \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-image hypriot/rpi-swarm:latest \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ip-address=$(getip pi01.local) \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ssh-user &quot;pirate&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-discovery=&quot;token://01&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; swarm&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;docker-machine create \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; -d generic \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-storage-driver=overlay \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-image hypriot/rpi-swarm:latest \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ip-address=$(getip pi02.local) \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ssh-user &quot;pirate&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-discovery=&quot;token://01&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; swarm-slave01&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;docker-machine create \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; -d generic \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-storage-driver=overlay \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-image hypriot/rpi-swarm:latest \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ip-address=$(getip pi03.local) \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ssh-user &quot;pirate&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-discovery=&quot;token://01&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; swarm-slave02&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;docker-machine create \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; -d generic \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-storage-driver=overlay \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-image hypriot/rpi-swarm:latest \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ip-address=$(getip pi04.local) \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ssh-user &quot;pirate&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-discovery=&quot;token://01&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; swarm-slave03&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;docker-machine create \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; -d generic \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --engine-storage-driver=overlay \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-image hypriot/rpi-swarm:latest \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ip-address=$(getip pi05.local) \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --generic-ssh-user &quot;pirate&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; --swarm-discovery=&quot;token://01&quot; \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; swarm-slave04&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now you can run list the nodes in the cluster using Docker Machine:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ docker-machine ls&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;NAME &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ACTIVE &amp;nbsp; DRIVER &amp;nbsp; &amp;nbsp;STATE &amp;nbsp; &amp;nbsp; URL &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SWARM &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;DOCKER &amp;nbsp; &amp;nbsp;ERRORS&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;swarm &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;generic &amp;nbsp; Running &amp;nbsp; tcp://192.168.1.12:2376 &amp;nbsp; swarm (master) &amp;nbsp; v1.11.1 &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;swarm-slave01 &amp;nbsp; - &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;generic &amp;nbsp; Running &amp;nbsp; tcp://192.168.1.7:2376 &amp;nbsp; &amp;nbsp;swarm &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;v1.11.1 &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;swarm-slave02 &amp;nbsp; - &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;generic &amp;nbsp; Running &amp;nbsp; tcp://192.168.1.11:2376 &amp;nbsp; swarm &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;v1.11.1 &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;swarm-slave03 &amp;nbsp; - &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;generic &amp;nbsp; Running &amp;nbsp; tcp://192.168.1.23:2376 &amp;nbsp; swarm &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;v1.11.1 &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;swarm-slave04 &amp;nbsp; - &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;generic &amp;nbsp; Running &amp;nbsp; tcp://192.168.1.22:2376 &amp;nbsp; swarm &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;v1.11.1 &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Notice that a master node is indicated but it is not marked as active. I don&#39;t know why.&lt;br /&gt;
&lt;br /&gt;
Before moving on, let&#39;s look at what containers are being run. There should be six.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;for i in `seq 1 5`; do echo &quot;RPI ${i}&quot;; ssh -oStrictHostKeyChecking=no -oCheckHostIP=no pirate@pi0${i}.local docker ps -a; done&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;RPI 1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;CONTAINER ID &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;IMAGE &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;COMMAND &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;CREATED &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; STATUS &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;PORTS &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;NAMES&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;ceb4a5255dc2 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;hypriot/rpi-swarm:latest &amp;nbsp; &quot;/swarm join --advert&quot; &amp;nbsp; About an hour ago &amp;nbsp; Up About an hour &amp;nbsp; &amp;nbsp;2375/tcp &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; swarm-agent&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;e9d3bf308284 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;hypriot/rpi-swarm:latest &amp;nbsp; &quot;/swarm manage --tlsv&quot; &amp;nbsp; About an hour ago &amp;nbsp; Up About an hour &amp;nbsp; &amp;nbsp;2375/tcp, 0.0.0.0:3376-&amp;gt;3376/tcp &amp;nbsp; swarm-agent-master&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;RPI 2&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;CONTAINER ID &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;IMAGE &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;COMMAND &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;CREATED &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; STATUS &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;PORTS &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NAMES&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;e2dca97c23fe &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;hypriot/rpi-swarm:latest &amp;nbsp; &quot;/swarm join --advert&quot; &amp;nbsp; About an hour ago &amp;nbsp; Up About an hour &amp;nbsp; &amp;nbsp;2375/tcp &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;swarm-agent&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;RPI 3&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;CONTAINER ID &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;IMAGE &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;COMMAND &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;CREATED &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; STATUS &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;PORTS &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NAMES&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;07d0b4fc4490 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;hypriot/rpi-swarm:latest &amp;nbsp; &quot;/swarm join --advert&quot; &amp;nbsp; 11 minutes ago &amp;nbsp; &amp;nbsp; &amp;nbsp;Up 11 minutes &amp;nbsp; &amp;nbsp; &amp;nbsp; 2375/tcp &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;swarm-agent&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;RPI 4&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;CONTAINER ID &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;IMAGE &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;COMMAND &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;CREATED &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; STATUS &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;PORTS &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NAMES&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;88712d8df693 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;hypriot/rpi-swarm:latest &amp;nbsp; &quot;/swarm join --advert&quot; &amp;nbsp; 6 minutes ago &amp;nbsp; &amp;nbsp; &amp;nbsp; Up 6 minutes &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;2375/tcp &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;swarm-agent&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;RPI 5&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;CONTAINER ID &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;IMAGE &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;COMMAND &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;CREATED &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; STATUS &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;PORTS &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; NAMES&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;b7738fb8c4b8 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;hypriot/rpi-swarm:latest &amp;nbsp; &quot;/swarm join --advert&quot; &amp;nbsp; 2 minutes ago &amp;nbsp; &amp;nbsp; &amp;nbsp; Up 2 minutes &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;2375/tcp &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;swarm-agent&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Currently, when you type &quot;docker ps&quot; you&#39;re looking at containers running on your local computer. You can switch so that &quot;docker&quot; connects to one of the &quot;docker machines&quot; using this command:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;eval $(docker-machine env swarm)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now &quot;docker ps&quot; returns information about containers running on pi01.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ docker ps&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;CONTAINER ID &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;IMAGE &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;COMMAND &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;CREATED &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; STATUS &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;PORTS &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;NAMES&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;ceb4a5255dc2 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;hypriot/rpi-swarm:latest &amp;nbsp; &quot;/swarm join --advert&quot; &amp;nbsp; About an hour ago &amp;nbsp; Up About an hour &amp;nbsp; &amp;nbsp;2375/tcp &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; swarm-agent&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;e9d3bf308284 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;hypriot/rpi-swarm:latest &amp;nbsp; &quot;/swarm manage --tlsv&quot; &amp;nbsp; About an hour ago &amp;nbsp; Up About an hour &amp;nbsp; &amp;nbsp;2375/tcp, 0.0.0.0:3376-&amp;gt;3376/tcp &amp;nbsp; swarm-agent-master&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
One neat &quot;trick&quot; is to look at the information from the &quot;swarm-agent-master&quot; container. This is done using Docker&#39;s -H option. Notice that the results indicate there are six containers running. Count the number of containers found using the &quot;for..loop&quot; earlier. They are the same number.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;$ docker -H $(docker-machine ip swarm):3376 info&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Containers: 6&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;Running: 6&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;Paused: 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;Stopped: 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Images: 15&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Server Version: swarm/1.2.3&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Role: primary&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Strategy: spread&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Filters: health, port, containerslots, dependency, affinity, constraint&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Nodes: 5&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;swarm: 192.168.1.12:2376&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ ID: P4OH:AB7Q:T2T3:P6OK:BW5F:YSIB:NACW:Q2F3:FKU4:IJFD:AUJQ:74CZ&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Status: Healthy&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Containers: 2&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Reserved CPUs: 0 / 4&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Reserved Memory: 0 B / 971.7 MiB&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Labels: executiondriver=, kernelversion=4.4.10-hypriotos-v7+, operatingsystem=Raspbian GNU/Linux 8 (jessie), provider=generic, storagedriver=overlay&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ UpdatedAt: 2016-06-22T01:39:56Z&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ ServerVersion: 1.11.1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;swarm-slave01: 192.168.1.7:2376&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ ID: GDQI:WYHS:OD2W:EE67:CKMU:A2PW:6K5T:YZSK:B5KL:SPCZ:6GVX:5MCO&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Status: Healthy&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Containers: 1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Reserved CPUs: 0 / 4&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Reserved Memory: 0 B / 971.7 MiB&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Labels: executiondriver=, kernelversion=4.4.10-hypriotos-v7+, operatingsystem=Raspbian GNU/Linux 8 (jessie), provider=generic, storagedriver=overlay&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ UpdatedAt: 2016-06-22T01:39:45Z&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ ServerVersion: 1.11.1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;swarm-slave02: 192.168.1.11:2376&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ ID: CA7H:C7UA:5V5N:NY4C:KECT:JK57:HDGN:2DNH:ASXQ:UJFQ:A5A4:US3Y&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Status: Healthy&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Containers: 1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Reserved CPUs: 0 / 4&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Reserved Memory: 0 B / 971.7 MiB&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Labels: executiondriver=, kernelversion=4.4.10-hypriotos-v7+, operatingsystem=Raspbian GNU/Linux 8 (jessie), provider=generic, storagedriver=overlay&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ UpdatedAt: 2016-06-22T01:39:32Z&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ ServerVersion: 1.11.1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;swarm-slave03: 192.168.1.23:2376&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ ID: 6H6D:P6EN:PTBL:Q5E3:MP32:T6CI:XU33:PCQV:KT6H:KRJ4:LYSN:76EJ&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Status: Healthy&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Containers: 1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Reserved CPUs: 0 / 4&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Reserved Memory: 0 B / 971.7 MiB&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Labels: executiondriver=, kernelversion=4.4.10-hypriotos-v7+, operatingsystem=Raspbian GNU/Linux 8 (jessie), provider=generic, storagedriver=overlay&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ UpdatedAt: 2016-06-22T01:39:25Z&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ ServerVersion: 1.11.1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;swarm-slave04: 192.168.1.22:2376&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ ID: 2ZBK:3DJE:D23C:7QAB:TLFS:L7EO:L4L4:IQ6Y:EC7D:UG7S:3WU6:QJ5D&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Status: Healthy&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Containers: 1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Reserved CPUs: 0 / 4&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Reserved Memory: 0 B / 971.7 MiB&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ Labels: executiondriver=, kernelversion=4.4.10-hypriotos-v7+, operatingsystem=Raspbian GNU/Linux 8 (jessie), provider=generic, storagedriver=overlay&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ UpdatedAt: 2016-06-22T01:39:32Z&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; └ ServerVersion: 1.11.1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Plugins:&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;Volume:&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp;Network:&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Kernel Version: 4.4.10-hypriotos-v7+&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Operating System: linux&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Architecture: arm&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;CPUs: 20&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Total Memory: 4.745 GiB&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Name: e9d3bf308284&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Docker Root Dir:&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Debug mode (client): false&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Debug mode (server): false&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;WARNING: No kernel memory limit support&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
And that&#39;s as far as I&#39;ve gotten.</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/4282831715555198095/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/4282831715555198095' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/4282831715555198095'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/4282831715555198095'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2016/06/how-did-i-prepare-my-picocluster-for.html' title='How Did I prepare My PicoCluster For Docker Swarm?'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-8339026673321635813</id><published>2015-08-24T21:20:00.002-04:00</published><updated>2015-08-24T21:20:42.303-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="docker"/><category scheme="http://www.blogger.com/atom/ns#" term="go"/><title type='text'>Go Program to Read Docker Image List From Unix Socket (/var/run/docker.sock)</title><content type='html'>It took me a bit of time to get this simple program working so I&#39;m sharing for other people new to Go.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;br /&gt;
package main&lt;br /&gt;&lt;br /&gt;import (&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;fmt&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;io&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;net&quot;&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;func reader(r io.Reader) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; buf := make([]byte, 1024)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; n, err := r.Read(buf[:])&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if err != nil {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; println(string(buf[0:n]))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;func main() {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; c, err := net.Dial(&quot;unix&quot;, &quot;/var/run/docker.sock&quot;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if err != nil {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; panic(err)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; defer c.Close()&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fmt.Fprintf(c, &quot;GET /images/json HTTP/1.0\r\n\r\n&quot;)&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; reader(c)&lt;br /&gt;}&lt;br /&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/8339026673321635813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/8339026673321635813' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/8339026673321635813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/8339026673321635813'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2015/08/go-program-to-read-docker-image-list.html' title='Go Program to Read Docker Image List From Unix Socket (/var/run/docker.sock)'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-6617868992146015197</id><published>2015-04-24T23:01:00.001-04:00</published><updated>2015-04-24T23:01:09.022-04:00</updated><title type='text'>Running the NodeJS Example Inside Docker Container</title><content type='html'>Yesterday, I showed how to run NodeJS inside a Docker container. Today, I updated my Github project (https://github.com/medined/docker-nodejs) so that the Example server works correctly.&lt;br /&gt;
&lt;br /&gt;
The trick is for the NodeJS code inside the container to find the container&#39;s IP address and listen on that address instead of localhost or 127.0.0.1. This is not difficult.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;br /&gt;
&amp;nbsp;require(&#39;dns&#39;).lookup(require(&#39;os&#39;).hostname(), function (err, add, fam) {&lt;br /&gt;&amp;nbsp; var http = require(&#39;http&#39;);&lt;br /&gt;&amp;nbsp; http.createServer(function (req, res) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; res.writeHead(200, {&#39;Content-Type&#39;: &#39;text/plain&#39;});&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; res.end(&#39;Hello World\n&#39;);&lt;br /&gt;&amp;nbsp; }).listen(1337, add);&lt;br /&gt;&amp;nbsp; console.log(&#39;Server running at http://&#39; + add + &#39;:1337/&#39;);&lt;br /&gt;})&lt;br /&gt;
&lt;br /&gt;
If you&#39;re using my Docker image, then you&#39;d just run the following to start the server. Use ^C to stop the server.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;br /&gt;
node example.js&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now you can browse from the host computer using the following URL. Note that the &#39;docker run&#39; command exposes port 1337.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;br /&gt;
http://localhost:1337/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/6617868992146015197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/6617868992146015197' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/6617868992146015197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/6617868992146015197'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2015/04/running-nodejs-example-inside-docker.html' title='Running the NodeJS Example Inside Docker Container'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-8570785172763123781</id><published>2015-04-23T22:58:00.001-04:00</published><updated>2015-04-23T22:58:19.960-04:00</updated><title type='text'>Running NodeJS (and related tools) from a Docker container.</title><content type='html'>In my continuing quest to run my development tools from within Docker containers, I looked at Node today.&lt;br /&gt;
&lt;br /&gt;
The Github project is at https://github.com/medined/docker-nodejs.&lt;br /&gt;
&lt;br /&gt;
My Dockerfile is fairly simple:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
&lt;/pre&gt;
FROM ubuntu:14.04&lt;br /&gt;&lt;br /&gt;RUN apt-get -qq update \&lt;br /&gt;&amp;nbsp; &amp;amp;&amp;amp; apt-get install -y curl \&lt;br /&gt;&amp;nbsp; &amp;amp;&amp;amp; curl -sL https://deb.nodesource.com/setup | sudo bash - \&lt;br /&gt;&amp;nbsp; &amp;amp;&amp;amp; apt-get install -y nodejs \&lt;br /&gt;&amp;nbsp; &amp;amp;&amp;amp; npm install -g inherits bower grunt grunt-cli&lt;br /&gt;&lt;br /&gt;RUN useradd -ms /bin/bash developer&lt;br /&gt;&lt;br /&gt;USER developer&lt;br /&gt;WORKDIR /home/developer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It&#39;s built using:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;br /&gt;
docker build -t medined/nodejs .&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
Using the &#39;developer&#39; user is important because bower can&#39;t be used by root. By itself, this container does not look impressive. Some magic is added by the following shell script called &#39;node&#39;:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;br /&gt;
#!/bin/bash&lt;br /&gt;&lt;br /&gt;CMD=$(basename $0)&lt;br /&gt;&lt;br /&gt;docker run \&lt;br /&gt;&amp;nbsp; -it \&lt;br /&gt;&amp;nbsp; --rm \&lt;br /&gt;&amp;nbsp; -p 1337:1337 \&lt;br /&gt;&amp;nbsp; -v &quot;$PWD&quot;:/home/developer/source \&lt;br /&gt;&amp;nbsp; -w /home/developer/source \&lt;br /&gt;&amp;nbsp; medined/nodejs \&lt;br /&gt;&amp;nbsp; $CMD $@&lt;br /&gt;
&lt;br /&gt;
I expose port 1337 because that&#39;s the port used on the NodeJS home page example. The current directory is exposed in the container at a convenient location. That location is used at the working directory.&lt;br /&gt;
&lt;br /&gt;
You might be puzzled at the use of $CMD. I symlink this script to bower, grunt, and npm. The $CMD invokes the proper command inside the container.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/8570785172763123781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/8570785172763123781' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/8570785172763123781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/8570785172763123781'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2015/04/running-nodejs-and-related-tools-from.html' title='Running NodeJS (and related tools) from a Docker container.'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-5535302795331616333</id><published>2015-04-20T21:26:00.001-04:00</published><updated>2015-04-20T21:26:14.021-04:00</updated><title type='text'>Running Spring Boot inside Docker</title><content type='html'>This is another in my series of very short entries about Docker. I&#39;ve been working to not install maven on my development laptop. But I still want to use spring-boot:run to launch my applications. Here is the Docker command I am using. Notice the server.port is specified on the command line so that I can change it as needed.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
&lt;/pre&gt;
docker run \&lt;br /&gt;&amp;nbsp; -it \&lt;br /&gt;&amp;nbsp; --rm \&lt;br /&gt;&amp;nbsp; -p 8090:8090 \&lt;br /&gt;&amp;nbsp; -e server.port=8090 \&lt;br /&gt;&amp;nbsp; --link artifactory:artifactory \&lt;br /&gt;&amp;nbsp; --link mysql:mysql \&lt;br /&gt;&amp;nbsp; -v &quot;$PWD/m2&quot;:/root/.m2 \&lt;br /&gt;&amp;nbsp; -v &quot;$PWD&quot;:/usr/src/mymaven \&lt;br /&gt;&amp;nbsp; -w /usr/src/mymaven \&lt;br /&gt;&amp;nbsp; maven:3.3-jdk-8 \&lt;br /&gt;&amp;nbsp; mvn spring-boot:run&lt;br /&gt;
&lt;br /&gt;
The MySQL container was started like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;br /&gt;
docker run \&lt;br /&gt;&amp;nbsp; --name mysql \&lt;br /&gt;&amp;nbsp; -p 3306:3306 \&lt;br /&gt;&amp;nbsp; -v /data/mysql:/var/lib/mysql \&lt;br /&gt;&amp;nbsp; -e MYSQL_ROOT_PASSWORD=password \&lt;br /&gt;&amp;nbsp; -e MYSQL_DATABASE=docker \&lt;br /&gt;&amp;nbsp; -e MYSQL_USER=docker \&lt;br /&gt;&amp;nbsp; -e MYSQL_PASSWORD=password \&lt;br /&gt;&amp;nbsp; -d \&lt;br /&gt;&amp;nbsp; mysql/mysql-server:5.5&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/5535302795331616333/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/5535302795331616333' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/5535302795331616333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/5535302795331616333'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2015/04/running-spring-boot-inside-docker.html' title='Running Spring Boot inside Docker'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-5247954407266276667</id><published>2015-04-20T16:23:00.001-04:00</published><updated>2015-04-20T16:23:49.924-04:00</updated><title type='text'>Running Maven inside Docker. </title><content type='html'>I recently reinstalled Ubuntu on my zareason laptop. As I was thinking about installing my development tools, I thought about how to integrate Docker into the process. Below I show how simple using the Maven container can be:&lt;br /&gt;
&lt;br /&gt;
* Create an alias to the Maven container.&lt;br /&gt;
&lt;br /&gt;
alias mvn=&quot;docker run \&lt;br /&gt;&amp;nbsp; -it \&lt;br /&gt;&amp;nbsp; --rm \&lt;br /&gt;
&amp;nbsp; --name my-maven-project \&lt;br /&gt;
&amp;nbsp; -v &quot;$PWD&quot;:/usr/src/mymaven \&lt;br /&gt;&amp;nbsp; -w /usr/src/mymaven \&lt;br /&gt;&amp;nbsp; maven:3.3-jdk-8 \&lt;br /&gt;&amp;nbsp; mvn&quot;&lt;br /&gt;
&lt;br /&gt;
* Clone my ragnvald Java project.&lt;br /&gt;
&lt;br /&gt;
git clone git@github.com:medined/ragnvald.git&lt;br /&gt;
&lt;br /&gt;
* cd ragnvald&lt;br /&gt;
&lt;br /&gt;
* Package&amp;nbsp; the project.&lt;br /&gt;
&lt;br /&gt;
mvn package&lt;br /&gt;
&amp;nbsp;That&#39;s it. You&#39;re using Maven without installing onto your laptop! The results of the compilation are placed into the target directory.&lt;br /&gt;
&lt;br /&gt;
If you need to specify a Maven settings.xml file that&#39;s fairly easy as well. Simply create it alongside the pom.xml file. Then slightly modify your alias:&lt;br /&gt;
&lt;br /&gt;
alias mvn=&quot;docker run \&lt;br /&gt;&amp;nbsp; -it \&lt;br /&gt;&amp;nbsp; --rm \&lt;br /&gt;
&amp;nbsp; --name my-maven-project \&lt;br /&gt;
&amp;nbsp;&amp;nbsp; -v &quot;$PWD&quot;:/root/.m2 \&lt;br /&gt;&amp;nbsp;&amp;nbsp; -v &quot;$PWD&quot;:/usr/src/mymaven \&lt;br /&gt;&amp;nbsp;&amp;nbsp; -w /usr/src/mymaven \&lt;br /&gt;&amp;nbsp; maven:3.3-jdk-8 \&lt;br /&gt;&amp;nbsp; mvn&quot;&lt;br /&gt;
&lt;br /&gt;
The ragnvald project goes one step farther to use an Artifactory container so that I can use the Artifactory web interface if needed. That&#39;s quite convenient!&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/5247954407266276667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/5247954407266276667' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/5247954407266276667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/5247954407266276667'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2015/04/running-maven-inside-docker.html' title='Running Maven inside Docker. '/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-6219763085323656729</id><published>2015-04-15T23:53:00.000-04:00</published><updated>2015-04-15T23:53:07.526-04:00</updated><title type='text'>Running MySQL on Docker</title><content type='html'>This entry doesn&#39;t reveal any hidden secrets just the simple steps to start using MySQL on Docker.&lt;br /&gt;
&lt;br /&gt;
* Install docker&lt;br /&gt;
&lt;br /&gt;
* Install docker-compose&lt;br /&gt;
&lt;br /&gt;
* mkdir firstdb&lt;br /&gt;
&lt;br /&gt;
* cd firstdb&lt;br /&gt;
&lt;br /&gt;
* vi docker-compose.yml&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;mysql:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;image: mysql:latest&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;environment:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MYSQL_DATABASE: sample&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MYSQL_USER: mysql&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MYSQL_PASSWORD: mysql&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MYSQL_ROOT_PASSWORD: supersecret&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* docker-compose up&lt;br /&gt;
* docker-compose ps&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Name                   Command          State    Ports&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;-----------------------------------------------------------------&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;firstdb_mysql_1   /entrypoint.sh mysqld   Up      3306/tcp&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Use a one-shot Docker instance to display environment variables. Notice &lt;br /&gt;
the variables that start with MYSQL? Your programs can use these variables&lt;br /&gt;
to make the database connection.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;b&gt;docker run --link=firstdb_mysql_1:mysql ubuntu env&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;HOSTNAME=abfc8d50633b&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MYSQL_PORT=tcp://172.17.0.23:3306&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MYSQL_PORT_3306_TCP=tcp://172.17.0.23:3306&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MYSQL_PORT_3306_TCP_ADDR=172.17.0.23&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MYSQL_PORT_3306_TCP_PORT=3306&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MYSQL_PORT_3306_TCP_PROTO=tcp&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MYSQL_NAME=/nostalgic_rosalind/mysqldb&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MYSQL_ENV_MYSQL_PASSWORD=mysql&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MYSQL_ENV_MYSQL_ROOT_PASSWORD=supersecret&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MYSQL_ENV_MYSQL_USER=mysql&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MYSQL_ENV_MYSQL_DATABASE=sample&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MYSQL_ENV_MYSQL_MAJOR=5.6&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;MYSQL_ENV_MYSQL_VERSION=5.6.24&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;HOME=/root&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
* Use a one-shot Docker instance for a MySQL command-line interface. Once this&lt;br /&gt;
is running, you&#39;ll be able to use command like &#39;show databases&#39;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;docker run -it \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;--link=firstcompose_mysqldb_1:mysql \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;--rm \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;mysql/mysql-server:latest \&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;sh -c &#39;exec mysql -h&quot;$MYSQL_PORT_3306_TCP_ADDR&quot; -P&quot;$MYSQL_PORT_3306_TCP_PORT&quot; -uroot -p&quot;$MYSQL_ENV_MYSQL_ROOT_PASSWORD&quot;&#39;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
That&#39;s all it takes to start.</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/6219763085323656729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/6219763085323656729' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/6219763085323656729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/6219763085323656729'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2015/04/running-mysql-on-docker.html' title='Running MySQL on Docker'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-6808407728483699104</id><published>2014-11-23T20:01:00.004-05:00</published><updated>2014-11-23T20:01:41.790-05:00</updated><title type='text'>Using AZUL 7 instead of OpenJDK Java for smaller Docker images.</title><content type='html'>Witness a tale of two Dockerfiles that perform the same task. See the size difference. Imagine how it might change infrastructure costs.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
DOCKERFILE ONE&lt;/h4&gt;
&lt;br /&gt;
&lt;pre&gt;FROM debian:wheezy

RUN apt-get update &amp;amp;&amp;amp; apt-get install -y openjdk-7-jre &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*

ADD target/si-standalone-sample-1.0-SNAPSHOT.jar /

ENV JAVA_HOME /usr/lib/jvm/java-7-openjdk-amd64
ENV CLASSPATH si-standalone-sample-1.0-SNAPSHOT.jar

CMD [ &quot;java&quot;, &quot;org.springframework.boot.loader.JarLauncher&quot; ]
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
DOCKERFILE TWO&lt;/h4&gt;
&lt;br /&gt;
&lt;pre&gt;FROM debian:wheezy

RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0x219BD9C9 &amp;amp;&amp;amp; \
  echo &quot;deb http://repos.azulsystems.com/ubuntu precise main&quot; &amp;gt;&amp;gt; /etc/apt/sources.list.d/zulu.list &amp;amp;&amp;amp; \
  apt-get -qq update &amp;amp;&amp;amp; \
  apt-get -qqy install zulu-7 &amp;amp;&amp;amp; \
  rm -rf /var/lib/apt/lists/*

ADD target/si-standalone-sample-1.0-SNAPSHOT.jar /

ENV JAVA_HOME /usr/lib/jvm/zulu-7-amd64
ENV CLASSPATH si-standalone-sample-1.0-SNAPSHOT.jar

CMD [ &quot;java&quot;, &quot;org.springframework.boot.loader.JarLauncher&quot; ]
&lt;/pre&gt;
&lt;br /&gt;
Notice the only difference is which Java is being installed. Here are the image sizes:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;spring-integration   openjdk  549.1 MB
spring-integration   azul     261.3 MB
&lt;/pre&gt;
&lt;br /&gt;
That&#39;s a 288MB difference.&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/6808407728483699104/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/6808407728483699104' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/6808407728483699104'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/6808407728483699104'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2014/11/using-azul-7-instead-of-openjdk-java.html' title='Using AZUL 7 instead of OpenJDK Java for smaller Docker images.'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-9044407709880552428</id><published>2014-11-23T17:28:00.000-05:00</published><updated>2015-01-05T22:18:06.154-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="docker"/><title type='text'>Is using &quot;lsb_release -cs&quot; a good idea inside a debian:wheezy Dockerfile?</title><content type='html'>Update from Jan 2015: The Zulu team added formal Debian support last October, I just did not know about it. Look at the version history for Zulu 8.4,  7.7, and 6.6 at http://www.azulsystems.com/zulurelnotes. Also look on DockerHub for their 8.4.x Docker files. They don&#39;t use lsb_release -cs in Debian Dockerfiles anymore, and instead allow the Zulu repository to honor &#39;stable&#39; as release name. &#39;stable&#39; always pushes the highest level for a Java major version. - I am paraphrasing the comments from Matthew Schuetze below.&lt;br /&gt;
&lt;br /&gt;
I saw the following line in a Dockerfile&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;RUN echo &quot;deb http://repos.azulsystems.com/ubuntu `lsb_release -cs` main&quot; &gt;&gt; /etc/apt/sources.list.d/zulu.list
&lt;/pre&gt;&lt;br /&gt;
The lsb_release program is not part of the wheezy standard programs. But we can install it:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;$ apt-get update &amp;&amp; apt-get install -y lsb
&lt;/pre&gt;&lt;br /&gt;
How many files were created by that install?&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;$ docker diff 09 | wc -l
30013
&lt;/pre&gt;&lt;br /&gt;
Over 30,000 files!&lt;br /&gt;
&lt;br /&gt;
I next tried being a bit more specific with&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;$ apt-get update &amp;&amp; apt-get install -y lsb-release
&lt;/pre&gt;&lt;br /&gt;
How many files were created by that install?&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;$ docker diff 23 | wc -l
1689
&lt;/pre&gt;&lt;br /&gt;
I conclude that hard-coding &quot;wheezy&quot; is better than using lsb_release in a Dockerfile. At least when using Debian as the base operating system.&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/9044407709880552428/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/9044407709880552428' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/9044407709880552428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/9044407709880552428'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2014/11/is-using-lsbrelease-cs-good-idea-inside.html' title='Is using &quot;lsb_release -cs&quot; a good idea inside a debian:wheezy Dockerfile?'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-7126437064384279929</id><published>2014-11-22T23:26:00.001-05:00</published><updated>2014-11-22T23:30:31.850-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bash"/><category scheme="http://www.blogger.com/atom/ns#" term="docker"/><title type='text'>Using Docker to find out what apt-get update does!</title><content type='html'>While I dabble in System Administration, I don&#39;t have a deep knowledge how packages are created or maintained. Today, we&#39;ll see how to use Docker to increase my understanding of &quot;apt-get update&quot;. I was curious about this command because I read that it&#39;s good practice to remove the files created during the update process. &lt;br /&gt;
&lt;br /&gt;
I started a small container using&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;docker run -i -t debian:wheezy /bin/bash
&lt;/pre&gt;&lt;br /&gt;
In another window, I found the ID of the running container using &quot;docker ps&quot;. Let&#39;s pretend that ID starts with &quot;45...&quot;. Look for any changed files using&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;docker diff &quot;45&quot;
&lt;/pre&gt;&lt;br /&gt;
You&#39;ll see nothing displayed. Now run &quot;apt-get update&quot; in the wheezy container. Then run the diff command again. You should see the following differences:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;C /var
C /var/lib
C /var/lib/apt
C /var/lib/apt/lists
A /var/lib/apt/lists/http.debian.net_debian_dists_wheezy-updates_Release
A /var/lib/apt/lists/http.debian.net_debian_dists_wheezy-updates_Release.gpg
A /var/lib/apt/lists/http.debian.net_debian_dists_wheezy-updates_main_binary-amd64_Packages.gz
A /var/lib/apt/lists/http.debian.net_debian_dists_wheezy_Release
A /var/lib/apt/lists/http.debian.net_debian_dists_wheezy_Release.gpg
A /var/lib/apt/lists/http.debian.net_debian_dists_wheezy_main_binary-amd64_Packages.gz
A /var/lib/apt/lists/lock
C /var/lib/apt/lists/partial
A /var/lib/apt/lists/security.debian.org_dists_wheezy_updates_Release
A /var/lib/apt/lists/security.debian.org_dists_wheezy_updates_Release.gpg
A /var/lib/apt/lists/security.debian.org_dists_wheezy_updates_main_binary-amd64_Packages.gz
&lt;/pre&gt;&lt;br /&gt;
Inside the wheezy container we now know where to look to find file sizes:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;# ls -lh /var/lib/apt/lists
total 8.0M
-rw-r--r-- 1 root root 121K Nov 23 02:49 http.debian.net_debian_dists_wheezy-updates_Release
-rw-r--r-- 1 root root  836 Nov 23 02:49 http.debian.net_debian_dists_wheezy-updates_Release.gpg
-rw-r--r-- 1 root root    0 Nov 23 02:37 http.debian.net_debian_dists_wheezy-updates_main_binary-amd64_Packages
-rw-r--r-- 1 root root 165K Oct 18 10:33 http.debian.net_debian_dists_wheezy_Release
-rw-r--r-- 1 root root 1.7K Oct 18 10:44 http.debian.net_debian_dists_wheezy_Release.gpg
-rw-r--r-- 1 root root 7.3M Oct 18 10:07 http.debian.net_debian_dists_wheezy_main_binary-amd64_Packages.gz
-rw-r----- 1 root root    0 Nov 23 04:09 lock
drwxr-xr-x 2 root root 4.0K Nov 23 04:09 partial
-rw-r--r-- 1 root root 100K Nov 20 16:31 security.debian.org_dists_wheezy_updates_Release
-rw-r--r-- 1 root root  836 Nov 20 16:31 security.debian.org_dists_wheezy_updates_Release.gpg
-rw-r--r-- 1 root root 270K Nov 20 16:31 security.debian.org_dists_wheezy_updates_main_binary-amd64_Packages.gz
&lt;/pre&gt;&lt;br /&gt;
Obviously, those .gz files might be interesting. It&#39;s easy enough to uncompress them:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;gzip -d http.debian.net_debian_dists_wheezy_main_binary-amd64_Packages.gz
&lt;/pre&gt;&lt;br /&gt;
And now it&#39;s possible to see what&#39;s inside:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;# more http.debian.net_debian_dists_wheezy_main_binary-amd64_Packages
Package: 0ad
Version: 0~r11863-2
Installed-Size: 8260
Maintainer: Debian Games Team &lt;pkg-games-devel lists.alioth.debian.org=&quot;&quot;&gt;
Architecture: amd64
Depends: 0ad-data (&amp;gt;= 0~r11863), 0ad-data (&amp;lt;= 0~r11863-2), gamin | fam, libboost-signals1.49.0 (&amp;gt;= 1.49.0-1), libc6 (&amp;gt;= 2.11), libcurl3-gnutls (&amp;gt;= 7.16.2), libenet1a, libgamin0 | libfam0, libgcc1 (&amp;gt;= 1:4.1.1), libgl1-mesa-glx | libgl1, lib
jpeg8 (&amp;gt;= 8c), libmozjs185-1.0 (&amp;gt;= 1.8.5-1.0.0+dfsg), libnvtt2, libopenal1, libpng12-0 (&amp;gt;= 1.2.13-4), libsdl1.2debian (&amp;gt;= 1.2.11), libstdc++6 (&amp;gt;= 4.6), libvorbisfile3 (&amp;gt;= 1.1.2), libwxbase2.8-0 (&amp;gt;= 2.8.12.1), libwxgtk2.8-0 (&amp;gt;= 2.8.12.1), l
ibx11-6, libxcursor1 (&amp;gt;&amp;gt; 1.1.2), libxml2 (&amp;gt;= 2.7.4), zlib1g (&amp;gt;= 1:1.2.0)
Pre-Depends: dpkg (&amp;gt;= 1.15.6~)
Description: Real-time strategy game of ancient warfare
Homepage: http://www.wildfiregames.com/0ad/
Description-md5: d943033bedada21853d2ae54a2578a7b
Tag: game::strategy, implemented-in::c++, interface::x11, role::program,
 uitoolkit::sdl, uitoolkit::wxwidgets, use::gameplaying,
 x11::application
Section: games
Priority: optional
Filename: pool/main/0/0ad/0ad_0~r11863-2_amd64.deb
Size: 2260694
MD5sum: cf71a0098c502ec1933dea41610a79eb
SHA1: aa4a1fdc36498f230b9e38ae0116b23be4f6249e
SHA256: e28066103ecc6996e7a0285646cd2eff59288077d7cc0d22ca3489d28d215c0a

...
&lt;/pkg-games-devel&gt;&lt;/pre&gt;&lt;br /&gt;
Given the information about the text file, we can find out how many packages are available:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;# grep &quot;Package&quot; http.debian.net_debian_dists_wheezy_main_binary-amd64_Packages | wc -l
36237
&lt;/pre&gt;&lt;br /&gt;
Now you know why it&#39;s important to run the following in your Dockerfile after using apt-get to install software.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;rm -rf /var/lib/apt/lists/*
&lt;/pre&gt;&lt;br /&gt;
Have fun exploring!&lt;br /&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/7126437064384279929/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/7126437064384279929' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/7126437064384279929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/7126437064384279929'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2014/11/using-docker-to-find-out-what-apt-get.html' title='Using Docker to find out what apt-get update does!'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-3984995026282226010</id><published>2014-11-12T23:13:00.001-05:00</published><updated>2014-11-12T23:14:42.369-05:00</updated><title type='text'>Using Docker to Build Brooklyn</title><content type='html'>Brooklyn is a large project with a lot of dependencies. I wanted to compile it, but I also wanted to remove all traces of the project when I was done experimenting. I used Docker to accomplish this goal.&lt;br /&gt;
&lt;br /&gt;
See the files below at https://github.com/medined/docker-brooklyn.&lt;br /&gt;
&lt;br /&gt;
First, I created a Dockerfile to load java, maven, and clone the repository.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;$ cat Dockerfile 
FROM ubuntu:14.04
MAINTAINER David Medinets &lt;david.medinets@gmail.com&gt;

#
# Install Java
#

RUN apt-get update &amp;&amp; \
  apt-get install -y software-properties-common &amp;&amp; \
  add-apt-repository -y ppa:webupd8team/java &amp;&amp; \
  echo debconf shared/accepted-oracle-license-v1-1 select true | sudo debconf-set-selections &amp;&amp; \
  echo debconf shared/accepted-oracle-license-v1-1 seen true | sudo debconf-set-selections &amp;&amp; \
  apt-get update &amp;&amp; \
  apt-get install -y oracle-java8-installer

ENV JAVA_HOME /usr/lib/jvm/java-8-oracle

#
# Install Maven
#
RUN echo &quot;deb http://ppa.launchpad.net/natecarlson/maven3/ubuntu precise main&quot; &gt;&gt; /etc/apt/sources.list &amp;&amp; \
  echo &quot;deb-src http://ppa.launchpad.net/natecarlson/maven3/ubuntu precise main&quot; &gt;&gt; /etc/apt/sources.list &amp;&amp; \
  apt-get update &amp;&amp; \
  apt-get -y --force-yes install maven3 &amp;&amp; \
  rm -f /usr/bin/mvn &amp;&amp; \
  ln -s /usr/share/maven3/bin/mvn /usr/bin/mvn

RUN mkdir -p /root/.m2

ADD settings.xml /root/.m2/settings.xml

#
# Clone the brooklyn project
#
RUN apt-get install -y git 
RUN git clone https://github.com/apache/incubator-brooklyn.git

WORKDIR /incubator-brooklyn

RUN apt-get clean &amp;&amp; rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
&lt;/pre&gt;&lt;br /&gt;
There is one twist - that settings.xml file. It&#39;s used to connect to a Docker-based Artifactory image later.&lt;br /&gt;
&lt;br /&gt;
Then I created a script to build the image.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;$ cat build_image.sh 
#!/bin/bash
sudo DOCKER_HOST=$DOCKER_HOST docker build --no-cache --rm=true -t medined/brooklyn.build .
&lt;/pre&gt;&lt;br /&gt;
Also a script to run the image.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;$ cat run_image.sh 
#!/bin/bash

#####
# Make sure that Artifactory is running.
#
ARTIFACTORY_COUNT=$(docker ps --filter=status=running | grep artifactory | wc -l)
if [ &quot;${ARTIFACTORY_COUNT}&quot; != &quot;1&quot; ]
then
  echo &quot;Starting Artifactory&quot;
  docker run --name &quot;artifactorydata&quot; -v /opt/artifactory/data -v /opt/artifactory/logs tianon/true
  docker run -d -p 8081:8081 --name &quot;artifactory&quot; --volumes-from artifactorydata  codingtony/artifactory
fi

IMAGEID=$(docker ps -a |grep &quot;brooklyn.build&quot; | awk &#39;{print $1}&#39;)
if [ &quot;$IMAGEID&quot; != &quot;&quot; ]
then
  echo &quot;Stopping $IMAGEID&quot;
  IMAGEID=$(sudo DOCKER_HOST=$DOCKER_HOST docker stop $IMAGEID | xargs docker rm)
fi

sudo DOCKER_HOST=$DOCKER_HOST \
  docker run \
    --link artifactory:artifactory \
    -i \
    -t medined/brooklyn.build \
    /bin/bash
&lt;/pre&gt;&lt;br /&gt;
In the run script, an Artifactory image is started if one isn&#39;t running. Artifactory lets you compile Brooklyn over and over with needing to download the dependencies more than once.&lt;br /&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/3984995026282226010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/3984995026282226010' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/3984995026282226010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/3984995026282226010'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2014/11/using-docker-to-build-brooklyn.html' title='Using Docker to Build Brooklyn'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-5575489132767619526</id><published>2014-10-31T16:03:00.001-04:00</published><updated>2014-10-31T22:17:56.935-04:00</updated><title type='text'>Using R to Fetch List of Pokemon Sets.</title><content type='html'>&lt;p&gt;This document shows how to extract a dataset from an HTML page.&lt;/p&gt;&lt;p&gt;We’ll start by loading two libraries. RCurl is used to read an HTML page. XML is used to parse HTML which can be viewed as a form of XML.&lt;/p&gt;&lt;pre class=&quot;r&quot;&gt;&lt;code&gt;library(RCurl)&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;## Loading required package: bitops&lt;/code&gt;&lt;/pre&gt;&lt;pre class=&quot;r&quot;&gt;&lt;code&gt;library(XML)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let R know where to find the HTML page. Then download and parse it.&lt;/p&gt;&lt;pre class=&quot;r&quot;&gt;&lt;code&gt;theurl &amp;lt;- &amp;quot;http://bulbapedia.bulbagarden.net/wiki/List_of_Pok%C3%A9mon_Trading_Card_Game_expansions&amp;quot;
webpage &amp;lt;- getURL(theurl)
webpage &amp;lt;- readLines(tc &amp;lt;- textConnection(webpage)); close(tc)
doc &amp;lt;- htmlTreeParse(webpage, error=function(...){}, useInternalNodes = TRUE)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Use XPATH to extract all tr (table row) nodes from the HTML page. There is a lot of extraneous information in those tr nodes so we’ll filter the list from 70 elements to 67 elements.&lt;/p&gt;&lt;pre class=&quot;r&quot;&gt;&lt;code&gt;tr &amp;lt;- getNodeSet(doc, &amp;quot;//*/tr&amp;quot;)
tr_with_pokemon_sets &amp;lt;- tr[4:length(tr)-1]&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let’s look at one example of the HTML. It holds information about one Pokemon set. The pound signs at the start of the lines are not part of the data, they are just part of the printing.&lt;/p&gt;&lt;pre class=&quot;r&quot;&gt;&lt;code&gt;tr_with_pokemon_sets[1]&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;[[1]]
&amp;lt;tr&amp;gt;&amp;lt;th&amp;gt; 1
&amp;lt;/th&amp;gt;
&amp;lt;td&amp;gt; 1
&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt;
&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt; &amp;lt;a href=&amp;quot;/wiki/Base_Set_(TCG)&amp;quot; title=&amp;quot;Base Set (TCG)&amp;quot;&amp;gt;Base Set&amp;lt;/a&amp;gt;
&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt; Expansion Pack
&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt; 102
&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt; 102
&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt; January 9, 1999
&amp;lt;/td&amp;gt;
&amp;lt;td&amp;gt; October 20, 1996
&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt; &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In order to make sense of that HTML, we’ll use a custom function to manipulate each element in tr_with_pokemon_sets. Generally speaking, the function removes newlines and HTML syntax. It also provides data types and column names.&lt;/p&gt;&lt;pre class=&quot;r&quot;&gt;&lt;code&gt;xmlToCsv &amp;lt;- function(xml) {
  a &amp;lt;- gsub(&#39;\n\n&#39;,&#39;\t&#39;, xmlValue(xml))
    b &amp;lt;- gsub(&#39;\t\t&#39;,&#39;\t \t&#39;, a)
    d &amp;lt;- gsub(&#39;\t\t&#39;,&#39;\t&#39;, b)
    e &amp;lt;- gsub(&#39;^ |\t$&#39;,&#39;&#39;, d)
    f &amp;lt;- gsub(&#39;\t &#39;,&#39;\t&#39;, e)
    cc &amp;lt;- c(&amp;quot;numeric&amp;quot;, &amp;quot;numeric&amp;quot;, &amp;quot;character&amp;quot;, &amp;quot;character&amp;quot;, &amp;quot;character&amp;quot;, &amp;quot;character&amp;quot;, &amp;quot;character&amp;quot;, &amp;quot;character&amp;quot;, &amp;quot;character&amp;quot;)
    cn &amp;lt;- c(&amp;quot;EngNumber&amp;quot;, &amp;quot;JpNumber&amp;quot;, &amp;quot;Icon&amp;quot;, &amp;quot;EngSet&amp;quot;, &amp;quot;JpSet&amp;quot;, &amp;quot;EngCardCount&amp;quot;, &amp;quot;JpCardCount&amp;quot;, &amp;quot;EngDate&amp;quot;, &amp;quot;JpDate&amp;quot;)
    g &amp;lt;- read.table(text=f, sep=&amp;quot;\t&amp;quot;, header=FALSE)
    colnames(g) &amp;lt;- cn
    keeps &amp;lt;- c(&amp;quot;EngNumber&amp;quot;, &amp;quot;EngSet&amp;quot;, &amp;quot;EngCardCount&amp;quot;)
    return(g[keeps])
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Magic happens next. We apply the custom function, convert results toa data.frame and remove NA values.&lt;/p&gt;&lt;pre class=&quot;r&quot;&gt;&lt;code&gt;pokemon_set_dataframe &amp;lt;- na.omit(do.call(rbind, lapply(tr_with_pokemon_sets, xmlToCsv)))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The information is displayed so you can see the data so far.&lt;/p&gt;&lt;pre class=&quot;r&quot;&gt;&lt;code&gt;pokemon_set_dataframe&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;   EngNumber                     EngSet EngCardCount
1          1                   Base Set          102
2          2                     Jungle           64
3          3                     Fossil           62
4          4                 Base Set 2          130
5          5                Team Rocket          83*
6          7              Gym Challenge          132
7          8                Neo Genesis          111
8          9              Neo Discovery           75
9         10             Neo Revelation          66*
10        11                Neo Destiny         113*
11        12       Legendary Collection          110
14        13        Expedition Base Set          165
15        14                  Aquapolis         186*
16        14                  Aquapolis         186*
17        15                   Skyridge         182*
18        15                   Skyridge         182*
19        16         EX Ruby &amp;amp; Sapphire          109
20        17               EX Sandstorm          100
21        18                  EX Dragon         100*
22        19 EX Team Magma vs Team Aqua          97*
23        20          EX Hidden Legends         102*
24        21     EX FireRed &amp;amp; LeafGreen         116*
25        22     EX Team Rocket Returns         111*
26        23                  EX Deoxys         108*
27        24                 EX Emerald         107*
28        25           EX Unseen Forces         145*
29        26           EX Delta Species         114*
30        27            EX Legend Maker          93*
31        28          EX Holon Phantoms         111*
32        29       EX Crystal Guardians          100
33        30        EX Dragon Frontiers          101
34        31           EX Power Keepers          108
35        32            Diamond &amp;amp; Pearl          130
36        33       Mysterious Treasures         124*
37        34             Secret Wonders          132
38        35           Great Encounters          106
39        36              Majestic Dawn          100
40        37           Legends Awakened          146
41        38                 Stormfront         106*
42        40              Rising Rivals         120*
43        41            Supreme Victors         153*
44        42                     Arceus         111*
45        43     HeartGold &amp;amp; SoulSilver         124*
46        44                  Unleashed          96*
47        45                  Undaunted          91*
48        46                 Triumphant         103*
49        47            Call of Legends          106
50        48              Black &amp;amp; White         115*
51        49            Emerging Powers           98
52        50            Noble Victories         102*
53        51             Next Destinies         103*
54        52             Dark Explorers         111*
55        53            Dragons Exalted         128*
56        54         Boundaries Crossed         153*
57        55               Plasma Storm         138*
58        56              Plasma Freeze         122*
59        57               Plasma Blast         105*
60        58        Legendary Treasures         138*
61        59                         XY          146
62        60                  Flashfire         109*
63        61              Furious Fists         113*
64        62             Phantom Forces         122*
65        63               Primal Clash         150+&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Notice those extra asterisks and plus signs? The next bit of code removes them.&lt;/p&gt;&lt;pre class=&quot;r&quot;&gt;&lt;code&gt;pokemon_set_dataframe$EngCardCount &amp;lt;- gsub(&amp;quot;\\*|\\+&amp;quot;, &amp;quot;&amp;quot;, pokemon_set_dataframe$EngCardCount)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here is the final dataset.&lt;/p&gt;&lt;pre class=&quot;r&quot;&gt;&lt;code&gt;pokemon_set_dataframe&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;   EngNumber                     EngSet EngCardCount
1          1                   Base Set          102
2          2                     Jungle           64
3          3                     Fossil           62
4          4                 Base Set 2          130
5          5                Team Rocket           83
6          7              Gym Challenge          132
7          8                Neo Genesis          111
8          9              Neo Discovery           75
9         10             Neo Revelation           66
10        11                Neo Destiny          113
11        12       Legendary Collection          110
14        13        Expedition Base Set          165
15        14                  Aquapolis          186
16        14                  Aquapolis          186
17        15                   Skyridge          182
18        15                   Skyridge          182
19        16         EX Ruby &amp;amp; Sapphire          109
20        17               EX Sandstorm          100
21        18                  EX Dragon          100
22        19 EX Team Magma vs Team Aqua           97
23        20          EX Hidden Legends          102
24        21     EX FireRed &amp;amp; LeafGreen          116
25        22     EX Team Rocket Returns          111
26        23                  EX Deoxys          108
27        24                 EX Emerald          107
28        25           EX Unseen Forces          145
29        26           EX Delta Species          114
30        27            EX Legend Maker           93
31        28          EX Holon Phantoms          111
32        29       EX Crystal Guardians          100
33        30        EX Dragon Frontiers          101
34        31           EX Power Keepers          108
35        32            Diamond &amp;amp; Pearl          130
36        33       Mysterious Treasures          124
37        34             Secret Wonders          132
38        35           Great Encounters          106
39        36              Majestic Dawn          100
40        37           Legends Awakened          146
41        38                 Stormfront          106
42        40              Rising Rivals          120
43        41            Supreme Victors          153
44        42                     Arceus          111
45        43     HeartGold &amp;amp; SoulSilver          124
46        44                  Unleashed           96
47        45                  Undaunted           91
48        46                 Triumphant          103
49        47            Call of Legends          106
50        48              Black &amp;amp; White          115
51        49            Emerging Powers           98
52        50            Noble Victories          102
53        51             Next Destinies          103
54        52             Dark Explorers          111
55        53            Dragons Exalted          128
56        54         Boundaries Crossed          153
57        55               Plasma Storm          138
58        56              Plasma Freeze          122
59        57               Plasma Blast          105
60        58        Legendary Treasures          138
61        59                         XY          146
62        60                  Flashfire          109
63        61              Furious Fists          113
64        62             Phantom Forces          122
65        63               Primal Clash          150&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With a bit more complexity the first column of numbers can be removed.&lt;/p&gt;&lt;pre class=&quot;r&quot;&gt;&lt;code&gt;x &amp;lt;- as.matrix(format(pokemon_set_dataframe))
rownames(x) &amp;lt;- rep(&amp;quot;&amp;quot;, nrow(x))
print(x, quote=FALSE)&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt; EngNumber EngSet                     EngCardCount
  1        Base Set                   102         
  2        Jungle                     64          
  3        Fossil                     62          
  4        Base Set 2                 130         
  5        Team Rocket                83          
  7        Gym Challenge              132         
  8        Neo Genesis                111         
  9        Neo Discovery              75          
 10        Neo Revelation             66          
 11        Neo Destiny                113         
 12        Legendary Collection       110         
 13        Expedition Base Set        165         
 14        Aquapolis                  186         
 14        Aquapolis                  186         
 15        Skyridge                   182         
 15        Skyridge                   182         
 16        EX Ruby &amp;amp; Sapphire         109         
 17        EX Sandstorm               100         
 18        EX Dragon                  100         
 19        EX Team Magma vs Team Aqua 97          
 20        EX Hidden Legends          102         
 21        EX FireRed &amp;amp; LeafGreen     116         
 22        EX Team Rocket Returns     111         
 23        EX Deoxys                  108         
 24        EX Emerald                 107         
 25        EX Unseen Forces           145         
 26        EX Delta Species           114         
 27        EX Legend Maker            93          
 28        EX Holon Phantoms          111         
 29        EX Crystal Guardians       100         
 30        EX Dragon Frontiers        101         
 31        EX Power Keepers           108         
 32        Diamond &amp;amp; Pearl            130         
 33        Mysterious Treasures       124         
 34        Secret Wonders             132         
 35        Great Encounters           106         
 36        Majestic Dawn              100         
 37        Legends Awakened           146         
 38        Stormfront                 106         
 40        Rising Rivals              120         
 41        Supreme Victors            153         
 42        Arceus                     111         
 43        HeartGold &amp;amp; SoulSilver     124         
 44        Unleashed                  96          
 45        Undaunted                  91          
 46        Triumphant                 103         
 47        Call of Legends            106         
 48        Black &amp;amp; White              115         
 49        Emerging Powers            98          
 50        Noble Victories            102         
 51        Next Destinies             103         
 52        Dark Explorers             111         
 53        Dragons Exalted            128         
 54        Boundaries Crossed         153         
 55        Plasma Storm               138         
 56        Plasma Freeze              122         
 57        Plasma Blast               105         
 58        Legendary Treasures        138         
 59        XY                         146         
 60        Flashfire                  109         
 61        Furious Fists              113         
 62        Phantom Forces             122         
 63        Primal Clash               150         &lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And we can plot the number of cards per set against the set number.&lt;/p&gt;&lt;pre class=&quot;r&quot;&gt;&lt;code&gt;plot(pokemon_set_dataframe[c(1,3)])&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;data:image/png;base64,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&quot; title alt width=&quot;672&quot; /&gt;&lt;/p&gt;&lt;p&gt;The EngCount column is actually a character data type which is not correct. The transform method changes the datatype.&lt;/p&gt;&lt;pre class=&quot;r&quot;&gt;&lt;code&gt;pokemon_set_dataframe &amp;lt;- transform(pokemon_set_dataframe, EngCardCount = as.numeric(EngCardCount))&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now it’s possible to sum the card counts.&lt;/p&gt;&lt;pre class=&quot;r&quot;&gt;&lt;code&gt;noquote(format(sum(pokemon_set_dataframe$EngCardCount), big.mark=&amp;quot;,&amp;quot;))&lt;/code&gt;&lt;/pre&gt;&lt;pre&gt;&lt;code&gt;[1] 7,372&lt;/code&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/5575489132767619526/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/5575489132767619526' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/5575489132767619526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/5575489132767619526'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2014/10/using-r-to-fetch-list-of-pokemon-sets.html' title='Using R to Fetch List of Pokemon Sets.'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-4526629904699148078</id><published>2014-10-10T16:01:00.000-04:00</published><updated>2014-10-10T16:01:41.303-04:00</updated><title type='text'>How do I provide a single file to multiple Docker containers?</title><content type='html'>http://www.cyberciti.biz/faq/bash-shell-change-the-color-of-my-shell-prompt-under-linux-or-unix/</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/4526629904699148078/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/4526629904699148078' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/4526629904699148078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/4526629904699148078'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2014/10/how-do-i-provide-single-file-to.html' title='How do I provide a single file to multiple Docker containers?'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-5208793946890656748</id><published>2014-09-29T17:07:00.001-04:00</published><updated>2014-09-29T17:08:06.615-04:00</updated><title type='text'>Simple Explanation of the MIT D4M Accumulo Schema</title><content type='html'>&lt;a target=&quot;_new&quot; href=&quot;https://github.com/medined/D4M_Schema&quot;&gt;https://github.com/medined/D4M_Schema&lt;/a&gt; provides a step-by-step introduction to the D4M nosql schema used by many organizations.&lt;br /&gt;
&lt;br /&gt;
D4M is a breakthrough in computer programming that combines the advantages of five distinct processing technologies (sparse linear algebra, associative arrays, fuzzy algebra, distributed arrays, and triple-store/NoSQL databases such as Hadoop HBase and Apache Accumulo) to provide a database and computation system that addresses the problems associated with Big Data.</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/5208793946890656748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/5208793946890656748' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/5208793946890656748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/5208793946890656748'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2014/09/simple-explanation-of-mit-d4m-accumulo.html' title='Simple Explanation of the MIT D4M Accumulo Schema'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-8614353736853698906</id><published>2014-07-15T14:17:00.001-04:00</published><updated>2014-07-15T15:12:41.755-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="docker"/><title type='text'>Sharing Files Between Docker Images Using Volumes</title><content type='html'>&lt;p&gt;Recently I wanted to provide the same configuration file to two different Docker containers. I choose to solve this using a Docker volume. The configuration file will be sourced from within each container and looks like this:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;$ cat bridge-env.sh 
export BRIDGENAME=brbob
export IMAGENAME=bob
export IPADDR=10.0.10.1/24
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Before any explanations, let&#39;s look at the files we&#39;ll be using:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;./configuration/build_image.sh - wrapper for _docker build_.
./configuration/run_image.sh - wrapper for _docker run_.
./configuration/Dockerfile - control file for Docker image.
./configuration/files/bridge-env.sh - environment setting script.
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;All of the files are fairly small. Since our main topic today is Docker, let&#39;s look at the Docker configuration file first.&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;$ cat Dockerfile
FROM stackbrew/busybox:latest
MAINTAINER David Medinets &amp;lt;david.medinets@gmail.com&amp;gt;
RUN mkdir /configuration
VOLUME /configuration
ADD files /configuration
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;And you can build this image.&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;$ cat build_image.sh
sudo DOCKER_HOST=$DOCKER_HOST docker build --rm=true -t medined/shared-configuration .
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;p&gt;I setup my docker to use a port instead of a UNIX socket. Therefore my DOCKER&lt;em&gt;HOST is &quot;tcp://0.0.0.0:4243&quot;. Since _sudo&lt;/em&gt; is being used, the environment variable needs to be set inside the sudo enviroment. If you want to use the default UNIX socker, leave DOCKER_HOST empty. The command will still work.&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;
&lt;p&gt;Then run it.&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;$ cat run_image.sh
sudo DOCKER_HOST=$DOCKER_HOST docker run --name shared-configuration -t medined/shared-configuration true
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;This command runs a docker container called &lt;em&gt;shared&lt;/em&gt;configuration&lt;em&gt;. You&#39;ll notice that the _true&lt;/em&gt; command is run which exits immediately. Since this container will only hold files, it&#39;s ok there are no processes running in it. &lt;b&gt;However, be very careful not to delete this container.&lt;/b&gt; Here is the output from &lt;em&gt;docker ps&lt;/em&gt; showing the container.&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;$ docker ps -a
CONTAINER ID        IMAGE                               COMMAND             CREATED             STATUS                      PORTS               NAMES
d4a2aa46b5d9        medined/shared-configuration:latest   true                7 seconds ago       Exited (0) 7 seconds ago                       -shared-configuration
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Now it&#39;s time to spin up two plain Ubuntu containers that can access the shared file.&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;$ sudo DOCKER_HOST=$DOCKER_HOST docker run --name A --volumes-from=shared-configuration -d -t ubuntu /bin/bash
94638de8b615f356f1240bbe602c0b7862e0589f1711fbff242b6d6f74c7de7d
$ sudo DOCKER_HOST=$DOCKER_HOST docker run --name B --volumes-from=shared-configuration -d -t ubuntu /bin/bash
sudo DOCKER_HOST=$DOCKER_HOST docker run --name B --volumes-from=shared-configuration -d -t ubuntu /bin/bash
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;How can we see the shared file? Let&#39;s turn to a very useful tool called &lt;em&gt;nsenter&lt;/em&gt; (or namespace enter). The following command installs nsenter if isn&#39;t already installed.&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;hash nsenter 2&amp;gt;/dev/null \
  || { echo &amp;gt;&amp;amp;2 &quot;Installing nsenter&quot;; \
  sudo DOCKER_HOST=$DOCKER_HOST \
  docker run -v /usr/local/bin:/target jpetazzo/nsenter;  }
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;I use a little script file to make nsenter easier to use:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;$ cat enter_image.sh
#!/bin/bash

IMAGENAME=$1

usage() {
  echo &quot;Usage: $0 [image name]&quot;
  exit 1
}

if [ -z $IMAGENAME ]
then
  echo &quot;Error: missing image name parameter.&quot;
  usage
fi

PID=$(sudo DOCKER_HOST=$DOCKER_HOST docker inspect --format {{.State.Pid}} $IMAGENAME)
sudo nsenter --target $PID --mount --uts --ipc --net --pid
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;This script is used by specifying the image name to use. For example,&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;$ ./enter_image.sh A
root@94638de8b615:/# cat /configuration/bridge-env.sh 
export BRIDGENAME=brbob
export IMAGENAME=bob
export IPADDR=10.0.10.1/24
root@94638de8b615:/# exit
logout
$ ./enter_image.sh B
root@925365faded2:/# cat /configuration/bridge-env.sh 
export BRIDGENAME=brbob
export IMAGENAME=bob
export IPADDR=10.0.10.1/24
root@925365faded2:/# exit
logout
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;We see the same information in both containers. Let&#39;s prove that the bridge-env.sh file is shared instead of being two copies.&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;$ ./enter_image.sh A
root@94638de8b615:/# echo &quot;export NEW_VARIABLE=VALUE&quot; &amp;gt;&amp;gt; /configuration/bridge-env.sh 
root@94638de8b615:/# exit
logout
$ ./enter_image.sh B
root@925365faded2:/# cat /configuration/bridge-env.sh 
export BRIDGENAME=brbob
export IMAGENAME=bob
export IPADDR=10.0.10.1/24
export NEW_VARIABLE=VALUE
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;We changed the file in the first container and saw the changes in the second container. As an alternative to using nsenter, you can simply run a container to list the files.&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;$ docker run --volumes-from shared-configuration busybox ls -al /configuration
&lt;/code&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/8614353736853698906/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/8614353736853698906' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/8614353736853698906'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/8614353736853698906'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2014/07/sharing-files-between-docker-images.html' title='Sharing Files Between Docker Images Using Volumes'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-8553817627625133807</id><published>2014-07-12T09:35:00.000-04:00</published><updated>2014-07-12T09:35:07.972-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="accumulo"/><category scheme="http://www.blogger.com/atom/ns#" term="docker"/><title type='text'>Running a Single-Node Accumulo Docker container</title><content type='html'>&lt;br /&gt;
&lt;p&gt;Based on the work by sroegner, I have a github project at https://github.com/medined/docker-accumulo which lets you run multiple single-node Accumulo instances using Docker.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;First, create the image.&lt;p&gt;&lt;br /&gt;
&lt;pre&gt;git clone https://github.com/medined/docker-accumulo.git
cd docker-accumulo/single_node
./make_image.sh
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Now start your first container.&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;export HOSTNAME=bellatrix
export IMAGENAME=bellatrix
export BRIDGENAME=brbellatrix
export SUBNET=10.0.10
export NODEID=1
export HADOOPHOST=10.0.10.1
./make_container.sh $HOSTNAME $IMAGENAME $BRIDGENAME $SUBNET $NODEID $HADOOPHOST yes
&lt;/pre&gt;&lt;br /&gt;
And then you can start a second one:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;export HOSTNAME=rigel
export IMAGENAME=rigel
export BRIDGENAME=brrigel
export SUBNET=10.0.11
export NODEID=1
export HADOOPHOST=10.0.11.1
./make_container.sh $HOSTNAME $IMAGENAME $BRIDGENAME $SUBNET $NODEID $HADOOPHOST no
&lt;/pre&gt;&lt;br /&gt;
And a third!&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;export HOSTNAME=saiph
export IMAGENAME=saiph
export BRIDGENAME=brbellatrix
export SUBNET=10.0.12
export NODEID=1
export HADOOPHOST=10.0.12.1
./make_container.sh $HOSTNAME $IMAGENAME $BRIDGENAME $SUBNET $NODEID $HADOOPHOST no
&lt;/pre&gt;&lt;br /&gt;
&lt;blockquote&gt;The SUBNET is different for all containers. This isolates the Accumulo containers from each other. &lt;/blockquote&gt;&lt;br /&gt;
&lt;p&gt;Look at the running containers&lt;/p&gt;&lt;br /&gt;
&lt;div style=&quot;overflow:auto;&quot;&gt;&lt;pre&gt;$ docker ps
CONTAINER ID        IMAGE                     COMMAND                CREATED             STATUS              PORTS
                    NAMES
41da6f17261f        medined/accumulo:latest   /docker/run.sh saiph   4 seconds ago       Up 2 seconds        0.0.0.0:49179-&gt;19888/tcp, 0.0.0.0:49180-&gt;2181/tcp, 0.0.0.0:49181-&gt;50070/tcp, 0.0.0.0:49182-&gt;50090/tcp, 0.0.0.0:49183-&gt;8141/tcp, 0.0.0.0:49184-&gt;10020/tcp, 0.0.0.0:49185-&gt;22/tcp, 0.0.0.0:49186-&gt;50095/tcp, 0.0.0.0:49187-&gt;8020/tcp, 0.0.0.0:49188-&gt;8025/tcp, 0.0.0.0:49189-&gt;8030/tcp, 0.0.0.0:49190-&gt;8050/tcp, 0.0.0.0:49191-&gt;8088/tcp   saiph               
23692dfe3f1e        medined/accumulo:latest   /docker/run.sh rigel   10 seconds ago      Up 9 seconds        0.0.0.0:49166-&gt;19888/tcp, 0.0.0.0:49167-&gt;2181/tcp, 0.0.0.0:49168-&gt;50070/tcp, 0.0.0.0:49169-&gt;8025/tcp, 0.0.0.0:49170-&gt;8088/tcp, 0.0.0.0:49171-&gt;10020/tcp, 0.0.0.0:49172-&gt;22/tcp, 0.0.0.0:49173-&gt;50090/tcp, 0.0.0.0:49174-&gt;50095/tcp, 0.0.0.0:49175-&gt;8020/tcp, 0.0.0.0:49176-&gt;8030/tcp, 0.0.0.0:49177-&gt;8050/tcp, 0.0.0.0:49178-&gt;8141/tcp   rigel               
63f8f1a7141f        medined/accumulo:latest   /docker/run.sh bella   21 seconds ago      Up 20 seconds       0.0.0.0:49153-&gt;19888/tcp, 0.0.0.0:49154-&gt;50070/tcp, 0.0.0.0:49155-&gt;8020/tcp, 0.0.0.0:49156-&gt;8025/tcp, 0.0.0.0:49157-&gt;8030/tcp, 0.0.0.0:49158-&gt;8050/tcp, 0.0.0.0:49159-&gt;8088/tcp, 0.0.0.0:49160-&gt;8141/tcp, 0.0.0.0:49161-&gt;10020/tcp, 0.0.0.0:49162-&gt;2181/tcp, 0.0.0.0:49163-&gt;22/tcp, 0.0.0.0:49164-&gt;50090/tcp, 0.0.0.0:49165-&gt;50095/tcp   bellatrix 
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;p&gt;You can connect to running instances using the public ports. Especially useful is the public zookeeper port. Rather than searching through the ports listed above, here is an easier way.&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;$  docker port saiph 2181
0.0.0.0:49180
$ docker port rigel 2181
0.0.0.0:49167
$ docker port bellatrix 2181
0.0.0.0:49162
&lt;/pre&gt;&lt;br /&gt;
&lt;blockquote&gt;Having &#39;0.0.0.0&#39; in the response means that any IP address can connect.&lt;/blockquote&gt;&lt;br /&gt;
&lt;p&gt;You can enter the namespace of a container (i.e., access a bash shell) this way.&lt;p&gt;&lt;br /&gt;
&lt;pre&gt;$ ./enter_image.sh rigel
-bash-4.1# hdfs dfs -ls /
Found 2 items
drwxr-xr-x   - accumulo accumulo            0 2014-07-12 09:13 /accumulo
drwxr-xr-x   - hdfs     supergroup          0 2014-07-11 21:06 /user

-bash-4.1# accumulo shell -u root -p secret
Shell - Apache Accumulo Interactive Shell
- 
- version: 1.5.1
- instance name: accumulo
- instance id: bb713243-3546-487f-b6d6-cfaa272efb30
- 
- type &#39;help&#39; for a list of available commands
- 
root@accumulo&amp;gt; tables
!METADATA
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Now let&#39;s start an edge node. For my purposes, an edge node can connect to Hadoop, Zookeeper and Accumulo without running any of those processes. All of the edge node&#39;s resources are dedicated to client work.&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;export HOSTNAME=rigeledge
export IMAGENAME=rigeledge
export BRIDGENAME=brrigel
export SUBNET=10.0.11
export NODEID=2
export HADOOPHOST=10.0.11.1
./make_container.sh $HOSTNAME $IMAGENAME $BRIDGENAME $SUBNET $NODEID $HADOOPHOST no
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;As this container is started, the &#39;no&#39; means that the supervisor configuration files will be deleted. So while supervisor will be running, it won&#39;t be managing any processes. This is not a best practice. It&#39;s just the way I chose for this prototype.&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/8553817627625133807/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/8553817627625133807' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/8553817627625133807'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/8553817627625133807'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2014/07/running-single-node-accumulo-docker.html' title='Running a Single-Node Accumulo Docker container'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-7651755936700575171</id><published>2014-07-10T08:52:00.001-04:00</published><updated>2014-07-10T08:55:11.009-04:00</updated><title type='text'>How find the published port of a Docker container in Java</title><content type='html'>After I spin up Accumulo in a Docker container, well-known ports (like 2181 for Zookeeper) are not well-known any more. The internal private port (i.e., 2181) is exposed as a different public port (i.e., 49143). Java program trying to connect to Accumulo must automatically find the public port numbers.&lt;br /&gt;
&lt;br /&gt;
The java code below finds the public port for Zookeeper for a Docker container named &quot;walt&quot;. I don&#39;t know why the slash is needed in the image name.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;int wantedPublicPort = -1;

        String wantedContainerName = &quot;/walt&quot;;
        int wantedPrivatePort = 2181;
        
        String dockerURL = &quot;http://127.0.0.1:4243&quot;;
        String dockerUser = &quot;medined&quot;;
        String dockerPassword = &quot;XXXXX&quot;;
        String dockerEmail = &quot;david.medinets@gmail.com&quot;;
        DockerClient docker = new DockerClient(dockerURL);
        docker.setCredentials(dockerUser, dockerPassword, dockerEmail);
        
        List&amp;lt;Container&amp;gt; containers = docker.listContainersCmd().exec();
        for (Container container : containers) {
            String[] names = container.getNames();
            for (String name : container.getNames()) {
                if (name.equals(wantedContainerName)) {
                    for (Container.Port port : container.getPorts()) {
                        if (port.getPrivatePort() == wantedPrivatePort) {
                            wantedPublicPort = port.getPublicPort();
                        }
                    }
                }
            }
        }

        System.out.println(&quot;Zookeeper Port: &quot; + wantedPublicPort);
&lt;/pre&gt;&lt;br /&gt;
In order to use the DockerClient object, I added the following to my pom.xml:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;lt;dependency&gt;gt;
    &lt;lt;groupId&gt;gt;com.github.docker-java&lt;lt;/groupId&gt;gt;
    &lt;lt;artifactId&gt;gt;docker-java&lt;lt;/artifactId&gt;gt;
    &lt;lt;version&gt;gt;0.9.0&lt;lt;/version&gt;gt;
  &lt;lt;/dependency&gt;gt;
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/7651755936700575171/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/7651755936700575171' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/7651755936700575171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/7651755936700575171'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2014/07/how-find-published-port-of-docker.html' title='How find the published port of a Docker container in Java'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-5916354884103280973</id><published>2014-07-10T08:34:00.005-04:00</published><updated>2014-07-10T08:34:50.520-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="docker"/><title type='text'>Finding Log Files Inside Docker Containers</title><content type='html'>As a simple lay programmer, I sometimes have trouble figuring out where log files are stored on unix systems. Sometimes logs are within application directories. Other times they are in /var/log. With Docker containers, this uncertainty is eliminated. How? By the &#39;docker diff&#39; command. I will show why. When connecting to a Docker-based system, you can see the running containers:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;$ docker ps
CONTAINER ID        IMAGE                     COMMAND             CREATED             STATUS              PORTS                                                                                                                                                                                                                                                                                                                                    NAMES
90a9f7122c02        medined/accumulo:latest   /run.sh walt        9 hours ago         Up 9 hours          0.0.0.0:49153-&gt;50070/tcp, 0.0.0.0:49154-&gt;50090/tcp, 0.0.0.0:49155-&gt;50095/tcp, 0.0.0.0:49156-&gt;8025/tcp, 0.0.0.0:49157-&gt;8030/tcp, 0.0.0.0:49158-&gt;8088/tcp, 0.0.0.0:49159-&gt;10020/tcp, 0.0.0.0:49160-&gt;19888/tcp, 0.0.0.0:49161-&gt;2181/tcp, 0.0.0.0:49162-&gt;22/tcp, 0.0.0.0:49163-&gt;8020/tcp, 0.0.0.0:49164-&gt;8050/tcp, 0.0.0.0:49165-&gt;8141/tcp   walt
&lt;/pre&gt;&lt;br /&gt;
Then you can list changed files within the container using the image id or name.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;$ docker diff walt
...
D /data1/hdfs/dn/current/BP-1274135865-172.17.0.10-1404767453280/current/finalized/blk_1073741825_1001.meta
...
A /var/log/supervisor/accumulo-gc-stderr---supervisor-5H7Rr7.log
A /var/log/supervisor/accumulo-gc-stdout---supervisor-LK8wDU.log
...
A /var/log/supervisor/namenode-stdout---supervisor-mciN4u.log
A /var/log/supervisor/secondarynamenode-stderr---supervisor-EaluLZ.log
A /var/log/supervisor/secondarynamenode-stdout---supervisor-Ap4Fri.log
C /var/log/supervisor/supervisord.log
A /var/log/supervisor/zookeeper-stderr---supervisor-CCwUGw.log
A /var/log/supervisor/zookeeper-stdout---supervisor-lDiuIF.log
C /var/run
C /var/run/sshd.pid
C /var/run/supervisord.pid
&lt;/pre&gt;&lt;br /&gt;
Armed with this list you can confidently either look in /var/lib/docker or use the nsenter command to join the namespace of the container to read interesting files.</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/5916354884103280973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/5916354884103280973' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/5916354884103280973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/5916354884103280973'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2014/07/finding-log-files-inside-docker.html' title='Finding Log Files Inside Docker Containers'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-2441487833470767016</id><published>2014-06-10T22:10:00.002-04:00</published><updated>2014-06-10T22:10:42.146-04:00</updated><title type='text'>How to Detach From a Running Docker Image</title><content type='html'>Here is another quick note. This time about Docker.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;# Run the standard Ubuntu image
docker run --name=bash -i -t ubuntu /bin/bash

# Do something
...

# Detach by typing Ctl-p and Ctl-q.

# Look at the image while on the Host system.
docker ps

# Reattach to the Ubuntu image
docker attach bash
&lt;/pre&gt;&lt;br /&gt;
While experimenting with these commands, I noticed that I needed to press &lt;ENTER&gt; to see the prompt after the ^P^Q combination and after reattaching.&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/2441487833470767016/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/2441487833470767016' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/2441487833470767016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/2441487833470767016'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2014/06/how-to-detach-from-running-docker-image.html' title='How to Detach From a Running Docker Image'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-4075567368171855702</id><published>2014-05-25T17:15:00.000-04:00</published><updated>2014-05-25T17:15:21.100-04:00</updated><title type='text'>Accumulo BatchScanner With and Without WholeRowIterator</title><content type='html'>This note shows the difference between an Accumulo query both without and with an WholeRowIterator. The code snippet below picks up the narrative after you&#39;ve initialized a Connector object. First we can see what a plain scan looks like:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;  // Read from the tEdge table of the D4M schema. 
  String tableName = &quot;tEdge&quot;;

  // Read from 5 tablets at a time.
  int numQueryThreads = 5;

  Text startRow = new Text(&quot;6000&quot;);
  Text endRow = new Text(&quot;6001&quot;);
  List&amp;lt;Range&amp;gt; range = Collections.singletonList(new Range(startRow, endRow));
 
  BatchScanner scanner = connector.createBatchScanner(tableName, new Authorizations(), numQueryThreads);
  scanner.setRanges(range);

  for (Entry&amp;lt;Key, Value&amp;gt; entry : scanner) {
    System.out.println(entry.getKey());
  }

  scanner.close();
&lt;/pre&gt;&lt;br /&gt;
The results of this query, using the data loaded by the SOICSVToAccumulo &lt;br /&gt;
class from https://github.com/medined/D4M_Schema, is shown below.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;600006a870bb4c8471a27c9bd0f3f064265d062d :a00100|0.0001 [] 1401023353637 false
600006a870bb4c8471a27c9bd0f3f064265d062d :a00200|0.0001 [] 1401023353637 false
...
600006a870bb4c8471a27c9bd0f3f064265d062d :state|UT [] 1401023353637 false
600006a870bb4c8471a27c9bd0f3f064265d062d :zipcode|84521 [] 1401023353637 false
6000338cbf2daede3efd4355165c98771b3e2b66 :a00100|29673.0000 [] 1401023273694 false
6000338cbf2daede3efd4355165c98771b3e2b66 :a00200|20421.0000 [] 1401023273694 false
...
6000338cbf2daede3efd4355165c98771b3e2b66 :state|OR [] 1401023273694 false
6000338cbf2daede3efd4355165c98771b3e2b66 :zipcode|97365 [] 1401023273694 false
&lt;/pre&gt;&lt;br /&gt;
Hopefully you can see that this output represents two &#39;standard&#39; RDMS records with &lt;br /&gt;
columns named &#39;a00100&#39;, &#39;a00200&#39;, etc. This organization becomes really obvious &lt;br /&gt;
when the WholeRowIterator is used. The scanner part of the code for this is shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;  BatchScanner scanner = connector.createBatchScanner(tableName, new Authorizations(), numQueryThreads);
  scanner.setRanges(range);

  IteratorSetting iteratorSetting = new IteratorSetting(1, WholeRowIterator.class);
  scanner.addScanIterator(iteratorSetting);

  for (Entry&amp;lt;Key, Value&amp;gt; entry : scanner) {
    System.out.println(entry.getKey());
  }

  scanner.close();
&lt;/pre&gt;&lt;br /&gt;
The output for this code is:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;600006a870bb4c8471a27c9bd0f3f064265d062d : [] 9223372036854775807 false
6000338cbf2daede3efd4355165c98771b3e2b66 : [] 9223372036854775807 false
&lt;/pre&gt;&lt;br /&gt;
What happened to all of the other information? We can find it again using the &lt;br /&gt;
WholeRowIterator.decodeRow method as shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;  for (Entry&amp;lt;Key, Value&amp;gt; entry : scanner) {
    try {
        SortedMap&amp;lt;Key, Value&amp;gt; wholeRow = WholeRowIterator.decodeRow(entry.getKey(), entry.getValue());
        System.out.println(wholeRow);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
  }
&lt;/pre&gt;&lt;br /&gt;
This code produces:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;{600006a870bb4c8471a27c9bd0f3f064265d062d :a00100|0.0001 [] 1401023353637 false=1, 600006a870bb4c8471a27c9bd0f3f064265d062d :a00200|0.0001 [] 1401023353637 false=1,
... 
600006a870bb4c8471a27c9bd0f3f064265d062d :state|UT [] 1401023353637 false=1, 
600006a870bb4c8471a27c9bd0f3f064265d062d :zipcode|84521 [] 1401023353637 false=1}
{6000338cbf2daede3efd4355165c98771b3e2b66 :a00100|29673.0000 [] 1401023273694 false=1, 6000338cbf2daede3efd4355165c98771b3e2b66 :a00200|20421.0000 [] 1401023273694 false=1,
...
6000338cbf2daede3efd4355165c98771b3e2b66 :state|OR [] 1401023273694 false=1, 
6000338cbf2daede3efd4355165c98771b3e2b66 :zipcode|97365 [] 1401023273694 false=1}
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/4075567368171855702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/4075567368171855702' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/4075567368171855702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/4075567368171855702'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2014/05/accumulo-batchscanner-with-and-without.html' title='Accumulo BatchScanner With and Without WholeRowIterator'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3207985.post-2401492234541240778</id><published>2014-05-25T08:21:00.000-04:00</published><updated>2014-05-25T08:21:26.307-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="accumulo"/><title type='text'>Data Distribution Throughout the Accumulo Cluster</title><content type='html'>&lt;br /&gt;
&lt;h1&gt;Data Distribution Throughout the Accumulo Cluster&lt;/h1&gt;&lt;br /&gt;
  This document answers these questions:&lt;br /&gt;
&lt;br /&gt;
 * What is a tablet?&lt;br /&gt;
 * What is a split point?&lt;br /&gt;
 * What is needed before data can be distributed?&lt;br /&gt;
&lt;br /&gt;
A distributed database typically is thought of as having data spread across multiple servers. But how does the data spread out? That&#39;s a question I hope to answer - at least for Accumulo.&lt;br /&gt;
&lt;br /&gt;
At a high level of abstraction, the concept is simple. If you have two servers, then 50% of the data should go to server one and 50% should go to server two. The examples below give concrete demonstrations of data distribution.&lt;br /&gt;
&lt;br /&gt;
Accumulo stores information as key-value pairs (or entries). For a visual reference, below is an empty key-value pair. &lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;-----------  ---------
| key     |  | value |
-----------  ---------
| [nothing here yet] |
-----------  ---------
&lt;/pre&gt;&lt;br /&gt;
&lt;h2&gt;Tables&lt;/h2&gt;&lt;br /&gt;
A collecton of key-values is called a table. This table is different from one&lt;br /&gt;
found in a relational database because there is no schema associated with it.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;What is a Key? See below.&lt;/blockquote&gt;&lt;br /&gt;
Note: Understanding the difference between a relational database and a &lt;br /&gt;
key-value database is beyond the scope of this discussion. If you want, you&lt;br /&gt;
can think of the &quot;key&quot; in this discussion as a primary key. But, fair warning,&lt;br /&gt;
that is a false analogy. One which you&#39;ll need to forget as you gain more&lt;br /&gt;
proficiency with key-value databases. &lt;br /&gt;
&lt;br /&gt;
A new Accumulo table has a single unit of storage called a tablet. When created, the tablet is empty. As more entries are inserted into a table, Accumulo may &lt;br /&gt;
automatically decide to split the initial tablet into two tablets. As the size &lt;br /&gt;
of the table continues to grow, the split operation is repeated. Or you can &lt;br /&gt;
specify how the splitting occurs. We&#39;ll discuss this further below.&lt;br /&gt;
&lt;br /&gt;
&gt;Tables have one or more tablets.&lt;br /&gt;
&lt;br /&gt;
Below is an empty table. For convenience, we&#39;ll use &#39;default&#39; as the name of &lt;br /&gt;
the initial tablet.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;-----------  -----------  ---------
| tablet  |  | key     |  | value |
-----------  -----------  ---------
| default |  | &lt;nothing here yet&gt; |
-----------  -----------  ---------
&lt;/pre&gt;&lt;br /&gt;
Even though the table is empty, it still has a starting key of -infinity and&lt;br /&gt;
an ending key of +infinity. All possible data occurs between the two extremes of infinity.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;  -infinity ==&gt; ALL DATA  &lt;== +infinity.
&lt;/pre&gt;

This concept of start and end keys can be shown in our tablet depiction as 
well.

&lt;pre&gt;-----------  -----------  ---------
| tablet  |  | key     |  | value |
-----------  -----------  ---------
|      start key: -infinity       |
-----------------------------------
| default |  | &lt;nothing here yet&gt; |
-----------------------------------
|        end key: +infinity       |
-----------  -----------  ---------
&lt;/pre&gt;
After inserting three records into a new table, you&#39;ll have the following 
situaton. Notice that Accumulo always stores keys in lexically sorted order.
So far, the start and end keys have not been changed.

&lt;pre&gt;-----------  -------  ---------
| tablet  |  | key |  | value |
-----------  -------  ---------
| default |  | 01  |  | X     |
| default |  | 03  |  | X     |
| default |  | 05  |  | X     |
-----------  -------  ---------
&lt;/pre&gt;
Accumulo stores all entries for a tablet on a single node in the clsuter. Since our
table has only one tablet, the information can&#39;t spread beyond one node. In 
order to distribute information, you&#39;ll need to create more than tablet for
your table.

&lt;blockquote&gt;The tablet&#39;s range is still from -infinity to +infinity. That hasn&#39;t changed yet.&lt;/blockquote&gt;
&lt;h2&gt;Splits&lt;/h2&gt;
Now we can introduce the idea of splits. When a tablet is split, one tablet
becomes two. If you want your information to be spread onto three nodes, you&#39;ll
need two splits. We&#39;ll illustrate this idea.

&lt;blockquote&gt;Split point - the place where one tablet becomes two.&lt;/blockquote&gt;
Let&#39;s add two split points to see what happens. As the split points are added, new tablets are created.

&lt;h3&gt;Adding Splits&lt;/h3&gt;
&lt;h4&gt;First Split&lt;/h4&gt;
First, adding split point 02 results in a second tablet being created. It&#39;s worth noting that the tablet names are meaningless. Accumulo assigns internal names that you rarely need to know. I picked &quot;A&quot; and &quot;B&quot; because they are easy to read.

&lt;pre&gt;-----------  -------  ---------
| tablet  |  | key |  | value |
-----------  -------  ---------
| A       |  | 01  |  | X     | range: -infinity to 02 (inclusive)
|       split point 02        |
| B       |  | 03  |  | X     | range: 02 (exclusive) to +infinity
| B       |  | 05  |  | X     | 
-----------  -------  ---------
&lt;/pre&gt;
The split point does not need to exist as an entry. This feature means that you can pre-split a table by simply giving Accumulo a list of split points.

&lt;h4&gt;Tablet Movement&lt;/h4&gt;
Before continuing, let&#39;s take a small step back to see how tablets are moved between servers. At first, the table resides on one server. This makes sense - one tablet is on one server.

&lt;pre&gt;--------------------------------
| Tablet Server                |
--------------------------------
|                              |
|  -- Tablet ----------------  |
|  | -infinity to +infinity |  |
|  --------------------------  |
|                              |
--------------------------------
&lt;/pre&gt;
Then the first split point is added. Now there are two tablets. However, they are still on a single server. And this also makes sense. Thinking about adding a split point to a table with millions of entries. While the two tablets reside on one server, adding a split is just an accounting change. 

&lt;pre&gt;-----------------------------------------------------------------------
| Tablet Server                                                       |
-----------------------------------------------------------------------
|                                                                     |
|  -- Tablet ---------------------   -- Tablet ---------------------  |
|  | -infinity to 02 (inclusive) |   | 02 (exclusive) to +infinity |  |
|  -------------------------------   -------------------------------  |
|                                                                     |
-----------------------------------------------------------------------
&lt;/pre&gt;
At some future point, Accumulo might move the second tablet to another Tablet Server. 

&lt;pre&gt;------------------------------------|  |------------------------------------
| Tablet Server                     |  | Tablet Server                     |
------------------------------------|  |------------------------------------
|                                   |  |                                   |
|  -- Tablet ---------------------  |  |  -- Tablet ---------------------  |
|  | -infinity to 02 (inclusive) |  |  |  | 02 (exclusive) to +infinity |  |
|  -------------------------------  |  |  -------------------------------  |
|                                   |  |                                   |
-------------------------------------  -------------------------------------
&lt;/pre&gt;
&lt;h4&gt;Second Split&lt;/h4&gt;
You&#39;ll wind up with three tablets when a second split point of &quot;04&quot; is added.

&lt;pre&gt;-----------  -------  ---------
| tablet  |  | key |  | value |
-----------  -------  ---------
| A       |  | 01  |  | X     | range: -infinity to 02 (inclusive)
|       split point 02        |
| B       |  | 03  |  | X     | range: 02 (exclusive) to 04 (inclusive)
|       split point 04        |
| C       |  | 05  |  | X     | range: 04 (exclusive) to +infinity
-----------  -------  ---------
&lt;/pre&gt;
The table now has three tablets. When enough tablets are created, some process 
inside Accumulo moves one or more tablets into different nodes. Once that 
happens the data is distributed.

Hopefully, you can now figure out which tablet any specific key inserts into.
For example, key &quot;00&quot; goes into tablet &quot;A&quot;.

&lt;pre&gt;-----------  -------  ---------
| tablet  |  | key |  | value |
-----------  -------  ---------
| A       |  | 00  |  | X     | range: -infinity to 02 (inclusive)
| A       |  | 01  |  | X     |
|       split point 02        |
| B       |  | 03  |  | X     | range: 02 (exclusive) to 04 (inclusive)
|       split point 04        |
| C       |  | 05  |  | X     | range: 04 (exclusive) to +infinity
-----------  -------  ---------
&lt;/pre&gt;
Internally, the first tablet (&quot;A&quot;) as a starting key of -infinity. Any entry 
with a key between -infinity and &quot;00&quot; inserts into the first key. The last 
tablet has an ending key of +infinity. Therefore any key between &quot;05&quot; and 
+infinity inserts into the last tablet.

Accumulo automatically creates split points based on some conditions. For example, if the tablet grows too large. However, that&#39;s a whole &#39;nother conversation.

&lt;h2&gt;What is a Key?&lt;/h2&gt;
Plenty of people have described Accumulo&#39;s Key layout. Here is the
bare-bones explanation:

&lt;pre&gt;-------------------------------------------------------------------
| row | column family | column qualifier | visibility | timestamp |
-------------------------------------------------------------------
&lt;/pre&gt;
These five components, combined, go into the _Key_.

&lt;h2&gt;Using Shards To Split a Row&lt;/h2&gt;
Each row resides on a single tablet which can cause a problem if any single row has a few million entries. For example, if your table held all ISBN&#39;s using this schema:

&lt;pre&gt;------------------------------------------------
| row | column family | column qualifier       |
------------------------------------------------
| book | 140122317    | Batman: Hush           |
| book | 1401216676   | Batman: A Killing Joke |
&lt;/pre&gt;
You can see how the _book_ row would have millions of entries. Potentially causing memory issues inside your TServer. Many people add a _shard_ value to the row to introduce potential split points. With shard values, the above table might look like this:

&lt;pre&gt;---------------------------------------------------
| row    | column family | column qualifier       |
---------------------------------------------------
| book_0 |  140122317    | Batman: Hush           |
| book_5 |  1401216676   | Batman: A Killing Joke |
&lt;/pre&gt;
With this style of row values, Accumulo could use book_5 as a split point so that the row are no longer unmanageable. Of course, this technique adds a bit of complexity to the query process. I&#39;ll leave the query issue to a future note.

Let&#39;s explore how shard values can be generated.

&lt;h3&gt;When an Accumulo table is created&lt;/h3&gt;
It may be tempting to have the computers flip a virtual coin to decide which
server to target for each record. In the RDBMS world that procedure works but
in key-value databases, information is stored vertically instead of 
horizontally so the coin flip analogy does not work. Let&#39;s quickly review why.

&lt;h4&gt;Coin Flip Sharding&lt;/h4&gt;
Relational databases spread information across columns (i.e., horizontally). Hopefully, there is in Id value using a synthetic key (SK) and I hope you have them in your data. If not your very first task is to get your DBA&#39;s to add  them. Seriously, synthetic keys save you a world of future trouble. Here is a simple relational record.

&lt;pre&gt;|--------------------------------------
| RELATIONAL REPRESENTATION           |
|--------------------------------------
| SK   | First Name | Last Name | Age |
|-------------------------------------|
| 1001 | John       | Kloplick  | 36  |
---------------------------------------
&lt;/pre&gt;
Key-value database spread information across several rows using the synthetic key to tie them together. In simplified form, the information is stored in three key-value combinations (or three entries).

&lt;pre&gt;|----------------------------------
| KEY VALUE REPRESENTATION        |
|----------------------------------
| ROW  | CF         | CQ          |
|---------------------------------|
| 1001 | first_name | John        |
| 1001 | last_name  | Kloplick    |
| 1001 | age        | 36          |
-----------------------------------
&lt;/pre&gt;
If the coin flip sharding strategy were used the information might look like the following. The potential split point shows that the entries can be spread across two tablets.

&lt;pre&gt;|-------------------------------------
| ROW     | CF         | CQ          |
|------------------------------------|
| 1001_01 | first_name | John        |
| 1001_01 | age        | 36          |
| 1001_02 | last_name  | Kloplick    | &lt;-- potential split point
--------------------------------------
&lt;/pre&gt;

To retrieve the information you&#39;d need to scan both servers! This coin flip sharding technique is not going to scale. Imagine information about a person spread over 40 servers. Collating that information would be prohibitively time-consuming.

&lt;h4&gt;HASH + MOD Sharding (using natural key)&lt;/h4&gt;
Of course, there is a better sharding strategy to use. You can base the strategy on one of the fields. Get its hash code and then mod it by the number of partitions. Ultimately, this strategy will fail but let&#39;s go through the process to see why. Skip to the next section if you already see the problem.

&quot;John&quot;.hashCode() is 2314539. Then we can mod that by the number of partitions (or servers) in our cluster. Let&#39;s pretend we have 5 servers instead of the two we used earlier for variety. Our key-value entries now look thusly:

&lt;blockquote&gt;2,314,539 modulo 5 = 4&lt;/blockquote&gt;
&lt;pre&gt;|-------------------------------------
| ROW     | CF         | CQ          |
|------------------------------------|
| John_04 | first_name | John        |
| John_04 | age        | 36          |
| John_04 | last_name  | Kloplick    |
--------------------------------------
&lt;/pre&gt;
&lt;blockquote&gt;Note that the shard value is _not_ related to any specific node. It&#39;s just a potential split point for Accumulo.&lt;/blockquote&gt;
It&#39;s time to look at a specific use case to see if this sharding strategy is sound. What if we need to add a set of friends for John? It&#39;s unlikely that the information about John&#39;s friends have his first name. But very likely for his synthetic key of 1001 to be there. We can now see choosing the first_name field as the base of the sharding strategy was unwise.

&lt;h4&gt;HASH + MOD Sharding (using synthetic key)&lt;/h4&gt;
Using the synthetic key as the basis for the hash provides more continuity between updates. And regardless of how information changes, we&#39;ll always put the information in the same shard. 

&quot;1001&quot;.hashCode() is 1507424. If we use the first prime number less than 1,000 then the shard calculation generates a shard value of 957.

So the key-value information is now:

&lt;blockquote&gt;1,507,424 modulo 997 = 957&lt;/blockquote&gt;
&lt;pre&gt;|--------------------------------------
| ROW      | CF         | CQ          |
|-------------------------------------|
| 1001_957 | first_name | John        |
| 1001_957 | age        | 36          |
| 1001_957 | last_name  | Kloplick    |
--------------------------------------
&lt;/pre&gt;
Using this technique makes it simple to add a height field. 

&lt;pre&gt;|--------------------------------------------
| ROW      | CF               | CQ          |
|-------------------------------------------|
| 1001_957 | height_in_inches | 68          |
---------------------------------------------
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://affy.blogspot.com/feeds/2401492234541240778/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/3207985/2401492234541240778' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/2401492234541240778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3207985/posts/default/2401492234541240778'/><link rel='alternate' type='text/html' href='http://affy.blogspot.com/2014/05/data-distribution-throughout-accumulo.html' title='Data Distribution Throughout the Accumulo Cluster'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/16707286767120221163</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>