{"id":1352,"date":"2019-02-19T23:30:10","date_gmt":"2019-02-19T23:30:10","guid":{"rendered":"https:\/\/www.appservgrid.com\/paw93\/?p=1352"},"modified":"2019-03-07T20:15:31","modified_gmt":"2019-03-07T20:15:31","slug":"riak-cluster-deployment-riak-docker","status":"publish","type":"post","link":"https:\/\/www.appservgrid.com\/paw93\/index.php\/2019\/02\/19\/riak-cluster-deployment-riak-docker\/","title":{"rendered":"Riak Cluster Deployment | Riak Docker"},"content":{"rendered":"<p>Recently I have been playing around with Riak and I wanted to get it<br \/>\nrunning with Docker, using RancherOS and Rancher. If you\u2019re not<br \/>\nfamiliar with Riak, it is a distributed key\/value store which is<br \/>\ndesigned for high availability, fault tolerance, simplicity, and<br \/>\nnear-linear scalability. Riak is written in Erlang programming language<br \/>\nand it runs on an Erlang virtual machine. Riak provides availability<br \/>\nthrough replication and faster operations and more capacity through<br \/>\npartitions, using the ring design to its cluster, hashed keys<br \/>\nare partitioned by default to 64 partitions (or vnodes), each vnode will<br \/>\nbe assigned to one physical node as following: <a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/Riak_ring.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/Riak_ring.png\" alt=\"Riak_ring\" \/><\/a><br \/>\nFrom <a href=\"http:\/\/basho.com\/assets\/RelationaltoRiak.pdf\">Relational to Riak<br \/>\nWhitepaper<\/a><br \/>\nFor example, if the cluster consists of 4 nodes: Node1, Node2, Node3,<br \/>\nand Node4, we will count around the nodes assigning each vnode to a<br \/>\nphysical node until the all vnodes are accounted for, so in the previous<br \/>\nfigure, Riak used 32 partition with 4 node cluster so we get:<\/p>\n<p>Node0 : [1, 5, 9, 13, 17, 21, 25, 29]<br \/>\nNode1 : [2, 6, 10, 14, 18, 22, 26, 30]<br \/>\nNode3 : [3, 7, 11, 15, 19, 23, 27, 31]<br \/>\nNode4 : [4, 8, 12, 16, 20, 24, 28, 32]<\/p>\n<p>So how about replication? Every time a write process happens Raik will<br \/>\nreplicate the value to the next N vnodes, where N is the value of<br \/>\nthe n_val setting in Riak cluster. By default, N is 3. To explain<br \/>\nthis, assume we will use the default n_val value and we will use<br \/>\nthe previous cluster setup with 4 nodes and 32 partitions, now lets<br \/>\nassume we will write a key\/value to partition (vnode) 2 which is<br \/>\nassigned to the second node then the value will be replicated to vnode 3<br \/>\nand vnode 4 which are assigned to the 3rd and 4th nodes respectively.<br \/>\nFor more information about Riak cluster, visit the <a href=\"http:\/\/docs.basho.com\/riak\/latest\/\">official riak<br \/>\ndocumentation<\/a>. In this post, I am<br \/>\ngoing to deploy Riak cluster using Docker on RancherOS, the setup will<br \/>\ninclude:<\/p>\n<ul>\n<li>Five Docker containers as Riak nodes.<\/li>\n<li>Each Container will be on separate EC2 Instance.<\/li>\n<li>RancherOS will be installed on each EC2 instance.<\/li>\n<li>The whole setup will be managed using Rancher platform.<\/li>\n<\/ul>\n<p>##<\/p>\n<h2>The Riak Docker Image<\/h2>\n<p>Before launching your EC2 instances and the Rancher platform, you should<br \/>\ncreate the Riak Docker image that will run each instance. I used the<br \/>\nimplementation of Riak Docker image of<br \/>\n<a href=\"https:\/\/github.com\/hectcastro\/docker-riak\">hectcastro<\/a>, although I<br \/>\nadded and removed some parts to become suitable to run on RancherOS.<br \/>\nFirst the Dockerfile:<\/p>\n<p>FROM phusion\/baseimage:latest<br \/>\nMAINTAINER Hussein Galal hussein.galal.ahmed.11@gmail.com<\/p>\n<p>RUN sed -i.bak &#8216;s\/main$\/main universe\/&#8217; \/etc\/apt\/sources.list<br \/>\nRUN apt-get update -qq &amp;&amp; apt-get install -y software-properties-common &amp;&amp;<br \/>\napt-add-repository ppa:webupd8team\/java -y &amp;&amp; apt-get update -qq &amp;&amp;<br \/>\necho oracle-java7-installer shared\/accepted-oracle-license-v1-1 select true | \/usr\/bin\/debconf-set-selections &amp;&amp;<br \/>\napt-get install -y oracle-java7-installer<\/p>\n<p># Install Riak<br \/>\nRUN curl https:\/\/packagecloud.io\/install\/repositories\/basho\/riak\/script.deb | bash<br \/>\nRUN apt-get install -y riak<\/p>\n<p># Setup the Riak service<br \/>\nRUN mkdir -p \/etc\/service\/riak<br \/>\nADD scripts\/riak.sh \/etc\/service\/riak\/run<\/p>\n<p>RUN sed -i.bak &#8216;s\/listener.http.internal = 127.0.0.1\/listener.http.internal = 0.0.0.0\/&#8217; \/etc\/riak\/riak.conf &amp;&amp; sed -i.bak &#8216;s\/listener.protobuf.internal = 127.0.0.1\/listener.protobuf.internal = 0.0.0.0\/&#8217; \/etc\/riak\/riak.conf &amp;&amp;<br \/>\necho &#8220;anti_entropy.concurrency_limit = 1&#8221; &gt;&gt; \/etc\/riak\/riak.conf &amp;&amp;<br \/>\necho &#8220;javascript.map_pool_size = 0&#8221; &gt;&gt; \/etc\/riak\/riak.conf &amp;&amp;<br \/>\necho &#8220;javascript.reduce_pool_size = 0&#8221; &gt;&gt; \/etc\/riak\/riak.conf &amp;&amp;<br \/>\necho &#8220;javascript.hook_pool_size = 0&#8221; &gt;&gt; \/etc\/riak\/riak.conf<\/p>\n<p># Add Automatic cluster support<br \/>\nADD scripts\/run.sh \/etc\/my_init.d\/99_automatic_cluster.sh<br \/>\nRUN chmod u+x \/etc\/my_init.d\/99_automatic_cluster.sh<br \/>\nRUN chmod u+x \/etc\/service\/riak\/run<\/p>\n<p># Enable insecure SSH key<br \/>\nRUN \/usr\/sbin\/enable_insecure_key.sh<\/p>\n<p>EXPOSE 22 8098 8087<br \/>\nCMD [&#8220;\/sbin\/my_init&#8221;]<\/p>\n<p>A couple of notes on the previous Dockerfile. The phusion\/baseimage is<br \/>\nused as the Docker base image, 2 important scripts were added to the<br \/>\nimage (riak.sh, automatic_cluster.sh) which I will explain in a second,<br \/>\nthe ports 8098 and 8087 are used for HTTP and Protocol Buffers and<br \/>\nfinally ssh support through insecure key was added. The purpose of the<br \/>\nriak.sh script is to start the Riak service and ensure that the node<br \/>\nname is set correctly, while the automatic_cluster.sh script is used to<br \/>\njoin the node to the cluster only if the RIAK_JOINING_IP is set<br \/>\nduring the starting of the contianer. riak.sh<\/p>\n<p>#! \/bin\/sh<\/p>\n<p># Ensure correct ownership and permissions on volumes<br \/>\nchown riak:riak \/var\/lib\/riak \/var\/log\/riak<br \/>\nchmod 755 \/var\/lib\/riak \/var\/log\/riak<\/p>\n<p># Open file descriptor limit<br \/>\nulimit -n 4096<br \/>\nIP_ADDRESS=$(ip -o -4 addr list eth0 | awk &#8221; | cut -d\/ -f1 | sed -n 2p)<\/p>\n<p># Ensure the Erlang node name is set correctly<br \/>\nsed -i.bak &#8220;s\/riak@127.0.0.1\/riak@$\/&#8221; \/etc\/riak\/riak.conf<br \/>\nrm -rf \/var\/lib\/riak\/ring\/*<\/p>\n<p># Start Riak<br \/>\nexec \/sbin\/setuser riak &#8220;$(ls -d \/usr\/lib\/riak\/erts*)\/bin\/run_erl&#8221; &#8220;\/tmp\/riak&#8221;<br \/>\n&#8220;\/var\/log\/riak&#8221; &#8220;exec \/usr\/sbin\/riak console&#8221;<\/p>\n<p>automatic_cluster.sh<\/p>\n<p>#!\/bin\/sh<br \/>\nsleep 10<br \/>\nif env | grep -q &#8220;RIAK_JOINING_IP&#8221;; then<br \/>\n# Join node to the cluster<br \/>\n(sleep 5;riak-admin cluster join &#8220;riak@$&#8221; &amp;&amp; echo -e &#8220;Node Joined The Cluster&#8221;) &amp;<\/p>\n<p># Are we the last node to join?<br \/>\n(sleep 8; if riak-admin member-status | egrep &#8220;joining|valid&#8221; | wc -l | grep -q &#8220;$&#8221;; then<br \/>\nriak-admin cluster plan &amp;&amp; riak-admin cluster commit &amp;&amp; echo -e &#8220;nCommiting The Changes&#8230;&#8221;<br \/>\nfi) &amp;<br \/>\nfi<\/p>\n<p>Also note that RIAK_CLUSTER_SIZE is used to specify the size of the<br \/>\ncluster used in this setup. We don\u2019t need more than that to start the<br \/>\ncluster, now build the image and push it to Docker Hub to be used later.<\/p>\n<p># docker build -t husseingalal\/riak2 .<br \/>\n# docker push husseingalal\/riak2<\/p>\n<h2>Launch Rancher Platform<\/h2>\n<p>The Rancher Management platform will be used manage the Docker<br \/>\ncontainers on RancherOS instances. First you need to run Rancher<br \/>\nplatform on a machine using the following command:<\/p>\n<p># docker run -d -p 8080:8080 rancher\/server<\/p>\n<p><a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/Rancher_platform1.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/Rancher_platform1.png\" alt=\"Rancher_platform1\" \/><\/a><\/p>\n<h2>Create RancherOS EC2 Instances<\/h2>\n<p>RancherOS is available as an Amazon Web Services AMI, and can be easily<br \/>\nrun on EC2, the next step is to create 5 EC2 instances to setup the<br \/>\ncluster:<br \/>\n<a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/riak1.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/riak1.png\" alt=\"riak1\" \/><\/a><br \/>\nYou will get something like that after creating five instances with<br \/>\nAmazon AWS:<br \/>\n<a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/riak3.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/riak3.png\" alt=\"riak3\" \/><\/a><br \/>\nAfter creating the five instances, its time to register each instance<br \/>\nwith Rancher by running the following command on each server:<\/p>\n<p>[rancher@rancher ~]$ sudo docker run &#8211;rm -it &#8211;privileged -v \/var\/run\/docker.sock:\/var\/run\/docker.sock rancher\/agent http:\/\/&lt;ip-address&gt;:8080\/v1\/scripts\/4E1D4A26B07A1539CD33:1426626000000:jZskPi71YEPSJo1uMISMEOpbUo<\/p>\n<p>After running the previous command on each server you will see that the<br \/>\nservers have been registered with Rancher:<br \/>\n<a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/riak4.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/riak4.png\" alt=\"riak4\" \/><\/a><\/p>\n<h2>Running The Riak cluster<\/h2>\n<p>The RIAK_CLUSTER_SIZE will provide the number of instances needed<br \/>\nto be added to the cluster before committing the changes, its<br \/>\nrecommended to add 5 Riak nodes to the cluster of a production<br \/>\nenvironment, although you can set the RIAK_CLUSTER_SIZE to more or<br \/>\nfewer as needed. **** **** To create a Docker container using the<br \/>\nRancher platform, on any instance click on \u201cAdd Container\u201d:<br \/>\n<a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/riak_6.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/riak_6.png\" alt=\"riak_6\" \/><\/a><br \/>\nOn the first node you just need to specify the name of the container<br \/>\nand select the Riak image, but for other Riak nodes you need to specify<br \/>\ntwo more environment variables which will help the node to connect to<br \/>\nthe cluster the RIAK_JOINING_IP which tells the Riak node to<br \/>\nconnect to a node in the cluster and RIAK_CLUSTER_SIZE which used<br \/>\nto specify the number of nodes joining the cluster:<br \/>\n<a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/riakn_6.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/riakn_6.png\" alt=\"riakn_6\" \/><\/a><\/p>\n<h2>Testing The Riak Cluster<\/h2>\n<p>From Rancher we can view the logs of the running containers, similar to<br \/>\nusing docker logs -f container-name. This allows us to see the logs of<br \/>\nthe Riak containers and ensure that everything is running as planned:<br \/>\n<a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/Screenshot-from-2015-03-17-234126.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/Screenshot-from-2015-03-17-234126.png\" alt=\"Screenshot from 2015-03-17\n23:41:26\" \/><\/a><br \/>\n<a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/Screenshot-from-2015-03-28-012257.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/Screenshot-from-2015-03-28-012257.png\" alt=\"Screenshot from 2015-03-28\n01:22:57\" \/><\/a><br \/>\nAt the last node you will see something different. Since the number of<br \/>\nthe node that joined the cluster matches the value of the environment<br \/>\nvariable RIAK_CLUSTER_SIZE, so the changes will be committed and the<br \/>\ncluster will be up and running: <a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/Screenshot-from-2015-03-28-002558.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/Screenshot-from-2015-03-28-002558.png\" alt=\"Screenshot from 2015-03-28\n00:25:58\" \/><\/a><br \/>\nTo see that the nodes are connected to the cluster, you can write<br \/>\nthe following command inside the shell of any of the Riak containers:<\/p>\n<p># riak-admin member-status<\/p>\n<p>And you will get the following output: <a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/Screenshot-from-2015-03-28-014031.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/Screenshot-from-2015-03-28-014031.png\" alt=\"Screenshot from 2015-03-28\n01:40:31\" \/><\/a><br \/>\nThis indicates that each node is a valid member of the cluster and<br \/>\nacquire a roughly equal percentage of the ring. Now to test the cluster<br \/>\nfrom outside the environment, you should map the ports of the Docker<br \/>\ncontainers to the host\u2019s ports, this can be achieved dynamically using<br \/>\nRancher platform:<br \/>\n<a href=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/19.png\"><img decoding=\"async\" src=\"http:\/\/cdn.rancher.com\/wp-content\/uploads\/2015\/03\/03053038\/19.png\" alt=\"19\" \/><\/a><br \/>\nI already created and activated a bucket-type called \u201ccluster,\u201d which I<br \/>\nused to test via the Riak HTTP API. You can see from below the<br \/>\nenvironment is up and running now.<\/p>\n<p>$ export RIAK=http:\/\/52.0.119.255:8098<br \/>\n$ curl -XPUT &#8220;$RIAK\/types\/cluster\/buckets\/rancher\/keys\/hello&#8221;<br \/>\n-H &#8220;Content-Type:text\/plain&#8221;<br \/>\n-d &#8220;World.. Riak&#8221;<\/p>\n<p>$ curl -i &#8220;$RIAK\/types\/cluster\/buckets\/rancher\/keys\/hello&#8221;<br \/>\nHTTP\/1.1 200 OK<br \/>\nX-Riak-Vclock: a85hYGBgzGDKBVIcqZfePk3k6vPOYEpkzGNlYAroOseXBQA=<br \/>\nVary: Accept-Encoding<br \/>\nServer: MochiWeb\/1.1 WebMachine\/1.10.5 (jokes are better explained)<br \/>\nurl: &lt;\/buckets\/rancher&gt;; rel=&#8221;up&#8221;<br \/>\nLast-Modified: Fri, 27 Mar 2015 22:04:50 GMT<br \/>\nETag: &#8220;4flAtEZ59hdYsKhSGVhKpZ&#8221;<br \/>\nDate: Fri, 27 Mar 2015 22:11:23 GMT<br \/>\nContent-Type: text\/plain<br \/>\nContent-Length: 5<\/p>\n<p>World.. Riak<\/p>\n<h2>Conclusion<\/h2>\n<p>Riak cluster provides a distributed, high available, and simple<br \/>\nkey-value store. Building the Riak cluster using RancherOS and Rancher<br \/>\nplatform provide docker management and networking capabilities, making<br \/>\ninstallation quick and making it simple to upgrade and scale the<br \/>\nenvironment in the future. You can download Riak<br \/>\n<a href=\"http:\/\/docs.basho.com\/riak\/2.0.2\/downloads\/\">here<\/a>. To download Rancher<br \/>\nor RancherOS please visit our <a href=\"https:\/\/github.com\/rancherio\/\">GitHub<br \/>\nsite<\/a>. You can find a detailed <a href=\"https:\/\/github.com\/rancherio\/os\/blob\/master\/GETTING_STARTED.md\">getting<br \/>\nstarted<br \/>\nguide<\/a> for<br \/>\nRancherOS on GitHub as well. If you would like to learn more, please<br \/>\njoin our next online meetup to meet the team and learn about the latest<br \/>\nwith Rancher and RancherOS. <em>Hussein Galal is<br \/>\na Linux System Administrator, with experience in Linux, Unix,<br \/>\nNetworking, and open source technologies like Nginx, Apache, PHP-FPM,<br \/>\nPassenger, MySQL, LXC, and Docker. You can follow Hussein<br \/>\non Twitter <a href=\"http:\/\/twitter.com\/galal_hussein\">@galal_hussein<\/a>.<\/em><\/p>\n<p><a href=\"https:\/\/rancher.com\/deploying-a-riak-cluster-using-rancher-and-rancheros-on-aws\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently I have been playing around with Riak and I wanted to get it running with Docker, using RancherOS and Rancher. If you\u2019re not familiar with Riak, it is a distributed key\/value store which is designed for high availability, fault tolerance, simplicity, and near-linear scalability. Riak is written in Erlang programming language and it runs &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.appservgrid.com\/paw93\/index.php\/2019\/02\/19\/riak-cluster-deployment-riak-docker\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Riak Cluster Deployment | Riak Docker&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-1352","post","type-post","status-publish","format-standard","hentry","category-kubernetes"],"_links":{"self":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/1352","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/comments?post=1352"}],"version-history":[{"count":1,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/1352\/revisions"}],"predecessor-version":[{"id":1427,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/1352\/revisions\/1427"}],"wp:attachment":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/media?parent=1352"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/categories?post=1352"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/tags?post=1352"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}