tag:blogger.com,1999:blog-9649732962899998212024-02-19T07:23:30.892+05:30tech cottagerbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.comBlogger28125tag:blogger.com,1999:blog-964973296289999821.post-52592139325206652812022-04-17T04:39:00.005+05:302022-05-23T12:20:56.443+05:30A solana on-chain contract and off-chain client in rust<p></p><p>https://github.com/ratulb/solana_program_and_rust_client</p><p><br /></p>rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-14355318829670773362021-07-01T06:48:00.001+05:302021-07-01T06:48:00.152+05:30Migrate kubernetes embedded etcd to external etcd - easy back and forth switch<p><span style="font-family: Ubuntu; font-size: medium;"><b>Gist: </b></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>Create a multi-master kubernetes cluster from the comfort of a shell menu without tweaking a thing. Front the apiservers with load balancer of your choice - namely<span style="color: #2b00fe;"> <span style="color: #073763;">h</span></span></b></span><span style="font-family: Ubuntu; font-size: medium;"><b><span style="font-family: Ubuntu; font-size: medium;"><span style="color: #0b5394;"><span style="color: #073763;"><a href="http://www.haproxy.org/" target="_blank">aproxy</a>/<a href="https://www.nginx.com/" target="_blank">nginx</a>/<a href="https://www.envoyproxy.io/" target="_blank">envoy</a></span>.</span> Do h<span style="color: black;">assle free back and forth switch between embedded etcd and external etcd.</span><br /></span></b></span></p><p><span style="font-family: Ubuntu; font-size: medium;">In this post, we discuss <b style="text-align: justify;"><a href="https://github.com/ratulb/kube-etcd-switch" target="_blank">kube-etcd-switch</a></b> - which is not quite a tool rather a <b>bunch of scripts behind a shell menu that help us to do all the above in a hassle free manner.</b></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><span style="text-align: justify;">Curious? Read on then. But you have been </span><b style="text-align: justify;">forewarned</b><span style="text-align: justify;"> - it might not be your cup of tea.</span></span></p><p style="text-align: justify;"><span style="font-size: medium;"><span style="font-family: Ubuntu;"><b>Kubernetes treats pods as cattle - they are discarded if not healthy</b>. No effort is wasted on reviving unhealthy pods - instead new ones are created to replace the bad ones.</span><span style="font-family: Ubuntu;"> </span></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Kubernetes is conjoined with etcd by an umbilical chord. Etcd stores kubernetes schema and state. Kubernetes is useless without etcd(as things stand currently). At times - it can be quite a challenge to bring up a kubernetes cluster if etcd starts throwing its tantrums. For example - you want to remove an etcd node because it has gone bad - but etcd cluster would not let you do that because the node is not up yet. Quite a vexatious situation to be in.</span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">So, what do we do in such a chicken and egg situation? Well, follow the same kubernetes philosophy - we discard the etcd cluster ( Not the cluster itself - we have compunction - mechanical sympathy. Instead we scrap etcd ) - create a new one to replace the faulty one. We treat everything as cattle - no pets. If a piece of software is not crunching data and providing information - it is not serving its cause - it's redundant. Below we provide a glimpse of how we do that. <b>That is, of course, as long as we have data at our hands, a backup or a snapshot - we care for data - it's valuable - amorphous gold.</b></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><span>First up, we need a kubernetes cluster -</span><b> kube-etcd-switch</b><span> can interface with any existing kubernetes cluster - but here we show how to setup a k8s cluster as well because we don't have one at hand currently and we need a cluster for the show to go on.</span></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>Requirements: </b>A set of machines (<b>Debian buster/ubuntu16/18/20 flavor</b>) with root <b>SSH access</b>.</span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Here, we use four machines - one for load balancer(lb), two for kubernetes master nodes(m-1,m-2), one worker(w-1) node.</span></p><p style="text-align: justify;"><b><span style="font-family: Ubuntu; font-size: medium;">We run everything from the load balancer node.</span></b></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">1) Clone the following GitHub repository - go inside and launch the 'cluster.sh' script.</span></p><p style="text-align: justify;"><span style="background-color: #0b5394; color: white; font-family: Ubuntu; font-size: medium;"><span style="caret-color: rgba(0, 0, 0, 0); font-variant-ligatures: none; white-space: pre;">git clone </span><a href="https://github.com/ratulb/kube-etcd-switch" style="caret-color: rgba(0, 0, 0, 0); font-variant-ligatures: none; text-decoration-line: none; white-space: pre;" target="_blank" title="https://github.com/ratulb/kube-etcd-switch"><span style="color: white;">https://github.com/ratulb/kube-etcd-switch</span></a></span></p><p style="text-align: justify;"><span style="background-color: #0b5394; caret-color: rgba(0, 0, 0, 0); color: white; font-family: Ubuntu; font-size: medium; font-variant-ligatures: none; white-space: pre;">cd kube-etcd-switch/</span></p><p style="text-align: justify;"><span style="background-color: #0b5394; caret-color: rgba(0, 0, 0, 0); color: white; font-family: Ubuntu; font-size: medium; font-variant-ligatures: none; white-space: pre;">./cluster.sh </span></p><p><span style="font-family: Ubuntu; font-size: medium;">We would be presented with menu which has quite a few choices as shown</span></p><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq2nI6_l5JTQZPRRdZOd92Dxmpbpq-DMj-2Yger0ckjZV-ary1pGSrSMagO6e1T286SfmVpRqW9FaO9fa_nZwBhfEAPXyCx4OvsltjNdBoSVLvj2xjoo2O-eQ7SyT4vNYzNbi_Jm2cMP4/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="218" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq2nI6_l5JTQZPRRdZOd92Dxmpbpq-DMj-2Yger0ckjZV-ary1pGSrSMagO6e1T286SfmVpRqW9FaO9fa_nZwBhfEAPXyCx4OvsltjNdBoSVLvj2xjoo2O-eQ7SyT4vNYzNbi_Jm2cMP4/s16000/image.png" /></span></a></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div class="separator" style="clear: both; text-align: left;"><span style="font-family: Ubuntu; font-size: medium; text-align: justify;">We need a cluster - hence we make the appropriate selection and get on with the cluster setup process driven by the menu choices.</span></div><p style="text-align: left;"><span style="font-family: Ubuntu; font-size: medium;">2) We enter the cluster details such as<b> load balancer, master nodes and worker node</b>. Following few snaps capture the steps.</span></p><p></p><div class="separator" style="clear: both; text-align: left;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIh86hY5RQtTm5Z7LwUbA17Da7t7aJ2ha2zX6eO0CUo30xR8vSH7XJUGtfuwmEZeEMygP6bpb0oizUwMUgAkEfQxk6H30edmSsoME0AoA-ABwhJGEVwv5vG1hLn-rk18kbXdllzOb2njs/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="154" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIh86hY5RQtTm5Z7LwUbA17Da7t7aJ2ha2zX6eO0CUo30xR8vSH7XJUGtfuwmEZeEMygP6bpb0oizUwMUgAkEfQxk6H30edmSsoME0AoA-ABwhJGEVwv5vG1hLn-rk18kbXdllzOb2njs/s16000/image.png" /></span></a></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><p><span style="font-size: medium;"><span style="font-family: Ubuntu;">3) </span><span style="font-family: Ubuntu;"> Load balancer details</span></span></p><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFnppRJTBYp0vNWgIs_I_XyMYEAZlj-x3b6NFdg3YLmXdNPlUYrzjgwL6pMo3YbiX7Xo1fAqy1f2-adzyhdUZ8Gyqgk82DGau7KBcx6YrpaqNJ1vkiosOJ6hlOuwLKnCGgud6rzYdxKig/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="445" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFnppRJTBYp0vNWgIs_I_XyMYEAZlj-x3b6NFdg3YLmXdNPlUYrzjgwL6pMo3YbiX7Xo1fAqy1f2-adzyhdUZ8Gyqgk82DGau7KBcx6YrpaqNJ1vkiosOJ6hlOuwLKnCGgud6rzYdxKig/s16000/image.png" /></span></a></p><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: left;"><div><br /></div><div><span style="text-align: left;"><span style="font-family: Ubuntu; font-size: medium;">4) Next we enter master and worker details:</span></span></div></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><span style="clear: left; float: left; font-family: Ubuntu; font-size: medium; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="304" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQA1jFMkX71BH384yNCvbSR2Z2HdzeuFTF1dv6SSbk7r44O8H3sJ4eje7K5jh7Z2v1b5ohy8xcHP8V-UC1MiOmj4ImiZHwzMN2bHkt_d26HyTXAPdQCHip3FbmdA1I7Aik-iF9I-lAgkQ/s16000/image.png" /></span></div></div></div><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large; text-align: justify;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large; text-align: justify;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large; text-align: justify;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large; text-align: justify;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large; text-align: justify;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large; text-align: justify;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large; text-align: justify;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium; text-align: justify;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium; text-align: justify;">5) Next we select option to launch the cluster creation process. This would provide us with <b>running kubernetes cluster in a matter of minutes with weave CNI plugin and demo nginx pod deployed.</b></span></p><p style="text-align: justify;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR3yjo9B4LTLF2sQP8vYdd2IsCyMXSc9O2UHB76nBcUnQ6gkoejjklPPf60EfWRvcIZZ2wxLY-fxzzWgS_wJXEC2AJeZyYBQbiLvsNUe9ER0wnAczLaULAnQTmoUWMUM4qvKXUbuJ-gew/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="377" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR3yjo9B4LTLF2sQP8vYdd2IsCyMXSc9O2UHB76nBcUnQ6gkoejjklPPf60EfWRvcIZZ2wxLY-fxzzWgS_wJXEC2AJeZyYBQbiLvsNUe9ER0wnAczLaULAnQTmoUWMUM4qvKXUbuJ-gew/s16000/image.png" /></span></a></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><br /><div style="text-align: left;"><span style="text-align: justify;">6) Following snap shows the end result of cluster creation:</span></div><div style="text-align: left;"><span style="text-align: justify;"><br /></span></div></span></div><div class="separator" style="clear: both; text-align: center;"><span style="clear: left; float: left; font-family: Ubuntu; font-size: medium; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="140" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhp0QiZN0JThq4zzdwBDiUriHwKenoJ2RYBfziM6tZfLpn7K4I0zf-9ibv0_goiQYbndG9buZkWmVPPi0SStLiVjufhXcldGILE_AVO643exDxoa7jDoLaOb0thmkWuicC-4xU5_k9drHs/s16000/image.png" /></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><br /><div style="text-align: left;"><span style="font-family: Ubuntu; text-align: justify;">7) Next is the initialization step. For </span><b style="text-align: justify;">k8s-etcd-switch</b><span style="font-family: Ubuntu; text-align: justify;"> to work with any cluster it needs to be initialized first. We need to provide the master IP (or name) of any one of the masters for this. <b>k8s-etcd-switch will query the cluster - gather information such a master members, copy ETCD CA cert and setup kubectl, </b></span><b><a href="https://github.com/cloudflare" style="text-align: justify;" target="_blank">cloudflare CFSSL</a></b><span style="font-family: Ubuntu; text-align: justify;"><b> and other required binaries to perform its duties</b>. The initialization process can be repeated - it is idempotent. <b>The initialization process is minimum once per servers' certificate rotation.</b></span></div></span></div><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Following snaps show the initialization choices.</span></p><div style="text-align: justify;"><img data-original-height="307" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqCVl4q3jt4zUTYLiyr61i2-YTSf51LiwyB90GLh0RfkUsJozYncsi4ZPBHX-VwjEBt9-YvpDpNClAUYNIcTk2kv_hTkHqPzDfqbUkHtAj08O-VeuxvVpuoz9iqdfwCdvojpE_MKvsXLs/s16000/image.png" style="font-family: Ubuntu; font-size: large; text-align: center;" /></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu;"><br /><div style="text-align: left;"><span style="text-align: justify;">Note: Above we see that master endpoints are already detected - that is because k8s setup has already configured kube config. It will not be so for a pre-existing cluster. Initialization would be needed in either case.</span></div></span></div><p><span style="font-size: medium;"><span style="font-family: Ubuntu; text-align: justify;">8) Post initialization k8s-etcd-switch show cluster's system pod states. Now it </span><span style="font-family: Ubuntu; text-align: justify;">can talk to the kubernetes cluster.</span></span></p><p style="text-align: justify;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQ9U2Rt3R2vMKzIcGHU-AdHudjjCklvvSe0fMGgHGGOz-wt9tE1N824NEHFPyfFo9tDlN8Uf1TazcArJX1GJXC0wSIhI8LIt8EamK75vQ2jKXCYEm79QxVNzGDSMDopHpcCqgzZJq21iI/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="439" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQ9U2Rt3R2vMKzIcGHU-AdHudjjCklvvSe0fMGgHGGOz-wt9tE1N824NEHFPyfFo9tDlN8Uf1TazcArJX1GJXC0wSIhI8LIt8EamK75vQ2jKXCYEm79QxVNzGDSMDopHpcCqgzZJq21iI/s16000/image.png" /></span></a></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><br /><div style="text-align: justify;"><span style="text-align: left;">9) <b>At this point - our cluster is pristine </b>( it would not be so for an existing cluster ). Lets go ahead and <b>deploy a demo nginx pod in the default namespace</b>. We select console and deploy the pod.</span></div></span></div><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvqKaP1Sbdq37dimq30ii28JxI6mob7Kp0TRU8A8AzMOv4R655qpJGOh01oEunFkEg9a1iLdukTQRLPnFTS_gQtX4z0N0KWMcuuIEyJxMWY6iGRNeNx0CGIDnT8YhUrKDgoro6Bgv8vPk/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="377" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvqKaP1Sbdq37dimq30ii28JxI6mob7Kp0TRU8A8AzMOv4R655qpJGOh01oEunFkEg9a1iLdukTQRLPnFTS_gQtX4z0N0KWMcuuIEyJxMWY6iGRNeNx0CGIDnT8YhUrKDgoro6Bgv8vPk/s16000/image.png" /></span></a></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><br /><div style="text-align: left;"><span style="text-align: justify;">10) We see that our <b>nginx pod is running along with demo pods</b> that were deployed during the cluster creation process. </span></div></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVYD91gBSbyC49LdojFs5VyoyOoKb_NyGY8KlsAPv-UkIHLKMhw-pZncdeLAGd0YEj1BGQoix-JAmdopSZYzys1qBKp2rnYbWmIjtlnsoh6SLcdz7RLu2Kw7clroEtr9GpOpWPodLfobg/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="168" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVYD91gBSbyC49LdojFs5VyoyOoKb_NyGY8KlsAPv-UkIHLKMhw-pZncdeLAGd0YEj1BGQoix-JAmdopSZYzys1qBKp2rnYbWmIjtlnsoh6SLcdz7RLu2Kw7clroEtr9GpOpWPodLfobg/s16000/image.png" /></span></a></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu; text-align: justify;">1</span><span style="font-family: Ubuntu; text-align: justify;">1) We want to survive cluster failure whether kubernetes or etcd. Kubernetes is done deal - we have shown it above. Etcd would be without it's salt - if it did not have data. But now it has data - whole kubernetes cluster's schema and state - that also contains our freshly deployed nginx pod's information. We need that data - <b>we want to preserve it to survive cluster failure - computation calamity. </b></span></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">We exit out of the console - that would take us back to where we were before. We select snapshot view from the menu - we would be presented with an option to choose between embedded and external etcd cluster. Presently, we do not have an external cluster. We choose embedded and take a snapshot. </span></p><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8-mE2U0t7_bexdeZzaWZxBOVcfAE2opr1fRo8nDIVOF-ODIpusEghO9DwqEuw_49YBGwXYKBYmWZZghm7ADUpF3GRC7Yj4anjKXJN3_uRtCkVT5AsTEuMoJM9Zge5O3GjpnAds0D_Dh4/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="278" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8-mE2U0t7_bexdeZzaWZxBOVcfAE2opr1fRo8nDIVOF-ODIpusEghO9DwqEuw_49YBGwXYKBYmWZZghm7ADUpF3GRC7Yj4anjKXJN3_uRtCkVT5AsTEuMoJM9Zge5O3GjpnAds0D_Dh4/s16000/image.png" /></span></a></p><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq6vruG22wvZMFsxLLmXOUClH6imeeGKo0L5K2NJtN9fcBLjU78FCpjGqRiq9Y9mR2wIySSJk7ruGVCnzHr6wl8WKyVQaqHfCjIX3I9tYRJJRSvbRzFhoo9C_BVWeqq3s8hJ6-W6Ju1jI/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="344" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq6vruG22wvZMFsxLLmXOUClH6imeeGKo0L5K2NJtN9fcBLjU78FCpjGqRiq9Y9mR2wIySSJk7ruGVCnzHr6wl8WKyVQaqHfCjIX3I9tYRJJRSvbRzFhoo9C_BVWeqq3s8hJ6-W6Ju1jI/s16000/image.png" /></span></a></p><div class="separator" style="clear: both; text-align: center;"><span style="clear: left; float: left; font-family: Ubuntu; font-size: medium; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="203" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCaSCFbRdfIE8fkgUJa0AnH7-zf8610Uv_thW4F7tw4-omwWMx9LRue1Jlj72nDKxLWgI9EUccrS5OgfRmgEmF_ikqM9yAR7hetkwZeOuIwLwthPvgw3BIUHNzoh4GQsFg9libTsRE3is/s16000/image.png" /></span></div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><div style="text-align: left;"><span style="text-align: justify;">12)<b> With a snapshot in hand - we are safe. We heave a sigh of relief. We are ready to combat disaster. We want put our conviction to test - we want to simulate a catastrophe and survive through it - making ourselves doubly reassured that we can infuse life back into etcd in the event of a cluster failure.</b></span></div></span></div><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">We head back to the main menu - choose console (this can be done from a usual terminal - there is no difference - but we want to be in the context of the menu - hence choose console anyway) and the run the script shown in the following snap. This script will wreak havoc on our cluster - it will wipe out our cluster and render it useless. All data would be expunged. <b>Only the static pods would be running meekly with utter indifference.</b> <b>Had it been a production cluster - business would have come to a grinding halt. Some may be updating their resumes - freshening up on the tricks of the trade. Yet some others may be philosophizing what life is all about - consequences may be far and beyond one's imagination - all due to a failed etcd cluster(pun intended 😜). </b></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyjEjjO085Nt9ET6TBa81TchRd11IpR44JyF5CMCsh2e-LnbOsR9-LBcB1kv4kbbBdB2fof4oIye8jGsnJJDHp-vpvRxyqTXFcZgTMavikvf3_ZBAHSdYW9T4GLluxX5Z0jN5ViIrO70M/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="258" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyjEjjO085Nt9ET6TBa81TchRd11IpR44JyF5CMCsh2e-LnbOsR9-LBcB1kv4kbbBdB2fof4oIye8jGsnJJDHp-vpvRxyqTXFcZgTMavikvf3_ZBAHSdYW9T4GLluxX5Z0jN5ViIrO70M/s16000/image.png" /></span></a></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><br /></div><div><b><span style="font-family: Ubuntu; font-size: medium;">Cluster demolition in progress:</span></b></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-1FO731on5LGT-Aj7-0mXi7Xc5W5b1CTylaOreDBE4dg9XGRpzmWXN-vWGeMkUHdbYT6z9aAm93hDa46K43T2W2tDRjxr-a_3bDBU_iazWnEfUstvm0VcctJU9QhkfIYx38esiCtMLJQ/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="251" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-1FO731on5LGT-Aj7-0mXi7Xc5W5b1CTylaOreDBE4dg9XGRpzmWXN-vWGeMkUHdbYT6z9aAm93hDa46K43T2W2tDRjxr-a_3bDBU_iazWnEfUstvm0VcctJU9QhkfIYx38esiCtMLJQ/s16000/image.png" /></span></a></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></div><div><b><span style="font-family: Ubuntu; font-size: medium;">Total annihilation:</span></b></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSfsR7Aixj6Gs5X0Ryk5f4EJ5vj2EjmyyRxULsIdhNY3xESfYiZ1pWicUEF6hYn2IxSE_3SNUTIK3uZCUXos8tkpYIKwZsQHMt_0OTpL90G99sjf0gdvx8KnXn_w2OTAYshrfsM22Bop8/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="298" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSfsR7Aixj6Gs5X0Ryk5f4EJ5vj2EjmyyRxULsIdhNY3xESfYiZ1pWicUEF6hYn2IxSE_3SNUTIK3uZCUXos8tkpYIKwZsQHMt_0OTpL90G99sjf0gdvx8KnXn_w2OTAYshrfsM22Bop8/s16000/image.png" /></span></a></div><div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></div><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">13) <b>Now that our cluster is decimated, we want to bring it back to life using the snapshot that we had taken. We can - and we would restore the snapshot on top of embedded etcd cluster - but first we would launch an external etcd cluster and restore the snapshot on top of it and verify that api servers are responding as expected. </b></span></div></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">We exit from the console and go back to main menu and choose 'Manage external etcd'</span></div><div><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAjnmqafajIQzA33t8uCQTErTFnyqgNCgViMRJ5bYAgcmxk6K_d-c9xyG5g3unKVJPIFBWVOYfpHRSAbyUWC_zwQdF338-Zt_8decsavW8A4opy6oYJnlwuV9sCAOVzKKIzAmPZMWFTYQ/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="211" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAjnmqafajIQzA33t8uCQTErTFnyqgNCgViMRJ5bYAgcmxk6K_d-c9xyG5g3unKVJPIFBWVOYfpHRSAbyUWC_zwQdF338-Zt_8decsavW8A4opy6oYJnlwuV9sCAOVzKKIzAmPZMWFTYQ/s16000/image.png" /></span></a></p><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><br /><div style="text-align: left;"><span style="text-align: justify;">14) <b>We proceed with external etcd cluster setup process. </b>For this post, we choose to host the cluster on the load balancer and the worker node ( Digression: we can also imagine kubernetes master nodes being part of external etcd cluster. For that to happen - the stacked/embedded etcd would need to bottom out one by one giving external etcd space to be hosted as separate processes on the master nodes).</span></div></span></div></div><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0356WuYWkwR4B8HMp01Jb88V_0Nmpjvz8NiASqpVKt8NCfvAbFiWDAvHDbHBxTNAttO3aVqjjjoKQLvmhM4DGHnTh88PNCBSpoNBiLJG5LYss35gUzhoAw3I-HQoAScCUKpBg60UPYR4/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="259" data-original-width="662" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0356WuYWkwR4B8HMp01Jb88V_0Nmpjvz8NiASqpVKt8NCfvAbFiWDAvHDbHBxTNAttO3aVqjjjoKQLvmhM4DGHnTh88PNCBSpoNBiLJG5LYss35gUzhoAw3I-HQoAScCUKpBg60UPYR4/s16000/image.png" /></span></a></p><div class="separator" style="clear: both; text-align: left;"><span style="font-family: Ubuntu; font-size: large; text-align: justify;"><br /></span></div><div class="separator" style="clear: both; text-align: left;"><span style="font-family: Ubuntu; font-size: medium; text-align: justify;">15) The external etcd cluster is ready with required configurations and binaries but not yet started.<b> It would be up once we restore the snapshot.</b></span></div><p></p><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQwtI9gpVOyvpJpGEQU9EDXYxKrxFFIkuWF81DiWvaLS3UTF4kGi0BABBGkioqrsQEn2CzCSR6udY4yNJlnHSYvKq_yTy_tNfnJAVs3BUgZxFLsIZTN1WPf3oStf6PdmQEuPluQXqkzaI/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="171" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQwtI9gpVOyvpJpGEQU9EDXYxKrxFFIkuWF81DiWvaLS3UTF4kGi0BABBGkioqrsQEn2CzCSR6udY4yNJlnHSYvKq_yTy_tNfnJAVs3BUgZxFLsIZTN1WPf3oStf6PdmQEuPluQXqkzaI/s16000/image.png" /></span></a></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><span style="text-align: justify;"><br /></span></span></div><div class="separator" style="clear: both; text-align: left;"><span style="font-family: Ubuntu; font-size: medium;"><span style="text-align: justify;">16) Lets go ahead and restore the snapshot. Following snaps capture the steps. We go back to snapshot view and select restore option.</span></span></div><p></p><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNsF5SJd0jz6rY-7TRCaCzlv9uLhQJoGkKuahao5tqDLPyBxdc_r4qUboIBPD5cfoUeiAoKzrSQgMYi7UnxsuHG5TkW7XaYF4o6EJjKaZSLGYHkJy_zym1_6WEdaeJUAae7ZQ0lRUHqFA/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="146" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNsF5SJd0jz6rY-7TRCaCzlv9uLhQJoGkKuahao5tqDLPyBxdc_r4qUboIBPD5cfoUeiAoKzrSQgMYi7UnxsuHG5TkW7XaYF4o6EJjKaZSLGYHkJy_zym1_6WEdaeJUAae7ZQ0lRUHqFA/s16000/image.png" /></span></a></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><br /><div style="text-align: justify;"><span style="text-align: left;">17) We choose external etcd as target cluster and select the snapshot that we had saved earlier.</span></div></span></div><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0Qf6yAIc9474RVUXKinCtdrhGXAwkTNjF1QZ6CP4CjAST7ofJlitf7xS99fMZDbZn2RiF-nheyQh_LZp6oIJspPe_hAJmZSffB7BiSpuZEIDhhCBiKt42uLMoLOM_Gdu9eNebdtErorA/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="253" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0Qf6yAIc9474RVUXKinCtdrhGXAwkTNjF1QZ6CP4CjAST7ofJlitf7xS99fMZDbZn2RiF-nheyQh_LZp6oIJspPe_hAJmZSffB7BiSpuZEIDhhCBiKt42uLMoLOM_Gdu9eNebdtErorA/s16000/image.png" /></span></a></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><br /><div style="text-align: justify;"><span style="text-align: left;">18) <b>We see snapshot restoration on external etcd cluster in progress.</b></span></div></span></div><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjy8bp0vsx-xRMwgX7ytJAuOMO6e39AYT1IYl8q328OYSBqhfNdz6MYe6KaimLCV_g5f-IlVLu1lszvFVBRgj2HqHib6utdP1D0eBFbFGKuXXc-6EEsGmNBus1qEAmjeV9Ttt-heKrJod0/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="326" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjy8bp0vsx-xRMwgX7ytJAuOMO6e39AYT1IYl8q328OYSBqhfNdz6MYe6KaimLCV_g5f-IlVLu1lszvFVBRgj2HqHib6utdP1D0eBFbFGKuXXc-6EEsGmNBus1qEAmjeV9Ttt-heKrJod0/s16000/image.png" /></span></a></p><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><br /><div style="text-align: justify;"><span style="text-align: left;">19) Snapshot restoration on <b>external etcd cluster is complete</b> and system pods are up and running in a couple of minutes. </span></div></span></div></div><p></p><div class="separator" style="clear: both; text-align: center;"><span style="clear: left; float: left; font-family: Ubuntu; font-size: medium; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="444" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjN7-c5_opBA0rzXIXdEB-VGDTjlDCUL8jEZk2Ro88GZeK4b2ZNmL3Alh-XHGwnY8CqPVlZbvmbJo3HVac820BM-37ZCEwlBNzA8qR7D97iY3d8jnPgUw6Ew2T_JMqL-7YgFRYPmXcf67Q/s16000/image.png" /></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;">20) <b>We have survived a disaster without a scratch. That was easy! Lets go ahead take out an etcd node for repair. Kubernetes cluster should suffer no hiccups. </b></span></p></div><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjL5X7hmFmo4BJxu1g3aRWvYBUpLFXw6nKOhHk9ReIEvUtIW1NdfDsB58M6bW3IcAkhhd2h9ZUjLm6gTHUOQHV_-Rq0ZrHz7_NH_vvglMpFib-6Zrwy-IFYHpHtjdwgMf8Gli75e7gvJAg/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="414" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjL5X7hmFmo4BJxu1g3aRWvYBUpLFXw6nKOhHk9ReIEvUtIW1NdfDsB58M6bW3IcAkhhd2h9ZUjLm6gTHUOQHV_-Rq0ZrHz7_NH_vvglMpFib-6Zrwy-IFYHpHtjdwgMf8Gli75e7gvJAg/s16000/image.png" /></span></a></div><div><div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></div><div class="separator" style="clear: both; text-align: center;"><br /></div><span style="font-family: Ubuntu; font-size: medium;">21) <b>There has been no hiccups</b> for the cluster as we can see from the kube system pods. Embedded etcd cluster is still running but api servers are not pointing at them. They will have nothing in them - because when the disaster struck - they were hollowed out.</span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguznlnGCghAIVirSB6VnXGhFE_hHTuOIS_xYBO2TiG6_TXLR8GCIs-vwW30nlX5XC02CQ_z8TF7Ao-GuFUFAWapAwBHV9VVd-pAYgnLk6Z8zetNkpzcqn7CGhtoaCvhNT1YC8OMcOxkBg/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="449" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguznlnGCghAIVirSB6VnXGhFE_hHTuOIS_xYBO2TiG6_TXLR8GCIs-vwW30nlX5XC02CQ_z8TF7Ao-GuFUFAWapAwBHV9VVd-pAYgnLk6Z8zetNkpzcqn7CGhtoaCvhNT1YC8OMcOxkBg/s16000/image.png" /></span></a></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;">22) <b>Node repaired. Lets add it back to the cluster again.</b></span></div><div><br /></div><div><div><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt581Yx6KybjC5UhZalficoNth82iwt20gS-zeMozU1EwxuqkZJqx5aSpBGJRfcshY9M-KXeiCnntuk6T1Xf9SBqi0XLAwfLpcMIh-sMy7eOz-bmrSXOgEuauXd7_Pqw9KfaLx4YZ6K_w/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="212" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt581Yx6KybjC5UhZalficoNth82iwt20gS-zeMozU1EwxuqkZJqx5aSpBGJRfcshY9M-KXeiCnntuk6T1Xf9SBqi0XLAwfLpcMIh-sMy7eOz-bmrSXOgEuauXd7_Pqw9KfaLx4YZ6K_w/s16000/image.png" /></span></a></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><br /></div><div><span style="font-family: Ubuntu; font-size: medium;">23) <b>Repaired node has become a member of the cluster again.</b></span></div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8wgRIU_9OeHPzkUQKxe0Ta8EE-Jzypsv3QXY7DXFA82SH0YIV_hrQfGMAmblVaDUGahdFoZYE7seNTxWqrJ1pLo5ecSPwmYKc5WmYmqSO4c8OXPetpID3-tlKeumnUhgL2Nhh_ZfbmB4/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="469" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8wgRIU_9OeHPzkUQKxe0Ta8EE-Jzypsv3QXY7DXFA82SH0YIV_hrQfGMAmblVaDUGahdFoZYE7seNTxWqrJ1pLo5ecSPwmYKc5WmYmqSO4c8OXPetpID3-tlKeumnUhgL2Nhh_ZfbmB4/s16000/image.png" /></span></a></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><br /></div><div><span style="font-family: Ubuntu; font-size: medium;">24) Lets bring the embedded etcd cluster back to live. We go back to snapshots view, select embedded cluster as restore target.</span></div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAs9zmNLn0kV4sL1yTfInLT7bS4u3phsgwtdRaF2oBYJ_-XXFYaGWOA90HbT4yBNkXSERVKmSxufGT048KpWF7TLkRPlyv2flJQT2X1eZ0xVYhCNa2PlHlx_32Ech5q-bDDlHqIjVn-H0/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="260" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAs9zmNLn0kV4sL1yTfInLT7bS4u3phsgwtdRaF2oBYJ_-XXFYaGWOA90HbT4yBNkXSERVKmSxufGT048KpWF7TLkRPlyv2flJQT2X1eZ0xVYhCNa2PlHlx_32Ech5q-bDDlHqIjVn-H0/s16000/image.png" /></span></a></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><br /></div><div><span style="font-family: Ubuntu; font-size: medium;">25) We see that <b>our embedded cluster is back - and system pods are back too.</b></span></div><div><br /></div><div><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUjmMAg1zvNQqhbxs42oknBKVX2WvTe2nxa2ZASo51V6LiXa-O2T02i4FtVEYh6P0s2Nc514Cn13AXsu3IGEeuXgbaqbO18gzdHht29is8-A_MJRHOXNB_IwDHN6i8QP2zCuV9HUyBMBk/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="371" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUjmMAg1zvNQqhbxs42oknBKVX2WvTe2nxa2ZASo51V6LiXa-O2T02i4FtVEYh6P0s2Nc514Cn13AXsu3IGEeuXgbaqbO18gzdHht29is8-A_MJRHOXNB_IwDHN6i8QP2zCuV9HUyBMBk/s16000/image.png" /></span></a></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;">26) Our nginx pod should be back on the default namespace. Lets check that.</span></div><div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG9-LIj8Wx0oLMjRTvDj9EPyErMrD3fpMCMpgbk0yUQYW93SAgxWeTv9QlysP8mxVLZ8glmFOVIzWAMJFCSHUYSN2IeqFDJ2S1nkB7Lal-etkGOjeOE0d2KE9h9L91yQkCGmwB14thKx4/" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="324" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG9-LIj8Wx0oLMjRTvDj9EPyErMrD3fpMCMpgbk0yUQYW93SAgxWeTv9QlysP8mxVLZ8glmFOVIzWAMJFCSHUYSN2IeqFDJ2S1nkB7Lal-etkGOjeOE0d2KE9h9L91yQkCGmwB14thKx4/s16000/image.png" /></span></a></div></div><div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></div></div><div><br /></div><div><span style="font-family: Ubuntu; font-size: medium;">This <b>effortless switch</b> between two environments using snapshots opens the door for lot of use cases - disaster recovery, cluster replication, fail over, rapid development and testing, preview releases to just name a few.</span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;">What about the situation - where we have just restored a snapshot but would like to <b>go back to the previous state we were in</b>? Well, we would definitely take a backup snapshot before migration - and use that as fallback option. But in reality - snapshot always takes us to a new state - it creates new data directories, new configurations - its not exactly the same setup as before.</span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><b>But we want to go back to the exact setup - we were in. Can we do that</b>? Of course we can. We would need o manually alter settings and configurations. That would involve rounds of testing and verification. That is going to be error prone and not hassle free. Well, <b>freedom from hassle is what k8s-kube-switch strives for.</b></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><b>As it turns out, these scripts can help us to go back to not only the previous state, but any previous state.</b> As said, when we are restoring a snapshot, we are creating new restore paths and configurations and moving on to them - whether it is embedded or external etcd. <b>We are leaving behind a trail of data directories and configurations. What it does is - any time we restore a snapshot, it looks at current settings and data directories across nodes and backs them all up in a single archive and saves it </b>(Where? Currently underneath a directory called <b>kube_vault </b>- in the node where k8s-kube-switch runs. These archives can be easily be pushed to a safe storage and duplicated to prevent data loss).</span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;">We have not talked about states so far. <b>States is the the mechanism that helps us to go back to any last good state. But it has challenges of its own. We are good if cluster topology remains same</b>. We can just spread out the archived state across the nodes and resume etcd and kubernetes api servers. But what if nodes leave or new nodes are added to the etcd cluster? <b>As we know - etcd does not like it if a node does not leave the cluster in good terms - it will not bury that hatchet otherwise. And talk of adding a node surreptitiously to the cluster - you have to dance a new dance to calm etcds' tantrums. States is a topic for another post, another day.</b></span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><div class="separator" style="clear: both; text-align: center;"><span style="clear: left; float: left; font-family: Ubuntu; font-size: medium; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="214" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkeUV_oJlLLl6m-NYkps51jSTJxA-Q0An7ZCJlCVuLpWvMPp17Na0DazPinZCeBkSeU9niktIDwrrGudO5C1RC518mHLh07M5H5ajLLqBq3rfkfx_avly5BaA8QPAZl66TE1Pz8T6Z1Wg/s16000/image.png" /></span></div></div><div><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><br /><div style="text-align: justify;"><b style="text-align: left;">Conclusion: </b></div></span></div></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><b>We have covered a lot. We started with a fresh cluster setup, taken a snapshot, brought it to its knees, created an external etcd cluster, restored a snapshot on it - brought it to life, taken a node out of the cluster, added it back - and finally switched back the kubernetes cluster to embedded etcd</b>. We have also touched upon states.</span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Behind all this are a bunch of shell scripts. We can see what they are doing because we are close to the metal. They enable experimentation - We can choose the console option - tweak/improve/cookie cut the scripts to suit our needs - exit the console - refresh the view and see the effects. </span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;">Happy experimentation - if you wish.</span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;">Source: <a href="https://github.com/ratulb/kube-etcd-switch/blob/main/cluster.sh">https://github.com/ratulb/kube-etcd-switch/blob/main/cluster.sh</a><br /></span></div><div><br /></div></div></div>rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-11983569602661188052021-06-16T01:41:00.000+05:302021-06-16T01:41:00.973+05:30VPC native kubernetes cluster in GCP<p><b> <span style="font-size: medium;"><span style="font-family: Ubuntu;">VPC native k8s clusters have quite a few advantages:</span></span></b></p><ul style="text-align: left;"><li style="text-align: justify;"><span style="font-size: medium;"><span style="font-family: Ubuntu;">POD IPs are directly routable. This eliminates the need for a load balancer to hop from node to pod. Instead traffic can reach PODs directly minimizing latency.</span></span></li><li><span style="font-size: medium;"><span style="font-family: Ubuntu;">POD IPs are reserved before PODs are created. This helps avoid POD IP collision with existing resource IPs.</span></span></li><li><span style="font-size: medium;"><span style="font-family: Ubuntu;">Firewall rules can be configured for POD IP ranges instead of node IP ranges.</span></span></li><li><span style="font-size: medium;"><span style="font-family: Ubuntu;">POD IPs can be accessed from on-premise connected networks via VPN or cloud inter-connect.</span></span></li></ul><p><span style="font-size: medium;"><span style="font-family: Ubuntu;">VPC native cluster requires a subnet for cluster nodes, 2 secondary subnets inside the subnet for nodes - one for POD IPs and another for service IPs.</span></span></p><p><b><span style="font-size: medium;"><span style="font-family: Ubuntu;">Commands to launch a VPC native k8s cluster quickly:</span></span></b></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;"><b>Create VPC network: </b><br /></span></span></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;">gcloud compute networks create gke --project=[project_id] --subnet-mode=custom --mtu=1460 --bgp-routing-mode=regional </span></span></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;"><b>Create subnet and secondary ranges for POD and services: </b><br /></span></span></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;">gcloud compute networks subnets create primary-subnet --project=[project_id] --range=10.0.0.0/8 <br />--network=gke --region=asia-south1 --secondary-range=pod-subnet=172.16.0.0/12 --secondary-range=service-subnet=192.168.0.0/16</span></span></p><p><b><span style="font-size: medium;"><span style="font-family: Ubuntu;">Launch the cluster:</span></span></b></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;">gcloud container clusters create gke-cluster \<br /> --network gke \<br /> --enable-ip-alias \<br /> --subnetwork=primary-subnet \<br /> --cluster-secondary-range-name=pod-subnet \<br /> --services-secondary-range-name=service-subnet \<br /> --num-nodes 3 \<br /> --zone asia-south1-b</span></span></p><p><b><span style="font-size: medium;"><span style="font-family: Ubuntu;">Initialize kubeconfig:</span></span></b></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;">gcloud container clusters get-credentials gke-cluster --zone asia-south1-b</span></span></p><p><b><span style="font-size: medium;"><span style="font-family: Ubuntu;">Deploy a nginx POD:</span></span></b></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;">kubectl run nginx --image nginx</span></span></p><p><b><span style="font-size: medium;"><span style="font-family: Ubuntu;">Expose POD via cloud load balancer:</span></span></b></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;">kubectl expose pod nginx -l run=nginx --port 80 --type LoadBalancer</span></span></p><p><b><span style="font-size: medium;"><span style="font-family: Ubuntu;">Access exposed POD via load balancer IP:</span></span></b></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;">curl [load balancer IP]<br /></span></span></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;"><br /></span></span></p><p><br /></p>rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-83712827521100257232021-04-19T04:01:00.089+05:302021-05-04T20:19:10.883+05:30grpc connect — rust, java and grpc-web<div><div><p style="text-align: justify;"><span style="font-size: medium;"><span style="font-family: Ubuntu;"><strong class="gu ct">Gist:</strong> Route calls from browser(using <a class="bu hk" href="https://github.com/grpc/grpc-web" rel="noopener nofollow">grpc-web</a>) to rust grpc application(implemented using <a class="bu hk" href="https://github.com/hyperium/tonic" rel="noopener nofollow">tonic</a>), which in turn delegates to java grpc and vice versa.</span></span></p><p style="text-align: justify;"><span style="font-size: medium;"><span style="font-family: Ubuntu;"><strong class="gu ct">Note</strong>: We use latest versions of various
libraries/binaries for this demonstration. One would be well advised to
use disposable cloud VMs to carry out the steps demonstrated in this
post. Verified for debian buster and various flavors of ubuntu.</span></span></p><p style="text-align: justify;"><span style="font-size: medium;"><span style="font-family: Ubuntu;">Grpc offers many advantages — schema fi<span id="rmm"><span id="rmm"><span id="rmm"><span id="rmm"><span id="rmm"><span id="rmm">r</span></span></span></span></span></span>st design enforces well-defined interfaces, <a class="bu hk" href="https://developers.google.com/protocol-buffers" rel="noopener nofollow">protobuf</a>
based binary protocol is performant, multiple requests over a single
connection, implementation of clients and servers in multiple languages
based on language specific artifacts generated by <a class="bu hk" href="https://grpc.io/docs/protoc-installation/" rel="noopener nofollow">protoc </a>compiler, bi-directional streaming etc.</span></span></p><p style="text-align: justify;"><span style="font-size: medium;"><span style="font-family: Ubuntu;">In this post, however, we stick to a simple example of request and reply
since our focus is on connectivity between different pieces. Following
figure captures the request and response flow:</span></span></p><p><img class="ih vq et en ek fs v c" height="199" role="presentation" src="https://miro.medium.com/max/700/1*SzM1MeamRnGaL08fS7LQiw.png" width="640" /> <br /></p><p> </p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="e8cd"><span style="font-family: Ubuntu;"><span style="font-size: medium;">Note: It will help to clone the following GitHub project to follow along the steps described:</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="6e1a"><span style="font-family: Ubuntu;"><span style="font-size: medium;">git clone <a class="bu hk" href="https://github.com/ratulb/grpc-rust-java-web.git" rel="noopener nofollow">https://github.com/ratulb/grpc-rust-java-web.git</a></span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="9b98"><span style="font-family: Ubuntu;"><span style="font-size: medium;"><strong class="gu ct">Part 1</strong>: java and rust grpc connectivity</span></span></p><ol class=""><li class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj qc qd qe dx" data-selectable-paragraph="" id="136a"><span style="font-family: Ubuntu;"><span style="font-size: medium;">Following is the protobuf interface definition that rust/java/grpc-web use to generate language specific<a class="bu hk" href="https://www.blogger.com/#" rel="noopener nofollow"> protocol buffer</a> artifacts, clients and services </span></span></li></ol><p><img class="ih vq et en ek fs v c" height="274" role="presentation" src="https://miro.medium.com/max/700/1*PK7CxGlInbd4Y4_cWhzXvA.png" width="640" /> <br /></p><p><span style="font-family: Ubuntu;"><span style="font-size: medium;">2. We implement the rust service first. We assume that rust is already installed.</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="68f0"><span style="font-family: Ubuntu;"><span style="font-size: medium;">3. We create the rust grpc server implementation within ../rust/server (refer to <a class="bu hk" href="https://github.com/ratulb/grpc-rust-java-web/tree/main/rust/server" rel="noopener nofollow">https://github.com/ratulb/grpc-rust-java-web/tree/main/rust/server</a>).</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="593c"><span style="font-family: Ubuntu;"><span style="font-size: medium;"><strong class="gu ct">cargo new server</strong></span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="c27f"><span style="font-family: Ubuntu;"><span style="font-size: medium;">4.
We create a new folder called ‘proto’ inside the ‘server’ project
created above and place the protobuf definition file ‘echo.proto’ inside
that.</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="530f"><span style="font-family: Ubuntu;"><span style="font-size: medium;">5. There are multiple grpc frameworks available in rust. We use <a class="bu hk" href="https://github.com/hyperium/tonic" rel="noopener nofollow">tonic</a>
as rust grpc framework because of its feature completeness, contributor
count and production readiness. Hence we edit the Cargo.toml file to
include <a class="bu hk" href="https://github.com/hyperium/tonic" rel="noopener nofollow">tonic</a> with its dependencies.</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="530f"><img class="ih vq et en ek fs v c" height="99" role="presentation" src="https://miro.medium.com/max/700/1*_aLEZthzSA1zzOaEhfhQeA.png" width="640" /> <br /></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;">6. To trigger the protobuf code generation we need to add a file named
‘build.rs’ inside the server folder with the following content.</span></span></p><p><img class="ih vq et en ek fs v c" height="76" role="presentation" src="https://miro.medium.com/max/700/1*4doqJOXdS1cPXtaji7ZMzA.png" width="640" /></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;">7. At this point, we are ready to build the project. We run ‘cargo
build’. Post build, we find that there is a echo.rs file generated
inside the target directory.</span></span></p><p> <img class="ih vq et en ek fs v c" height="31" role="presentation" src="https://miro.medium.com/max/700/1*6S6s42UTmJIxoBP1N4NNMw.png" width="640" /></p><p><b><span style="font-family: Ubuntu;"><span style="font-size: medium;"> </span></span></b><span style="font-family: Ubuntu;"><span style="font-size: medium;">8. We add a <strong class="gu ct">src/echo.rs</strong> with content of the file as shown below:</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="e062"><span style="font-family: Ubuntu;"><span style="font-size: medium;"><strong class="gu ct">tonic::include_proto!(“echo”);</strong></span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="3f14"><span style="font-family: Ubuntu;"><span style="font-size: medium;">9. Next we modify the src/main.rs file with content shown as below:</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="3f14"><img class="fr" height="438" role="presentation" src="https://miro.medium.com/proxy/1*uZOHXleqTPxO1q7o10U4cw.png" width="640" /> <br /></p><p> <strong class="gu ct"> </strong></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;"><strong class="gu ct">Note</strong>: The the content of <a class="bu hk" href="https://github.com/ratulb/grpc-rust-java-web/blob/main/rust/server/src/main.rs" rel="noopener nofollow">https://github.com/ratulb/grpc-rust-java-web/blob/main/rust/server/src/main.rs</a>
file differs from the one shown above. That is because — once the rust
grpc server receives a request — it will try to pass on the request to a
java delegate if registered. Also, we need to make sure there is no
endless delegation cycle. The rust implementation uses grpc request
headers and the java implementation(<a class="bu hk" href="https://github.com/ratulb/grpc-rust-java-web/blob/main/java/server/src/main/java/grpc/java/server/EchoServer.java" rel="noopener nofollow">https://github.com/ratulb/grpc-rust-java-web/blob/main/java/server/src/main/java/grpc/java/server/EchoServer.java</a>) uses request header along with request interceptor to break the cycle.</span></span></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;"><b><span><span> </span></span></b></span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="fd0c"><span style="font-size: medium;"><span style="font-family: Ubuntu;">10. At this point — we are ready to launch rust grpc server implementation by running “<strong class="gu ct">cargo run</strong>”.</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="4187"><span style="font-size: medium;"><span style="font-family: Ubuntu;">11. Our rust server should be running at this point. We would be using ‘<a class="bu hk" href="https://github.com/fullstorydev/grpcurl/releases" rel="noopener nofollow"><strong class="gu ct">grpcurl</strong></a>’ to invoke the server.</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="29e4"><span style="font-size: medium;"><span style="font-family: Ubuntu;">12. We run the “grpc-curl.sh” script as shown below:</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="2f54"><span style="font-size: medium;"><span style="font-family: Ubuntu;">./grpc-curl.sh 0.0.0.0:30031</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="ae5c"><span style="font-size: medium;"><span style="font-family: Ubuntu;">13. We should get back a response from the server.</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="18cf"><span style="font-size: medium;"><span style="font-family: Ubuntu;">14. At this point we should be able navigate to the ./rust/client folder and run the rust client implementation(<a class="bu hk" href="https://github.com/ratulb/grpc-rust-java-web/blob/main/rust/client/src/main.rs" rel="noopener nofollow">https://github.com/ratulb/grpc-rust-java-web/blob/main/rust/client/src/main.rs</a>) as shown below:</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="57e0"><span style="font-size: medium;"><span style="font-family: Ubuntu;"><strong class="gu ct">cargo run</strong> or just call <strong class="gu ct">./run.sh</strong></span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="22df"><span style="font-size: medium;"><span style="font-family: Ubuntu;">15. At this point — we should be able to navigate to <strong class="gu ct">./java/server/</strong> and <strong class="gu ct">./java/client/</strong> folders and run the ‘<strong class="gu ct">run.sh</strong>’ script in respective folders.</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="b7e1"><span style="font-size: medium;"><span style="font-family: Ubuntu;">16.
If both rust and java grpc servers are running — then running rust
client should get a response from the java grpc server and vice versa —
this would mean that rust and<strong class="gu ct"> java grpc connectivity</strong> is working as expected.</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="a4a1"><span style="font-size: medium;"><span style="font-family: Ubuntu;"><strong class="gu ct">Part 2</strong>: <a class="bu hk" href="https://github.com/envoyproxy/envoy" rel="noopener nofollow">Envoy proxy</a></span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="f48b"><span style="font-size: medium;"><span style="font-family: Ubuntu;"><strong class="gu ct">Note</strong>:
Rust and java grpc do not need envoy proxy to connect to each other.
They talk proper grpc which makes use of HTTP2 as the underlying
transport protocol. We are just setting things up for what is coming
next- <a class="bu hk" href="https://github.com/grpc/grpc-web" rel="noopener nofollow"><strong class="gu ct">Grpc-web</strong></a>.</span></span></p><ol class=""><li class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj qc qd qe dx" data-selectable-paragraph="" id="9f51"><span style="font-size: medium;"><span style="font-family: Ubuntu;">Navigate to <strong class="gu ct">./envoy</strong> folder and run ‘<strong class="gu ct">./setup.sh</strong>’ - this would install envoy proxy locally.</span></span></li><li class="gs gt ga gu b gv qj gc gw gx qk gf gy gz ql ha hb hc qm hd he hf qn hg hh hj qc qd qe dx" data-selectable-paragraph="" id="57ea"><span style="font-size: medium;"><span style="font-family: Ubuntu;">Next run ‘<strong class="gu ct">./runs.sh</strong>’. Envoy would start listening at port <strong class="gu ct">10000</strong>. Envoy is configured to route request based on a request header called “<strong class="gu ct">target_cluster</strong>”
. So grpc payload to envoy should carry the request header called
“target-cluster” as part of grpc request metadata. Later we would see
that <strong class="gu ct">grpc-web</strong> client is sending this
header from the browser request. Based on the grpc request metadata
header, the incoming request is routed to upstream rust or java grpc
server.</span></span></li></ol><p><b><span style="font-family: Ubuntu;"><span style="font-size: medium;"> </span></span></b><img class="ih vq et en ek fs v c" height="180" role="presentation" src="https://miro.medium.com/max/700/1*JwbYM85eTwBHBDBU_OCQBw.png" width="640" /></p><p><span style="font-family: Ubuntu;"><span style="font-size: medium;">3. For now we can navigate to ./java/server or ./rust/server folder and
execute the ‘grpc-curl.sh’ script. We should be able to get a response
back because these scripts are configured to send the <strong class="gu ct">target_cluster</strong> request header as shown below:</span></span></p><p><img class="ih vq et en ek fs v c" height="76" role="presentation" src="https://miro.medium.com/max/700/1*OYJm3n88db0JW3JRxxvEqw.png" width="640" /> </p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="a5e2"><span style="font-family: Ubuntu;"><span style="font-size: medium;">4.
So far we have made sure that if we can deliver a grpc request payload
to the envoy listening address, the request would be answered by either
java or rust grpc server. Next, we would look at sending a grpc request
from the browser.</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="4b17"><span style="font-family: Ubuntu;"><span style="font-size: medium;"><strong class="gu ct">Part 3</strong>: <a class="bu hk" href="https://github.com/grpc/grpc-web" rel="noopener nofollow">Grpc-web</a></span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="5207"><span style="font-family: Ubuntu;"><span style="font-size: medium;">As
things stand currently, the browser does not talk grpc (though it
supports HTT2 - and remember grpc != HTT2 ). Also, the browser does not
expose APIs with enough control for request manipulation and make
outgoing grpc request. So — that’s where grpc-web comes in — it is a
JavaScript client library that facilitate connectivity between a browser
application and grpc server. but grpc-web does not talk <a class="bu hk" href="https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md" rel="noopener nofollow">proper grpc</a>
either. It talks in terms of a protocol which makes it easy to change
the conversation into proper grpc — which is what is done by the envoy
proxy (by making use of a filter — “envoy.filters.http.grpc_web” —in
./envoy/envoy.yaml & ./envoy/envoy-local.yaml).</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="2200"><span style="font-family: Ubuntu;"><span style="font-size: medium;">The overall process of making a grpc application available in the browser is as follows:</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="b4cb"><span style="font-family: Ubuntu;"><span style="font-size: medium;">a) Generate JavaScript protobuf message classes and client stub for the client using <a class="bu hk" href="https://github.com/ratulb/grpc-rust-java-web/blob/main/web/gen-js-proto.sh" rel="noopener nofollow">protoc compiler</a> from protobuf definition file.</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="473a"><span style="font-family: Ubuntu;"><span style="font-size: medium;">b)
Compile all the required libraries along with generated protobuf
message classes and stub into one javascript library compatible with
browsers. This can be achieved using tools like “<a class="bu hk" href="http://browserify.org/" rel="noopener nofollow">browserify</a>”, <a class="bu hk" href="https://webpack.js.org/" rel="noopener nofollow">webpack </a>etc. Optionally, we can minify the the compiled library. We are using <a class="bu hk" href="https://github.com/ratulb/grpc-rust-java-web/blob/main/web/deploy-app.sh" rel="noopener nofollow">webpack </a>in this example.</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="7123"><span style="font-family: Ubuntu;"><span style="font-size: medium;">c) Host client app(index.html) in a webserver (tomcat in our example).</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="7243"><span style="font-family: Ubuntu;"><span style="font-size: medium;">d)
Set up a proxy (envoy proxy) to intercept grpc-web request from the
browser. Delegate the intercepted request to grpc server, gather
response and send it back to the browser.</span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="a5d2"><span style="font-family: Ubuntu;"><span style="font-size: medium;"><strong class="gu ct">Detailed steps:</strong></span></span></p><p class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj dg dx" data-selectable-paragraph="" id="2def"><span style="font-family: Ubuntu;"><span style="font-size: medium;">Note:
We are using NodeJS packages npx and webpack-cli along with
dependencies to compile required libraries and protobuf message classes
and client stub into one single library. That’s why the installation of
NodeJS and the dependencies.</span></span></p><ol class=""><li class="gs gt ga gu b gv pe gc gw gx pf gf gy gz pg ha hb hc ph hd he hf pi hg hh hj qc qd qe dx" data-selectable-paragraph="" id="ddbc"><span style="font-family: Ubuntu;"><span style="font-size: medium;">Navigate
to ./web folder and run the ‘./install-protoc.sh’ script — This would
install ‘protoc’ and ‘protoc-gen-grpc-web’ required for generating
javascript protobuf message classes and client stub from the protobuf
definition.</span></span></li><li class="gs gt ga gu b gv qj gc gw gx qk gf gy gz ql ha hb hc qm hd he hf qn hg hh hj qc qd qe dx" data-selectable-paragraph="" id="603d"><span style="font-family: Ubuntu;"><span style="font-size: medium;">Next,
run the ‘./gen-js-proto.sh’ script. This would compile the
proto/echo.proto definition and generate two output files — namely
‘echo_pb.js’ and ‘echo_grpc_web_pb.js’. We are using definitions from
these two files in ‘client.js’.</span></span></li><li class="gs gt ga gu b gv qj gc gw gx qk gf gy gz ql ha hb hc qm hd he hf qn hg hh hj qc qd qe dx" data-selectable-paragraph="" id="3fe1"><span style="font-family: Ubuntu;"><span style="font-size: medium;">Change the IP address in line <strong class="gu ct">9 of ‘client.js’</strong> to that of <strong class="gu ct">envoy proxy</strong> <strong class="gu ct">IP</strong>(if required). The javascript function “main” defined in <strong class="gu ct">client.js</strong> is being used in <strong class="gu ct">index.html</strong>. <strong class="gu ct">Note: IP address change is not required — if everything is running locally.</strong></span></span></li><li class="gs gt ga gu b gv qj gc gw gx qk gf gy gz ql ha hb hc qm hd he hf qn hg hh hj qc qd qe dx" data-selectable-paragraph="" id="f7fe"><span style="font-family: Ubuntu;"><span style="font-size: medium;">We are using NodeJS <strong class="gu ct">npx</strong> and <strong class="gu ct">webpack-cli</strong>
along with dependencies to compile required libraries and protobuf
message classes and client stub into one single library. Execute the “<strong class="gu ct">./setup-node-wp.sh</strong>” script install NodeJS and dependencies.</span></span></li><li class="gs gt ga gu b gv qj gc gw gx qk gf gy gz ql ha hb hc qm hd he hf qn hg hh hj qc qd qe dx" data-selectable-paragraph="" id="782b"><span style="font-family: Ubuntu;"><span style="font-size: medium;">We would need a webserver to host our grpc-web client app(index.html). Navigate to ./web/tomcat/ directory and run ‘<strong class="gu ct">./setup.sh’</strong>. This would install tomcat server.</span></span></li><li class="gs gt ga gu b gv qj gc gw gx qk gf gy gz ql ha hb hc qm hd he hf qn hg hh hj qc qd qe dx" data-selectable-paragraph="" id="b933"><span style="font-family: Ubuntu;"><span style="font-size: medium;">At this point, we are ready to deploy our client app(index.html) to tomcat server. We navigate to ./web folder and run “<strong class="gu ct">./deploy-app.sh</strong>”. This would compile all the javascript files into one single <strong class="gu ct">./web/dist/main.js</strong> file followed by copying resources to<strong class="gu ct"> ./web/tomcat../webapp/client</strong> directory.</span></span></li><li class="gs gt ga gu b gv qj gc gw gx qk gf gy gz ql ha hb hc qm hd he hf qn hg hh hj qc qd qe dx" data-selectable-paragraph="" id="b6b5"><span style="font-family: Ubuntu;"><span style="font-size: medium;">At
this point, we can navigate back to the project root folder and execute
‘./run.sh’. This would run rust and java grpc servers and tomcat and
envoy proxy. We should be able to access the webpage at <a class="bu hk" href="http://IP:8080/client" rel="noopener nofollow">http://IP:8080/client</a> (http://127.0.0.1:8080/client -if running locally) -where the IP is the address of the tomcat server ip address.</span></span></li><li class="gs gt ga gu b gv qj gc gw gx qk gf gy gz ql ha hb hc qm hd he hf qn hg hh hj qc qd qe dx" data-selectable-paragraph="" id="a116"><span style="font-family: Ubuntu;"><span style="font-size: medium;">Browser
should display a page as shown below. We should be able to select rust
or java from the the drop down and call the grpc servers.</span></span></li></ol><p> <img class="ih vq et en ek fs v c" height="103" role="presentation" src="https://miro.medium.com/max/700/1*tbJlx4aVckpN-V-Srr0EYw.png" width="640" /></p></div></div><br />rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-30418466937267763962021-04-13T13:45:00.007+05:302021-04-13T13:45:51.575+05:30Format shell script<p><span style="-webkit-text-stroke-width: 0px; background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: inline !important; float: none; font-family: "courier new", monospace; font-size: 20px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: none; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: pre; widows: 2; word-spacing: 0px;">snap install shfmt</span> </p><p><span style="-webkit-text-stroke-width: 0px; background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: inline !important; float: none; font-family: "courier new", monospace; font-size: 20px; font-style: normal; font-variant-caps: normal; font-variant-ligatures: none; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: pre; widows: 2; word-spacing: 0px;">shfmt -i 2 -ci -w ./*.sh</span></p>rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-57048574725170893442021-03-25T03:57:00.003+05:302021-03-25T03:58:16.132+05:30Linus Torvalds on rust in linux<p><b><span style="font-family: Ubuntu;"> <a href="https://www.zdnet.com/article/linus-torvalds-on-where-rust-will-fit-into-linux/">https://www.zdnet.com/article/linus-torvalds-on-where-rust-will-fit-into-linux/</a></span></b></p>rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-579100024123027682021-03-21T19:15:00.000+05:302021-03-21T19:15:09.845+05:30Algorithmic Muscle Excercise - maximum subsequence length in rust<p><span style="font-size: medium;"><span style="font-family: Ubuntu;">Maximum sub-sequence length of 3 strings - bottom up approach:</span></span></p><p><img height="327" src="data:image/png;base64,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" width="640" /></p><p></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;"></span></span></p><p><img height="110" src="data:image/png;base64,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" width="640" /> </p><p><span style="font-family: Ubuntu;">Source:<a href="https://github.com/ratulb/algos_in_rust/blob/master/max_sub_sequence_bottom_up/src/lib.rs" target="_blank"> https://github.com/ratulb/algos_in_rust/blob/master/max_sub_sequence_bottom_up/src/lib.rs </a></span><br /></p><p> </p>rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-13075727390066258242021-03-20T05:38:00.006+05:302021-03-24T17:56:02.306+05:30Algorithmic Muscle Excercise - Word Search In Rust<p><span style="font-size: medium;"><span style="font-family: Ubuntu;"> Word search in a grid:<span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span><span> </span> </span></span></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;"> <img height="355" src="data:image/png;base64,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" width="640" /></span></span></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p><img height="352" src="data:image/png;base64,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" width="643" /></p><p></p><p></p><p><img height="385" src="data:image/png;base64,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" width="643" /></p><p></p><p><span style="font-size: small;"><span style="font-family: Ubuntu;">Source: <a href="https://github.com/ratulb/algos_in_rust/blob/master/word_search_in_matrix/src/lib.rs">https://github.com/ratulb/algos_in_rust/blob/master/word_search_in_matrix/src/lib.rs</a></span></span><br /></p><p><br /></p>rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-74820330768286228692021-03-18T03:36:00.011+05:302021-03-24T17:57:43.311+05:30Algorithmic Muscle Excercise - Rain Water Trapping Problem In Rust<p><span style="font-size: medium;"><span style="font-family: Ubuntu;"> Water trapped along continuous extent of buildings of different heights: <span> </span><span> </span><span> </span> </span></span><br /></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p><span> </span><span></span><img height="382" src="data:image/png;base64,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" width="640" /></p><p> <img height="395" src="data:image/png;base64,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" width="640" /></p><p></p><p><span><span style="font-family: Ubuntu;"> Source: <a href="https://github.com/ratulb/algos_in_rust/blob/master/rain_water_trapping/src/lib.rs">https://github.com/ratulb/algos_in_rust/blob/master/rain_water_trapping/src/lib.rs</a></span><br /></span></p>rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-35660416312085862322020-11-19T03:02:00.029+05:302021-04-18T19:31:10.123+05:30Nesting all the way - kubernetes on openstack on google compute engine<p style="text-align: justify;"><span style="font-size: large;"><span style="font-family: Ubuntu;"><b>The gist:</b> </span></span><span style="font-size: medium;"><span style="font-family: Ubuntu;"><span><span>Can gcp/azure/AWS can be squeezed into one machine?</span></span></span></span></p><p style="text-align: justify;"><b><span style="font-size: medium;"><span style="font-family: Ubuntu;">Openstack is a cloud provider framework(read GCP/AWS/Azure - except that it is opensource). Here we squeeze the whole storage/compute/network virtualization framework to one GCP instance - create tenant, provision VMs and create a kubernetes cluster out of those VMs and deploy PODs.</span></span></b><br /></p><p style="text-align: justify;"><br /></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><b>Provisioning the compute engine: </b></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><b>Not all compute engines support virtualization - we need to create them from disks which are tagged specifically to support virtualization</b> and we need to provision the compute engines on N1(Haswell) and later series of CPUs and these CPUs are not available in all the GCP regions. At this point - US central and some Europe regions have N1 series of CPUs. <a href="http://rbsomeg.blogspot.com/2020/09/nested-virtualbox-vm-inside-google.html" target="_blank">See my earlier post on how to do this</a>.</span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>Create the disks in the GCP cloud console:</b></span></p><p><span style="font-family: Ubuntu; font-size: medium;">We execute the the following command in the google cloud console to create a disk that would support virtualization:</span></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4NUxH8jv4pwczk-nImDdIJ3IgTavgK6V7A10xX3_HpCG2gBH0ZwdNZmkh0rPuUP0ldeJpKcPeZkVtWPHLLRNvL28BdVNgEIEZDVaQpwF107Ab3kA9jMSHojD6Oc6lZeY1XvaQd6HnHRI/s680/tagged-disk-for-virtualization.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="237" data-original-width="680" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4NUxH8jv4pwczk-nImDdIJ3IgTavgK6V7A10xX3_HpCG2gBH0ZwdNZmkh0rPuUP0ldeJpKcPeZkVtWPHLLRNvL28BdVNgEIEZDVaQpwF107Ab3kA9jMSHojD6Oc6lZeY1XvaQd6HnHRI/s16000/tagged-disk-for-virtualization.png" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div><p></p><p><span style="font-family: Ubuntu;"><b>$</b><b><span style="font-size: x-small;">gcloud compute disks create disk-tagged-for-virtualization --image-project ubuntu-os-cloud --image-family ubuntu-1804-lts --zone us-central1-a --licenses "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"</span></b></span></p><p><span style="font-family: Ubuntu;"><b><span style="font-size: x-small;"><br /></span></b></span></p><p><span style="font-family: Ubuntu;"><b><span style="font-size: x-small;"></span></b></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu;"><b><span style="font-size: x-small;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3Mss9_Eyc31DnQErSpXJV_npLsvS4YEkx71I6whIvvee87jRfpF5hzX2IrmsDyUlzX84TdSrVGBaXclHT1DkKxXIzdMVBFiHhdHkZmLBQDiFAvGmkV1Cjiqk5tI0jU_cg-kHJOpqVlQ0/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="281" data-original-width="730" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3Mss9_Eyc31DnQErSpXJV_npLsvS4YEkx71I6whIvvee87jRfpF5hzX2IrmsDyUlzX84TdSrVGBaXclHT1DkKxXIzdMVBFiHhdHkZmLBQDiFAvGmkV1Cjiqk5tI0jU_cg-kHJOpqVlQ0/w640-h246/image.png" width="640" /></a></span></b></span></div><span style="font-family: Ubuntu;"><b><span style="font-size: x-small;"><br /><br /></span></b></span><p></p><p><span style="font-family: Ubuntu;"><b><span style="font-size: x-small;"><br /></span></b></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">This would create a 10 GB disk - which can be resized as per our requirements. In this case we resize it to 120 GB to launch our ubuntu 18.04 bionic compute engine VM. Inside this VM we would deploy Openstack using Devstack. So, whole Openstack deployment would be contained within one compute engine with 6 vCPUs, 16 GB RAM and 120 GB hard disk. </span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Within the Openstack deployment, we would launch 2 ubuntu 18.04 VMs - one would be the master node and another would be worker node of the kubernetes cluster. Both nodes would be 2 vCPU and 20 GB hard disk each. We would deploy weave CNI network plugin for POD networking and would validate that POD connectivity works without any hiccups. Would check for POD port forwarding, expose a deployment as NodePort and check for NodePort service accessibility. We would also, validate kubernetes DNS by going inside POD a container and access other containers by POD DNS names.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>Disclaimer:</b> </span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><b>This is not an advisable production setup and compute and storage capacities are not based on any benchmark. This could be a POC, academic exercise or a guide for someone looking to get started with Openstack and hack its internals from there.</b> We could have taken nesting and virtualization levels deeper just by making use of <a href="https://linuxcontainers.org/lxd/introduction/">Linux lxd</a> containers because ubuntu has in-built support for them. But that is a post for another day.</span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Following are the snaps of the provisioned GCP compute VM based off of the disk that we have created above.</span></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiYaJKvggks2y8YopO23ObnYoCi_ss85tKwwz65HicZEU0u9eiMkEUCeZqpyendo8hFY3_GiuDTH7DlTaSmd5bwgGqonOQhjZTDMyLa8z1hNw2Zx9NSEbZRQiBEt7xQZVUGfYEjPK4pB8/s736/provisioned-compute-engine-1.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="536" data-original-width="736" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiYaJKvggks2y8YopO23ObnYoCi_ss85tKwwz65HicZEU0u9eiMkEUCeZqpyendo8hFY3_GiuDTH7DlTaSmd5bwgGqonOQhjZTDMyLa8z1hNw2Zx9NSEbZRQiBEt7xQZVUGfYEjPK4pB8/s16000/provisioned-compute-engine-1.png" /></a></div><br /><span style="font-family: Ubuntu; font-size: medium;"><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">We have selected N1 series of CPU and US central region for required virtualization support. We have appropriately named the compute engine 'openstack'(pun intended)!</span></p><p style="text-align: justify;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLxp1hkokJZK6mn89nIQ2JiWETa9y0lX9PMW-a0HtbRA1UIccXTD39w2xjumB5aVVZWMXRfbCJm5ZYTYlJ38gqnDFocOixixzeoT6rQOo33wiIwNoxxqnEl0SSSthWD-P785eP8selOew/s759/provisioned-compute-engine.png" style="clear: left; margin-bottom: 1em; margin-right: 1em; text-align: center;"><img border="0" data-original-height="137" data-original-width="759" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLxp1hkokJZK6mn89nIQ2JiWETa9y0lX9PMW-a0HtbRA1UIccXTD39w2xjumB5aVVZWMXRfbCJm5ZYTYlJ38gqnDFocOixixzeoT6rQOo33wiIwNoxxqnEl0SSSthWD-P785eP8selOew/s16000/provisioned-compute-engine.png" /></a></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikmqOxcroFjFnLwwUcbI2MMgHC6LZ1z1iXnacTDYVCV0gcCp9G5Vqq1JAqssEGrERerqFC9FMEel8froh_b7RV6Pf14aN-qv0IXc5km8xyfhdVdZs5Dv5OStxc-mkuut9O79WqxI9RXvQ/s665/Hard-disk-and-http.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="430" data-original-width="665" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikmqOxcroFjFnLwwUcbI2MMgHC6LZ1z1iXnacTDYVCV0gcCp9G5Vqq1JAqssEGrERerqFC9FMEel8froh_b7RV6Pf14aN-qv0IXc5km8xyfhdVdZs5Dv5OStxc-mkuut9O79WqxI9RXvQ/s16000/Hard-disk-and-http.png" /></a></div><br /><span style="font-family: Ubuntu; font-size: medium;"><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">There are various ways we can deploy Openstack. But here we are going to use 'devstack' - which facilitate single or multi-node deployment of Openstack. Devstack is collection of scripts used to bring up a complete Openstack setup quickly. The whole setup is triggered by a script 'stack.sh'. It pulls down various components of Openstack from GitHub source code repository mirrors, configures the system and makes it ready. Hence, Devstack is a natural choice to get started with Openstack. Below is quick rundown of various openstack core infrastructure components:</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>Dashboard:</b></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Web-based management interface of openstack. Also, interchangeably referred to as horizon, it is an intuitive UI to create, configure and manage various components and services that a cloud framework must provide - such as control, compute, network and storage. More specifically, horizon is a core UI infrastructure based on which component specific management UIs are built and the dashboard stiches them together.</span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Note: API and CLI exploits are there underneath to execute the tasks that are performed on the dashboard. The dashboard piggy back on the APIs.</span></p><p><b style="font-family: Ubuntu; font-size: large;">Keystone:</b></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">The identity management component that handles user, roles, tenants. Also, manages catalog of services and service endpoints. One thing to notice is that - in Openstack parlance - tenants and projects mean the same thing. Operations are executed in a project or tenant context. Once openstack setup is complete, two users 'admin' and 'demo' will be present in the system. Admin is the super user over the whole cloud setup.</span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><b>Glance:</b></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Glance is the OS image registry. The </span><span style="font-size: medium;"><span style="font-family: Ubuntu;">Glance is the VM image management component. Before we launch a VM we need to make</span><span style="font-family: Ubuntu;"> </span><span style="font-family: Ubuntu;">M boot images will get their authorized host key(to access them via SSH) and network device MAC address populated during the cloud initialization phase of VM launch.</span></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><b>Neutron:</b></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Neutron is responsible for virtual networking in Openstack. It exposes APIs to manage the software defined tenant networks(<b>SDN</b>) to which VMs are launched. Neutron provides inter-network connectivity via virtual routers. External connectivity to internal VMs can be provided if a router is has a gateway that is connected to an external network. VMs can be accessed via <b>floating</b> IPs which have direct one-to-one with VMs' internal IPs.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>Nova:</b></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Nova manages the VM instances. Once a VM image is available in Glance and a virtual network is defined, with the addition of SSH key pair (which can either be generated or imported) and security group (which controls VM's ingress and egress traffic), Nova looks at the hypervisor resources and schedules a VM on a compute node. Once the VM is launched, the public key of the SSH key pair is injected into the authorized_keys file of launched VM during the cloud initialization phase.</span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><b>Cinder:</b></span></p><p><span style="font-family: Ubuntu; font-size: medium;">Cinder is the component for block storage management. It manages the volumes that get attached to and detached from VMs. Cinder works with glusterFS, ceph and many more solutions.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>Swift:</b></span></p><p><span style="font-family: Ubuntu; font-size: medium;">Swift is the object storage in Openstack. It is analogous to AWS S3. </span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>Ceilometer:</b></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Originally designed for tenant resource consumption billing purposes, it is the telemetry component of openstack. Its provides resource usage statistics and can be configured for alert and monitoring.</span></p><p><span style="font-family: Ubuntu; font-size: medium;">Now that we know what core components of openstack are, let get started with the first up.</span></p><p><b style="font-family: Ubuntu; font-size: large;">Setting things up:</b></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">We SSH into our provisioned GCP instance called 'openstack'. First thing, we do is create an user called 'stack' with home directory set to /opt/stack. This is done because devstack scripts are required to be executed by the 'stack' user.</span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">We update the system, create the 'stack' user, login as stack and checkout the latest stable release 'victoria' of Devstack repo.</span></p><p><span style="font-size: medium;"><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: #04ff00; font-family: "courier new", monospace; font-variant-ligatures: none; white-space: pre;">$</span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-family: "courier new", monospace; font-variant-ligatures: none; white-space: pre;"> sudo su -</span></span></p><p><span style="font-family: courier new, monospace;"><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); font-size: medium; font-variant-ligatures: none; white-space: pre;"><span style="color: #04ff00;">root@openstack:~#</span><span style="color: white;"> apt update</span></span></span></p><p><span style="font-size: medium;"><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: #04ff00; font-family: "courier new", monospace; font-variant-ligatures: none; white-space: pre;">root@openstack:~#</span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-family: "courier new", monospace; font-variant-ligatures: none; white-space: pre;"> apt upgrade -y<span></span></span></span></p><a name='more'></a><span style="font-size: medium;"><!--more--></span><p></p><p><span style="font-size: medium;"><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: #04ff00; font-family: "courier new", monospace; font-variant-ligatures: none; white-space: pre;">root@openstack:~#</span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-family: "courier new", monospace; font-variant-ligatures: none; white-space: pre;"> useradd -s /bin/bash -d /opt/stack -m stack</span></span></p><p><span style="font-size: medium;"><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: #04ff00; font-family: "courier new", monospace; font-variant-ligatures: none; white-space: pre;">root@openstack:~#</span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-family: "courier new", monospace; font-variant-ligatures: none; white-space: pre;"> echo "stack ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/stack</span><span style="font-family: Ubuntu;"><br /></span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: #04ff00; font-family: "courier new", monospace; font-variant-ligatures: none; white-space: pre;">root@openstack:~#</span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-family: "courier new", monospace; font-variant-ligatures: none; white-space: pre;"> su - stack</span></span></p><p><x-row line-overflow="true" style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;"><span style="color: #04ff00;"><span>stack@openstack</span>:<span>~#</span></span><span style="color: white;"> git clone https://github.com/openstack-dev/devstack.git -b stable</span></span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;">/victoria devstack/</span></x-row></p><p><span style="font-size: medium;"><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: #00ba13; font-family: "courier new", monospace; font-variant-ligatures: none; white-space: pre;">stack@openstack</span><span style="color: #04ff00;"><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); font-family: "courier new", monospace; font-variant-ligatures: none; white-space: pre;">:</span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); font-family: "courier new", monospace; font-variant-ligatures: none; white-space: pre;">~</span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); font-family: "courier new", monospace; font-variant-ligatures: none; white-space: pre;">$</span></span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-family: "courier new", monospace; font-variant-ligatures: none; white-space: pre;"> cd devstack/</span></span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;"><span style="color: #04ff00;">stack@openstack</span><span style="color: #04ff00;">:<span>~/devstack</span>$</span><span style="color: white;"> ip addr</span></span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;"><span style="color: red;">inet 10.128.0.48/48 </span><span style="color: white;">scope global dynamic ens4</span></span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;"><br /></span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;">Extra output ommitted...</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><br /></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;">Replace the <span style="color: red;">HOST_IP</span> below as necessary.</span></p><p><span style="font-family: Ubuntu; font-size: medium;">At this point, we create local configuration file as follows:</span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;"><span style="color: #04ff00;"><span>stack@openstack</span>:<span>~/devstack</span>$</span><span style="color: white;"> cat > local.conf <<EOF</span></span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;">[[local|localrc]]</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;"> ADMIN_PASSWORD=secret</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;"> DATABASE_PASSWORD=\$ADMIN_PASSWORD</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;"> RABBIT_PASSWORD=\$ADMIN_PASSWORD</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;"> SERVICE_PASSWORD=\$ADMIN_PASSWORD</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;"><span style="color: white;"> </span><span style="color: red;">HOST_IP=10.128.0.48</span></span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;"> RECLONE=yes</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;"> LOGFILE=/opt/stack/logs/stack.sh.log</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;"> VERBOSE=True</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;"> LOG_COLOR=False</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;"> SCREEN_LOGDIR=/opt/stack/logs</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;"> EOF</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"></x-row></p><p><span style="color: #00ba13;"><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; white-space: pre;">stack@openstack</span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; white-space: pre;">:</span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; white-space: pre;">~/devstack</span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; white-space: pre;">$</span></span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; white-space: pre;"> ./stack.sh</span></p><p></p><p style="-webkit-text-stroke-width: 0px; color: black; font-family: "Times New Roman"; font-size: medium; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"></p><p></p><p style="-webkit-text-stroke-width: 0px; color: black; font-family: "Times New Roman"; font-size: medium; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: justify; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span style="font-family: Ubuntu; font-size: medium;">The above script will install Openstack and related dependencies, configure the components with each other and setup a single node running Openstack cloud framework for us. Successful deployment will have output similar to the following at the command prompt:</span></p><p style="-webkit-text-stroke-width: 0px; color: black; font-family: "Times New Roman"; font-size: medium; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span style="font-family: Ubuntu; font-size: medium;"><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); text-align: justify; visibility: visible; white-space: pre;">Total runtime 1159</x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;">This is your host IP address: 10.128.0.48</x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;">This is your host IPv6 address: ::1</x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;">Horizon is now available at <a href="http://10.128.0.48/dashboard" style="text-decoration-line: none;" target="_blank" title="http://10.128.0.48/dashboard">http://10.128.0.48/dashboard</a></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;">Keystone is serving at <a href="http://10.128.0.48/identity/" style="text-decoration-line: none;" target="_blank" title="http://10.128.0.48/identity/">http://10.128.0.48/identity/</a></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;">The default users are: admin and demo</x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;">The password: secret</x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;">Services are running under systemd unit files.</x-row></span></p><p style="-webkit-text-stroke-width: 0px; color: black; font-family: "Times New Roman"; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span style="font-family: Ubuntu; font-size: medium;">At this point, we can access the horizon dashboard using the external IP address of compute engine from our local machine.</span></p><p style="-webkit-text-stroke-width: 0px; color: black; font-family: "Times New Roman"; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5ujv27MDC3maoe_5ZkIqQXUNJ9wnjbUXncMMugyq32SiYjO6of7uvpuLNL1pFAC3vLCKvFd1IbjmS4BK7-Jv82GpdNlVtFArHGdlqdvgXRr5ozA_ZNZsUJ3fUlfINcs669i4R17ipix8/s638/external-ip.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="104" data-original-width="638" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5ujv27MDC3maoe_5ZkIqQXUNJ9wnjbUXncMMugyq32SiYjO6of7uvpuLNL1pFAC3vLCKvFd1IbjmS4BK7-Jv82GpdNlVtFArHGdlqdvgXRr5ozA_ZNZsUJ3fUlfINcs669i4R17ipix8/s16000/external-ip.png" /></a></div><br /><span style="font-family: Ubuntu; font-size: medium;"><br /></span><p></p><p style="-webkit-text-stroke-width: 0px; color: black; font-family: "Times New Roman"; font-size: medium; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-size: medium;"><b style="font-family: Ubuntu;"><br /></b></span></p><p><span style="font-size: medium;"><b style="font-family: Ubuntu;">1. </b><span style="font-family: Ubuntu;">We access the the horizon dashboard using the external IP.</span></span></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU9f10eMTMuHVWMANYbnUsNalALNn5pOSI_HnMDmRc6iezWROFyjmfY2P89JRIuWNjeqty20K-cobyBuMtS0LDnesrRyUy1dL0-2DJ-x5BP8lcxOUfejJgnQ6rOOBksRr0ToDQiEUFr6w/s638/admin-login.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="487" data-original-width="638" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU9f10eMTMuHVWMANYbnUsNalALNn5pOSI_HnMDmRc6iezWROFyjmfY2P89JRIuWNjeqty20K-cobyBuMtS0LDnesrRyUy1dL0-2DJ-x5BP8lcxOUfejJgnQ6rOOBksRr0ToDQiEUFr6w/s16000/admin-login.png" /></a></div><br /><span style="font-family: Ubuntu; font-size: large;"><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-size: medium;"><b style="font-family: Ubuntu;"><br /></b></span></p><p><span style="font-size: medium;"><b style="font-family: Ubuntu;">2.</b><span style="font-family: Ubuntu;"> Next, create an user call 'dev' with role 'member'. </span></span></p><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihGidNBoJ-rBPtrXTEM5W4RYk8-_T4WPIZa7zJRCIZurAODPYDTBKCl-31I5XDFHAMp2229dLDQOZE_XsOsQoDNct9w_13uALBbZoYMeqyS1UGFqV0OzyGeER9ZOVVr_kiPHIB1knmtMQ/s743/create-dev-user1.png" style="clear: left; display: inline; margin-bottom: 1em; margin-right: 1em; text-align: center;"><img border="0" data-original-height="532" data-original-width="743" height="458" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihGidNBoJ-rBPtrXTEM5W4RYk8-_T4WPIZa7zJRCIZurAODPYDTBKCl-31I5XDFHAMp2229dLDQOZE_XsOsQoDNct9w_13uALBbZoYMeqyS1UGFqV0OzyGeER9ZOVVr_kiPHIB1knmtMQ/w640-h458/create-dev-user1.png" width="640" /></a></p><p><br /></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>3. </b><span>We create a project called 'dev-project' for the user.</span></span></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIL0ZNAk7PFkHJw9SwIpedYjHYKlGoG4BtyQtOmeVt3a3yBesSy4aYPQ1ZKMerw6aebrcYlePgpWLgvsPpqbbo-QhEUt1i2WifEed1qzN7PcmiN_4aa9vO8g4RZtTsyi30mEWE_YeV0RM/s638/create%253Dproject.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="376" data-original-width="638" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIL0ZNAk7PFkHJw9SwIpedYjHYKlGoG4BtyQtOmeVt3a3yBesSy4aYPQ1ZKMerw6aebrcYlePgpWLgvsPpqbbo-QhEUt1i2WifEed1qzN7PcmiN_4aa9vO8g4RZtTsyi30mEWE_YeV0RM/s16000/create%253Dproject.png" /></a></div><br /><span style="font-family: Ubuntu; font-size: large;"><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><b style="font-family: Ubuntu; font-size: large;"><br /></b></p><p><b style="font-family: Ubuntu; font-size: large;"><br /></b></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>4.</b><span> We complete the user creation along with project creation and logout and login as dev.</span></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">At this point we have provisioned a tenant. We should able to upload a VM image (ubuntu 18.04 cloud image), define virtual network, generate SSH key pair, create a security group. These are the requirement for launching a VM.</span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFbLkCYVcwHbXvuLAhjQjl9H6PjHmxteh2Fp0oJtFR9RAIp22cTQRvvmMROpF-97_brJPTm-gCBpo0LBm6OBO0esxJ2VYZgXq0n3s_A7h1ImnyCqA528iGfW8vV_rg_OkmmGWUXhW7gQU/s607/login-dev.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-size: medium;"><img border="0" data-original-height="494" data-original-width="607" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFbLkCYVcwHbXvuLAhjQjl9H6PjHmxteh2Fp0oJtFR9RAIp22cTQRvvmMROpF-97_brJPTm-gCBpo0LBm6OBO0esxJ2VYZgXq0n3s_A7h1ImnyCqA528iGfW8vV_rg_OkmmGWUXhW7gQU/s16000/login-dev.png" /></span></a></div><span style="font-size: medium;"><br /><span style="font-family: Ubuntu;"><br /></span></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;"><b>5.</b> First we download ubuntu 18.04 bionic image to our local machine from <a href="https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img ." target="_blank">this link.</a> </span><span style="font-family: Ubuntu;">See </span><a href="https://docs.openstack.org/image-guide/obtain-images.html" style="font-family: Ubuntu;" target="_blank">this page</a><span style="font-family: Ubuntu;"> </span><span style="font-family: Ubuntu;">for details.</span></span></p><p><span style="font-family: Ubuntu; font-size: medium;">In case download or upload taking long time - we can download the image on the </span></p><p><span style="font-family: Ubuntu; font-size: medium;">compute engine itself and upload the image to the system by using the CLI. Fire the following commands from /opt/stack/devstack directory:</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><x-row line-overflow="true" style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"><span style="color: #04ff00; font-size: medium;"><span style="font-weight: bold;">stack@openstack</span>:<span style="font-weight: bold;">~/devstack</span>$ </span><span style="color: white;"><span style="font-size: medium;">wget</span><span style="font-size: medium;"> <a href="https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img" style="text-decoration-line: none;" target="_blank" title="https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img"><span style="color: white;">https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg</span></a></span></span></span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><a href="https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img" style="text-decoration-line: none;" target="_blank" title="https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img"><span style="color: #04ff00; font-family: Ubuntu; font-size: medium;">-amd64.img</span></a></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;"><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: #00ba13; font-variant-ligatures: none; font-weight: bold; white-space: pre;">stack@openstack</span><span style="color: #04ff00;"><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); font-variant-ligatures: none; white-space: pre;">:</span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); font-variant-ligatures: none; font-weight: bold; white-space: pre;">~/devstack</span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); font-variant-ligatures: none; white-space: pre;">$</span></span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-variant-ligatures: none; white-space: pre;"> source openrc dev dev-project</span></span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></x-row></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><span style="color: #04ff00; font-weight: bold;">stack@openstack</span><span style="color: #04ff00;">:<span style="font-weight: bold;">~/devstack</span>$</span><span style="color: white;"> openstack image create --disk-format qcow2 --container-format bare \</span></span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> --public --file bionic-server-cloudimg-amd64.img ubuntu-18.04-image</span></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;">If we use the CLI to upload the image, we ignore step 6.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>6</b>. Next we upload the image:</span></p><p></p><div class="separator" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;"><span style="clear: left; float: left; font-size: medium; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="392" data-original-width="642" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-WgfgdaWO327-I4ZRRZvSHlb6cb6BCg-0jHHhs5kyljqEE_l_EJI0c7sfE_gGvm4-4r9hVqBijEMBIboygUIgMBYiT_B_Cwb15G9G6TOzMww-pGdeqdZs4c9Khi1xynAlk8kWnS6vrrM/s16000/image.png" /></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>7</b>. Now image listing should show our image.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYQb67TAUeZH4L3yVzFAU7F_pZLPOhX1Kh9Ql354SDFFwcBp7K8vrQSuAQm26TEjc4OwEuW1lXKF_vM6o3kDE-MKLDzKG4P5Wmr_Mr989aKv5lOXvqqc1HHZioDe0nwZsBh40aJ8el5jA/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="360" data-original-width="672" height="342" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYQb67TAUeZH4L3yVzFAU7F_pZLPOhX1Kh9Ql354SDFFwcBp7K8vrQSuAQm26TEjc4OwEuW1lXKF_vM6o3kDE-MKLDzKG4P5Wmr_Mr989aKv5lOXvqqc1HHZioDe0nwZsBh40aJ8el5jA/w640-h342/image.png" width="640" /></a></div><br /><br /></div><span style="font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>8</b>. Next we, create the security group called 'dev-security-group'.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgME7VBEU7Y7LY8SsdUl-x0y4UsemSTtMPKBugabarZQOQpWWTO2bnF7es4Xkq_2wUMhfstdRMNCf0VO_s-9lV1y9ji9YmqSxhHJr_YPt_4TmMRBMr8U_1OxAn0Vzmf0bqjLDZNPfiq1CE/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="309" data-original-width="694" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgME7VBEU7Y7LY8SsdUl-x0y4UsemSTtMPKBugabarZQOQpWWTO2bnF7es4Xkq_2wUMhfstdRMNCf0VO_s-9lV1y9ji9YmqSxhHJr_YPt_4TmMRBMr8U_1OxAn0Vzmf0bqjLDZNPfiq1CE/s16000/image.png" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;">We add 3 rules -</span></p><p></p><ol style="text-align: left;"><li><span style="font-family: Ubuntu; font-size: medium;">All ICMP</span></li><li><span style="font-family: Ubuntu; font-size: medium;">All TCP</span></li><li><span style="font-family: Ubuntu; font-size: medium;">SSH</span></li></ol><div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgleFwWAGNL_r6OilMKRd676px5zZqbEzbP8zeyz-oDqeG7hQnAeVZH9adMo87saB_TZECr10IESeK5eMOU5TPdp3U3qLWaUOnxYXxYbODmLvonttUen2E8cGa4SSewX8FjarP9J9qEO0I/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="408" data-original-width="523" height="499" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgleFwWAGNL_r6OilMKRd676px5zZqbEzbP8zeyz-oDqeG7hQnAeVZH9adMo87saB_TZECr10IESeK5eMOU5TPdp3U3qLWaUOnxYXxYbODmLvonttUen2E8cGa4SSewX8FjarP9J9qEO0I/w640-h499/image.png" width="640" /></span></a></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></div><div><span style="font-size: medium;"><br /></span></div><div><span style="font-size: medium;"><br /></span></div><div><span style="font-size: medium;"><br /></span></div><div><span style="font-size: medium;"><br /></span></div><div><span style="font-size: medium;"><br /></span></div><div><span style="font-size: medium;"><br /></span></div><div><span style="font-size: medium;"><br /></span></div><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>9</b>. Next, we create the SSH key pair called 'dev-key-pair'. </span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="clear: left; float: left; font-size: medium; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="390" data-original-width="677" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRSr6E_kOeihL7XDjvWCiA1Rr7K2D6UEd-ZwcU6E6SpfusYdkK9_VtM2j9oq3BttgkbrRCy7gEZAlfen1yGMic2JkKY5SFwd69eShhVBhXYqgzs6_4E3zQmjp2zR1JPLR5Eanam2G9jHA/s16000/image.png" /></span></div><span style="font-size: medium;"><br /></span><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: large;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;">We save the downloaded private key in a file called 'dev-key-pair.pem' in the compute engine.</span></p><p><span style="font-family: Ubuntu; font-size: medium;">We change the permission on the dev-key-pair.pem by executing the following command:</span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><span style="color: #00ba13;"><span style="font-weight: bold;">stack@openstack</span>:<span style="font-weight: bold;">~/devstack</span>$</span><span style="color: white;"> ls -la | grep pem</span></span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-size: medium;"><span style="color: white; font-family: Ubuntu;">-rw-rw-r-- 1 stack stack dev-key-pair.<span style="font-weight: bold;">pem</span></span></span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><span style="color: #00ba13;"><span style="font-weight: bold;">stack@openstack</span>:<span style="font-weight: bold;">~/devstack</span>$</span><span style="color: white;"> chmod 0600 dev-key-pair.pem </span></span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="color: #00ba13; font-family: Ubuntu; font-size: medium;"><span style="font-weight: bold;">stack@openstack</span>:<span style="font-weight: bold;">~/devstack</span>$</span></x-row></p><div><span style="font-family: Ubuntu; font-size: medium;"><b>10.</b> Next we are going to create network called 'dev-network'. </span></div><div><span style="font-family: Ubuntu; font-size: large;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: large;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgE_nuTDDOyo4J5IFyoTDUxcE1gSMdHX2WUCpUze2eeBgpaw2ASxfLNfBPKsCQxH9vohyphenhyphenHZlhjpQpJLDkEMUAK8o7wLo7sM080s26wZyK4hyphenhyphenrcon7vvIt0dWaR1XFiWiHq_2ulWCadVP_Y/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="427" data-original-width="525" height="521" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgE_nuTDDOyo4J5IFyoTDUxcE1gSMdHX2WUCpUze2eeBgpaw2ASxfLNfBPKsCQxH9vohyphenhyphenHZlhjpQpJLDkEMUAK8o7wLo7sM080s26wZyK4hyphenhyphenrcon7vvIt0dWaR1XFiWiHq_2ulWCadVP_Y/w640-h521/image.png" width="640" /></a></div><br /><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu; font-size: large;"><span style="font-size: large;"><br /></span></span></div><div><span style="font-family: Ubuntu;"><span style="font-size: medium;"><b>11</b>. We create a subnet called dev-subnet.</span></span></div><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoiP_e0Jz-M5JLCFo93y2-aU1_F6AlSY1Cde8r32Tn82AKGA7e97w_CAie59DrSu3DCk9nxVPTQhipeqGDUJdbpP_y6sXNnma7oRyZzRYdOqFci3A90RM1RQWGC_KSfS6cDgxxtcjDF8M/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="372" data-original-width="603" height="394" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoiP_e0Jz-M5JLCFo93y2-aU1_F6AlSY1Cde8r32Tn82AKGA7e97w_CAie59DrSu3DCk9nxVPTQhipeqGDUJdbpP_y6sXNnma7oRyZzRYdOqFci3A90RM1RQWGC_KSfS6cDgxxtcjDF8M/w640-h394/image.png" width="640" /></a></div><br /><br /></div><span style="font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>12</b>. Enter the subnet allocation details and DNS address 8.8.8.8</span></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEichXetT8w8nP120yBN79X1cR2MUUpGJ0bNYlzUpsNgHiJ2crIxt-gmB3qTxO5L4uUAyqmXnv08aKUDqjIzQOBynoqpI-BKzYfr-gKgLU6BTNoYyvml4LVaChmjY1CleDZW0PUSxGhIOyk/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="362" data-original-width="547" height="424" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEichXetT8w8nP120yBN79X1cR2MUUpGJ0bNYlzUpsNgHiJ2crIxt-gmB3qTxO5L4uUAyqmXnv08aKUDqjIzQOBynoqpI-BKzYfr-gKgLU6BTNoYyvml4LVaChmjY1CleDZW0PUSxGhIOyk/w640-h424/image.png" width="640" /></a></div><br /><br /><p></p><span style="font-size: medium;"><br /></span><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><b>13</b>. At this point we have an internal network without any external connectivity. We would connect this internal network to the public network which was provisioned as part of openstack deployment. To do this we would create a router called 'dev-router' which would stitch together public and dev-network. This would provide external connectivity from the internal network.</span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHFo1vreeoFn_mEMGSCnrwsY1Q6dMaJXtpYxlwJF8WE_9Lk0h35LeNp22WPp8GW6FKuojWVhc0JXRnY4zN2NmHA1g3rmvR469LDFaFkt6tycu4DeyHfjZvVJsr8EHVgotQx9J0yRvigag/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="382" data-original-width="538" height="454" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHFo1vreeoFn_mEMGSCnrwsY1Q6dMaJXtpYxlwJF8WE_9Lk0h35LeNp22WPp8GW6FKuojWVhc0JXRnY4zN2NmHA1g3rmvR469LDFaFkt6tycu4DeyHfjZvVJsr8EHVgotQx9J0yRvigag/w640-h454/image.png" width="640" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>14</b>. We add the internal 'dev-network' as an interface to the router.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1sLBo97RG3EndueQTszTj6MgKUh8E1VK0M-jURFPkCy_rv7hyjFreriv4aZ1KnAI7HrP84JMvAzJZJki2IJCbUJNbCqER1sYHjRtUNvK_3_NaHmA-yWeTfnaxCC0XvrZrvxWCL3hyjbQ/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="328" data-original-width="510" height="412" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1sLBo97RG3EndueQTszTj6MgKUh8E1VK0M-jURFPkCy_rv7hyjFreriv4aZ1KnAI7HrP84JMvAzJZJki2IJCbUJNbCqER1sYHjRtUNvK_3_NaHmA-yWeTfnaxCC0XvrZrvxWCL3hyjbQ/w640-h412/image.png" width="640" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>15</b>. Current network topology.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoS78G5dwUqqsNS7U8zqTIhGFCvMcM-fR1ZKwQWnItUOI99Ig3xbc-jAHa6l3ztyUJcLunAO2k-h1XlztO6JDpEVutSlEK_8rp9vLE1qRkM-o8xPjeSh7oYC6Gl836CFwpXYOnuK0uOoY/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="290" data-original-width="596" height="312" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoS78G5dwUqqsNS7U8zqTIhGFCvMcM-fR1ZKwQWnItUOI99Ig3xbc-jAHa6l3ztyUJcLunAO2k-h1XlztO6JDpEVutSlEK_8rp9vLE1qRkM-o8xPjeSh7oYC6Gl836CFwpXYOnuK0uOoY/w640-h312/image.png" width="640" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;">At this stage we are ready to get on with the VM launch process. We would first create a VM named master - select the uploaded ubuntu image, associate the dev-network, dev-key-pair, dev-security-group and finally launch the VM.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>16</b>. VM named 'master'.</span></p><p><span style="font-family: Ubuntu; font-size: large;"></span></p><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfnZXuyOGxMH6HU8WeFtwJ-PriR8Nk7tyYD4lW5cwgsXB5WKdqOkM22alReBZI6Cw7Ani0ZShfgn7wDJXDL4o2QAkYWO5NsWRmHM4S-JDr9CX98PKtvwgJmYi8-lhIrlBH_-ECT-aOzlA/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="405" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfnZXuyOGxMH6HU8WeFtwJ-PriR8Nk7tyYD4lW5cwgsXB5WKdqOkM22alReBZI6Cw7Ani0ZShfgn7wDJXDL4o2QAkYWO5NsWRmHM4S-JDr9CX98PKtvwgJmYi8-lhIrlBH_-ECT-aOzlA/s16000/image.png" /></a></div></div><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>17</b>. Next we select the ubuntu image.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjabDJnAQsOivDroVdsp2O6MkR06Xc_Csccb9nnxzuR3QAA1cXTQodCQFU4tGmen49XckN2zk8DrvAD8rTc4iec5vncAApm8VcVjiP74s_Xj7lJkdGggwBEBqWIHfYC9gdC6OJIN_TNqqY/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="318" data-original-width="729" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjabDJnAQsOivDroVdsp2O6MkR06Xc_Csccb9nnxzuR3QAA1cXTQodCQFU4tGmen49XckN2zk8DrvAD8rTc4iec5vncAApm8VcVjiP74s_Xj7lJkdGggwBEBqWIHfYC9gdC6OJIN_TNqqY/s16000/image.png" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>18</b>. Next we select m1.small flavor with 2 GB RAM and 20 GB hard disk.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrDWB6InZrN9T1ujRktPu3I3fWSq_mtb7OYSwGvp7bfATwG6VCCIETBegarORQ363lMLdxIY8QQcBLyNbYCdj3qVrt1AxJb304p2HsiDDnmsdCMGZwRf8XHgqB0khMiaXjO6qB2mm2GWs/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="228" data-original-width="678" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrDWB6InZrN9T1ujRktPu3I3fWSq_mtb7OYSwGvp7bfATwG6VCCIETBegarORQ363lMLdxIY8QQcBLyNbYCdj3qVrt1AxJb304p2HsiDDnmsdCMGZwRf8XHgqB0khMiaXjO6qB2mm2GWs/s16000/image.png" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>19</b>. We select the dev-network.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxv0fcbvhBcJdIULV60tGgearSeb3WhO6h6OcLbcJ1TNZneIdx_bN7tHl7Zx6p94kQgZriRbppuZzhyNNcFlnJwLfdJwAk_j62-7HL9pOEp_M9xBHWaYVQ4SmitkodWRZcvazvl2V61Wo/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="255" data-original-width="700" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxv0fcbvhBcJdIULV60tGgearSeb3WhO6h6OcLbcJ1TNZneIdx_bN7tHl7Zx6p94kQgZriRbppuZzhyNNcFlnJwLfdJwAk_j62-7HL9pOEp_M9xBHWaYVQ4SmitkodWRZcvazvl2V61Wo/s16000/image.png" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>20</b>. We select the dev-security-group.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihf64dNfWx28Rpr_VapRvcxXYLlY3LPgshgNA5DVs_CpuzQhj0UxD21RUUCWnSwT0565uICe952zAUr-1tpA41Fz6iju7MeADyEMNMBAiyHphrPktZGlm3OFU9-qJw8NPBs_7uksJ_9sM/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="312" data-original-width="690" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihf64dNfWx28Rpr_VapRvcxXYLlY3LPgshgNA5DVs_CpuzQhj0UxD21RUUCWnSwT0565uICe952zAUr-1tpA41Fz6iju7MeADyEMNMBAiyHphrPktZGlm3OFU9-qJw8NPBs_7uksJ_9sM/s16000/image.png" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>21</b>. Select the dev-key-pair.</span></p><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZnJvnZhPu9NgpO7_M4-44Eu8SerWWUy9FkteR-c2mwad68NHCOfzmnB28gtRoJo8qMYYe50Wn1TiwSvV5wCN0DbSkICQsRK_Jlrh0DnlbuyKJtPk97rkky6BCg7xDkZk0erHkKbA2FXY/" style="clear: left; display: inline; font-family: Ubuntu; font-size: large; margin-bottom: 1em; margin-right: 1em; text-align: center;"><img data-original-height="295" data-original-width="636" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZnJvnZhPu9NgpO7_M4-44Eu8SerWWUy9FkteR-c2mwad68NHCOfzmnB28gtRoJo8qMYYe50Wn1TiwSvV5wCN0DbSkICQsRK_Jlrh0DnlbuyKJtPk97rkky6BCg7xDkZk0erHkKbA2FXY/s16000/image.png" /></a></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /><b>22</b>. We follow the same procedure to another VM called 'worker'. We see both instances are running.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjOwbdzeWvdnaP09aQJ8l75w0G-7ooPgN1KrMpKWEwuostAgRshssUaz7ng-9-JVTNBNZr2Mq7q5VjO334hh7uhgprIeFCzLrxSAAsU-MAka1hjztnhNGNOPTjClcLI984V5zW_sY4LX0/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="270" data-original-width="633" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjOwbdzeWvdnaP09aQJ8l75w0G-7ooPgN1KrMpKWEwuostAgRshssUaz7ng-9-JVTNBNZr2Mq7q5VjO334hh7uhgprIeFCzLrxSAAsU-MAka1hjztnhNGNOPTjClcLI984V5zW_sY4LX0/w640-h272/image.png" width="640" /></a></div><br /><br /><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>23</b>. Lets try to open the console of the master. </span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhed9gMp1r-y5xLq0uNbobT3YJDOMo_pn0rcA4vkU44zD31xxH_moIQxa4L6yhyOPDgcFWWU_4_wDI_B-M9-sHtKQz1Ol-qHRJZpe4IYbUpJRtMKHtsg4aW5GIwPXISd33YBynIWVnpo-o/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="274" data-original-width="754" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhed9gMp1r-y5xLq0uNbobT3YJDOMo_pn0rcA4vkU44zD31xxH_moIQxa4L6yhyOPDgcFWWU_4_wDI_B-M9-sHtKQz1Ol-qHRJZpe4IYbUpJRtMKHtsg4aW5GIwPXISd33YBynIWVnpo-o/s16000/image.png" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">We don't get to see the console. Hovering over the 'Click here to see only the console' - we find that the link is pointing to the internal IP of the compute engine at port 6080. </span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">We would need to open firewall port 6080 on the compute engine and also we replace the internal IP with the external IP of the compute engine to open that link.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>24</b>. Open the firewall port 6080 of the compute engine.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4zhBpIhGfnnR46e8EKjCiWGIjDdhCRXWfEg8iAUb9N_HUnbwJvyK4PvkUZCDn5gs1BuLfX6NEiLQhUXuCaw-8E9oaQbxWrttNGMsilcE32EnMlC6G0sQ9-3OlBVzRC9IU_CvEfF8M8RA/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="394" data-original-width="803" height="314" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4zhBpIhGfnnR46e8EKjCiWGIjDdhCRXWfEg8iAUb9N_HUnbwJvyK4PvkUZCDn5gs1BuLfX6NEiLQhUXuCaw-8E9oaQbxWrttNGMsilcE32EnMlC6G0sQ9-3OlBVzRC9IU_CvEfF8M8RA/w640-h314/image.png" width="640" /></a></div><br /><br /></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>25</b>. We access the master VM console.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUrZldFZ7iuNvQeB0Kv-grrMWipo0nL4ey6pEqa4Ie5ngDibv2dzT5ztqCLtPiJTrbHguzfdIbuSuihkIkp5kx-TSTkaw9fJM3LC9oOvUSI1mZ3r_In0jJedvkTrw3EMMVCcRPAT7iiD8/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="406" data-original-width="776" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUrZldFZ7iuNvQeB0Kv-grrMWipo0nL4ey6pEqa4Ie5ngDibv2dzT5ztqCLtPiJTrbHguzfdIbuSuihkIkp5kx-TSTkaw9fJM3LC9oOvUSI1mZ3r_In0jJedvkTrw3EMMVCcRPAT7iiD8/s16000/image.png" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>26</b>. Master has got an internal IP of 192.168.0.61. Let's ping that from the compute engine. Ping does not go through.</span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="color: #00ba13; font-weight: bold;">stack@openstack</span>:<span style="color: #729fcf; font-weight: bold;">~</span>$ ping 192.168.0.61</x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-size: 20px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;">PING 192.168.0.61(192.168.0.61) 56(84) bytes of data.</x-row></p><p><span style="font-family: Ubuntu; font-size: medium;">That's because we cant not ping the internal IP. </span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><b>27</b>. For accessing the VMs we would need to assign floating IPs to the VMs. Floating IP provides an one to one external mapping to a VM. Lets assign floating IPs to them.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFpSymptBAX8jvkYxuK8VxAn_SsEuoGDp0_kt4TbscBEuHi65Gc01GNucXvuvfqajAOyDaV6rSmI3vl_jv6NCJMz9SORzFGxPTVEqWDpJm5_pZV7PsZuPesLrLsTEs5OWJUsNPLpYV3RA/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="286" data-original-width="635" height="288" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFpSymptBAX8jvkYxuK8VxAn_SsEuoGDp0_kt4TbscBEuHi65Gc01GNucXvuvfqajAOyDaV6rSmI3vl_jv6NCJMz9SORzFGxPTVEqWDpJm5_pZV7PsZuPesLrLsTEs5OWJUsNPLpYV3RA/w640-h288/image.png" width="640" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixwwcfWEMH6b84Lg_f7ZZ28N7htPApyu-9d69SyzGyX1dVgoKzugfaUpljjWBnfgenRV7PfZH4GFrOSc04Hhy26xNB9qkR_KONLN627eT9OYTRPypc3meaRGsreZUs9ZSBoP4GFq-9VMU/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="344" data-original-width="649" height="340" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixwwcfWEMH6b84Lg_f7ZZ28N7htPApyu-9d69SyzGyX1dVgoKzugfaUpljjWBnfgenRV7PfZH4GFrOSc04Hhy26xNB9qkR_KONLN627eT9OYTRPypc3meaRGsreZUs9ZSBoP4GFq-9VMU/w640-h340/image.png" width="640" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLRjcl5KXtHnHuI0BJxtw_nG4aFHlbpG03pHaAbzgpFh3Rb_oImYu_P3IwF79RGs0R6fzNrPdv8QcxinqAjSFoUxcF_lTwkqm4_g2JM3NfYP9rFB0VpnSHqaYMBxffgbUozZ_RefPM1zA/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="277" data-original-width="644" height="276" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLRjcl5KXtHnHuI0BJxtw_nG4aFHlbpG03pHaAbzgpFh3Rb_oImYu_P3IwF79RGs0R6fzNrPdv8QcxinqAjSFoUxcF_lTwkqm4_g2JM3NfYP9rFB0VpnSHqaYMBxffgbUozZ_RefPM1zA/w640-h276/image.png" width="640" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>28</b>. VMs with floating IPs assigned.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5EEHj96Wnx6niAQ_br9p7f-en9BJ-Fhytg38oAcgTBg0ggI8vUfOtlvgBP2QFkgDrJWx5-CscDtsN-jKtGJjQ4vkIHToiUyTF8tZ5s0eCCy94r4mCe4uzCodNOstwcHCW8OFqOc3_3ig/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="308" data-original-width="623" height="316" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5EEHj96Wnx6niAQ_br9p7f-en9BJ-Fhytg38oAcgTBg0ggI8vUfOtlvgBP2QFkgDrJWx5-CscDtsN-jKtGJjQ4vkIHToiUyTF8tZ5s0eCCy94r4mCe4uzCodNOstwcHCW8OFqOc3_3ig/w640-h316/image.png" width="640" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><br /></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>29</b>. At this point we should be able to ping the VMs and SSH into them using the floating IPs.</span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><span style="color: #00ba13; font-weight: bold;">stack@openstack</span>:<span style="color: #729fcf; font-weight: bold;">~</span>$ ping 172.24.4.252</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">PING 172.24.4.252 (172.24.4.252) 56(84) bytes of data.</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">64 bytes from 172.24.4.252: icmp_seq=1 ttl=63 time=1.65 ms</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">64 bytes from 172.24.4.252: icmp_seq=2 ttl=63 time=0.976 ms</span></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><span style="color: #00ba13; font-weight: bold;">stack@openstack</span>:<span style="color: #729fcf; font-weight: bold;">~</span>$ ping 172.24.4.25</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">PING 172.24.4.25 (172.24.4.25) 56(84) bytes of data.</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">64 bytes from 172.24.4.25: icmp_seq=1 ttl=63 time=1.66 ms</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">64 bytes from 172.24.4.25: icmp_seq=2 ttl=63 time=0.734 ms</span></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>30</b>. We are able to ping them. Lets SSH now.</span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><span style="color: #00ba13; font-weight: bold;">stack@openstack</span>:<span style="color: #729fcf; font-weight: bold;">~/devstack</span>$ ssh -i dev-key-pair.pem ubuntu@172.24.4.25</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">Are you sure you want to continue connecting (yes/no)? yes</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">Warning: Permanently added '172.24.4.25' (ECDSA) to the list of known hosts.</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-123-generic x86_64)</span></x-row></p><p><br /></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><b>31</b>. We are now inside both the VMs. We would update them and get on with process of setting up the kubernetes cluster. We run the following commands in both the VMs.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# apt update</span></x-row></p><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# apt install -y apt-transport-https ca-certificates \</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> curl software-properties-common gnupg2</span></x-row></div><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# #Prepare for docker install</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key \</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> --keyring /etc/apt/trusted.gpg.d/docker.gpg add -</span></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# #Add docker repository</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# add-apt-repository "deb [arch=amd64] \</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> <a href="https://download.docker.com/linux/ubuntu" style="text-decoration-line: none;" target="_blank" title="https://download.docker.com/linux/ubuntu">https://download.docker.com/linux/ubuntu</a> $(lsb_release -cs) stable"</span></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# #Install containerd and docker</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# sudo apt update && sudo apt install -y \</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> containerd.io=1.2.13-2 \</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> docker-ce=5:19.03.11~3-0~ubuntu-$(lsb_release -cs) \</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> docker-ce-cli=5:19.03.11~3-0~ubuntu-$(lsb_release -cs)</span></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">#Specify cgroup driver to be systemd</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# cat <<EOF | sudo tee /etc/docker/daemon.json</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> {</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> "exec-opts": ["native.cgroupdriver=systemd"],</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> "log-driver": "json-file",</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> "log-opts": {</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> "max-size": "100m"</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> },</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> "storage-driver": "overlay2"</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> }</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> EOF</span></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~#Done with docker - reload daemon and restart docker</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# sudo systemctl daemon-reload</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# sudo systemctl restart docker</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# sudo systemctl enable docker</span></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>32</b>. Next we would install kubernetes - we do not install kubectl on the worker node.</span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-family: Ubuntu; font-size: medium; font-variant-ligatures: none; white-space: pre;">root@master:~# sudo apt update</span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# curl -s <a href="https://packages.cloud.google.com/apt/doc/apt-key.gpg" style="text-decoration-line: none;" target="_blank" title="https://packages.cloud.google.com/apt/doc/apt-key.gpg">https://packages.cloud.google.com/apt/doc/apt-key.gpg</a> \</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> | sudo apt-key add -</span></x-row></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> deb <a href="https://apt.kubernetes.io/" style="text-decoration-line: none;" target="_blank" title="https://apt.kubernetes.io/">https://apt.kubernetes.io/</a> kubernetes-xenial main</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> EOF</span></x-row></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-family: Ubuntu; font-size: medium; font-variant-ligatures: none; white-space: pre;">root@master:~# apt update</span></p><p><span style="font-family: Ubuntu; font-size: medium;">On the master only:</span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-family: Ubuntu; font-size: medium; font-variant-ligatures: none; white-space: pre;">root@master:~# apt install -y kubelet kubeadm kubectl</span></p><p><span style="font-family: Ubuntu; font-size: medium;">On the worker</span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-family: Ubuntu; font-size: medium; font-variant-ligatures: none; white-space: pre;">root@worker:~# apt install -y kubelet kubeadm</span></p><p><span style="font-family: Ubuntu; font-size: medium;">Again on both VMs.</span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# systemctl daemon-reload</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# systemctl restart kubelet</span></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>33</b>. We are now done with kubernetes installation. Lets initialize the master and then join the worker to the cluster. We avoid the pre-flight check errors because the settings we have chosen are not optimum for the cluster and kubernetes is not very happy about that.</span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-family: Ubuntu; font-size: medium; font-variant-ligatures: none; white-space: pre;">root@master:~# kubeadm init --ignore-preflight-errors=all</span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgs5ksWgOPDB-IOPAP9msx99ZCJy6-jJkF3VBZn-1fqbnWGpBxDImwREQvhqvgQtH-q7jMg7ZgCcybqNBAATdcGjN1ol-OZL0qZkE3CJcBzDrSMP-YnAIhKBz4QOtkIpu4BsrFLIaCnf00/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: Ubuntu; font-size: medium;"><img data-original-height="342" data-original-width="648" height="338" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgs5ksWgOPDB-IOPAP9msx99ZCJy6-jJkF3VBZn-1fqbnWGpBxDImwREQvhqvgQtH-q7jMg7ZgCcybqNBAATdcGjN1ol-OZL0qZkE3CJcBzDrSMP-YnAIhKBz4QOtkIpu4BsrFLIaCnf00/w640-h338/image.png" width="640" /></span></a></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# {</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> mkdir -p $HOME/.kube</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> sudo chown $(id -u):$(id -g) $HOME/.kube/config</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> }</span></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;">We copy the kube config to the home directory as instructed and proceed to the worker node and execute the join command.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqN8tKQaWkFkCdKBX-BMIGzR-1M10AcO2m4rwonrdKJ2hQsXagunVKxKSi3tb1PMf9U4yWbNlqsOy1D750GT1a5GumGIc7qGPvivAiL2E1wIZAcfGi1k7d6io3pVI95jBJ2VSrZ5nOrJI/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="68" data-original-width="668" height="66" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqN8tKQaWkFkCdKBX-BMIGzR-1M10AcO2m4rwonrdKJ2hQsXagunVKxKSi3tb1PMf9U4yWbNlqsOy1D750GT1a5GumGIc7qGPvivAiL2E1wIZAcfGi1k7d6io3pVI95jBJ2VSrZ5nOrJI/w640-h66/image.png" width="640" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtFevN7hLgS2fLOfaf6F65KLU0OqxFkMuWO90C2ccuzWGIm-8ocPFwYchkqK0TDGVoRgU1Tg_SG3DGqO8sQZDICgcvkdXSeZ3hpIvqjNpZBhv_5b91eYJtm4NerijVnr57gKYzC8rL73Q/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="123" data-original-width="670" height="118" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtFevN7hLgS2fLOfaf6F65KLU0OqxFkMuWO90C2ccuzWGIm-8ocPFwYchkqK0TDGVoRgU1Tg_SG3DGqO8sQZDICgcvkdXSeZ3hpIvqjNpZBhv_5b91eYJtm4NerijVnr57gKYzC8rL73Q/w640-h118/image.png" width="640" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>34.</b> Lets fire the following command.</span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# kubectl get nodes</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">NAME STATUS ROLES AGE VERSION</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">master NotReady master 16m v1.19.4</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">worker NotReady <none> 2m54s v1.19.4</span></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;">The nodes are not ready - that's expected - because we have not deployed CNI plugin yet. Lets do that next.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>35.</b> Install weave POD network plugin.</span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# kubectl apply -f \</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl \</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"> version | base64 | tr -d '\n')"</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">serviceaccount/weave-net created</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">clusterrole.rbac.authorization.k8s.io/weave-net created</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">clusterrolebinding.rbac.authorization.k8s.io/weave-net created</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">role.rbac.authorization.k8s.io/weave-net created</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">rolebinding.rbac.authorization.k8s.io/weave-net created</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">daemonset.apps/weave-net created</span></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>36.</b> Let's check the nodes again.</span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# kubectl get nodes</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">NAME STATUS ROLES AGE VERSION</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">master Ready master 25m v1.19.4</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">worker Ready <none> 12m v1.19.4</span></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;">Cluster is finally ready! Next we deploy a nginx pod.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>37</b>. Deploy nginx pod.</span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# kubectl run nginx-pod --image nginx</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">pod/nginx-pod created</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">root@master:~# kubectl get pod -w</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">NAME READY STATUS RESTARTS AGE</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;">nginx-pod 1/1 Running 0 21s</span></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;">We see that pod is running.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>38</b>. Let's port-forward to the pod in another terminal and curl it from current terminal.</span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;">root@master:~# kubectl port-forward nginx-pod 9999:80</x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;">Forwarding from 127.0.0.1:9999 -> 80</x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-family: "courier new", monospace; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;">Forwarding from [::1]:9999 -> 80</x-row></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7qmOQich8LukkBo2yyoP91lUunXl6EOkF6C4CO7yNXnbjiXF_GDOLjXCckNSvm5pCPs19PjpGhBV7Xhp-heAxS9k4K7nUR9WYAalrcH6E0RyZtUUTY2plbDbNDkPQ5ZwC_Jn7-pzefg0/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="348" data-original-width="545" height="408" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7qmOQich8LukkBo2yyoP91lUunXl6EOkF6C4CO7yNXnbjiXF_GDOLjXCckNSvm5pCPs19PjpGhBV7Xhp-heAxS9k4K7nUR9WYAalrcH6E0RyZtUUTY2plbDbNDkPQ5ZwC_Jn7-pzefg0/w640-h408/image.png" width="640" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;">Port forward is working fine. </span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>39.</b> Lets create create a NodePort service and access it from the cluster nodes.</span></p><p><span style="font-family: Ubuntu; font-size: medium;">First we create the deployment:</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhL25e1Fr3TDo2x_2EfTFwmQkQ5mANvOe1ZuG1vP9RpeRvukg5gfNMnHlu6Vax9biRbwpufbtEgy_JuCUATeCPaXmVRCorW4JRcvEZgj2jEm2zINqb9sKZ5ql8qoxxRk-VElrVgQ24VcCE/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="433" data-original-width="516" height="537" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhL25e1Fr3TDo2x_2EfTFwmQkQ5mANvOe1ZuG1vP9RpeRvukg5gfNMnHlu6Vax9biRbwpufbtEgy_JuCUATeCPaXmVRCorW4JRcvEZgj2jEm2zINqb9sKZ5ql8qoxxRk-VElrVgQ24VcCE/w640-h537/image.png" width="640" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;">We deploy the above deployment yaml.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI2dUqPw8q_77zJjTT1mMb5P9f9tnnR3XXuAkazeXCAfWY4OV5Sa7cGs4EXuuvRi482JLfamy-SgHF6OhZE05jMKQw-DrT-6hq3NIrWRs9OOLbMdfaAt8mt7L55chHCwqbFp2O6bViSJM/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="99" data-original-width="607" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI2dUqPw8q_77zJjTT1mMb5P9f9tnnR3XXuAkazeXCAfWY4OV5Sa7cGs4EXuuvRi482JLfamy-SgHF6OhZE05jMKQw-DrT-6hq3NIrWRs9OOLbMdfaAt8mt7L55chHCwqbFp2O6bViSJM/s16000/image.png" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><br /></div><span style="font-family: Ubuntu; font-size: medium;"><br /><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikFhL_AIkMgumJGNnVncZGNGLEBTyKQeOu5SoeyOq1obkQeK7sHILXNxfelegry1oxE2QOPGuwkRFznwrCorsE-j5GhBjwR0zucDpTUEwFLiUIbnowHDUXziZhcAJ1dMdDcLy2zjgmXmc/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="51" data-original-width="503" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikFhL_AIkMgumJGNnVncZGNGLEBTyKQeOu5SoeyOq1obkQeK7sHILXNxfelegry1oxE2QOPGuwkRFznwrCorsE-j5GhBjwR0zucDpTUEwFLiUIbnowHDUXziZhcAJ1dMdDcLy2zjgmXmc/s16000/image.png" /></a></div><br /><br /></span><p></p><p><br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZxrdAfTO17iA8CukZArr9LlBuFuur8wKBSWtZtzVx28l2yHye99uI718BVUApghU6FwrgVVcborwcn9PhbxqCdZsvT0iM5YxpVEGsY83KZ25-pI1kKRrIIBvMEfIhwqD1WJFQNvjKQBs/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="83" data-original-width="596" height="90" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZxrdAfTO17iA8CukZArr9LlBuFuur8wKBSWtZtzVx28l2yHye99uI718BVUApghU6FwrgVVcborwcn9PhbxqCdZsvT0iM5YxpVEGsY83KZ25-pI1kKRrIIBvMEfIhwqD1WJFQNvjKQBs/w640-h90/image.png" width="640" /></a></div><br /><br /><p></p><p><br /></p><p><br /></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcW5AxgDejy__WSQKYrZnKCLaOEacfLmBVCwOK8KL44iY_7ZuFmLbHT69JPX4PybdXWEboXrdsMTEFB4aSC32lYUTvI5s7qiREJ-7eHHxKMrHNacizM8Htc3LHqVEDVWNfwuF8QvNXitM/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="63" data-original-width="626" height="64" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcW5AxgDejy__WSQKYrZnKCLaOEacfLmBVCwOK8KL44iY_7ZuFmLbHT69JPX4PybdXWEboXrdsMTEFB4aSC32lYUTvI5s7qiREJ-7eHHxKMrHNacizM8Htc3LHqVEDVWNfwuF8QvNXitM/w640-h64/image.png" width="640" /></a></div><br /><br /><p></p><p><br /></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>40. </b>Now, lets access it from the worker node.</span></p><p></p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizLpgPWVNLoPegf_EBd1UTf0hgu5IFV_2luBCYaYcmdB0C5ukqBuQEtU1FaqOXFAku3su5GWzUmCyIUO23Ts_hUuaObxoraj22Nx2MfNLyLBAZE5gpVt8GGRdOyR7KbFxbR4O_NNwHbMI/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="206" data-original-width="486" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizLpgPWVNLoPegf_EBd1UTf0hgu5IFV_2luBCYaYcmdB0C5ukqBuQEtU1FaqOXFAku3su5GWzUmCyIUO23Ts_hUuaObxoraj22Nx2MfNLyLBAZE5gpVt8GGRdOyR7KbFxbR4O_NNwHbMI/s16000/image.png" /></a></div><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><span style="font-family: Ubuntu; font-size: medium;">We can access the NodePort service from the host machine. </span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>41. </b>Let's access it via the floating IP.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi76ljfyd-gRnBPb179mhGzlf2MSaHN2uDXhnPq3mwNn1p0Q_3UMn0Buf9BHEVJfli__22FOvcz_SjnEOVXDfibdS7673uPTfdaJa19B41CzWy3FM-003YDRwa6G10hLksw5xoSu_kta6w/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="230" data-original-width="715" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi76ljfyd-gRnBPb179mhGzlf2MSaHN2uDXhnPq3mwNn1p0Q_3UMn0Buf9BHEVJfli__22FOvcz_SjnEOVXDfibdS7673uPTfdaJa19B41CzWy3FM-003YDRwa6G10hLksw5xoSu_kta6w/w640-h206/image.png" width="640" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;">We can access the NodePort via floating IP too.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>42. </b>Next, let go inside a POD container and check if other PODs are available via kube DNS.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"></span></p><div class="separator" style="clear: both; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgORHMwGK_sMsPjcjEEU4J1NptxkE4_yWY2378v1TmE3u2kNreMQZbwzWo3nH6bLPZjpek9DjYVm-VK4RIE-kpvFcKPUACk8Zf4kjFBbVYnF-myUOeOYV6R_DYwCTfkTPI1FN2FGvPIiDc/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="234" data-original-width="841" height="178" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgORHMwGK_sMsPjcjEEU4J1NptxkE4_yWY2378v1TmE3u2kNreMQZbwzWo3nH6bLPZjpek9DjYVm-VK4RIE-kpvFcKPUACk8Zf4kjFBbVYnF-myUOeOYV6R_DYwCTfkTPI1FN2FGvPIiDc/w640-h178/image.png" width="640" /></a></span></div><span style="font-family: Ubuntu; font-size: medium;"><br /><br /></span><p></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span><br /></p><p><br /></p><p><span style="font-family: Ubuntu; font-size: medium;">As expected, kube DNS access is working fine.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>Conclusion:</b></span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;"><b>At the heart of cloud computing is virtualization. It combines storage, compute and network virtualization. Here, in this exercise, we used a google compute engine, which itself is virtual machine and we deployed whole openstack network, storage and compute virtualization framework, provisioned two ubuntu VMs, launched a kubernetes cluster, deployed PODs and everything works!</b> As mentioned in the beginning, we could have taken this nesting and virtualization much further but this has been already long post. We stop here for today.</span></p><p style="text-align: justify;"><br /></p><p style="text-align: justify;"><span style="font-family: Ubuntu;">Lastly: The CLI version of this can be found at <a href="https://github.com/ratulb/k8s-openstack-gcp" target="_blank">github</a> - which is a hassle free way of achieving the whole thing by running couple of scripts. Following is a snap of the same.</span></p><p style="text-align: justify;"> </p><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBTUBm6NYz3g4zO3EXjSnqajtixUwcvYhLKtUo8-SlgZKJCQzcHV3yoQe85FywXbNQEnjAyrbYwKDaTGgjS2i9TXq-mNdOKYrqxn71z1tacvL00raQwvvqtspFFzTBg5V9r4UceD1YHms/" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img data-original-height="351" data-original-width="669" height="336" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBTUBm6NYz3g4zO3EXjSnqajtixUwcvYhLKtUo8-SlgZKJCQzcHV3yoQe85FywXbNQEnjAyrbYwKDaTGgjS2i9TXq-mNdOKYrqxn71z1tacvL00raQwvvqtspFFzTBg5V9r4UceD1YHms/w640-h336/image.png" width="640" /></a></div><br /><p></p><p><br /></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-family: "courier new", monospace; font-size: 16px; font-variant-ligatures: none; white-space: pre;"><br /></span></p>rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-73437977487102498852020-10-25T08:29:00.015+05:302020-11-23T06:21:46.499+05:30NFS persistent volume and claim in kubernetes<p><span style="font-family: Ubuntu;"><span style="font-size: medium;">This write up shows detailed steps of how to setup a nfs server as a storage backend and make use of it in POD's<a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/" target="_blank"> persistent volume via persistent volume claim</a>. These have been tested to work with kubernetes </span><span style="font-size: medium;"><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-variant-ligatures: none; white-space: pre;">v1.19.3 </span><span>and </span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-variant-ligatures: none; white-space: pre;">nfs v4.2 </span><span>version ubuntu </span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-variant-ligatures: none; white-space: pre;">Ubuntu 18.04.5 LTS</span><span>.</span></span></span></p><p><span><b><span style="font-family: Ubuntu; font-size: medium;">Set up nfs server:</span></b></span></p><p><span><span style="font-family: Ubuntu; font-size: medium;">Following commands would set up the server for storage backend:</span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-size: 16px; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu;">apt update && apt install nfs-kernel-server -y </span></span></p><p><span><span style="font-family: Ubuntu; font-size: medium;">Create a directory called /mnt/nfs-share and provide all permission to clients. We may need to re-consider what permissions are allowed based on requirements. </span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-size: 16px; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu;"> mkdir -p /mnt/nfs-share/ && chmod -R 777 /mnt/nfs-share</span></span></p><p><span><span style="font-family: Ubuntu; font-size: medium;">We also, change the ownership of the shared directory next.</span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-size: 16px; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu;">chown -R nobody:nogroup /mnt/nfs_share/</span></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><span>We need to edit the <b>/etc/exports</b> file to grant access to clients. Here we are </span><span>specifically</span><span> granting access to couple of machines.</span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-size: 16px; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu;"> vi /etc/exports </span></span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">/mnt/nfs<span style="color: #cc0000;">-</span><span style="background-color: #ef2929; color: #eeeeec;">share</span>/ 10.148.0.13/32(rw<span style="color: #cc0000;">,</span>sync<span style="color: #cc0000;">,</span>no_subtree_check)</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">/mnt/nfs<span style="color: #cc0000;">-</span><span style="background-color: #ef2929; color: #eeeeec;">share</span>/ 10.148.0.12/32<span style="background-color: #00b5bd;">(</span>rw<span style="color: #cc0000;">,</span>sync<span style="color: #cc0000;">,</span>no_subtree_check<span style="background-color: #00b5bd;">)</span></span></x-row></p><p><span><span style="font-family: Ubuntu; font-size: medium;">Execute the following commands to complete the server setup process:</span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-size: 16px; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu;">exportfs -a</span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-size: 16px; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu;">systemctl restart nfs-kernel-server</span></span></p><p><span style="font-family: Ubuntu;">Note: We might need to allow firewall access depending on whether firewall is active or not:</span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">root@master:~/deployments/nfs# ufw status</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">Status: inactive</span></x-row></p><p><span style="font-family: Ubuntu;">If firewall is <b>active </b>fire the following commands:</span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-size: 16px; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu;">ufw allow from 10.148.0.12 to any port nfs</span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-size: 16px; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu;">ufw allow from 10.148.0.13 to any port nfs</span></span></p><p><b style="font-size: large;"><span style="font-family: Ubuntu;"><br /></span></b></p><p><b style="font-size: large;"><span style="font-family: Ubuntu;">Set up a client and check that shared access is working:</span></b></p><p><span><span style="font-family: Ubuntu; font-size: medium;">Install nfs client in one of the boxes that would share kubernetes workloads :</span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-size: 16px; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu;">root@worker-1:~# apt install nfs-common</span></span></p><p><span><span style="font-family: Ubuntu; font-size: medium;">Create a directory and mount the shared nfs server directory as shown below:</span></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-size: 16px; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu;">mount 10.148.0.10:/mnt/nfs_share /mnt/client_share</span></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><span>Writing something in the client's </span><b>/mnt/client_share</b><span> folder should reflect it on the server and other connected clients.</span></span></p><p><span><span style="font-family: Ubuntu; font-size: medium;"><br /></span></span></p><p><span><b><span style="font-family: Ubuntu; font-size: medium;">Create PV and PVC (Persistent volume & claim):</span></b></span></p><p><span style="font-family: Ubuntu; font-size: medium;">First we create PV definition on the kubernetes server:</span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">root@master:~/deployments/nfs# cat pv-nfs.yaml </span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">apiVersion: v1</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">kind: PersistentVolume</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">metadata:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> name: pv-nfs-vol</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">spec:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> capacity:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> storage: 1Gi</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> volumeMode: Filesystem</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> accessModes:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> - ReadWriteMany</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> persistentVolumeReclaimPolicy: Retain</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> storageClassName: nfs-storage-class</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> mountOptions:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> - hard</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> - nfsvers=4.2</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> nfs:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> path: /mnt/nfs-share</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> server: 10.148.0.10</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">root@master:~/deployments/nfs# kubectl apply -f pv-nfs.yaml </span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">persistentvolume/pv-nfs-vol created</span></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="font-family: Ubuntu; font-size: medium;">Next, we create the PVC definition followed by the busybox pod definition as shown below:</span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">root@master:~/deployments/nfs# cat pvc-nfs.yaml </span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">apiVersion: v1</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">kind: PersistentVolumeClaim</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">metadata:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> name: pvc-nsf</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">spec:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> accessModes:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> - ReadWriteMany</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> storageClassName: nfs-storage-class</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> resources:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> requests:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> storage: 100Mi</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">root@master:~/deployments/nfs# kubectl apply -f pvc-nfs.yaml </span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">persistentvolumeclaim/pvc-nsf created</span></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-size: 16px; font-variant-ligatures: none; white-space: pre;"><span style="font-family: Ubuntu;">kubectl get pv,pvc </span></span></p><p><span style="font-family: Ubuntu;"><span style="font-size: medium;">The above command out should show the status of <b>PV and PVC</b> as </span><span style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; font-size: 16px; font-variant-ligatures: none; white-space: pre;">BOUND</span><span style="font-size: medium;"> at this point.</span></span></p><p><span style="font-family: Ubuntu; font-size: medium;">The POD definition:</span></p><p><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">root@master:~/deployments/nfs# cat pod-busybox.yaml </span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">apiVersion: v1</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">kind: Pod</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">metadata:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> name: busybox</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">spec:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> containers:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> - image: busybox</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> name: busybox</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> command:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> - sh</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> - -c</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> - 'while true; do date >> /tmp/nfs/index.html; hostname >> /tmp/nfs/index.html; sleep 10; done'</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> imagePullPolicy: IfNotPresent</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> volumeMounts:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> - name: nfs-claim</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> mountPath: "/tmp/nfs"</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> restartPolicy: OnFailure</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> volumes:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> - name: nfs-claim</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> persistentVolumeClaim:</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> claimName: pvc-nsf</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;"> nodeName: master</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">root@master:~/deployments/nfs# kubectl apply -f pod-busybox.yaml </span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">pod/busybox created</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">root@master:~/deployments/nfs# kubectl get pod busybox </span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">NAME READY STATUS RESTARTS AGE</span></x-row><x-row style="background-color: #222222; caret-color: rgba(0, 0, 0, 0); color: white; display: block; font-size: 16px; font-variant-ligatures: none; height: var(--hterm-charsize-height); line-height: var(--hterm-charsize-height); visibility: visible; white-space: pre;"><span style="font-family: Ubuntu;">busybox 1/1 Running 0 10s</span></x-row></p><p><span style="font-family: Ubuntu; font-size: medium;">The changes in <b>index.html</b> can be seen in server<b>/mnt/nfs_share</b>, client<b>/mnt/client_share</b> and inside the busybox container's <b>/tmp/nfs</b> directories.</span></p><p><br /></p>rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-81675723819925250372020-09-24T04:21:00.008+05:302021-02-16T11:43:47.487+05:30Nested virtualbox VM inside google compute engine<p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Though guest VM inside google compute engine raises concerns about performance, there are situations where they prove useful. In this post I am going to discuss how we can install a ubuntu guest VM on google compute engine instance.</span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">There are few caveats though - we can install a KVM compatible hypervisor only on Linux VM instances running only on<b> Haswell or newer processors</b>. Also, Haswell based processors <b>are not available in all GCP regions</b> - they are available in certain regions in US(US central) and Europe.</span></p><p><span style="font-family: Ubuntu; font-size: medium;">Windows compute engines do not support nested virtualization.</span></p><p><span style="font-family: Ubuntu; font-size: medium;">We need to create compute engines supporting nested virtualization off of disk images tagged with a specific license, namely:</span></p><p><b><span style="font-family: Ubuntu; font-size: medium;">"--licenses https://compute.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx";</span></b></p><p><span style="font-family: Ubuntu; font-size: medium;">With these restrictions in mind, lets proceed with the following steps to launch a compute engine which will host a ubuntu guest VM on top of oracle virtualbox.</span></p><p><b><span style="font-family: Ubuntu; font-size: medium;">1) Log into GCP console and launch the cloud shell:</span></b></p><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiISX3flYS58LZp9uFS0ldGbB-qH83KIY3mMvs7VMjPqVF7a2bD5RZQqq7Eu8YaI3PY1qrxNyerGkriMhkeU43WeSCueGfVbFxjNLkH-QqWKzgH88igs4CG0XPwEd4b1h9L9OqK1QCVG04/s726/cloud-shell1.png" style="margin-left: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img border="0" data-original-height="251" data-original-width="726" height="219" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiISX3flYS58LZp9uFS0ldGbB-qH83KIY3mMvs7VMjPqVF7a2bD5RZQqq7Eu8YaI3PY1qrxNyerGkriMhkeU43WeSCueGfVbFxjNLkH-QqWKzgH88igs4CG0XPwEd4b1h9L9OqK1QCVG04/w631-h219/cloud-shell1.png" width="631" /></span></a></p><b><span style="font-family: Ubuntu; font-size: medium;"> 2) set project:</span></b><div><b><span style="font-family: Ubuntu; font-size: medium;"> gcloud config set project [PROJECT]</span></b></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><b><span style="font-family: Ubuntu; font-size: medium;">3) We would create disk image from ubuntu family tagging it with above license as shown:</span></b></div><p><b><span style="font-family: Ubuntu; font-size: medium;">$ gcloud compute disks create virtualization-tagged-disk --image-project ubuntu-os-cloud --image-family ubuntu-1804-lts --zone us-central1-a --licenses "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"</span></b></p><p><span style="font-family: Ubuntu; font-size: medium;">It might ask for authorization - click on <b>"Authorize".</b></span></p><p><span style="font-family: Ubuntu; font-size: medium;"><br /></span></p><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuhyphenhyphenKoja_ccDnFE0kMfXrKDW9KSDR8dNufmt9leGI_9M2qt0b7NZ22yL9SC6l_vvjkILYQ3dmqAl2Unf0EwS6eFXSX34U5TSwPfDd_NnheC-lP8lPit6hIyYggwIENx8yFis1iAcgrucU/s844/cloud-shell-disk-iamge.png" style="margin-left: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img border="0" data-original-height="191" data-original-width="844" height="138" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuhyphenhyphenKoja_ccDnFE0kMfXrKDW9KSDR8dNufmt9leGI_9M2qt0b7NZ22yL9SC6l_vvjkILYQ3dmqAl2Unf0EwS6eFXSX34U5TSwPfDd_NnheC-lP8lPit6hIyYggwIENx8yFis1iAcgrucU/w613-h138/cloud-shell-disk-iamge.png" width="613" /></span></a></p><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><span style="font-family: Ubuntu; font-size: medium;">This will create a disk image called "virtualization-tagged-disk". We can launch a ubuntu VM based off of this image and install oracle virtualbox on that compute engine instance and then launch a guest VM inside virtualbox.</span></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><span style="font-family: Ubuntu; font-size: medium;">Note: We would have to launch the instance in a <b>GCP region where Haswell processors (N1 family) </b>are available.</span><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><b><span style="font-family: Ubuntu; font-size: medium;">4) Select the disk image as shown:</span></b></div><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdm4eMd1fv4vkmxj_tIheQaVbqhcp83ggxEZVhxryc10cQoZrrHFb39gQYBl2-7jOsgQ4dZagXTQGzC-ntUwVUbUbz33lLnhXGdRTl2h3qQawwnHPxBjzpngRbfZHHLQNGPFL1MEHCU5Q/s905/select-disk.png" style="margin-left: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img border="0" data-original-height="302" data-original-width="905" height="220" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdm4eMd1fv4vkmxj_tIheQaVbqhcp83ggxEZVhxryc10cQoZrrHFb39gQYBl2-7jOsgQ4dZagXTQGzC-ntUwVUbUbz33lLnhXGdRTl2h3qQawwnHPxBjzpngRbfZHHLQNGPFL1MEHCU5Q/w657-h220/select-disk.png" width="657" /></span></a></div><span style="font-family: Ubuntu; font-size: medium;"><br /></span><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span><p><b><span style="font-family: Ubuntu; font-size: medium;">5) Launch an instance selecting the disk and appropriate region and processor:</span></b></p><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4L2ynOfQ39mlNjDhOqNfXZwkVjVxh1tHAZojcokL1Twz2dlocIdvWk8WBMg1LbT7YhL_jt0iOCGhlTpVguceBdxPtyXIqJ9gk-Yf6zKWyrQUmAU5eK15jIOBg60vlnWgx9BRNuQ0TEtg/s831/n1-central-us.png" style="margin-left: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img border="0" data-original-height="434" data-original-width="831" height="305" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4L2ynOfQ39mlNjDhOqNfXZwkVjVxh1tHAZojcokL1Twz2dlocIdvWk8WBMg1LbT7YhL_jt0iOCGhlTpVguceBdxPtyXIqJ9gk-Yf6zKWyrQUmAU5eK15jIOBg60vlnWgx9BRNuQ0TEtg/w584-h305/n1-central-us.png" width="584" /></span></a></p><span style="font-family: Ubuntu; font-size: medium;"><br /></span><p><span style="font-family: Ubuntu; font-size: medium;">Once the compute engine instance is started - we can ssh into it and setup a desktop environment so that we can access it via RDP.</span></p><p><b><span style="font-family: Ubuntu; font-size: medium;">Setting up RDP and install oracle virtualbox:</span></b></p><p><b><span style="font-family: Ubuntu; font-size: medium;">Setup RDP on the compute engine:</span></b></p><p><b><span style="font-family: Ubuntu; font-size: medium;">1) Once inside the compute engine instance - we can uncomment following series of command to setup the RDP server environment and change the password for root user and then exit and connect back to the box via a remove RDP client:</span></b></p><p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgmVQ0K7LaP9WzlOe5FTFGwZvgJ5oJ1nw_J5cYPLjb5CiR5F9TvH9mqim3Rf6iGvEa6LEFUFK6uWhEdNk4yj8K_16rsOYdfFJcWu-dQnKQSzrenVjGX5_HUJD8kGMPzAb5TmF4fZEkBsk/s464/rdp.png" style="margin-left: 1em; margin-right: 1em; text-align: center;"><span style="font-family: Ubuntu; font-size: medium;"><img border="0" data-original-height="140" data-original-width="464" height="165" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgmVQ0K7LaP9WzlOe5FTFGwZvgJ5oJ1nw_J5cYPLjb5CiR5F9TvH9mqim3Rf6iGvEa6LEFUFK6uWhEdNk4yj8K_16rsOYdfFJcWu-dQnKQSzrenVjGX5_HUJD8kGMPzAb5TmF4fZEkBsk/w544-h165/rdp.png" width="544" /></span></a></p><div><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><b><span style="font-family: Ubuntu; font-size: medium;">2) Connect to the box via a remote desktop client client install virtualbox.</span></b></div><br /><div><b>curl -O https://download.virtualbox.org/virtualbox/6.1.14/virtualbox-6.1_6.1.14-140239~Ubuntu~bionic_amd64.deb</b></div><div><b>apt install ./virtualbox-6.1_6.1.14-140239~Ubuntu~bionic_amd64.deb</b></div><div><br /></div><div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9tWapQxE16QJ4AMKanbv9NZHgjaXzK3cMQJwUoNarluy4piBFJUlEalGvVvRQ-HeNcLPK-jmYdp1ovn_vDzJnsP78UIZNKSG31H7k_R1codhme2cNjOJbiX0kVuaCsAfoB7YRwRFUWdQ/s899/virtualbox.png" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" data-original-height="242" data-original-width="899" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9tWapQxE16QJ4AMKanbv9NZHgjaXzK3cMQJwUoNarluy4piBFJUlEalGvVvRQ-HeNcLPK-jmYdp1ovn_vDzJnsP78UIZNKSG31H7k_R1codhme2cNjOJbiX0kVuaCsAfoB7YRwRFUWdQ/w716-h192/virtualbox.png" width="716" /></a></div><br /><div><br /></div><div><p><br /></p><p><span style="font-family: Ubuntu;"><span style="font-size: medium;"><b>Note: </b>For better view install xfce4 goodies:</span></span></p><p><span style="font-size: medium;"><span style="font-family: Ubuntu;"><span style="-webkit-text-stroke-width: 0px; background-color: #f2f2f2; color: #292929; display: inline !important; float: none; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: -0.352px; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: pre-wrap; word-spacing: 0px;">apt-get install xfce4 xfce4-goodies</span></span></span></p><p><br /></p></div>rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-45786113137345544882020-09-15T04:02:00.006+05:302020-11-23T06:53:21.843+05:30Exploring envoyproxy<p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">With the adoption of micro-services, we need to tackle hosts of issues associated with remote calls and networking - because what used to be an in-process function call now becomes a RPC call that need to be handled by a service <b>which needs to be discovered</b>. Service discovery has its own issues - among others, the most important being able to <b>discover services that are active</b>. Once services are discovered - we need to handle <b>uniform spread of requests</b> among discovered service instances. <b>Traffic encryption </b>becomes another issue that we need to handle once a call goes out over the wire from one micro-service to another. </span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Another very obvious requirement in a cluster of micro-services is the need to monitor and trace requests. Without this requirement being taken care, it is difficult to figure out how services are executing on distributed network.</span></p><p><span style="font-family: Ubuntu; font-size: medium;">While there still many more issues that we need to take care of in a micro-services' setup - what should be our approach on a high-level to tackle them?</span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Among others - one approach could be to develop client side libraries - which handle issues of service discovery, load balancing(retry, timeout, circuit breaking etc) and others. This was the approach Netflix Eureka/ribbon/zuul stack had proposed. Eureka client acted as a service proxy - eureka server acting as a service registry and ribbon providing client side load balancing and zuul handling request routing.</span></p><p><span style="font-family: Ubuntu; font-size: medium;">While the library approach works - there are few things to consider while we embark on the library journey:</span></p><p><span style="font-family: Ubuntu; font-size: medium;">- Business code now get entangled with infrastructure code.</span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">- We are sticking are head out either as an one language shop or we are undertaking quite a complicated job of developing/maintaining client libraries in multiple programming languages.</span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Is there an easy way to tackle the issues associated with micro-services? Yes! That is what out-of-process proxies like <b><a href="https://www.envoyproxy.io/" target="_blank">envoy </a></b>and <b><a href="https://linkerd.io/">linkerd </a></b>provide. All ready existing proxies like Nginx and HA-PROXY etc are adding support for capabilities similar to those provided by envoy proxy. We will discuss linkerd in a later post - here we will talk about envoy proxy.</span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Envoy's website talks of envoy being a edge and service service proxy - this means we can use envoy for north-south as well as east-west traffic. Envoy is written in modern C++ and most of requests handling run concurrently in lock free code. This make envoy very fast. </span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">Envoy has lot of goodies to offer - it's <b>out of process architecture</b> straight away boosts developer productivity. The network and myriad of associated issues go away instantly - letting the developer focus on his business problem. Envoy being out of process - provides a huge advantage - we can develop our services in any language of our choice and necessity. </span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">As mentioned earlier - envoy provides many load balancing features - automatic request retries, circuit breaking, request timeouts, request shadowing, rate limit etc.</span></p><p><span style="font-family: Ubuntu; font-size: medium;">With envoy's traffic routing features, we can easily do <b>rolling upgrade of services, blue/green and canary deployment</b> etc.</span></p><p><span style="font-family: Ubuntu; font-size: medium;">Envoy provides <b>wire level observability of request traffic and native support for distributed tracing.</b></span></p><p><span style="font-family: Ubuntu; font-size: medium;">Envoy supports <b>HTTP/1.1, HTTP/2 & gRPC</b> - it <b>transparently switches between HTTP/1.1 and HTTP/2</b>.</span></p><p style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">One very important aspect of envoy proxy is that - while envoy can be configured statically - yet it provides<b> robust APIs for dynamic configuration</b>. What is more - <b>envoy can patched and upgraded</b> without shutting it down via what is called "<b>Hot-Restart</b>". We would configure some of envoy's features in upcoming posts - but before that following concepts about envoy would help.</span></p><p style="text-align: justify;"><b><span style="font-family: Ubuntu; font-size: medium;">Envoy proxy concepts:</span></b></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>Downstream:</b> A downstream host connects to Envoy, sends requests, and receives responses.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>Upstream:</b> An upstream host receives connections and requests from Envoy and returns responses.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>Listeners:</b> They are the addresses where envoy process listens for incoming connections. For example,</span></p><p><span style="font-family: Ubuntu; font-size: medium;">0.0.0.0:9090. There can multiple listeners in an envoy process.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>Filter chains:</b> Each listener in an envoy process can be configured with filter chains - where each chain consists of one or more filters. Filter chains are selected based on incoming request and some matching criteria.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>Routes:</b> Based on matching criteria - requests are delegated to be handled by back-end clusters.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>Clusters: </b>Named collection of back-ends called endpoints. Requests are load balanced among the cluster endpoints.</span></p><p><span style="font-family: Ubuntu; font-size: medium;"><b>Endpoints:</b> Endpoints are the delegates which handles requests. They are part of cluster definition.</span></p><p><span style="font-family: Ubuntu; font-size: medium;">In the next post - we would install envoy and look at traffic routing. Stay tuned.</span></p>rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-70291979663987065192020-08-02T23:43:00.008+05:302020-11-19T04:23:33.087+05:30Algorithms and data structures in rust - mergesort<div dir="ltr" style="text-align: justify;" trbidi="on"><span style="font-family: Ubuntu; font-size: medium;">Bets about<a href="https://www.rust-lang.org/"><b> rust</b></a> are turning out to be right. Initially proposed as system programming language(read servo - rewrite of firefox browser) - numerous front end web frameworks are appearing and becoming ubiquitous. Rust has a steep learning curve - but that is a reasonable investment considering the low level power it gives to do system level things at the same time high level abstraction that comes without the price(zero cost). Borrow and ownership prevent memory issues, move semantics avoids data races, effort less C binding, avoidance of a runtime are some of the salient features of rust. Its implementation of <a href="https://rust-lang.github.io/async-book/"><b>Async & wait</b></a> is also novel.</span></div><div dir="ltr" style="text-align: justify;" trbidi="on"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div dir="ltr" style="text-align: justify;" trbidi="on"><span style="font-family: Ubuntu; font-size: medium;">Its has been quite some time following the developments in rust - have been utilizing rust in one of my projects currently. I am going to be publishing some posts on rust and what better way than implementing algorithms and data structures to start with?</span></div><div dir="ltr" style="text-align: justify;" trbidi="on"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div dir="ltr" trbidi="on"><span style="font-family: Ubuntu; font-size: medium;">Following is an implementation of merge sort algorithm in rust. </span></div><div dir="ltr" trbidi="on"><span style="font-family: Ubuntu; font-size: medium;"><br /></span></div><div dir="ltr" trbidi="on"><span style="font-family: Ubuntu; font-size: medium;">Rust allows defining local functions. Which is kind of neat & compact. Below is merge sort algorithm implemented using local functions. <br /><br /><img alt="" src="data:image/png;base64,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" /><br /><br /><br />We make use of life times to return the sorted array. There does not seem to be an easy way to create arrays at runtime - the reason being arrays are allocated at the stack.<br /></span></div><div dir="ltr" trbidi="on"><span style="background-color: white; color: #333333; font-family: Ubuntu; font-size: medium;"><br /></span></div><div dir="ltr" trbidi="on"><b><span style="font-family: Ubuntu; font-size: medium;"><span face="verdana, geneva, sans-serif" style="background-color: white; color: #333333;">Source: </span><a href="https://github.com/ratulb/algos_in_rust" style="background-color: white; color: #015782; text-decoration-line: none;">https://github.com/ratulb/algos_in_rust</a></span></b></div>rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-29690452966498414462020-07-30T03:18:00.002+05:302020-10-25T08:32:21.776+05:30Quick sort routine in rust<div dir="ltr" style="text-align: left;" trbidi="on"><span style="font-family: Ubuntu; font-size: medium;">
A quick sort routine in rust:<br />
<br /><img alt="" src="data:image/png;base64,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" /><br />
<br />
Source: <a href="https://github.com/ratulb/algos_in_rust">https://github.com/ratulb/algos_in_rust</a><br /></span>
<br /></div>
rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-71878016918930608042019-12-22T22:57:00.001+05:302020-10-25T08:33:19.073+05:30Install PySpark on windows<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><ol style="text-align: left;">
<li><b><span style="font-family: Ubuntu; font-size: medium;">Install java and expose JAVA_HOME</span></b></li>
<li><b><span style="font-family: Ubuntu; font-size: medium;">Install spark and expose SPARK_HOME</span></b></li>
<li><b><span style="font-family: Ubuntu; font-size: medium;">Install findspark:</span></b></li>
</ol>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgNdc8KYxXUkmDHFLNRcm5yhTY-g0A1if4VIDQAI7FrGbZw7gUOVcdng-dMp-Oadfc1Lhpo6q5nNDIeo1GJh4RYSOFlid1MRnacz5xrFWPaG6gGKvf2XGGPmsIfcjpRrRsG2bYfxg0gIs/s1600/install-findspark.PNG" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: Ubuntu; font-size: medium;"><img border="0" data-original-height="184" data-original-width="653" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgNdc8KYxXUkmDHFLNRcm5yhTY-g0A1if4VIDQAI7FrGbZw7gUOVcdng-dMp-Oadfc1Lhpo6q5nNDIeo1GJh4RYSOFlid1MRnacz5xrFWPaG6gGKvf2XGGPmsIfcjpRrRsG2bYfxg0gIs/s1600/install-findspark.PNG" /></span></a></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<b><span style="font-family: Ubuntu; font-size: medium;">Launch jupyter lab and use pyspark in notebook:</span></b></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0xT1s96-iOsxbDh_xSdDVpQNoq1GFIJuOHfKJ1pYA4dX46hUGD5jxEzpWlLiUVx6fdBn005jxx5Y59PhtJbtPyZuVNZoAn7n1Cl3_c4xzxppbzrJ5d2lsWI0aciMYmSNc4mIJGmUk3hA/s1600/pyspark-jupyter-notebook.PNG" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><span style="font-family: Ubuntu; font-size: medium;"><img border="0" data-original-height="365" data-original-width="675" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0xT1s96-iOsxbDh_xSdDVpQNoq1GFIJuOHfKJ1pYA4dX46hUGD5jxEzpWlLiUVx6fdBn005jxx5Y59PhtJbtPyZuVNZoAn7n1Cl3_c4xzxppbzrJ5d2lsWI0aciMYmSNc4mIJGmUk3hA/s1600/pyspark-jupyter-notebook.PNG" /></span></a></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div>
<br /></div>
</div>
rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-87715631379215395142019-12-17T02:18:00.001+05:302020-10-25T08:33:44.131+05:30Kubernetes Secrets in plain English<div dir="ltr" style="text-align: left;" trbidi="on">
<b>Want to get a high level view of kubernetes secrets?<a href="https://enterprisersproject.com/article/2019/8/kubernetes-secrets-explained-plain-english?extIdCarryOver=true&sc_cid=701f2000001Css5AAC"> Read on...</a></b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQ2Moox8ARP3cNNOl3zx5Xj1AvNVZZxLEKb_WiQjUZjoyBJAbEmwWWidHHjZHFRAg3X2iwVK1ejiCeFj6k22u75hahWvW9dztX6iXUvR8NEnmgaRxIIDpPj6i8n4X70Lk0wcJJliqpFI0/s1600/kubernetes_secrets.PNG" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="212" data-original-width="633" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQ2Moox8ARP3cNNOl3zx5Xj1AvNVZZxLEKb_WiQjUZjoyBJAbEmwWWidHHjZHFRAg3X2iwVK1ejiCeFj6k22u75hahWvW9dztX6iXUvR8NEnmgaRxIIDpPj6i8n4X70Lk0wcJJliqpFI0/s1600/kubernetes_secrets.PNG" /></a></div>
<br /></div>
rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-27422457449691295012019-12-17T01:10:00.002+05:302021-03-28T00:56:12.567+05:30Back propagation in neural network training<div dir="ltr" style="text-align: left;" trbidi="on"><span style="font-family: Ubuntu; font-size: medium;">
Back propagation fundamental to neural network training. As always, <a href="https://cs.stanford.edu/people/karpathy/" target="_blank">Andrej Karpathy</a> does a fantastic job explaining how it is calculated and applied during neural network training.<b> <a href="https://www.youtube.com/watch?reload=9&v=i94OvYb6noo">Check this out!</a></b></span><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQ7JOqcSZthrhjHoxv1F_e8CaCAYS8dtR4KgzhpE2CzJ_dPhWeuYUaaJtok4miXungsqBxcG5_-MRVVkz_WV74zs7AArdkWmIs9NgTKVP-lsCbzVDujkH93FwjC0GW3ut0i8d2USu3gn0/s1600/bakpropagation.PNG" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="326" data-original-width="609" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQ7JOqcSZthrhjHoxv1F_e8CaCAYS8dtR4KgzhpE2CzJ_dPhWeuYUaaJtok4miXungsqBxcG5_-MRVVkz_WV74zs7AArdkWmIs9NgTKVP-lsCbzVDujkH93FwjC0GW3ut0i8d2USu3gn0/s1600/bakpropagation.PNG" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
</div>
rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-2929807142820954862014-08-21T18:37:00.006+05:302021-03-28T01:00:40.412+05:30The essence of a monad<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
<b>Many people when they encounter the term 'monad' for the the first time, they decide to look it up, at least the curious bunch.</b> But when they do consult the blogs, articles, Wikipedia, haskell documentations- explaining the term monad - they <b>become deeply confused and angry at themselves for not being able to make any sense of it - at least people like me, whose brain is not bigger than the size of a peanut. They curse themselves and grok more blogs, articles, try to learn haskell in the hope that, may be this time they would be able to grasp it - but to no avail</b>. Their brain hurts and they become even more confused. As they keep persisting in their efforts -<b> they come across monads being described as elephants, space suits/burritos/fluffy clouds and what not</b>! Some say - you need to know category theory to understand monad, some say no you do not - while people trying understand monad remain in a state of utter confusion for months or maybe years on end. This happened to me also - couple of years back(As I said before my brain is not bigger than a peanut!).</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
People say, "when you finally figure out what a monad is - you write a blog about it - that is a tradition". Well, I had decided to break with that tradition and not to write about it then - when that enlightenment happened! But I have now decided to go with tradition mainly because functional programming is being so ubiquitous and terms like monad/functors etc keep appearing all over the web and many people out their may be languishing to come to terms with monads. Hope this post would help them see what a monad is.</span></div>
<div style="text-align: justify;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
<b>Then, why is monad so difficult to understand? I suppose there are couple of reasons for this. First, expectation on part of the person trying to understand monad. He/she expects monad to be self describing one whole thing. Once you read couple of blogs and articles, you expect to get a self explanatory picture of a concrete thing. That is a wrong expectation on the part of the learner. Monad is an abstraction of a design concept and there are different concrete implementations of this concept specific to particular problems. We need to keep this in mind.</b></span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Second, except for couple of blogs/presentations, people who try to explain monad to the uninitiated, are also, to some extent, to be blamed for the confusion they cause to the people trying learn monads. I just googled for "what is a monad" - opened three top links that came up.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
This <a href="http://stackoverflow.com/questions/44965/what-is-a-monad">one</a> straight away goes into examples like 'List comprehension', 'Input/Output', 'A parser' and ending with an example of 'Asynchronous programming'.The questioner was asking for a <b>brief, succinct, practical explanation</b> as to what a monad essentially is! Straight away jumping to some arbitrary examples does not help. Not to speak of the haskell syntax that may be unfamiliar to the user. So the user trying to learn monad become bewildered, deeply confused and perplexed. Here questioner's mistake was that - he asked for a a <b>brief, succinct, practical</b> explanation. That is a wrong expectation.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Second one from <a href="http://en.wikipedia.org/wiki/Monad_(functional_programming)">Wikipedia</a> says, "In functional programming, a monad is a structure that represents computations defined as sequences of steps. A type with a monad structure defines what it means to chain operations, or nest functions of that type together. This allows the programmer to build pipelines that process data in steps, in which each action is decorated with additional processing rules provided by the monad". This one does not help. It sounds too abstract.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Another post mentions- "<a href="https://www.youtube.com/watch?v=b0EF0VTs9Dc">Douglas Crockford once said that monads are cursed – that once you understand monads for yourself you lose the ability to explain them to others</a>". Then goes on to talk about 'Maybe' & JQuery being monad. This does not help either - why should we be not able to explain what a monad is? </span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
All these and many more explanations have one thing in common. And that is that - they lack the motivation for monad and where it came from. That is where Brian Beckman: <a href="https://www.youtube.com/watch?v=ZhuHCtR3xq8">Don't fear the Monads</a> and <a href="http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html">sigfpe</a> shines. They talk about the motivation for monad.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<b>So what is a monad?</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
<b>In functional programming, functions are first class as is function composition</b>. We build small functions and compose them to build bigger functions.<b> So the way to tackle complexity is composition - it's of paramount importance. If functions do not compose, there arises an impedance mismatch.</b> <b>In pure functional languages like Haskell function are considered to be mathematical- no side effect, no logging, </b></span><span style="font-family: Ubuntu; font-size: medium;"><b>no exceptions. </b>Same function called with same input should give the same output irrespective of who called it, when called it or however called it. Period. No deviation from this contract. <b>But real world is not like this - Exception occur, latency happens, we need to handle unexpected result. So how do we account for these deviations? Well, taking recourse to monads of course!</b> Monad is the vehicle we hop on to stay in course in face of these unavoidable deviations. Let's see some examples:</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<b>Example 1:</b><br />
<br />
<span style="color: blue;">def getConnection(c: Credentials): Connection </span><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
If we look at the signature of the method above carefully, we are lying about something! We are hiding something. What if the network is down or the database is down? We might not get a connection at all. We are not being explicit about this aspect of getConnection method failing to give us connection. That is where motivation for using or designing Maybe/Option monad comes from.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
So the correct signature should be:<br />
<br />
<span style="color: blue;">def getConnection(c: Credentials): Option[Connection]</span><br />
<br />
If indeed getConnection returns a connection, we return <span style="color: blue;">Some(connection)</span> or <span style="color: blue;">None</span> if it fails. That we say beforehand so that caller may take alternate processing pipe line in the event of failing to get a connection.<br />
<br />
While previous fails to compose, second composes and the signature speak out loudly what the contract is.<br />
<br />
<b>Example 2:</b><br />
<br />
In scala, it is very idiomatic to do things like following:<br />
<br />
<span style="color: blue;">(1 to 10).toList.filter(_ % 2 == 0).flatMap(x => (0 to x).toList</span><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Basically we like to keep piping or chaining output of one function call as the input to the other function till we compute our desired result(Like after each semi-colon we keep executing statement afer statement in imperative programming). But many very times output of one function call does not conform to the input of another function which is to say they do not compose. We need to coerce the output of a function to a format that can be fed as input to other function, we need to get rid of the impedance mismatch. That is the role flatMap/bind in monads. And each monad will have its own implementation of this method that is specific to the problem it is trying to solve. To drive home the point, we conjure up the following fictitious problem:</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<span style="color: blue;">val urls = List("facebook.com", "twitter.com")</span><br />
<span style="color: blue;"><br /></span>
<span style="color: blue;">class Page</span><br />
<span style="color: blue;"><br /></span>
<span style="color: blue;">def getPage(url: String): Page = new Page</span><br />
<span style="color: blue;"><br /></span>
<span style="color: blue;">def outGoingLinks(page: Page): List[String] =List("bbc.com", "cnn.com")</span><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
What we want do to is this: we start with list of urls, crawl the pages corresponding to those urls & </span><span style="font-family: Ubuntu; font-size: medium;">get the total count of outgoing urls for all those pages. To achieve this we have defined our functions above. So following is the call to get the job done:</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<span style="color: blue;">urls.map(url => getPage(url)).flatMap(page => outGoingLinks(page)).size</span><br />
<span style="color: blue;"><br /></span>
<span style="color: blue;">res5: Int = 4</span><br />
<br />
</span><div style="text-align: justify;">
<div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
And we are done. '<span style="color: blue;">outGoingLinks</span>' function takes a page and returns a <span style="color: blue;">List[String]</span>. <b>This is the crucial point to understand</b>. So, when all the pages(here two) considered, the result would be <span style="color: blue;">List(List[String], List[String]).</span> But this not what we want - we want <span style="color: blue;">List[String]</span>. This where <span style="color: blue;">output is deviating</span>. But '<span style="color: blue;">flatMap</span>' apart from calling the '<span style="color: blue;">outGoingLinks</span>' function for each page also does one more thing. It concatenates the <span style="color: blue;">List[List[String], List[String])</span> to one <span style="color: blue;">List[String]</span>. '<span style="color: blue;">flatMap'</span> implementation in the case of List monad just happens to be that it takes a function (something) -> List[something] and concatenates the resulting lists into a single List[something] - so that we can stay the course. '<span style="color: blue;">flatMap</span>' guides you to the <b>happy path</b> as <b>Erik Meijer</b>(of Rx/Link fame) says while teaching '<a href="https://www.coursera.org/instructor/headinthebox">Principles of Reactive Programming'</a> . It keeps you from falling off the cliff.</span></div>
</div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
So, monad is an abstraction of a design concept in functional programming and the motivation comes from recognizing the fact that composition is important. There are various implementation of this concept like Try, Either, Future, Option etc.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Of course, there are <b>monadic laws that monad should hold. But they are not a prerequisite to an understanding of what the essence of monads is</b>. When monads hold all three monad laws, it is a guarantee that they will not misbehave. In fact, the Try monad above holds only two of the monad laws and but for all practical purposes, it behaves like a monad. </span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
As a last note, monads are not specific to functional programming alone. The .Net implementation <a href="https://github.com/ReactiveX/RxJava"><b>Rx(Reactive extention) </b>has been ported to <b>java</b></a> by Netflix and it is all monadic underneath. Its changing the the whole game of event/stream processing and how to write reactive applications that scales up to millions of user requests.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
It has been a long post. But hope it helps people who are trying to get on with monad and removes some of the mists surrounding monads.<br /></span>
<br /></div>
rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-34766724629729746452013-03-01T21:42:00.001+05:302020-10-25T08:34:56.706+05:30Fun with scala's for comprehension: Solving sudoku in 11 lines!<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Scala's for loop(comprehension) may look deceptively similar to java's for loop, but it is much more powerful than java's for loop. While java's for loop is just to repeat some computation for specified number of times, scala's for comprehension has a mathematical underpining to it. They are analogous to set comprehensions, which are normally used for building more specific sets out of general sets. Shown below is a basic set comprehension of 10 even natural numbers.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<span style="color: blue;"><b> S = {2*x; x <- N; x <= 10}</b></span><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
The first part <b>2*x</b> is called the output, <b>N</b> is the input set and <b>x <= 10</b> is the predicate filter. The same translated to for comprehension along with output is shown below:</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;">
<span style="color: blue; font-family: Ubuntu; font-size: medium;">scala> val s = for { </span></div>
<div style="text-align: justify;">
<span style="color: blue; font-family: Ubuntu; font-size: medium;"> | x <- 1 to Integer.MAX_VALUE</span></div>
<div style="text-align: justify;">
<span style="color: blue; font-family: Ubuntu; font-size: medium;"> | if(x <= 10)</span></div>
<div style="text-align: justify;">
<span style="color: blue; font-family: Ubuntu; font-size: medium;"> | } yield 2*x</span></div>
<div style="text-align: justify;">
<span style="color: blue; font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="text-align: justify;">
<span style="color: blue; font-family: Ubuntu; font-size: medium;">s: (2, 4, 6, 8, 10, 12, 14, 16, 18, 20)</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<b>Problem: Given a positive integer n, find all the pairs of integers (i,j) such that 1 <= j < i < n, and i+j is a prime number.</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Such combinatorial problems lend themselves to be solved beautifully with for comprehensions. Let's first define a function that tells us if a number is prime or not!</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
We know a number is a prime if it's only divisors are 1 and the number itself. While in imperative style we would start out with how to do it, in functional style we state what the problem is! So here goes our definition of isPrime.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<span style="color: blue;">scala> def isPrime(n: Int) = (2 until n).forall(d => n % d != 0)</span><br />
<span style="color: blue;">isPrime: (n: Int)Boolean</span><br />
<br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Now, to find all the pairs of numbers such that each two elements of the pairs sum up to a prime number, we just make use of for comprehensions and the isPrime function defined above:</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;">
<span style="color: blue; font-family: Ubuntu; font-size: medium;">scala> def findPrimePairs(n: Int) = </span></div>
<div style="text-align: justify;">
<span style="color: blue; font-family: Ubuntu; font-size: medium;"> | for {</span></div>
<div style="text-align: justify;">
<span style="color: blue; font-family: Ubuntu; font-size: medium;"> | i <- 1 until n</span></div>
<div style="text-align: justify;">
<span style="color: blue; font-family: Ubuntu; font-size: medium;"> | j <- 1 until i</span></div>
<div style="text-align: justify;">
<span style="color: blue; font-family: Ubuntu; font-size: medium;"> | if isPrime(i+j)</span></div>
<div style="text-align: justify;">
<span style="color: blue; font-family: Ubuntu; font-size: medium;"> | } yield(i,j)</span></div>
<div style="text-align: justify;">
<span style="color: blue; font-family: Ubuntu; font-size: medium;">findPrimePairs: (n: Int) IndexedSeq[(Int, Int)]</span></div>
<div style="text-align: justify;">
<span style="color: blue; font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="text-align: justify;">
<span style="color: blue; font-family: Ubuntu; font-size: medium;">scala> val primePairs = findPrimePairs(10)</span></div>
<div style="text-align: justify;">
<span style="color: blue; font-family: Ubuntu; font-size: medium;">primePairs: IndexedSeq[(Int, Int)] = Vector((2,1), (3,2), (4,1), (4,3), (5,2), (6,1), (6,5), (7,4), (7,6), (8,3), (8,5), (9,2), (9,4), (9,8))</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
Neat, elegant and concise.<br />
<br />
Let's try one more problem before we delve into solving sudoku in less than 11 line!<br />
<br />
Let's try find the numbers <b>x,y,z</b> below <b>n</b> such that <b>x^2 + y^2 == z^2</b>. Let's call the function rightAngledNumbers!<br />
<br />
<span style="color: blue;">scala> def rightAngledNumbers(n: Int) = </span><br />
<span style="color: blue;"> | for {</span><br />
<span style="color: blue;"> | x <- 1 until n</span><br />
<span style="color: blue;"> | y <- x+1 until n</span><br />
<span style="color: blue;"> | z <- y+1 until n</span><br />
<span style="color: blue;"> | if(x*x + y*y == z*z)</span><br />
<span style="color: blue;"> | } yield (x,y,z)</span><br />
<span style="color: blue;"><br /></span>
<span style="color: blue;">rightAngledNumbers: (n: Int)IndexedSeq[(Int, Int, Int)] </span><br />
<span style="color: blue;"><br /></span>
<span style="color: blue;">val result = rightAngledNumbers(100)</span><br />
<br />
result: = Vector((3,4,5), (5,12,13), (6,8,10), (7,24,25), (8,15,17), (9,12,15), (9,40,41), (10,24,26), (11,60,61), (12,16,20), (12,35,37), (13,84,85), (14,48,50), (15,20,25), (15,36,39), (16,30,34), (16,63,65), (18,24,30), (18,80,82), (20,21,29), (20,48,52), (21,28,35), (21,72,75), (24,32,40), (24,45,51), (24,70,74), (25,60,65), (27,36,45), (28,45,53), (30,40,50), (30,72,78), (32,60,68), (33,44,55), (33,56,65), (35,84,91), (36,48,60), (36,77,85), (39,52,65), (39,80,89), (40,42,58), (40,75,85), (42,56,70), (45,60,75), (48,55,73), (48,64,80), (51,68,85), (54,72,90), (57,76,95), (60,63,87), (65,72,97))<br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
I am not sure how many lines of code will be needed, if we try to do the same thing in an imperative way!</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Now, let's get back to solving sudoku in 11 lines. Let me clarify here - though our main logic of solving sudoku is confined to only 11 lines, yet the whole program is hardly but 11 lines. That is because, we have to do things like read the input from a file, index the cells with row, column and cell value etc. Also, we have to check on which box an empty cell falls along with a helper function to tell us if a particular value is allowed in an empty cell. Barring these, actual logic is, indeed confined to 11 lines. Let's first define few type aliases and show the function with 11 lines which solves the problem.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<b>type Cell = (Int,Int,Int)</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Cell represents a sudoku cell with <b>._1</b> being the <b>value</b>,<b>._2</b> being the <b>row</b> and <b>._3</b></span></div>
<div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
being <b>column</b> of the cell.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<b>type Solutions = List[List[Cell]]</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
We can have more than one possible solution to a sudoku problem depending on how many cells are already filled in. That is why our <b>Solutions</b> type alias is List of List of Cells. Shown below is the function that solves the sudoku.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<span style="color: blue;">def fillCells(emptyCells: List[Cell]): Solutions = {</span><br />
<span style="color: blue;"> if(emptyCells == Nil) List(List())</span><br />
<span style="color: blue;"> else {</span><br />
<span style="color: blue;"> for {</span><br />
<span style="color: blue;"> filledCells <- fillCells(emptyCells.init)</span><br />
<span style="color: blue;"> cellValue <- 1 to 9</span><br />
<span style="color: blue;"> cell = (cellValue,emptyCells.last._2, emptyCells.last._3)</span><br />
<span style="color: blue;"> if(isOk(cell, filledCells ::: nonEmpties)) </span><br />
<span style="color: blue;"> } yield cell :: filledCells </span><br />
<span style="color: blue;"> }}</span><br />
<br />
<br />
</span><div style="text-align: justify;">
<span style="font-family: Ubuntu; font-size: medium;"><b>Explanation:</b> We first take all the empty cells. Out of these empty cells, take all but last one and call fillCells recursively, which in turn repeats the process until we hit the base case when we call fillCells(Nil) - this returns an empty list of list. Now call stack unfolds inside out, calling fillCells with one empty cell and trying fill that with one of the possible values in the range from 1 to 9 and checking if that value is ok(isOk) for that cell. If so, that cell is concatenated to the base case, giving us one partial solution. And process continues till we fill all the empty cells.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Shown below is couple of inputs and along with their solutions. The whole Sudoku code is to be found at:</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<span style="color: blue;"><b>https://github.com/ratulb/sudoku/</b></span><br />
<br />
<b>Problem 1:</b><br />
<br />
1 9 0 2 0 0 8 0 0<br />
4 0 7 0 9 0 0 0 0<br />
0 3 0 0 0 1 4 0 0<br />
0 0 3 0 0 0 0 0 2<br />
9 8 0 0 0 0 0 7 3<br />
2 0 0 0 0 0 6 0 0<br />
0 0 5 3 0 0 0 1 0<br />
0 0 0 0 4 0 9 0 6<br />
0 0 9 0 0 6 0 5 4 <br />
<br />
<br />
scala> val sol1: Sudoku.Solution = List(List((3,8,6), (8,8,4), (1,8,3), (2,8,1), (7,8,0), (2,7,7), (7,7,5), (5,7,3), (8,7,2), (1,7,1), (3,7,0), (8,6,8), (7,6,6), (9,6,5), (2,6,4), (4,6,1), (6,6,0), (9,5,8), (8,5,7), (5,5,5), (3,5,4), (4,5,3), (1,5,2), (7,5,1), (5,4,6), (2,4,5), (1,4,4), (6,4,3), (4,4,2), (4,3,7), (1,3,6), (8,3,5), (7,3,4), (9,3,3), (6,3,1), (5,3,0), (5,2,8), (9,2,7), (6,2,4), (7,2,3), (2,2,2), (8,2,0), (1,1,8), (6,1,7), (2,1,6), (3,1,5), (8,1,3), (5,1,1), (7,0,8), (3,0,7), (4,0,5), (5,0,4), (6,0,2)))<br />
<br />
<b>Problem 2:</b><br />
<br />
0 0 6 9 0 0 3 0 1<br />
0 0 4 0 3 1 0 0 7<br />
2 0 0 0 0 0 0 6 0<br />
1 0 0 0 0 0 0 0 0<br />
0 2 0 7 0 3 0 8 0<br />
0 0 0 0 0 0 0 0 3<br />
0 4 0 0 0 0 0 0 2<br />
3 0 0 1 7 0 9 0 0<br />
8 0 9 0 0 2 1 0 0<br />
<br />
scala> val sol2 = Sudoku.solution<br />
sol2: Sudoku.Solution = List(List((6,8,8), (3,8,7), (4,8,4), (5,8,3), (7,8,1), (8,7,8), (4,7,7), (6,7,5), (2,7,2), (5,7,1), (7,6,7), (5,6,6), (9,6,5), (8,6,4), (3,6,3), (1,6,2), (6,6,0), (1,5,7), (7,5,6), (5,5,5), (9,5,4), (2,5,3), (8,5,2), (6,5,1), (4,5,0), (4,4,8), (6,4,6), (1,4,4), (5,4,2), (9,4,0), (5,3,8), (9,3,7), (2,3,6), (8,3,5), (6,3,4), (4,3,3), (7,3,2), (3,3,1), (9,2,8), (4,2,6), (7,2,5), (5,2,4), (8,2,3), (3,2,2), (1,2,1), (2,1,7), (8,1,6), (6,1,3), (9,1,1), (5,1,0), (5,0,7), (4,0,5), (2,0,4), (8,0,1), (7,0,0)))<br />
<br />
Following listing shows the complete sudoku code. <br />
<br />
</span><pre><span style="color: blue; font-family: Ubuntu; font-size: medium;">import io.Source
object Sudoku {
type Input = List[List[Int]]
type Cell = (Int,Int,Int)
type Solutions = List[List[Cell]]
def readFile = {
val lines = io.Source.fromFile("sudoku1.txt").getLines.toList
lines.map { line => line.split(" ").toList.map(e => e.toInt)
}
}
def solution = {
val in = readFile
val cells = index(in)
val empties = emptyCells(cells)
val nonEmpties = nonEmptyCells(cells)
solve(empties,nonEmpties)
}
def solve(empties: List[Cell], nonEmpties: List[Cell]): Solutions = {
//Actual logic
<span style="color: #274e13;"> def fillCells(emptyCells: List[Cell]): Solutions = {
if(emptyCells == Nil) List(List())
else {
for {
filledCells <- fillCells(emptyCells.init)
cellValue <- 1 to 9
cell = (cellValue,emptyCells.last._2, emptyCells.last._3)
if(isOk(cell, filledCells ::: nonEmpties))
} yield cell :: filledCells
}
}</span>
fillCells(empties)
}
def isOk(c:Cell, cells: List[Cell]) = {
(colCells(c,cells) ::: rowCells(c,cells) ::: boxCells(c,cells)).forall(e => e._1 != c._1)
}
def colCells(c: Cell, cells: List[Cell]) = cells.filter(e => e._3 == c._3)
def rowCells(c: Cell, cells: List[Cell]) = cells.filter(e => e._2 == c._2)
def emptyCells(cells: List[Cell]) = cells.filter(e => e._1 == 0) </span></pre>
<pre><span style="color: blue; font-family: Ubuntu; font-size: medium;"> def nonEmptyCells(cells: List[Cell]) = cells.filterNot(e => e._1 == 0) </span></pre>
<pre><span style="color: blue; font-family: Ubuntu; font-size: medium;"> def boxCells(c: Cell, cells: List[Cell]) = {
val inBox = cellAt(c)
val filtered = inBox match {
case 1 => cells.filter{e =>(e._2 < 3 && e._3 < 3)}
case 2 => cells.filter{e =>(e._2 < 3 && (e._3 > 2 && e._3 < 6))}
case 3 => cells.filter{e => (e._2 < 3 && e._3 > 5)}
case 4 => cells.filter{e => ((e._2 > 2 && e._2 < 6) && e._3 < 3)}
case 5 => cells.filter{e => ((e._2 > 2 && e._2 < 6) && (e._3 > 2 && e._3 < 6))}
case 6 => cells.filter{e => ((e._2 > 2 && e._2 < 6) && (e._3 > 5))}
case 7 => cells.filter{e => (e._2 > 5 && e._3 < 3)}
case 8 => cells.filter{e => (e._2 > 5 && (e._3 > 2 && e._3 < 6))}
case 9 => cells.filter{e => (e._2 > 5 && e._3 > 5)}
}
filtered
}
def index(in: Input) = in.zipWithIndex.map{r => r._1.zipWithIndex.map { c => (c._1, r._2, c._2) }}.flatMap(l => l) </span></pre>
<pre></pre>
<pre><span style="color: blue; font-family: Ubuntu; font-size: medium;"> def cellAt(c: Cell) = c match {
case (_,x,y) if(x < 3 && y < 3) => 1
case (_,x,y) if (x < 3 && ( y > 2 && y < 6)) => 2
case (_,x,y) if (x < 3 && (y > 5 && y < 9)) => 3
case (_,x,y) if ((x > 2 && x < 6) && y < 3) => 4
case (_,x,y) if ((x > 2 && x < 6) && (y > 2 && y < 6)) => 5
case (_,x,y) if ((x > 2 && x < 6) && (y > 5 && y < 9)) => 6
case (_,x,y) if (x > 5 && y < 3) => 7
case (_,x,y) if (x > 5 && (y > 2 && y < 6)) => 8
case _ => 9
}
}</span></pre>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
<br />
</span><div style="text-align: justify;">
<span style="font-family: Ubuntu; font-size: medium;"><b>Conclusion:</b> Scala's for comprehensions might look very ordinary - but they are not. They turn out to be extremely handy while trying to solve combinatorial problems like the ones shown above. Like many other constructs of functional programming, for comprehensions allow programmers to tackle complicated problems from a higher level of abstraction.</span></div>
<div style="text-align: justify;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br /></span>
<br /></div>
rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com2tag:blogger.com,1999:blog-964973296289999821.post-73315761274189116582013-01-21T21:10:00.001+05:302020-10-25T08:35:18.904+05:30Recovering from scala delimited continuation encounter<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
As I have said before, delimited continuations are wild beasts. Its one of those things that bends and hurts the mind. You might have to spend months in a state of delirium trying to figure them out! In the scala-lang.org's delimited continuation page, one reader commented and I quote, <b><i>"From my perspective, these are convoluted ways of adding numbers and I have no idea what is being gained or accomplished"</i></b>. Reading his comment - I had laughed my heart out -really! I could understand his frustration - even though my plight was only marginally better! So, if this is the first time you are hearing about them - maybe you should do some googling for them before going through rest of the stuff in this post. Once you are sure that you are confused enough - you should take some rest and then start with this post. Hopefully, once you are through with this post - some of the mists would disappear and you will be better equipped to explore them further. So, without further ado, let's get to them.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<b>What is a continuation?</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
This is a rather simple idea. Its any computation that has a starting point, a body that the computation runs through and a exit point. It could be a servlet request-response cycle, where start point is when the request is received by the container, the whole rest of the compuation being the proccessing and rendering of the response by the container. Or in even more simplistic terms, it's just a method invocation. Starting with the call, till the method returns, is the full continuation. So you get the idea - it is nothing complicated - a routine idea. So, in the interest of keeping things simple, we would stick to this last defintion i.e. the method body is a continuation. </span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<b>CPS:</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Now, let's say our method takes a parameter of type `A` and produces a result of type `C`. Now, imagine, when the execution reaches some arbitray point `P`, we slice the method body into two halves with our mental scissor. Let us also presume that - at the moment we cut the method at point P, the first half was producing a value of type `B` and that value would have been passed on to the second half, as its input, had we not made the cut. If we think of our two halves as two methods, one taking an A and producing a B and another taking a B and producing a C and we combine them sequentially(telling the first method to feed its output to the second) - what we are effectively doing is - passing a continuation to the first method telling it not to return instead feed its produce to the supplied function. So, as it turns out, CPS(continuation passing style) is again a rather simple idea!</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<b>Delimited continuation:</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
In the above example, we passed a method to the first method which respresented the whole rest of the computation. Once the supplied continuation(method representing the second half) has run its run, we have a final result of type C. What if instead of passing the whole rest, we could pass a function(or some snippet of code) that would serve as partial rest? So, delimted or partial continuation denotes portion of the whole rest instead of the whole rest itself. This is important to remember. </span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<b>Delimited continuation in scala:</b><br />
<br />
</span><div style="text-align: justify;">
<span style="font-family: Ubuntu; font-size: medium;"><b>Deviation</b>:[Delimited continuation in scala is achieved via code transformation. This transormation is done by a compiler plugin(enabled by passing `-P:continuations:enable` flag). So, wherever the plugin sees reset/shift combinations, those code sections are CPS transformed.] </span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
The extent to which, the continuation reaches is denoted by `reset`.`shift` can occur only within a reset. Using shift, we basically say, transform the code surrounded by the inner most reset into a function body. Input and output types of the transformed function, of course, should line up with those specified in the shift signature. The reified function we may call, call as many times as we like, store it somewhere and call later or throw it out of the window. Its all upto us. <b>This is all there is to in delimited continuation in scala</b>. Lets now look at some examples which would help straighten these ideas.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
scala -P:continuations:enable</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
import util.continuations._</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def fun = { println("I am not part of reset. Hence not part of the reified function.")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
reset {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
shift {k: (Int => Int) => //Reify reset body into Int => Int function</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
println("Calling the reified function with 2")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
k(2)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
} * 300 //reset body _ * 300 </span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
} </span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
println("I am outside reset - hence not part of the delimited continuation")</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
"Delimited continuations are hallucinating" // return value of fun</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
fun: String</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
scala> val v = fun</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
I am not part of reset. Hence not part of the reified function.</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
Calling the reified function with 2</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
I am outside reset - hence not part of the delimited continuation</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
v: String = Delimited continuations are hallucinating</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Shown below is the same function as above without comments and print statements. Also, we store the reified function in the cont variable. We are also not calling the continuation i.e. the reified function.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
var cont: Int => Int = _</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def fun = { </span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
reset {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
shift {k: (Int => Int) => </span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
cont = k //Store it</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
} * 300</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
} </span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
"Delimited continuations are hallucinating" // return value of fun</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
fun: String</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
scala> val v = fun</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
v: String = Delimited continuations are hallucinating</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
scala> val v = cont(2)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
v: Int = 600</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
<b>Programming inside out:</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Its illuminating to think about what would happen if we were to nest resets within shifts. Turns out that inner resets are evaluated before the outer ones! Why would it behave like that? Well, as we now know, resets are reified into functions or closures. So when the outer reset is being reified, if there is any nested reset inside shift, that needs to be reified as well - and that has to happen before so that we are able to reify outer ones based on the inner ones. Some people call it programming inside out or inverted. Shown below is an example. </span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def fun = {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
reset {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
shift { k1: (Int => Int) => </span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
{</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
println("A")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
reset {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
shift { k2: (Int => Int) =></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
println("C")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
} * 200</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
println("B")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
} * 300</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
scala> fun</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
A</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
C</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
B</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<b>Possible use cases for delimited continuation:</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Though scala delimited continuations have been out there for quite some time now(they came with scala 2.8) - their adoption has not quite taken off. One reason being, at least, at first glance, they are quite hard to understand. But once, more more developers become more comfortable with them, their usage would definitely grow. The biggest apeal of delimited continuations' is that we can pause a running program and rerun it later. This opens the door for event based programming and workflows. Since rest of the running program gets converted into a closure, we can transmit the closure accross the wire and rerun it at some other location. `Swarm` is an example of this. In the near future, we are definitely going to see some novel applications of delimited continuations.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br /></span>
<br /></div>
rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com1tag:blogger.com,1999:blog-964973296289999821.post-82617665732488049962013-01-14T19:55:00.002+05:302020-10-25T08:36:03.343+05:30Scala for the uninitiated java developer: 22 scala things you may not have known<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Scala's popularity is rising among developers. Yet, many java developers have hardly paid any attention to it - thinking it is some sort of esoteric programming langauge isolated from the java main land. They are the target audience of this post. This post is not a tutorial - it presents the scala features with minimum technical detail and tries to show how java and scala reside under the same roof(JVM). </span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
First up - scala is a statically typed language that runs on the jvm and fully compatible with java. That means scala can use java classes and vice versa. It combines object oriented programming with functional programming - which means functions are treated on par with things like strings, objects, Integers etc. You can toss them around like you toss around an int as method parameter or a return value from a method. Scala is the brain child of Prof. Martin Odersky - the same guy who was hired by Sun to write the java compiler in those back old days. Big players like amazon, twitter, linkedin, NASA etc have already adopted scala. Martin Odersky taught a 7 week long online(cousera.org) scala course which ended in Nov 2012 - the course was attended by some 50,000 students! That goes on to show the rising popularity of scala. With that background, let's see what are the featues that scala has to offfer. </span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
<b>1) Seamless integration with Java</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Scala has been designed for seamless interoperabilty with java. Scala codes get compiled to JVM byte codes. Scala can make use of existing java libraries. Scala code can call java methods, access java fields, extends java classes and implement java interfaces without any wrapper classes or glue code. Scala not only re-uses java's types -it also dresses them up. Following is perfectly vaild scala code.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
import java.util.ArrayList</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val users = new ArrayList[String]</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
users.add("me")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
users.add("you")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val size = users.size</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
size: Int = 2</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<span style="font-family: Ubuntu; font-size: medium;"><span style="color: blue;">val res = 100 > 90 </span>// Dressed up java int with `>` method<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
res: Boolean = true</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
<b>2) Scala is concise </b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
In general scala programs are half the size of typical java programs. Fewer lines of code not only means less typing but also less bugs, less effort to develop and understand. Scala becomes less noisy and less boiler-platey by avoiding unnecessary keywords(like classes are public by default - hence no need for `public` keyword), making the body of the class definition the primary constructor, making semi colons optional and in most of the cases - by inferencing types, by allowing call to parameterless methods without parenthesis. Shown below are two classes with same functionality:</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
// this is Java<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
public class MyClass {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
private int index;</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
private String name;</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
public MyClass(int index, String name) {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
this.index = index;</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
this.name = name;</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
System.out.println("Constructor initialized")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
//This is scala<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
class MyClass(index: Int, name: String) {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
println("Constructor initialized")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
// this is Java<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
boolean nameHasUpperCase = false;</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
for (int i = 0; i < name.length(); ++i) {// name is String</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
if (Character.isUpperCase(name.charAt(i))) {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
nameHasUpperCase = true;</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
break;</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
// this is scala<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val nameHasUpperCase = name.exists(_.isUpper)</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
So much less noisy and less ceremony!<br />
<br />
<br />
<b>3) Traits - Eat your cake and have it too</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
We have been talking about component based, write once run anywhere software more than a decade now. But in reality, software is still a craft rather than a industry. We don't build software from reusable components. We keep re-implementing same interface again and again - violating the DRY principle. What if we could implement `run` method for running junit testcases once for all? Traits let's do that. Not only that, it also allows a scala class to inherit behaviour from multiple traits without leading to any diamond problem! Is not that the best of the both worlds? You bet - In deed it is!</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
class TestCase {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def setup = println("setting up")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def testMethod1 = println("Test1")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def testMethod2 = println("Test2")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def tearDown = println("shutting down")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
trait TestRunner {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
self: TestCase =></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
<span style="color: black;">// Find the test methods via reflection and execute them </span></span></div>
<div style="color: black;"><span style="font-family: Ubuntu; font-size: medium;">
// Hard coded here!</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def run = { </span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
setup</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
testMethod1</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
testMethod2</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
tearDown</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val tests = new TestCase with TestRunner</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
tests.run </span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
setting up</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
Test1</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
Test2</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
shutting down</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
In the following example we add `product` and `add` method to ArrayList.<br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
import java.util.ArrayList</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
trait Product {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
self: ArrayList[Int] =>// I like to mingle with ArrayList</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def product = {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
var p = 1</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
for(i <- 0 until size)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
p = p * get(i)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
p</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
trait Add {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
self: ArrayList[Int] =></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def add = {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
var s = 0</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
for(i <- 0 until size)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
s = s + get(i)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
s</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val xs = new ArrayList[Int] with Product with Add</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
xs.add(100)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
xs.add(200)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
xs.add(300)</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<span style="color: blue;">xs.add</span> // 600<br />
<span style="background-color: white; color: blue;">xs.product</span> // 6000000<br />
<br />
Needless to say, these are very simplified usage of traits but they show how code reuse can be achieved.<br />
<br />
<br />
<b>4) Everything is objects</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Scala is purely object oriented, in fact, more object oriented than java. Java distinguishes primitive types (such as boolean and int) from reference types - scala does not.So + is a method of the Int object and you can write 2.+(3) instead of 2+3. Methods are allowed to be operators, so that you can write 2+3 instead of 2.+(3). Scala functions are also objects which is why we can toss them around like any other value. </span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
<b>5) Singleton objects </b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
In the spirit of being purely object oriented, scala avoids arcane concepts like static classes and members because they are not so object oriented! What scala has instead is singleton objects. They are automatically instantiated when accessed for the first time. They provide a nice way of modularising programs. Shown is an example of singleton object defintion.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
object MySingleton {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
println("I am being materialized")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def doIt = println("Yes sirrrr!")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
MySingleton.doIt</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
I am being instantiated</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
Yes sirrrr!</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
<b>6) Structural equality</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Comparing to values for equality is every day business in programming. While java promotes referential equality, scala prefers structural equality with the commonly used `==` operator. We can check referential equality with the `eq` method though. Shown below is an example:</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val list1 = new ArrayList[String]</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
list1.add("apple")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
list1.add("banana")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
list1.add("orange")</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val list2 = new ArrayList[String]</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
list2.add("apple")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
list2.add("banana")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
list2.add("orange")</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<span style="color: blue;">list1 == list2</span> //returns true<br />
<br />
<span style="color: blue;">list1 eq list2</span> //returns false<br />
<br />
<br />
<b>7) Implicit conversion</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
This is a double-edged sword. While outrageously useful for extending and adapting existing and new types, care must to be taken since overuse might lead to ambiguity. They also support writing DSLs in scala. Shown below is an example where we add a new method to java String class without even touching it!</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
class CamelCaser(val str: String) {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def toCamelCase =str.split(" ").map(s=> s.head.toUpper + s.tail.toLowerCase).mkString(" ")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
implicit def camelCase(s: String) = new CamelCaser(s)</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
"tHIS JAVA STRING iS being CONVERTED to camel case BY IMPLICT conversion".toCamelCase</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
Result: <span style="color: blue;">This Java String Is Being Converted To Camel Case By Implict Conversion</span><br />
<br />
<b>8) Pattern matching</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Scala has pattern matching, a functional programming technique that hasn't been seen before in mainstream languages.Pattern matching is switch statements on steroids. While java has recently added support for strings in switch statements - scala allows to pattern match on any sort of of data! Is not that awesome? You can pattern match on even user defined types! Just put the `case` keyword before your type definition and start match making as you like! </span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def whatIsIt(thingy: Any ) = thingy match {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
case (x,y) => println(x + " and "+ y)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
case (x,y,z) => println(x + ", "+ y + " and " + z)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
case s: String if s.length < 10 => println("Its a short string : "+ s)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
case s: String => println("Long strings are sooo long: "+s)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
case l:List[String] => println("Got a list of String")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
case _ => println("I am not programmed to receive you!")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<span style="font-family: Ubuntu; font-size: medium;"><span style="color: blue;">whatIsIt((10,"big"))</span>//prints 10 and big<br />
<span style="color: blue;">whatIsIt(new Object)</span>//I am not programmed to receive you!<br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
case class Name(first: String, last: String)</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
case class Address(name: Name,street: String, city: String, state: String, zip: Int)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val name=Name("Mr.","Cowboy")</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val address = new Address(name,"Luna road", "Dallas ","Texus", 75201)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
address match {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
case Address(Name(first, last), street, city, state, zip) => println(last + ", " + zip)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
case _ => println("not an address") // the default case</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
// prints Cowboy, 75201<br />
<br />
<br />
<b>9) Option & Tuples </b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
We need to check for Null references and guard against them all the time.It is such a nuisance. Programmers abhore them. That is where Option type comes handy. Option can be in two states - it has either something(Some(x)) or nothing(None). We can easily pattern match on option types.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val connection = Some(getConnection(url,user,password))</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
connection match {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
case Some(con) => println("Connected")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
case None => println("Opening connection")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Another very useful type is the tuple type. Tuples can contain different types of elements - And this makes life whole lot more easier while writting code! Bye bye value classes and pojos! Life does not get better than this - atleast not for me!</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val item =("Mango", "fruit", 2.5, 10)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
item: (String, String, Double, Int) = (Mango,fruit,2.5,10)</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<span style="font-family: Ubuntu; font-size: medium;"><span style="color: blue;">val quantity = item._4</span> //10<br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val emp =(101, "MARTIN", "SALESMAN", 7698, "28-11-81", 1400,30)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
emp: (Int, String, String, Int, String, Int, Int) = (101,MARTIN,SALESMAN,7698,28-11-81,1400,30)</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<span style="font-family: Ubuntu; font-size: medium;"><span style="color: blue;">emp._5</span> //returns 28-11-81<br />
<br />
<br />
<br />
<b>10) Rich collection APIs</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Scala has a common, uniform, and extremely useful collection framework. They are easy to use, concise, safe and performant.A small vocabulary of 20-50 methods is enough to solve most collection problems in a couple of operations.You can achieve with a single word what used to take one or several loops.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
Example:<br />
<br />
Here's one line of code that demonstrates many of the advantages of Scala's collections.<br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val (minors, adults) = people partition (_.age < 18)</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
Concise and elegant!<br />
<br />
<br />
<b>11) For expression</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
In scala everything is an expression. Every expression eveluates to something. `If` is an expression and has to return something. The last expression of a method is the return value of the expression. If a method does not return anything, it still returns `()` which is the instance value of `Unit`(Unit is sort of java `void` type). For expressions are not exception. They accept generators and optional guards and yield something.Also, any type that defines `map` can be used as a single genrator in a for expression. A type with map and `flatMap` allows for being used as multiple generators. Types with map, flatMap & `withFilter` can accept `if` conditions(guards) in for expression. And finally, types with `foreach` method can be used as for loop. Shown below is a usage of for expression used to count the occurrence of a particular word in the .txt files underneath the current directory.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
import java.io.File</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
import io.Source</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def wordCount(word: String) = {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def perLine(line: String) = line.split(" ").count(w => w.equalsIgnoreCase(word))</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def lines(f: File) = Source.fromFile(f).getLines.toList</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val files = new File(".").listFiles</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val counts = for {</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><span style="color: blue;"> file <- files</span> //Generator<br />
<span style="color: blue;"> if file.isFile && file.getName.endsWith(".txt") <span style="color: black;">//Guard</span></span><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
line <- lines(file)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
} yield perLine(line)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
counts.sum</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
<b>12) Asynch concurrency with futures</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Like java scala has futures but unlike java they are much more pleasant to deal with. We can combine multiple futures together. You wrap your codes inside futures and let them loose out in the wild. Scala will turn back and do the rest. No submitting to thread pools and checking to see if they have completed what you told them to do. Really!</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val f = future { </span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
println("Going to do some time consuming stuff")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
Thread.sleep(1000)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
println("Done the stuff and returning `Some result`")</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
"Some result"</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
f onComplete {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
onDone</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><span style="color: blue;">}</span> // Future returned : Some result<br />
<br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def onDone(r: Try[String]): Unit = r match {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
case Success(v) => println("Future returned : " + v)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
case Failure(e) => println("Something gone wrong :"+e)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
<b>13) Scala is functional</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
This is where scala has raised the bar for future programming language development. Before scala, functional and object oriented programmers did not see eye to eye. Scala broke with tradition and unified functional and object oriented programming, after all, they both have their own sweet spots. </span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Scala treats functions on par with other values like int, boolean objects. As a consequence, we can store a function in a variable, pass it as argument to some other function and return a function from a method call. This helps a lot in composing bigger things from smaller parts and vice versa. Functions accepting/returning functions are called higher order functions.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
Let's define a function that adds the integers between a and b.<br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def addInts(a: Int, b: Int): Int =</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
if(a > b) 0 else a + addInts(a+1, b)</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
addInts(10,20) // 165</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
Now let's define another function that adds the squares of integers between a & b.<br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def addSquares(a: Int, b: Int):Int = </span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
if(a > b) 0 else a * a + addSquares(a+1, b)</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<span style="font-family: Ubuntu; font-size: medium;"><span style="color: blue;">addSquares(10,20)</span> //2585<br />
<br />
Now, we define two functions with following signatures.<br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def id(a: Int) = a</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def square(a: Int) = a * a</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
Now, let's define a generic sum function which take a function as a parameter.<br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def sum(f: Int => Int, a: Int, b: Int):Int =</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
if(a > b) 0 else f(a) + sum(f, a+1, b)</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
We can now write:<br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def addInts(a: Int, b: Int) = sum(id,a,b)</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def addSquares(a: Int, b: Int) = sum(square,a,b)</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
We just touched upon the functional side of scala. We can nest functions(refer to `For expressions`), partially or incrementaly apply arguments to get back partially applied or curried functions. We can define partial functions that are not defined for some input values. We can also create closures and toss them around. We can even pattern match on functions.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
What follows is an example of function composition:<br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def str(a: Int) = String.valueOf(a)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def len(s: String) = s.length</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def fun(f: Int => String, g: String => Int) = g compose f</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val digits = fun(toStr, strLen)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val numOfDigits = digits(10000)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
numOfDigits: Int = 5</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
<b>14) By name parameter</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
In normal cases, arguments to functions are evaluated and then passed along. But in case of by name parameters, the arguments are evaluated late at the call site. They come very handy for logging frameworks etc where we don't want log messages to be evaluated in case logging is turned off.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
var loggingOn = true</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def log(stmt: => Unit) =</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
if(loggingOn) stmt else ()</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<span style="font-family: Ubuntu; font-size: medium;"><span style="color: blue;">log { println("A log message") }</span> // A log message <br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
loggingOn = false</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<span style="font-family: Ubuntu; font-size: medium;"><span style="color: blue;">log { println("A log message") }</span> // Prints nothing<br />
<br />
In a by name parameter, the type of argument is preceded by <span style="color: blue;">`=>`. </span><br />
<br />
<br />
<b>15) Structural types</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Structural types are types having similar members. For example, we might want to be able to close a resource without caring whether it is a database connection or a file handle. So, given a resource we want do some operation on it and finally close the resource calling the `close` method on it. We also want to return the operation result. Let's call our method `withResource`. The type of the resource can be anything as long as it has a `close` method. Similarly, type of the operation result can be anything. Hence, `withResource` will have to have two type parameters. Shown below is the signature:</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<span style="color: blue;">def withResource[T <: { def close}, R](resource: T)</span><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
(operation: T => R) = {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val result = operation(resource)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
resource.close</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
result</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
} </span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
<b>16) Actor based concurrency</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Actors are objects which encaptulate state and behaviours, and communicates exclusively via message passing. The messages are placed into the recipients' mail boxes. Messages are passed on to the `receive` method of an actor. Multiple actors piggy back on a single thread. Actors provide you following:</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><ul style="text-align: left;">
<li><span style="font-family: Ubuntu; font-size: medium;">Simple and high-level abstractions for concurrency and parallelism.</span></li>
<li><span style="font-family: Ubuntu; font-size: medium;">Asynchronous, non-blocking and highly performant event-driven programming model.</span></li>
<li><span style="font-family: Ubuntu; font-size: medium;">Very lightweight event-driven processes (Order of millions of actors per GB RAM).</span></li>
</ul>
<span style="font-family: Ubuntu; font-size: medium;"><br />
Shown below is a simple actor printing out the received message.<br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
import akka.actor._</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val actorSystem = ActorSystem("actorsystem")</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
class MyActor extends Actor {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def receive = {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
case x => println("Received : "+ x)</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val myActor = actorSystem.actorOf(Props[MyActor])</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><span style="color: blue;">myActor ! "Hi" </span>// Received : Hi <br />
<br />
<b>17) Delimited continuations</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Delimited continuations are wild beasts. Its one of those things that bends and hurts the mind. You might have to spend months in a state of stupor trying to grasp what the heck they are!</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
It does help if I told you delimited continuations are segments of a program flow that has been reified into functions. The `reset` sets the limit for the continuation while the `shift` reifies the current continuation up to the innermost enclosing reset. </span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
var cont: Int => Int = _</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
def f = {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
reset {</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
shift { k: (Int=>Int) =></span></div>
<span style="font-family: Ubuntu; font-size: medium;"><span style="color: blue;"> cont = k</span> //Save it for calling later<br />
<span style="color: blue;">k(7)</span> //calling the continuation<br />
<span style="color: blue;"> } + 1</span><br />
<span style="color: blue;"> }</span> //Continuation boundary ends<br />
<span style="color: blue;">println("Not part of reified continuation")</span><br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
}</span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<span style="font-family: Ubuntu; font-size: medium;"><span style="color: blue;">f</span> // Not part of reified continuation<br />
<span style="color: blue;">cont(100)</span> // 101<br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
As mentioned before, delimited continuations take some efforts to get used to. This post is not about teaching stuffs - its about showing features of scala with minimum technical details. </span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<b>18) Macro</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Scala macros are functions that are called by the compiler during code compilations. Macros are written in scala and they work with expression trees rather than raw strings. They can generate and typecheck code and have access to compiler APIs.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
<b>19) Compiler plugin</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Scala compiler has an architecture that allow for custom compiler plugins to be invoked during compilation. A plugin adds an extra phase in the compilation process - wherein it might do extra type checks, code generation etc. Delimited continuations are implemented via a compiler plugin in scala.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
<b>20) In-built xml support</b><br />
<br />
Scala has inbuilt xml support. You can easily create, parse, and process XML documents in scala. <br />
<br />
</span><div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val date = new java.util.Date</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
val xml = <today> {date} </today></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
xml: scala.xml.Elem = <today> Mon Jan 14 15:54:44 IST 2013 </today></span></div>
<div style="color: blue;">
<span style="font-family: Ubuntu; font-size: medium;"><br /></span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
xml \\ "today"</span></div>
<div style="color: blue;"><span style="font-family: Ubuntu; font-size: medium;">
scala.xml.NodeSeq = NodeSeq(<today> Mon Jan 14 15:54:44 IST 2013 </today>)</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
<b>21) Combinator Parsing</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
This is one good thing parser and DSL writters would love. No need to roll out your own - which is difficult - if you are not an expert - or fall back on something like javacc or antlar etc. Scala combinator parsers greatly simplifies parsing your DSL or embedded language. </span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
<b>22) GUI Programming</b><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Scala provides a GUI library based on java swing classes but hides many of the complexities of swing APIs. The scala GUI APIs are much easier to deal with.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
<br />
<br /></span>
<br /></div>
rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com4tag:blogger.com,1999:blog-964973296289999821.post-80821200557770378172012-12-28T17:43:00.001+05:302020-10-25T08:36:27.575+05:30Iteratee fundamentals for the beginer<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Iteratees are an alternative to commonly prevalent, imperative blocking IO. While reading from a stream, if is data is not available - the reading thread blocks - which is not desirable. The alernative would be to register a callback which gets invoked as data become available. Iteratees are callback handlers and much more. If you have heard about them but not sure what they are - then this post is for you.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Simply put, an iteratee is a consumer of data in chunks and it's counterpart, which is called `Enumerator`- is a producer of data. The imperative way of reading data conforms to pulling data out in chunks from the source. But in an iteratee based system, the producer pushes data into an iteratee in successive chunks, which finally computes a value. Iteratee's state changes as it receives chunks of data. Or to be more precise(since state change is a side-effect and side-effects don't compose) - when an iteratee receives a chunk of data - the iteratee is replicated with it's new state being computed from the old iteratee's state and chunk of input that it received. Also, with iteratees its a two way conversation between the producer and the consumer(i.e. the iteratee). The producer might hand out a chunk of data to the iteratee or it might say, I'm Empty now - but hang on - I will feed you as soon as I get a chunk in the near future or it might say - I have run out of data(EOF) - you make a call what to do next.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
On the other hand, the iteratee might say - I am ready for next chunck(Cont), or I have had enough(Done) or it might throw up(Error) - because it is monday. I will not talk about Error anymore because ours' is an ideal world and it does not add any insight to the understanding of iteratees.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
So, when an iteratee gets a chunk of input, it replicates itself transitioning from one state to other. It might transition to a `Done` state which would contain a computed value and possibly some unconsumed input. The iteratee might transition to a `Cont` state which would hold a function waiting to be invoked with next chunk of input once it arrives. Or the iteratee might enter into a Error state which might hold a error message and possibly the chunk of input that caused it to error out.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
I have been talking about iteratees in the context of IO streams. For understanding's sake lets consider Lists as our source of data. So the examples I would develop would use Lists instead of streams. Once we get the idea of how iteratees behave - it should not be difficult to relate Lists to streams.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
So, based on the ponderings so far, two types emerge. One is the input and another is the state of the iteratee. We parameterize on the element type of the input because each chunk of data could represent a byte, word, event or anything. So the types are:</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<span style="color: blue;">scala> trait Input[+E]</span><br />
<span style="color: blue;">defined trait Input</span><br />
<br style="color: blue;" />
<br />
<span style="color: blue;">scala> object Empty extends Input[Nothing]</span><br />
<span style="color: blue;">defined module Empty</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> //Producer has finished producing</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> object EOF extends Input[Nothing]</span><br />
<span style="color: blue;">defined module EOF</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> //The producer has produced a chunk</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> case class Elem[+E](e: E) extends Input[E]</span><br />
<span style="color: blue;">defined class Elem</span><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Next up, we define the iteratee itself anlong with the various states it can be in after it receives a chunk of input. We paramterize the iteratee with `E` and `A` where former and later being the type of input it consumes and value it computes respectively. We also add a run method to our iteratee to extract the computed value. If our iteratee is already in the Done state then - we return the value inside it. If on the other hand, the iteratee is still in the Cont state, we send a EOF signal to it to indicate that we are interested in the value it has computed thus far.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<span style="color: blue;">scala> :paste</span><br />
<span style="color: blue;">// Entering paste mode (ctrl-D to finish)</span><br />
<br style="color: blue;" />
<span style="color: blue;">trait Iteratee[E,+A] {</span><br />
<span style="color: blue;"> def run: A = this match {//run will get us the result computed thus far - sending a EOF to itself if needed</span><br />
<span style="color: blue;"> case Done(a, _) => a</span><br />
<span style="color: blue;"> case Cont(k) => k(EOF).run</span><br />
<span style="color: blue;"> }</span><br />
<span style="color: blue;">}</span><br />
<br style="color: blue;" />
<span style="color: blue;">//Done holds computed result of type A and input it may not have consumed</span><br />
<span style="color: blue;"> case class Done[E,+A](a: A, next: Input[E]) extends Iteratee[E,A]</span><br />
<span style="color: blue;"> //Cont state holds a function, which given an input, would return a new iteratee instance(Done or Cont) </span><br />
<span style="color: blue;"> case class Cont[E,+A](k: Input[E] => Iteratee[E,A]) extends Iteratee[E,A]</span><br />
<br style="color: blue;" />
<br style="color: blue;" />
<span style="color: blue;">// Exiting paste mode, now interpreting.</span><br />
<br style="color: blue;" />
<span style="color: blue;">defined trait Iteratee</span><br />
<span style="color: blue;">defined class Done</span><br />
<span style="color: blue;">defined class Cont</span><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
We have said before that it is the job of the producer(aka the enumerator) to feed the iteratee its produce in chunks. To keep things simple lets write an enumerate function instead of a full-blown enumerator. In the enumerate function below, the produce is held in a List.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<span style="color: blue;">scala> :paste</span><br />
<span style="color: blue;">// Entering paste mode (ctrl-D to finish)</span><br />
<br style="color: blue;" />
<span style="color: blue;"> def enumerate[E,A](produce: List[E], itr:Iteratee[E,A]): Iteratee[E,A] = {</span><br />
<span style="color: blue;"> produce match {</span><br />
<span style="color: blue;"> //No produce - return the Iteratee as it is</span><br />
<span style="color: blue;"> case Nil => itr</span><br />
<span style="color: blue;"> case e :: elems => itr match {//produced an elem/chunk</span><br />
<span style="color: blue;"> case i@Done(_,_) => i//if Done - return current Iteratee</span><br />
<span style="color: blue;"> case Cont(k) => enumerate(elems, k(Elem(e)))//Not yet `Done` continue feeding chunks of produce</span><br />
<span style="color: blue;"> }</span><br />
<span style="color: blue;"> }</span><br />
<span style="color: blue;"> } </span><br />
<br style="color: blue;" />
<br style="color: blue;" />
<span style="color: blue;">// Exiting paste mode, now interpreting.</span><br />
<br style="color: blue;" />
<span style="color: blue;">enumerate: [E, A](produce: List[E], itr: Iteratee[E,A])Iteratee[E,A]</span><br />
<br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Iteratees can come in different categories - some would take finite chunks of input and then they would be in Done state. Iteratees that take the head of a List and returns it or drops few elements and then returns the rest of the List would fall in this category. On the other hand some would consume the entire List and then return a result - iteratees that sum up the List elements would fall in this category. Some other iteratees never enter the Done state even after receiving an `EOF` signal - these iteratees are termed as divergent iteratees. Below are shown few example iteratees.</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
An iteratee which returns the head from an enumerator's produce:</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<span style="color: blue;">scala> :paste</span><br />
<span style="color: blue;">// Entering paste mode (ctrl-D to finish)</span><br />
<br style="color: blue;" />
<span style="color: blue;">def head[E]: Iteratee[E, Option[E]] = {</span><br />
<span style="color: blue;"> def step[E](in: Input[E]): Iteratee[E, Option[E]] = in match {</span><br />
<span style="color: blue;"> //Got an elem - return a Done iteratee right away</span><br />
<span style="color: blue;"> case Elem(e) => Done(Some(e),Empty)</span><br />
<span style="color: blue;"> //Cont iteratee waiting for an input</span><br />
<span style="color: blue;"> case Empty => Cont(step)</span><br />
<span style="color: blue;"> case EOF => Done(None, EOF) </span><br />
<span style="color: blue;">}</span><br />
<span style="color: blue;"> Cont(step)</span><br />
<span style="color: blue;"> }</span><br />
<br style="color: blue;" />
<span style="color: blue;">// Exiting paste mode, now interpreting.</span><br />
<br style="color: blue;" />
<span style="color: blue;">head: [E]=> Iteratee[E,Option[E]]</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> val v = enumerate(List(1,2,3), head[Int])</span><br />
<span style="color: blue;">v: Iteratee[Int,Option[Int]] = Done(Some(1),Empty$@ade4cd)</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> val result = v.run</span><br />
<span style="color: blue;">result: Option[Int] = Some(1)</span><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Iteratee that computes the length of the produce of an enumerator:</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<span style="color: blue;">scala> :paste</span><br />
<span style="color: blue;">// Entering paste mode (ctrl-D to finish)</span><br />
<br style="color: blue;" />
<span style="color: blue;">def length[E]: Iteratee[E,Int] = {</span><br />
<span style="color: blue;"> def step[E](acc: Int): Input[E] => Iteratee[E,Int] = {</span><br />
<span style="color: blue;"> case Elem(e) => Cont(step(acc+1))</span><br />
<span style="color: blue;"> case Empty => Cont(step(acc))</span><br />
<span style="color: blue;"> case EOF => Done(acc, EOF)</span><br />
<span style="color: blue;"> }</span><br />
<span style="color: blue;"> Cont(step(0))</span><br />
<span style="color: blue;">} </span><br />
<br style="color: blue;" />
<span style="color: blue;">// Exiting paste mode, now interpreting.</span><br />
<br style="color: blue;" />
<span style="color: blue;">length: [E]=> Iteratee[E,Int]</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> val lenItr = enumerate(List(1,2,3,4,5,6), length[Int])</span><br />
<span style="color: blue;">lenItr: Iteratee[Int,Int] = Cont(<function1>)</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> val len = lenItr.run</span><br />
<span style="color: blue;">len: Int = 6</span><br />
<br />
</span><div style="text-align: justify;"><span style="font-family: Ubuntu; font-size: medium;">
Iteratee that will return a List containing every alternate element starting with the first:</span></div>
<span style="font-family: Ubuntu; font-size: medium;"><br />
<span style="color: blue;">scala> :paste</span><br />
<span style="color: blue;">// Entering paste mode (ctrl-D to finish)</span><br />
<br style="color: blue;" />
<span style="color: blue;">def alternate[E]: Iteratee[E, List[E]] = {</span><br />
<span style="color: blue;"> def step(flag: Boolean, xs: List[E]): Input[E] => Iteratee[E, List[E]] = {</span><br />
<span style="color: blue;"> case Elem(e) if(flag) => Cont(step(false,xs ::: List(e)))</span><br />
<span style="color: blue;"> case Elem(e) if(!flag) => Cont(step(true, xs))</span><br />
<span style="color: blue;"> case Empty => Cont(step(flag,xs))</span><br />
<span style="color: blue;"> case EOF => Done(xs, EOF)</span><br />
<span style="color: blue;">}</span><br />
<span style="color: blue;"> Cont(step(true,Nil))</span><br />
<span style="color: blue;">}</span><br />
<br style="color: blue;" />
<span style="color: blue;">// Exiting paste mode, now interpreting.</span><br />
<br style="color: blue;" />
<span style="color: blue;">alternate: [E]=> Iteratee[E,List[E]]</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> val altItr = enumerate(List(1,2,3,4,5,6,7), alternate[Int])</span><br />
<span style="color: blue;">altItr: Iteratee[Int,List[Int]] = Cont(<function1>)</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> val altList = altItr.run</span><br />
<span style="color: blue;">altList: List[Int] = List(1, 3, 5, 7)</span><br />
<br />
<br />
</span><div style="text-align: justify;">
<span style="font-family: Ubuntu; font-size: medium;"><b>Conclusion:</b> I have just shown the basics of iteratees. Frameworks like Play 2 - have taken the iteratees to a whole new level combining them with scala futures and executing them asynchronously. As web applications are becoming more and more real-time data centric, iteratees provide yet another tool in the arsenal of developer to scale up web application. </span></div>
</div>
rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0tag:blogger.com,1999:blog-964973296289999821.post-7912608040727029232012-12-05T13:55:00.000+05:302012-12-28T20:19:00.679+05:30Asynch concurrency: In the promised land of scala futures<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<b><i>The basics:</i></b><br />
<br />
<div style="text-align: justify;">
The concept of future is not new - java added them in 1.5 -scala actors had futures from the start, lift webframework had its own futures. As more and more libraries and toolkits sprang up based on the scala language - many had futures with more or less similar functionalities - akka, playframework, twitter's finagle etc had their respective implementations.</div>
<br />
<div style="text-align: justify;">
With SIP-14, the case was made that all these different implementations should be unified and made available as part of the scala core library. And the result is scala.concurrent package. This write-up looks at futures and promises API, how they take asynch concurrency to a whole new level and provide a higher level of abstraction.</div>
<br />
Lets fire up the REPL and see futures in action:<br />
<br />
<span style="color: blue;">scala> import concurrent.future</span><br />
<span style="color: blue;">import concurrent.future</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> import concurrent.ExecutionContext.Implicits.global</span><br />
<span style="color: blue;">import concurrent.ExecutionContext.Implicits.global</span><br />
<br />
<br />
<div style="text-align: justify;">
The first import is for the `future` method in the `concurrent` package object. The second import basically brings into scope the default execution context (i.e. thread pool) - which is used for computing chunks of code asynchronously. We can use our own custom execution context if one is available in the scope.</div>
<br />
<div style="text-align: justify;">
Computation of a future may yield a successful result or an exception and we can register callbacks to handle them appropriately.</div>
<br />
<span style="color: blue;">scala> val f = future { 100 }</span><br />
<span style="color: blue;">f: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise...</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> f onComplete {</span><br />
<span style="color: blue;"> | case x => println("Future has returned :"+ x)</span><br />
<span style="color: blue;"> | }</span><br />
<span style="color: blue;">Future has returned : 100</span><br />
<br />
<div style="text-align: justify;">
We can attach multiple callbacks to a future, attach them even after the future has returned - all of them will be fired - the only caveat is that there is no guarantee in what order they will fire. Since - the future may or may not hold a value - we pattern match on instances of Either type - and as is the tradition - Left is used for signalling error condition.</div>
<br />
<span style="color: blue;">scala> val f1 = future { 100 }</span><br />
<span style="color: blue;">f1: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise...</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> val f2 = future { throw new Exception("Boom") }</span><br />
<span style="color: blue;">f2: scala.concurrent.Future[Nothing] = scala.concurrent.impl.Promise...</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> f1 onComplete {</span><br />
<span style="color: blue;"> | case </span><span style="color: blue;">Success</span><span style="color: blue;">(r) => println(r)</span><br />
<span style="color: blue;"> | case </span><span style="color: blue;">Failure</span><span style="color: blue;">(e) => println(e)</span><br />
<span style="color: blue;"> | }</span><br />
<span style="color: blue;">100</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> f2 onComplete {</span><br />
<span style="color: blue;"> | case </span><span style="color: blue;">Success</span><span style="color: blue;">(r) => println(r)</span><br />
<span style="color: blue;"> | case Failure(e) => println(e)</span><br />
<span style="color: blue;"> | }</span><br />
<span style="color: blue;">java.lang.Exception: Boom</span><br />
<br />
<br />
`onComplete` is called called irrespective of success or failure. We could use `onSuccess` or `onFailure` - if we want.<br />
<br />
<span style="color: blue;">scala> f1 onSuccess {</span><br />
<span style="color: blue;"> | case r => println(r)</span><br />
<span style="color: blue;"> | }</span><br />
<span style="color: blue;">100</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> f2 onFailure {</span><br />
<span style="color: blue;"> | case e => println(e)</span><br />
<span style="color: blue;"> | }</span><br />
<span style="color: blue;">java.lang.Exception: Boom</span><br />
<br />
<br />
<div style="text-align: justify;">
future has its counterpart called `promise`. future and promise are two sides of the same coin.futures are read-many (times) whereas promises are write-once. We can make a promise, fullfill that promise later - when we do so - the corresponding future get its value(aka, returns). Once a promise is made and fullfilled(i.e. written to) - we can not go back on it - it's illegal.</div>
<br />
<span style="color: blue;">scala> import concurrent.promise</span><br />
<span style="color: blue;">import concurrent.promise</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> val p = promise[Int]</span><br />
<span style="color: blue;">p: scala.concurrent.Promise[Int] = scala.concurrent.impl.Promise...</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> val f = p.future</span><br />
<span style="color: blue;">f: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise...</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> f onSuccess {</span><br />
<span style="color: blue;"> | case v => println(v)</span><br />
<span style="color: blue;"> | }</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> p.success(200)</span><br />
<span style="color: blue;">200</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> p.success(500)</span><br />
<span style="color: blue;">java.lang.IllegalStateException: Promise already completed.</span><br />
<br />
<br />
<b><i>Higher order functions and future specific combinators:</i></b><br />
<br />
<br />
<div style="text-align: justify;">
Apart from `map`, `flatMap` and `filter` - future has some other higher order functions making it possible to combine futures smart ways to achieve the task at hand.</div>
<br />
<span style="color: blue;">scala> val f1 = future { 50 }</span><br />
<span style="color: blue;">f1: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise...</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> val f2 = future { 50 }</span><br />
<span style="color: blue;">f2: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise...</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> val result = for {</span><br />
<span style="color: blue;"> | x <- f1</span><br />
<span style="color: blue;"> | y <- f2</span><br />
<span style="color: blue;"> | } yield x * y</span><br />
<span style="color: blue;">result: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise...</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> result map( _ * 2) filter(_ > 4000) onSuccess {</span><br />
<span style="color: blue;"> | case value => println(value)</span><br />
<span style="color: blue;"> | }</span><br />
<span style="color: blue;">5000</span><br />
<br />
<br />
Fall back to that future in case of failure with `fallbackTo`<br />
<br />
<br />
<span style="color: blue;">scala> val blowUp = future { throw new Exception("Crashed") }</span><br />
<span style="color: blue;">blowUp: scala.concurrent.Future[Nothing] = scala.concurrent.impl.Promise...</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> val planB = future { "Recovered" }</span><br />
<span style="color: blue;">planB: scala.concurrent.Future[String] = scala.concurrent.impl.Promise...</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> blowUp fallbackTo planB onComplete {</span><br />
<span style="color: blue;"> | case Failure(e) => println(e)</span><br />
<span style="color: blue;"> | case Success</span><span style="color: blue;">(r) => println(r)</span><br />
<span style="color: blue;"> | }</span><br />
<span style="color: blue;">Recovered</span><br />
<br style="color: blue;" />
<br />
Sequential execution with `andThen`<br />
<br />
<span style="color: blue;">scala> lazy val f = future { println("First here") }</span><span style="color: blue;">f: scala.concurrent.Future[Unit] = <lazy></span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> f andThen {</span><br />
<span style="color: blue;"> | case r => println("Then here")</span><br />
<span style="color: blue;"> | } andThen {</span><br />
<span style="color: blue;"> | case _ => println("At the end")</span><br />
<span style="color: blue;"> | }</span><br />
<br style="color: blue;" />
<span style="color: blue;">First here</span><br />
<span style="color: blue;">Then here</span><br />
<span style="color: blue;">At the end</span><br />
<br />
<br />
Fold and reduce:<br />
<br />
<br />
<span style="color: blue;">scala> val f1 = future { 100 }</span><br />
<span style="color: blue;">f1: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise...</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> val f2 = future { 200 }</span><br />
<span style="color: blue;">f2: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise...</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> val f3 = future { 300 }</span><br />
<span style="color: blue;">f3: scala.concurrent.Future[Int] = scala.concurrent.impl.Promise...</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> val futures = List(f1,f2,f3)</span><br />
<span style="color: blue;">futures: List[scala.concurrent.Future[Int]] = List...</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> import concurrent.Future</span><br />
<span style="color: blue;">import concurrent.Future</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> Future.fold(futures)(0)(_ + _ ) onSuccess {</span><br />
<span style="color: blue;"> | case r => println(r)</span><br />
<span style="color: blue;"> | }</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> 600</span><br />
<br style="color: blue;" />
<br style="color: blue;" />
<span style="color: blue;">scala> Future.reduce(futures)(_ * _ ) onSuccess {</span><br />
<span style="color: blue;"> | case r => println(r)</span><br />
<span style="color: blue;"> | }</span><br />
<br style="color: blue;" />
<span style="color: blue;">scala> 6000000</span><br />
<br />
<i><b>Conclusion: </b></i><br />
<br />
<div style="text-align: justify;">
We have looked at just some of the APIs scala futures offer. And they by themselves are more than enough to solve many real world asynch concurrent problems. But there is more<b> </b>to them than what we have seen here. They will be an extremely useful tool in any developer's repertoire.</div>
</div>
rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com2tag:blogger.com,1999:blog-964973296289999821.post-22154618026603026772012-10-22T19:21:00.002+05:302012-10-22T19:29:45.286+05:30scala xml wrapper utility<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
XDoc is a utility wrapper over scala.xml.Elem. It's simplifies xml processing. Following needs to be considered while using this utility:<br />
<br />
1) It does not support namespaces. That can easily incorporated - But our use case did not have any namespaces.<br />
2) It does not consider text within an element to be a child element of the container as opposed to normal convention - But text can set and retrieved from an element.<br />
<br />
<br />
Following REPL session shows how to use it.<br />
<br />
Shows how to create an instance XDoc:<br />
<br />
<span style="color: blue;">scala> var d = XDoc("animals") addChild "tiger" addChild "lion" addAttr("test", "attrValue")</span><br />
<span style="color: blue;">d: XDoc = </span><br />
<span style="color: blue;"><animals test="attrValue"></span><br />
<span style="color: blue;"> <tiger/></span><br />
<span style="color: blue;"> <lion/></span><br />
<span style="color: blue;"></animals></span><br />
<br />
<br />
Querying child count:<br />
<br />
<span style="color: blue;">scala> d.childCount</span><br />
<span style="color: blue;">res13: Int = 2</span><br />
<br />
Setting text :<br />
<br />
<span style="color: blue;">scala> d = d.setText("Sample text")</span><br />
<span style="color: blue;">d: XDoc = <animals test="attrValue"></span><br />
<span style="color: blue;"> Sample text</span><br />
<span style="color: blue;"> <tiger/></span><br />
<span style="color: blue;"> <lion/></span><br />
<span style="color: blue;"></animals></span><br />
<br />
Shows that text is not considered as a child:<br />
<br />
<span style="color: blue;">scala> d.childCount</span><br />
<span style="color: blue;">res14: Int = 2</span><br />
<span style="color: blue;"><br /></span>
<span style="color: blue;">scala> d = d addChild(XDoc("zebra").addAttr("hasStripes", "true"))</span><br />
<span style="color: blue;">d: XDoc = <animals test="attrValue"></span><br />
<span style="color: blue;"> Sample text</span><br />
<span style="color: blue;"> <tiger/></span><br />
<span style="color: blue;"> <lion/></span><br />
<span style="color: blue;"> <zebra hasStripes="true"/></span><br />
<span style="color: blue;"></animals></span><br />
<span style="color: blue;"><br /></span>
<span style="color: blue;">scala> d.childCount</span><br />
<span style="color: blue;">res15: Int = 3</span><br />
<span style="color: blue;"><br /></span>
<span style="color: blue;">scala> d = d.addAttr("test2", "Value")</span><br />
<span style="color: blue;">d: XDoc = <animals test2="Value" test="attrValue"></span><br />
<span style="color: blue;"> Sample text</span><br />
<span style="color: blue;"> <tiger/></span><br />
<span style="color: blue;"> <lion/></span><br />
<span style="color: blue;"> <zebra hasStripes="true"/></span><br />
<span style="color: blue;"></animals></span><br />
<br />
Querying attributes. Attributes are an instance of the case class :<br />
<br />
<b>case class XAttr(name: String, value: String)</b><br />
<br />
<span style="color: blue;">scala> val atrs = d.attrs</span><br />
<span style="color: blue;">atrs: List[XAttr] = List(XAttr(test,attrValue), XAttr(test2,Value))</span><br />
<span style="color: blue;"><br /></span>
<span style="color: blue;">scala> d.hasAttrs</span><br />
<span style="color: blue;">res16: Boolean = true</span><br />
<span style="color: blue;"><br /></span>
<span style="color: blue;">scala> d.attr("test2")</span><br />
<span style="color: blue;">res17: Option[XAttr] = Some(XAttr(test2,Value))</span><br />
<span style="color: blue;"><br /></span>
<span style="color: blue;">scala> d.attr("testxx")</span><br />
<span style="color: blue;">res18: Option[XAttr] = None</span><br />
<br />
<br />
Querying childrens :<br />
<br />
<span style="color: blue;">scala> d.childrenByName("tiger")</span><br />
<span style="color: blue;">res20: List[XDoc] = List(<tiger/>)</span><br />
<span style="color: blue;"><br /></span>
<span style="color: blue;">scala> d = d addChild((XDoc("tiger").addAttr("male", "true")) addChild "females")</span><br />
<span style="color: blue;">d: XDoc = <animals test2="Value" test="attrValue"></span><br />
<span style="color: blue;"> Sample text</span><br />
<span style="color: blue;"> <tiger/></span><br />
<span style="color: blue;"> <lion/></span><br />
<span style="color: blue;"> <zebra hasStripes="true"/></span><br />
<span style="color: blue;"> <tiger male="true"></span><br />
<span style="color: blue;"> <females/></span><br />
<span style="color: blue;"> </tiger></span><br />
<span style="color: blue;"></animals></span><br />
<span style="color: blue;"><br /></span>
<span style="color: blue;">scala> d.childrenByName("tiger")</span><br />
<span style="color: blue;">res21: List[XDoc] = </span><br />
<span style="color: blue;">List(<tiger/>, <tiger male="true"></span><br />
<span style="color: blue;"> <females/></span><br />
<span style="color: blue;"></tiger>)</span><br />
<br />
<br />
Filtering children based on a predicate:<br />
<br />
<span style="color: blue;">scala> d = d filter(_.name !="zebra")</span><br />
<span style="color: blue;">d: XDoc = <animals test2="Value" test="attrValue"></span><br />
<span style="color: blue;"> <tiger/></span><br />
<span style="color: blue;"> <lion/></span><br />
<span style="color: blue;"> <tiger male="true"></span><br />
<span style="color: blue;"> <females/></span><br />
<span style="color: blue;"> </tiger></span><br />
<span style="color: blue;"></animals></span><br />
<br />
<br />
Checking existence of children based on predicate:<br />
<br />
<span style="color: blue;">scala> d exists(_.isChildLess == false)</span><br />
<span style="color: blue;">res22: Boolean = true</span><br />
<span style="color: blue;"><br /></span>
<span style="color: blue;">scala> val tigerWithFemales = d filter (_.isChildLess == false)</span><br />
<span style="color: blue;">tigerWithFemales: XDoc = </span><br />
<span style="color: blue;"><animals test2="Value" test="attrValue"></span><br />
<span style="color: blue;"> <tiger male="true"></span><br />
<span style="color: blue;"> <females/></span><br />
<span style="color: blue;"> </tiger></span><br />
<span style="color: blue;"></animals></span><br />
<br />
Mapping over child elements and transforming them:<br />
<br />
<span style="color: blue;">scala> d = d map (_.addAttr("wild","true"))</span><br />
<span style="color: blue;">d: XDoc = <animals test2="Value" test="attrValue"></span><br />
<span style="color: blue;"> <tiger wild="true"/></span><br />
<span style="color: blue;"> <lion wild="true"/></span><br />
<span style="color: blue;"> <tiger wild="true" male="true"></span><br />
<span style="color: blue;"> <females/></span><br />
<span style="color: blue;"> </tiger></span><br />
<span style="color: blue;"></animals></span><br />
<br />
<br />
Finding based on a predicate condition on children:<br />
<br />
<span style="color: blue;">scala> val withFemale = d find(_.isChildLess == false)</span><br />
<span style="color: blue;">withFemale: Option[XDoc] = </span><br />
<span style="color: blue;">Some(<tiger wild="true" male="true"></span><br />
<span style="color: blue;"> <females/></span><br />
<span style="color: blue;"></tiger>)</span><br />
<br />
Checking if some conditions holds for all children:<br />
<br />
<span style="color: blue;">scala> d forall(_.attr("wild") match {</span><br />
<span style="color: blue;"> | case None => false</span><br />
<span style="color: blue;"> | case Some(x) => true</span><br />
<span style="color: blue;"> | })</span><br />
<span style="color: blue;">res23: Boolean = true</span><br />
<br />
Finally, we can partition the elements based on some criteria.<br />
<br />
<span style="color: blue;">scala> val (d1, d2) = d partition (_.isChildLess)</span><br />
<span style="color: blue;">d1: XDoc = </span><br />
<span style="color: blue;"><animals test2="Value" test="attrValue"></span><br />
<span style="color: blue;"> <tiger wild="true"/></span><br />
<span style="color: blue;"> <lion wild="true"/></span><br />
<span style="color: blue;"></animals></span><br />
<span style="color: blue;">d2: XDoc = </span><br />
<span style="color: blue;"><animals test2="Value" test="attrValue"></span><br />
<span style="color: blue;"> <tiger wild="true" male="true"></span><br />
<span style="color: blue;"> <females/></span><br />
<span style="color: blue;"> </tiger></span><br />
<span style="color: blue;"></animals></span><br />
<br />
<br />
As can be seen XDoc can be pretty handy for dealing with xmls without namespaces. It is an utility class of a bigger project - And can be improved upon. In the mean while the source can be found at:<br />
<br />
<span style="color: blue;">https://github.com/ratulb/scala-xml-wrapper</span><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br /></div>
</div>
rbsomeghttp://www.blogger.com/profile/05453183134897252847noreply@blogger.com0