<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Posts on Development the way it should be</title>
        <link>/posts/</link>
        <description>Recent content in Posts on Development the way it should be</description>
        <generator>Hugo -- gohugo.io</generator>
        <copyright>&lt;a href=&#34;https://creativecommons.org/licenses/by-nc/4.0/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;CC BY-NC 4.0&lt;/a&gt;</copyright>
        <lastBuildDate>Tue, 30 Jan 2018 00:00:00 +0000</lastBuildDate>
        <atom:link href="/posts/index.xml" rel="self" type="application/rss+xml" />
        
        <item>
            <title>AWS CloudFormation gotchas - Security groups</title>
            <link>/posts/2018/01/aws-cloudformation-gotchas-security-groups/</link>
            <pubDate>Tue, 30 Jan 2018 00:00:00 +0000</pubDate>
            
            <guid>/posts/2018/01/aws-cloudformation-gotchas-security-groups/</guid>
            <description>If you are working with AWS and keeping your infrastructure as code (Hint: you really should) then you&amp;rsquo;ve probably come across CloudFormation or Terraform at some point. If you are using the former option, then there&amp;rsquo;s a small gotcha related to security groups that might cause some unexpected behaviour if you are not aware of it (for me it caused a production incident&amp;hellip;).
The use case Imagine you have the following small template defining a security group that allows incoming HTTPS traffic from a specific IP range and a load balancer that will use that security group:</description>
            <content type="html"><![CDATA[

<p>If you are working with AWS and keeping your infrastructure as code (Hint: you
really should) then you&rsquo;ve probably come across
<a href="https://aws.amazon.com/cloudformation/" target="_blank">CloudFormation</a> or
<a href="https://www.terraform.io/" target="_blank">Terraform</a> at some point.
If you are using the former option, then there&rsquo;s a small gotcha related to
security groups that might cause some unexpected behaviour if you are not aware
of it (for me it caused a production incident&hellip;).</p>

<h1 id="the-use-case">The use case</h1>

<p>Imagine you have the following small template defining a security group that
allows incoming HTTPS traffic from a specific IP range and a load balancer that
will use that security group:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml">AWSTemplateFormatVersion: <span style="color:#e6db74">&#39;2010-09-09&#39;</span>
Description: My awesome template
Outputs:
  SecurityGroup:
    Value: !Ref SecurityGroup
Resources:
  SecurityGroup:
    Properties:
      GroupDescription: Security group used for the test
      SecurityGroupEgress:
        - CidrIp: <span style="color:#ae81ff">0.0</span>.<span style="color:#ae81ff">0.0</span>/<span style="color:#ae81ff">0</span>
          IpProtocol: <span style="color:#e6db74">&#39;-1&#39;</span>
      SecurityGroupIngress:
        - CidrIp: <span style="color:#ae81ff">10.2</span>.<span style="color:#ae81ff">2.0</span>/<span style="color:#ae81ff">24</span>
          FromPort: <span style="color:#e6db74">&#39;443&#39;</span>
          IpProtocol: tcp
          ToPort: <span style="color:#e6db74">&#39;443&#39;</span>
      VpcId: &lt;your_vpc_id<span style="color:#e6db74">&gt;
</span><span style="color:#e6db74">    Type: &#39;AWS::SecurityGroup&#39;</span>

  LoadBalancer:
    Type: AWS::LoadBalancer
    Properties:
      Scheme: internal
      Subnets: &lt;subnets<span style="color:#e6db74">&gt;
</span><span style="color:#e6db74">      SecurityGroups:</span>
        - !Ref SecurityGroup</code></pre></div>

<p>You create your CloudFormation stack and everything works as expected. Both
resources are created and the security group is associated with the load
balancer to make sure that only HTTPS traffic from that specific IP range is
accepted. After a short test, you start routing all traffic to your new shiny
load balancer.</p>

<h1 id="the-problem">The problem</h1>

<p>A few weeks later you come back to this simple template to add a new resource
and you try to remember what that specific IP range meant. Was it the subnet of
one of your clients? If so, which one? Who do I need to notify in case the port
or range needs to change?
After some searching through your archived emails you finally find where that
range came from. Since you are a good engineer and you don&rsquo;t want anyone else to
waste 20 minutes of their life trying to understand why that rule is the way it
is, you decide &ldquo;I should probably add a description to my rule now that AWS <a href="https://aws.amazon.com/blogs/aws/new-descriptions-for-security-group-rules/" target="_blank">supports
it</a>&rdquo;.</p>

<p>So you go ahead and add that:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml">SecurityGroup:
  Properties:
    GroupDescription: Security group used for the test
    SecurityGroupEgress:
      - CidrIp: <span style="color:#ae81ff">0.0</span>.<span style="color:#ae81ff">0.0</span>/<span style="color:#ae81ff">0</span>
        IpProtocol: <span style="color:#e6db74">&#39;-1&#39;</span>
    SecurityGroupIngress:
      - CidrIp: <span style="color:#ae81ff">10.2</span>.<span style="color:#ae81ff">2.0</span>/<span style="color:#ae81ff">24</span>
        FromPort: <span style="color:#e6db74">&#39;443&#39;</span>
        IpProtocol: tcp
        ToPort: <span style="color:#e6db74">&#39;443&#39;</span>
        Description: <span style="color:#e6db74">&#34;This IP range belongs to the subnet of Team X&#34;</span>
    VpcId: &lt;your_vpc_id<span style="color:#e6db74">&gt;
</span><span style="color:#e6db74">  Type: &#39;AWS::SecurityGroup&#39;</span></code></pre></div>

<p>Quite happy with yourself you do your usual <code>aws cloud-formation update-stack</code>
and you switch to something else.
Immediately after firing the stack update you start getting alarms (because of
course you monitor your infrastructure) telling you that no traffic is getting
through your load balancer. After a few minutes the alarms go away and you start
getting traffic again but it was enough for your clients to notice that all
their requests were timing out.
What the hell happened!?</p>

<p>You know the problem is related to your change in the security group but how can
adding a description possibly cause that? You quickly go to your CloudFormation
console and look at the events of the stack, nothing wrong there.
You go to the CloudFormation
<a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html#cfn-ec2-securitygroup-securitygroupingress" target="_blank">documentation</a>
to see if you missed something, but nowhere does it say anything special about
adding a description to one of the rules. In fact, it explicitly says that
changes to the <code>SecurityGroupIngress</code> require &ldquo;No interruption&rdquo;.</p>

<p>You start to think that maybe it had nothing to do with your update and that it
was an extremely unlucky coincidence. But on a last attempt to see if you find
anything weird you log in to your AWS Console and find your security group there.
It looks correct but just for fun you click the &ldquo;Edit&rdquo; button. Of course you
would never update stuff like that manually (infra as code remember?) but you
are desperate at this point. And in there (only in there) you see this:</p>

<p><img src="/images/aws-sg/sg.png" alt="sg" /></p>

<p><strong>NOTE: Any edits made on existing rules will result in the edited rule being
deleted and a new rule created with the new details. This will cause traffic
that depends on that rule to be dropped for a very brief period of time until
the new rule can be created.</strong></p>

<p>What? How? Why? You would understand if that was the case when changing the port
or the IP range, but adding a description to it? Really?
To add salt to the wound, you then find out that AWS has an operation on their
API to do exactly this, it&rsquo;s aptly called
<a href="https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_UpdateSecurityGroupRuleDescriptionsIngress.html" target="_blank">UpdateSecurityGroupRuleDescriptionsIngress</a>.
So this feels like pure laziness. Instead of checking what actually changed in
the definition of the rule and call the proper API in case that was only the
description, CloudFormation decides it&rsquo;s easier to fully recreate the rule
if anything changes (with the corresponding traffic drop).</p>

<p>You decide to test this for yourself by creating a new test template with only
the security group definition, initially without description:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml">AWSTemplateFormatVersion: <span style="color:#e6db74">&#39;2010-09-09&#39;</span>
Description: Security group description update test
Outputs:
  TestSecurityGroup:
    Value: !Ref TestSecurityGroup
Resources:
  TestSecurityGroup:
    Properties:
      GroupDescription: Security group used for the test
      SecurityGroupEgress:
        - CidrIp: <span style="color:#ae81ff">0.0</span>.<span style="color:#ae81ff">0.0</span>/<span style="color:#ae81ff">0</span>
          IpProtocol: <span style="color:#e6db74">&#39;-1&#39;</span>
      SecurityGroupIngress:
        - CidrIp: <span style="color:#ae81ff">10.2</span>.<span style="color:#ae81ff">2.0</span>/<span style="color:#ae81ff">24</span>
          FromPort: <span style="color:#e6db74">&#39;443&#39;</span>
          IpProtocol: tcp
          ToPort: <span style="color:#e6db74">&#39;443&#39;</span>
      VpcId: &lt;your_vpc_id<span style="color:#e6db74">&gt;
</span><span style="color:#e6db74">    Type: &#39;AWS::SecurityGroup&#39;</span></code></pre></div>

<p>After the stack is created you check your security group from the AWS cli:
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-raw" data-lang="raw">$&gt; aws ec2 describe-security-groups --group-ids &lt;your_sg_id&gt; | jq &#39;.SecurityGroups[0].IpPermissions&#39;

[
  {
    &#34;PrefixListIds&#34;: [],
    &#34;FromPort&#34;: 443,
    &#34;IpRanges&#34;: [
      {
        &#34;CidrIp&#34;: &#34;10.2.2.0/24&#34;
      }
    ],
    &#34;ToPort&#34;: 443,
    &#34;IpProtocol&#34;: &#34;tcp&#34;,
    &#34;UserIdGroupPairs&#34;: [],
    &#34;Ipv6Ranges&#34;: []
  }
]</code></pre></div></p>

<p>Now, as you did before, you add a nice description to your ingress rule and do
an <code>update-stack</code>. And here&rsquo;s where it gets really interesting. As soon as you
trigger the stack update you run your <code>describe-security-groups</code> command again
and you see this as the output:</p>

<p><div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-raw" data-lang="raw">$&gt; aws ec2 describe-security-groups --group-ids &lt;your_sg_id&gt; | jq &#39;.SecurityGroups[0].IpPermissions&#39;

[]</code></pre></div>
That&rsquo;s right, no ingress rules for your security group. Which of course means no
traffic can get through.
You try again after you stack is finished updating and you see your rule there
again, this time with the description.</p>

<p>Like I said before, given that the functionality to update only a rule
description is present on their API, this feels like a pretty serious bug in
CloudFormation to me.
But even if it wasn&rsquo;t, I would definitely expect to see some sort of
warning on CloudFormation docs (not in some obscure part of the AWS UI).</p>

<h1 id="the-solution">The solution</h1>

<p>So, given this limitation in CloudFormation, how do you work around it? How do
you add descriptions to your existing rules?</p>

<p>The most straightforward approach is simply to have a planned maintenance window
for your service (or services) and just do the update. As far as I could see in
my tests it usually takes less than a minute for the new rule to be created and
put in place.</p>

<p>If that&rsquo;s not acceptable for your use case then it gets a bit more tricky. Here
are some of the things I tried and didn&rsquo;t work.</p>

<p>Using the AWS cli, you can update the description using the API I mentioned
previously
(<a href="https://docs.aws.amazon.com/cli/latest/reference/ec2/update-security-group-rule-descriptions-ingress.html" target="_blank">https://docs.aws.amazon.com/cli/latest/reference/ec2/update-security-group-rule-descriptions-ingress.html</a>).
That works and doesn&rsquo;t incur in any downtime but now your CloudFormation
template doesn&rsquo;t really represent the current state of your infrastructure. You
might think that adding the same description as you used in the cli to your
template would work but it doesn&rsquo;t.
Since the latest version of the template that CloudFormation knows about doesn&rsquo;t
contain any description, the next update will recreate the rule just as it did
the first time.</p>

<p>A second potential approach was to just add a second ingress rule to the
template with the same IP range and port that includes our awesome description.
By doing this I was expecting CloudFormation to leave the old rule untouched
while creating a new one and, on a second update after that, to remove the first
rule (the one without description). Unfortunately this doesn&rsquo;t work because
CloudFormation seems to use the (IP, port) pair as a way to identify each rule. That
means 2 things for our example: the first update will not create a new rule
and, even worse, the second update to remove the old rule will actually leave
your security group without any ingress rules.</p>

<p>The only approach that has worked for me so far is a slight variation of the
previous one:
- Add a new rule that is more permissive than the original one so that it allows
  traffic from the same IP range (0.0.0.0/0 for instance if you are not worried
  about opening access to everyone for a few minutes) and update your stack
- At this point you should have 2 ingress rules in your security group. Now you
  can add your description to the original rule and do an update. This will
  recreate the rule but that should be fine because we have our second rule
  still there that should allow traffic from the same source
- Finally, delete the second rule. Now you should be back to having only your
  original IP range with the description included</p>

<p>Having to do 3 stack updates to add a simple description to an ingress rule is
less than ideal but I haven&rsquo;t found a better way to do it without incurring in
some downtime for your clients.</p>

<h1 id="what-about-terraform">What about Terraform?</h1>

<p>If you are using Terraform then things should work as expected. Terraform will
do the update without incurring in any packet loss.
From the output of <code>terraform plan</code> you can actually see that it is creating a
new rule with your description and deleting the old one, but it does so in a way
that you always have at least 1 of them present.
Kudos to HashiCorp for that!</p>
]]></content>
        </item>
        
        <item>
            <title>Why you should follow the robustness principle in your APIs</title>
            <link>/posts/2017/03/why-you-should-follow-the-robustness-principle-in-your-apis/</link>
            <pubDate>Sat, 25 Mar 2017 00:00:00 +0000</pubDate>
            
            <guid>/posts/2017/03/why-you-should-follow-the-robustness-principle-in-your-apis/</guid>
            <description>Microservices are all the rage right now. Everyone is taking their big monoliths and decomposing them into smaller services with exposed APIs. If you are doing this right then your services should be completely decoupled and independently releasable. Yet the way some APIs are designed makes this extremely hard to accomplish, if not impossible. Let&amp;rsquo;s take a look at the problem and how to solve it.
Postel&amp;rsquo;s Law Postel&amp;rsquo;s Law, also known as the robustness principle states that you should be conservative in what you send and liberal in what you accept from others.</description>
            <content type="html"><![CDATA[

<p>Microservices are all the rage right now. Everyone is taking their big monoliths
and decomposing them into smaller services with exposed APIs. If you are doing
this right then your services should be completely decoupled and independently
releasable. Yet the way some APIs are designed makes this extremely hard to
accomplish, if not impossible.
Let&rsquo;s take a look at the problem and how to solve it.</p>

<h1 id="postel-s-law">Postel&rsquo;s Law</h1>

<p>Postel&rsquo;s Law, also known as the <a href="https://www.wikiwand.com/en/Robustness_principle" target="_blank">robustness
principle</a> states that you
should be conservative in what you send and liberal in what you accept from
others.  Although this was proposed initially for the specification of the TCP
protocol, it has a very important place in the design and evolution of APIs and
we&rsquo;ll see why with an example.</p>

<p>Imagine we have 2 small, independent services owned by different teams: the user
service and the address service. The address service exposes a small API to
store users&rsquo; addresses, which initially only consists of the street address.  The
user service can POST a request with a JSON body like <code>{&quot;street_address&quot;: &quot;1234
Fake St.&quot;}</code> and the address service responds with a 201 - Created.</p>

<p>So far so good. However, we quickly realize that street address alone is not
enough information so we want to start sending in city and postal code as well.
Unfortunately, the address service does not follow the robustness principle we
mentioned before because if it happens to receive any field on the request that
it doesn&rsquo;t recognize (anything other than street_address at the moment) it
immediately fails, returning a 400 - Bad Request</p>

<p>The user service team is done with their part of the work needed to start
sending the new fields but they can not release it until the address service is
updated to take in those fields.  We effectively introduced a major coupling
point between the 2 services that adds the need to sync their releases. This is
even worse if we have multiple environments with potentially different versions
of our services deployed and/or multiple clients of the address service.</p>

<p>Of course, one approach to mitigate this would be for the user service to have
this new functionality behind a <a href="https://martinfowler.com/bliki/FeatureToggle.html" target="_blank">feature
flag</a>. Then they can do their
work and release to any environment with the flag disabled. Once the address
service is updated the new feature can be enabled.
Not a big problem, but each feature flag does introduce some extra complexity to
the code. What happens the next time we want to add another field? Will we have
one flag for each field that we want to send to the address service?</p>

<p>Now imagine that both services are running with the latest changes, the feature
flag is enabled and we are storing the data we wanted. It&rsquo;s Saturday 11 PM
and consumers start calling in complaining that their address data is completely
messed up. They are getting data from other people, which is not only a terrible
user experience but a potential privacy disaster.
It turns out that the latest release of the address service with the addition of
the 2 new fields also included a nasty bug that caused the data to be assigned
to the wrong users.
The address team decides to rollback the release immediately to the latest known
functioning version (the one that had only street_address on the API).</p>

<p>There are 2 possible scenarios at this point. Scenario 1 is that they rollback
their service without realizing that the user service is still sending the new
fields. This causes all new requests after the rollback to fail with a 400,
effectively loosing all new data.
Scenario 2 involves someone contacting the user team for them to disable the
feature flag (if it&rsquo;s still there) before doing the rollback.
The result is equally bad in either case. You introduce unnecessary dependencies
between teams and unexpected bugs.</p>

<p>This whole thing could have been avoided if the address service would&rsquo;ve
adhered to the robustness principle and simply ignored all unknown fields.
The user service then could&rsquo;ve started sending the new fields in all
environments without worrying about when the address service was ready.
Similarly, in the production incident scenario, the address service can safely
rollback and the user service team doesn&rsquo;t even have to know about it. No
coupling, no synchronization between teams, no hassle.</p>

<p>Note that you can still enforce the presence of mandatory fields. The only thing
we&rsquo;ve done is to make sure we just ignore the fields we don&rsquo;t care about.</p>

<p>This is very easy to do if you are using Jackson for instance, either globally
by configuring you object mapper like:
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java"><span style="color:#66d9ef">new</span> ObjectMapper<span style="color:#f92672">()</span>
  <span style="color:#f92672">.</span><span style="color:#a6e22e">configure</span><span style="color:#f92672">(</span>DeserializationFeature<span style="color:#f92672">.</span><span style="color:#a6e22e">FAIL_ON_UNKNOWN_PROPERTIES</span><span style="color:#f92672">,</span> <span style="color:#66d9ef">false</span><span style="color:#f92672">)</span></code></pre></div></p>

<p>or on a class by class basis, with a simple annotation:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java"><span style="color:#a6e22e">@JsonIgnoreProperties</span><span style="color:#f92672">(</span>ignoreUnknown <span style="color:#f92672">=</span> <span style="color:#66d9ef">true</span><span style="color:#f92672">)</span>
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">Address</span> <span style="color:#f92672">{</span>
<span style="color:#f92672">}</span></code></pre></div>

<p>Other languages and serialization/deserialization frameworks should provide
similar options.
If you are using JSON schema to validate your incoming requests you can set
<a href="http://json-schema.org/latest/json-schema-validation.html#rfc.section.5.18" target="_blank">additionalProperties</a> to true.</p>

<h1 id="api-versioning">API versioning</h1>

<p>Of course this doesn&rsquo;t mean that your service should accept completely invalid
input and try to make sense of it. As they say, keep an open mind but not so
open that your brain falls off.</p>

<p>Adding new optional fields to an API, like we saw in the previous example, is a classic
example of a change that is perfectly backwards compatible. Your service should
be able to handle both the presence and the absence of those fields.
Other times, however, there&rsquo;s a fundamental change in the structure of your API.
In these cases it&rsquo;s a lot harder, if not impossible, to keep backwards
compatibility.</p>

<p>This is one of the main reasons why it&rsquo;s a good idea to have versioning of your
APIs from day one. You never know how your service will need to evolve in the
future so it&rsquo;s better to start with the assumption that you will need versioning
at some point.
You have several alternatives to handle API versioning (URL vs Content-Type
header for instance). Which one you choose will depend on your particular needs
and constraints.</p>

<h1 id="also-important-for-consumers-of-apis">Also important for consumers of APIs</h1>

<p>So far we&rsquo;ve been assuming that this applies only to providers of an API in what
they accept from their clients. But it is equally important for consumers as
well.</p>

<p>When you consume an external API, most of the time you are not interested in
every single field of the response. By making sure that you ignore any field you
don&rsquo;t have an interest in, you are not only writing less code but you are also
making your service more resilient to changes in that API.</p>

<p>We can go back to the user and address service example from before, but this
time looking at things from the point of view of the user service. In the same
way that the address service provides an endpoint to POST data to, it also
provides an endpoint where clients can GET address details. In the response the
address service includes the street address, city, latitude and longitude.</p>

<p>The user service is only interested in the street address and city, it has no
use for latitude and longitude. But for some reason it still maps every field
of the response. With time the address service adds more fields to the response
because other consumers need those. Every new addition involves extra work for
the user service team, even when they still only care about the original street
address and city.</p>

<p>To make things worse, the address service doesn&rsquo;t really sync with its clients
before doing backwards compatible changes (and why should they?). So the user
service only realizes that they have to adapt to a new response after things
start failing on their side.</p>

<h1 id="is-it-ever-worth-it">Is it ever worth it?</h1>

<p>So why would you want to be really conservative in what you accept and fail all
requests that have any additional field?
I haven&rsquo;t found a real-life use case where the benefits from doing so outweigh
the problems we discussed before.
I suspect most services that actually do this are doing it because they just
haven&rsquo;t thought about it and they use the default behaviour of their
language/tool. In the case of Jackson this default behaviour is to fail the
deserialization when extra fields are present.</p>

<p>Some people argue that making the request fail early can make it explicit to the
consumers of their API that they are doing something wrong. I don&rsquo;t really find
that argument compelling enough. This sort of issues should be detected through
testing, either <a href="https://martinfowler.com/articles/consumerDrivenContracts.html" target="_blank">consumer driven
contracts</a> or
integration/E2E tests.</p>

<h1 id="conclusion">Conclusion</h1>

<p>Postel&rsquo;s law, or the Robustness principle, is essential in the evolution of
APIs. No one can accurately anticipate how your requirements are going to change
or how many different number and types of consumers you are going to have. By
making sure that you are lenient and ignore the fields you don&rsquo;t really care
about for specific requests you will be decoupling your service from your
consumers. This is fundamental in a micro-service environment where the
dependencies between services should be kept to a minimum, especially when
considering releases.</p>
]]></content>
        </item>
        
        <item>
            <title>Single interface to parse and update JSON/YAML from your terminal</title>
            <link>/posts/2016/05/single-interface-to-parse-and-update-json/yaml-from-your-terminal/</link>
            <pubDate>Tue, 24 May 2016 00:00:00 +0000</pubDate>
            
            <guid>/posts/2016/05/single-interface-to-parse-and-update-json/yaml-from-your-terminal/</guid>
            <description>If you&amp;rsquo;ve ever had to parse JSON from your terminal you probably know about jq. It&amp;rsquo;s basically sed for JSON and it works wonderfully well. If you&amp;rsquo;ve had to parse YAML from your terminal however, the problem becomes a bit harder. You can either go for some super obscure 15 lines sed and awk combination that has the advantage of being pure bash, or go with a higher level language (ruby or python comes to mind) to actually do the parsing and outputting the result to stdout.</description>
            <content type="html"><![CDATA[

<p>If you&rsquo;ve ever had to parse JSON from your terminal you probably know about
<a href="https://stedolan.github.io/jq/" target="_blank">jq</a>. It&rsquo;s basically <code>sed</code> for JSON and it works
wonderfully well.
If you&rsquo;ve had to parse YAML from your terminal however, the problem becomes a
bit harder. You can either go for some super obscure <a href="http://stackoverflow.com/a/21189044" target="_blank">15 lines sed and awk
combination</a> that has the advantage of
being pure bash, or go with a higher level language (ruby or python comes to
mind) to actually do the parsing and outputting the result to stdout.
In this post I&rsquo;ll show <a href="https://github.com/jlordiales/jyparser" target="_blank">jyparser</a>, a
simple tool (packaged as a nice docker image) that allows you to use a jq-like
syntax to parse and also update JSON and YAML files from your terminal using
exactly the same commands.</p>

<h1 id="the-problem">The problem</h1>

<p>So imagine you have your app and different JSON files for the different
environments your app will be deployed to, with each file containing things like
the environment name, the build version currently deployed, etc.
Maybe something like:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">~ cat my_app.json

<span style="color:#f92672">{</span>
  <span style="color:#e6db74">&#34;app_name&#34;</span> : <span style="color:#e6db74">&#34;awesome app&#34;</span>,
  <span style="color:#e6db74">&#34;build_version&#34;</span> : <span style="color:#ae81ff">1</span>,
  <span style="color:#e6db74">&#34;tags&#34;</span> : <span style="color:#f92672">[</span><span style="color:#e6db74">&#34;myTeam&#34;</span>, <span style="color:#e6db74">&#34;myCompany&#34;</span><span style="color:#f92672">]</span>
<span style="color:#f92672">}</span></code></pre></div>

<p>Now as part of your deployment process you want to read the <code>build_version</code>
variable from the JSON file, increase it by 1 and then update the original JSON
with the new value.</p>

<p>This would not be super hard to do with plain <code>jq</code>:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">~ version<span style="color:#f92672">=</span><span style="color:#66d9ef">$(</span>cat my_app.json | jq <span style="color:#e6db74">&#39;.build_version&#39;</span><span style="color:#66d9ef">)</span>
~ echo $version
<span style="color:#ae81ff">1</span>

~ new_version<span style="color:#f92672">=</span><span style="color:#66d9ef">$((</span>version+1<span style="color:#66d9ef">))</span>
~ echo $new_version
<span style="color:#ae81ff">2</span>

~ cat my_app.json | jq --arg value $new_version <span style="color:#e6db74">&#39;.build_version |= $value&#39;</span>
<span style="color:#f92672">{</span>
  <span style="color:#e6db74">&#34;app_name&#34;</span>: <span style="color:#e6db74">&#34;awesome app&#34;</span>,
  <span style="color:#e6db74">&#34;build_version&#34;</span>: <span style="color:#e6db74">&#34;2&#34;</span>,
  <span style="color:#e6db74">&#34;tags&#34;</span>: <span style="color:#f92672">[</span>
    <span style="color:#e6db74">&#34;myTeam&#34;</span>,
    <span style="color:#e6db74">&#34;myCompany&#34;</span>
  <span style="color:#f92672">]</span>
<span style="color:#f92672">}</span></code></pre></div>

<p>It&rsquo;s not too hard but it&rsquo;s not straightforward either, specially the update
part. You have to know about <code>jq</code> update operator (<code>|=</code>) and how you can pass
env variables using <code>--arg</code>.</p>

<p>Now imagine you decide to switch to YAML instead of JSON because either you
started using a different tool that only accepts YAML or the same tool accepts
both and you prefer it over JSON.</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">~ cat my_app.yml

app_name: awesome app
build_version: <span style="color:#ae81ff">1</span>
tags:
- myTeam
- myCompany</code></pre></div>

<p>You still want to accomplish the same thing, bump the <code>build_version</code> of your
YAML. But your previous deployment bash script with your fancy <code>jq</code> query
obviously doesn&rsquo;t work anymore.
Now you need to figure out how you&rsquo;re going to parse and update that YAML, which
like I mentioned in the beginning is not trivial (or at least I didn&rsquo;t find a
nice and easy way to do it).</p>

<p>Wouldn&rsquo;t it be nice if you could somehow say: <code>cat my_app.{yml, json} | get
.build_version</code> to read the value you are interested in and <code>cat my_app.{yml,
json} | set .build_version &lt;new_value&gt;</code> to update it?
That is, use exactly the same command regardless of where the input is coming
from (JSON or YAML). Enter <code>jyparser</code></p>

<h1 id="jyparser">jyparser</h1>

<p>jyparser stands for JSON/YAML Parser (I know, not very original but I always
sucked at names) and it was created specifically for the use
case I described above. Getting a single value from a JSON or YAML, doing
something with it (if needed) and then setting a new value for it on the
original input. Of course reading/updating entire objects/arrays in JSON or
entire hashes/lists in YAML is also supported.</p>

<p>At its hearth jyparser is a simple wrapper around <code>jq</code> and 2 python 1 liners to
convert from JSON to YAML and vice versa. It will detect the input&rsquo;s type and,
in the case of YAML, convert to JSON before applying <code>jq</code> and then convert the
result back to YAML.
Note that since YAML is actually a <a href="http://yaml.org/spec/1.2/spec.html#id2759572" target="_blank">superset of
JSON</a> this will only work for
those YAML files that can be correctly converted to JSON.</p>

<p>You can see the code <a href="https://github.com/jlordiales/jyparser" target="_blank">here</a> and the
docker image <a href="https://hub.docker.com/r/jlordiales/jyparser/" target="_blank">here</a>.</p>

<h2 id="usage">Usage</h2>

<p>Let&rsquo;s look at some examples of how you would usually use the tool.</p>

<p>The image&rsquo;s entry point accepts 2 operations: <code>get</code> and <code>set</code>. It can
take its inputs from stdin or read from a file if this is passed as the first
parameter.</p>

<h3 id="read">Read</h3>

<p>The <code>get</code> command takes an arbitrary <code>jq</code> filter. If the result is a simple
value (number, string or boolean) then that value is returned. Otherwise, the
resulting JSON or YAML is returned (depending on what the input was).</p>

<p>Given the following JSON file:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">~ cat test.json

<span style="color:#f92672">{</span><span style="color:#e6db74">&#34;menu&#34;</span>: <span style="color:#f92672">{</span>
  <span style="color:#e6db74">&#34;id&#34;</span>: <span style="color:#e6db74">&#34;file&#34;</span>,
  <span style="color:#e6db74">&#34;value&#34;</span>: <span style="color:#e6db74">&#34;File&#34;</span>,
  <span style="color:#e6db74">&#34;popup&#34;</span>: <span style="color:#f92672">{</span>
    <span style="color:#e6db74">&#34;menuitem&#34;</span>: <span style="color:#f92672">[</span>
      <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;value&#34;</span>: <span style="color:#e6db74">&#34;New&#34;</span>, <span style="color:#e6db74">&#34;onclick&#34;</span>: <span style="color:#e6db74">&#34;CreateNewDoc()&#34;</span><span style="color:#f92672">}</span>,
      <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;value&#34;</span>: <span style="color:#e6db74">&#34;Open&#34;</span>, <span style="color:#e6db74">&#34;onclick&#34;</span>: <span style="color:#e6db74">&#34;OpenDoc()&#34;</span><span style="color:#f92672">}</span>,
      <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;value&#34;</span>: <span style="color:#e6db74">&#34;Close&#34;</span>, <span style="color:#e6db74">&#34;onclick&#34;</span>: <span style="color:#e6db74">&#34;CloseDoc()&#34;</span><span style="color:#f92672">}</span>
    <span style="color:#f92672">]</span>
  <span style="color:#f92672">}</span>
<span style="color:#f92672">}}</span></code></pre></div>

<p>If you wanted to get the value of the <em>id</em> property you could use:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">~ cat test.json | docker run -i --rm jlordiales/jyparser get .menu.id

<span style="color:#e6db74">&#34;file&#34;</span></code></pre></div>

<p>The JSON is passed via stdin, which is useful if you get that from something like
<code>curl</code>. If you have an actual file that you want to use as input then you can
pass it directly as the first parameter to the script:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">~ docker run -i --rm -v <span style="color:#e6db74">`</span>pwd<span style="color:#e6db74">`</span>:/jyparser:ro jlordiales/jyparser test.json get <span style="color:#e6db74">&#34;.menu.id&#34;</span>

<span style="color:#e6db74">&#34;file&#34;</span></code></pre></div>

<p>The example above mounts the current dir with the file into <code>/jyparser</code> (which
is the default WORKDIR for the docker image) and then uses that file as input.</p>

<p>Exactly the same command works for YAML as well. Given the equivalent YAML file:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">~ cat test.yml
menu:
  id: file
  value: File
  popup:
    menuitem:
    - onclick: CreateNewDoc<span style="color:#f92672">()</span>
      value: New
    - onclick: OpenDoc<span style="color:#f92672">()</span>
      value: Open
    - onclick: CloseDoc<span style="color:#f92672">()</span>
      value: Close</code></pre></div>

<p>We can get the <code>id</code> property with:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">~ cat test.yml | docker run -i --rm jlordiales/jyparser get .menu.id

<span style="color:#e6db74">&#34;file&#34;</span></code></pre></div>

<p>If the result from running the <code>jq</code> filter is not a simple value, then the
corresponding JSON or YAML is returned:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">~ cat test.json | docker run -i --rm jlordiales/jyparser get <span style="color:#e6db74">&#34;.menu.popup.menuitem[1]&#34;</span>

<span style="color:#f92672">{</span>
  <span style="color:#e6db74">&#34;value&#34;</span>: <span style="color:#e6db74">&#34;Open&#34;</span>,
  <span style="color:#e6db74">&#34;onclick&#34;</span>: <span style="color:#e6db74">&#34;OpenDoc()&#34;</span>
<span style="color:#f92672">}</span>

~ cat test.yml | docker run -i --rm jlordiales/jyparser get <span style="color:#e6db74">&#34;.menu.popup.menuitem[1]&#34;</span>

onclick: OpenDoc<span style="color:#f92672">()</span>
value: Open</code></pre></div>

<p>The <code>jq</code> filter that is passed as parameter is sent as is to the tool, so you
are not limited so simple filters. Anything that is valid for <code>jq</code> is valid for
<code>jyparser</code> as well.</p>

<h3 id="update">Update</h3>

<p>Similarly to the <code>get</code> operation, there&rsquo;s a <code>set</code> one. This operation takes 2
parameters: a <code>jq</code> filter to select a specific element of the input and a new
value to update that element to. The result is the original input with the value
updated.</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">~ cat test.json | docker run -i --rm jlordiales/jyparser set <span style="color:#e6db74">&#34;.menu.id&#34;</span> <span style="color:#ae81ff">\&#34;</span>new_id<span style="color:#ae81ff">\&#34;</span>
<span style="color:#f92672">{</span>
  <span style="color:#e6db74">&#34;menu&#34;</span>: <span style="color:#f92672">{</span>
    <span style="color:#e6db74">&#34;id&#34;</span>: <span style="color:#e6db74">&#34;new_id&#34;</span>,
    <span style="color:#e6db74">&#34;value&#34;</span>: <span style="color:#e6db74">&#34;File&#34;</span>,
    <span style="color:#e6db74">&#34;popup&#34;</span>: <span style="color:#f92672">{</span>
      <span style="color:#e6db74">&#34;menuitem&#34;</span>: <span style="color:#f92672">[</span>
        <span style="color:#f92672">{</span>
          <span style="color:#e6db74">&#34;value&#34;</span>: <span style="color:#e6db74">&#34;New&#34;</span>,
          <span style="color:#e6db74">&#34;onclick&#34;</span>: <span style="color:#e6db74">&#34;CreateNewDoc()&#34;</span>
        <span style="color:#f92672">}</span>,
        <span style="color:#f92672">{</span>
          <span style="color:#e6db74">&#34;value&#34;</span>: <span style="color:#e6db74">&#34;Open&#34;</span>,
          <span style="color:#e6db74">&#34;onclick&#34;</span>: <span style="color:#e6db74">&#34;OpenDoc()&#34;</span>
        <span style="color:#f92672">}</span>,
        <span style="color:#f92672">{</span>
          <span style="color:#e6db74">&#34;value&#34;</span>: <span style="color:#e6db74">&#34;Close&#34;</span>,
          <span style="color:#e6db74">&#34;onclick&#34;</span>: <span style="color:#e6db74">&#34;CloseDoc()&#34;</span>
        <span style="color:#f92672">}</span>
      <span style="color:#f92672">]</span>
    <span style="color:#f92672">}</span>
  <span style="color:#f92672">}</span>
<span style="color:#f92672">}</span></code></pre></div>

<p><strong>Important</strong>: given the way bash scripts handle quotes on parameters passed to
them, if the new value you want to set for the property is a string you need to
explicitly escape the quotes as in the example. Otherwise, <code>jq</code> will complain
that the value is not valid (rightfully so). This is not needed for numbers or
booleans.
So the following works as expected:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">~ cat test.json | docker run -i --rm jlordiales/jyparser set <span style="color:#e6db74">&#34;.menu.id&#34;</span> <span style="color:#ae81ff">15</span>
<span style="color:#f92672">{</span>
  <span style="color:#e6db74">&#34;menu&#34;</span>: <span style="color:#f92672">{</span>
    <span style="color:#e6db74">&#34;id&#34;</span>: <span style="color:#ae81ff">15</span>,
    <span style="color:#e6db74">&#34;value&#34;</span>: <span style="color:#e6db74">&#34;File&#34;</span>,
    <span style="color:#e6db74">&#34;popup&#34;</span>: <span style="color:#f92672">{</span>
      <span style="color:#e6db74">&#34;menuitem&#34;</span>: <span style="color:#f92672">[</span>
        <span style="color:#f92672">{</span>
          <span style="color:#e6db74">&#34;value&#34;</span>: <span style="color:#e6db74">&#34;New&#34;</span>,
          <span style="color:#e6db74">&#34;onclick&#34;</span>: <span style="color:#e6db74">&#34;CreateNewDoc()&#34;</span>
        <span style="color:#f92672">}</span>,
        <span style="color:#f92672">{</span>
          <span style="color:#e6db74">&#34;value&#34;</span>: <span style="color:#e6db74">&#34;Open&#34;</span>,
          <span style="color:#e6db74">&#34;onclick&#34;</span>: <span style="color:#e6db74">&#34;OpenDoc()&#34;</span>
        <span style="color:#f92672">}</span>,
        <span style="color:#f92672">{</span>
          <span style="color:#e6db74">&#34;value&#34;</span>: <span style="color:#e6db74">&#34;Close&#34;</span>,
          <span style="color:#e6db74">&#34;onclick&#34;</span>: <span style="color:#e6db74">&#34;CloseDoc()&#34;</span>
        <span style="color:#f92672">}</span>
      <span style="color:#f92672">]</span>
    <span style="color:#f92672">}</span>
  <span style="color:#f92672">}</span>
<span style="color:#f92672">}</span></code></pre></div>

<p>This way of updating the JSON is arguably a lot easier to read and use than the
<code>jq</code> version we saw at the beginning. It&rsquo;s just <code>set &lt;key&gt; &lt;value&gt;</code> and, best of
all, the same works for YAML:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">~ cat test.yml | docker run -i --rm jlordiales/jyparser set <span style="color:#e6db74">&#34;.menu.id&#34;</span> <span style="color:#ae81ff">\&#34;</span>new_id<span style="color:#ae81ff">\&#34;</span>

menu:
  id: new_id
  popup:
    menuitem:
    - onclick: CreateNewDoc<span style="color:#f92672">()</span>
      value: New
    - onclick: OpenDoc<span style="color:#f92672">()</span>
      value: Open
    - onclick: CloseDoc<span style="color:#f92672">()</span>
      value: Close
  value: File</code></pre></div>

<p>As with the get operation, set can take the input both from stdin and a file if
passed as first argument.</p>

<h1 id="conclusion">Conclusion</h1>

<p>If you are doing regular parsing/updating of JSON and/or YAML and you don&rsquo;t want
to have hugely complex combinations of <code>jq</code> with <code>sed</code> and <code>awk</code> but instead
have a simple interface to work with both types then give jyparser a try.
It was created for a very specific use case but it might be able to adapt to
yours as well.</p>

<p>jyparser was heavily inspired by <a href="https://github.com/wildducktheories/y2j" target="_blank">y2j</a>,
so make sure to check it out as well.</p>
]]></content>
        </item>
        
        <item>
            <title>Orchestrating your containers with CoreOS, an introduction</title>
            <link>/posts/2015/07/orchestrating-your-containers-with-coreos-an-introduction/</link>
            <pubDate>Sun, 12 Jul 2015 00:00:00 +0000</pubDate>
            
            <guid>/posts/2015/07/orchestrating-your-containers-with-coreos-an-introduction/</guid>
            <description>Most docker tutorials that you&amp;rsquo;ll find out there (the ones in this blog included) will assume that you have a single host running all your containers or a few hosts but where you are manually managing them. While this is nice and simple to explain the basic concepts, it is probably not the way you want to run your applications in production. In most cases you will have a cluster of servers all running different containers that need to talk to each other and know how to function properly, even when some of those servers suddenly go offline.</description>
            <content type="html"><![CDATA[

<p>Most docker tutorials that you&rsquo;ll find out there (the ones in this blog
included) will assume that you have a single host running all your containers or
a few hosts but where you are manually managing them. While this is nice and
simple to explain the basic concepts, it is probably not the way you want to run
your applications in production.
In most cases you will have a cluster of
servers all running different containers that need to talk to each other and
know how to function properly, even when some of those servers suddenly go
offline.</p>

<p>This is the area of orchestration and scheduling of containers, a topic that is
extremely hot these days. Particularly with big players in the industry working
in new projects to abstract away most of the complexities inherent to running
distributed containers. Amazon recently opened up their <a href="http://aws.amazon.com/ecs/" target="_blank">EC2 container
service</a>, Google has
<a href="http://kubernetes.io/" target="_blank">Kubernetes</a> and <a href="https://mesosphere.com/" target="_blank">Mesosphere</a> is
becoming pretty popular with
the underlying <a href="http://mesos.apache.org/" target="_blank">Apache Mesos project</a>.</p>

<p>One additional project that has been gaining a lot of attention in this area is
<a href="https://coreos.com/" target="_blank">CoreOS</a>. In this post I&rsquo;m going to try to explore CoreOS
and give a basic overview of the problem that it tries to solve, how it works
and how to work effectively with it.</p>

<h1 id="introduction">Introduction</h1>

<p>The idea behind CoreOS is the same as with any other cluster management system.
You stop thinking about your individual servers and how they work together.
Instead you think about your data center (a cluster of individual servers). In
other words, you no longer say &ldquo;run this container in server 1 and this other
container in server 2&rdquo; but &ldquo;run these 2 containers in my data center&rdquo; and let
the cluster manager take care of where and how to do that.</p>

<p>This also means that if one or more of your individual servers die the
cluster manager will take the containers that were running in those servers and
distribute them across the remaining healthy nodes.</p>

<p>Following this philosophy, CoreOS is an open source lightweight operating system
that comes together with a set of simple tools.<br />
The main building block behind CoreOS is Docker. Since CoreOS doesn&rsquo;t come with
a package manager, everything you want to run on it has to run as a container.
It should be noted that while CoreOS fully supports Docker, they are also working
on their own container runtime called <a href="https://github.com/coreos/rkt" target="_blank">rkt</a>.</p>

<p>To start and manage all these containers CoreOS uses Fleet. Fleet is based on
<a href="http://en.wikipedia.org/wiki/Systemd" target="_blank">systemd</a> and extends it in order to work
at the cluster level. In other words, while systemd works as a single machine
init system, fleet works as a cluster init system.</p>

<p>To coordinate all different nodes and let Fleet know where to run your
containers, CoreOS provides <a href="https://coreos.com/etcd/" target="_blank">etcd</a>, a distributed
key/value store with a strong consistency and partition tolerance model. Etcd
uses the <a href="https://raftconsensus.github.io/" target="_blank">Raft consensus algorithm</a> to handle
the communication between the different nodes. This is the same algorithm used
by Consul by the way.</p>

<p>I will go into some detail about each of this tools and how they can work
together with Docker. But first, lets setup our CoreOS cluster running on
Vagrant.</p>

<h1 id="bootstraping-a-coreos-cluster">Bootstraping a CoreOS cluster</h1>

<p>The CoreOS documentation has very comprehensive guides to run CoreOS on anything
from bare metal hardware, to cloud providers to virtualization platforms. You
can follow the step by step guide in
<a href="https://coreos.com/docs/running-coreos/platforms/vagrant/" target="_blank">here</a> to run a basic
cluster locally on Vagrant.</p>

<p>The short version is that you can clone <a href="https://github.com/coreos/coreos-vagrant" target="_blank">this
repo</a> and then do some minimal
configuration.
The relevant files for this part are the <code>config.rb</code> and
<code>user-data</code> ones.</p>

<p>The <code>Vagrantfile</code> is pretty generic and reads all the configuration it needs
from <code>config.rb</code>, so no need to change anything there. This latter file looks
something like the following:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-ruby" data-lang="ruby"><span style="color:#75715e"># Size of the CoreOS cluster created by Vagrant</span>
$num_instances<span style="color:#f92672">=</span><span style="color:#ae81ff">6</span>

<span style="color:#75715e"># Official CoreOS channel from which updates should be downloaded</span>
$update_channel<span style="color:#f92672">=</span><span style="color:#e6db74">&#39;stable&#39;</span>

<span style="color:#75715e"># Customize VMs</span>
$vm_memory <span style="color:#f92672">=</span> <span style="color:#ae81ff">2048</span>
$vm_cpus <span style="color:#f92672">=</span> <span style="color:#ae81ff">2</span>

<span style="color:#75715e"># Enable port forwarding from guest(s) to host machine, syntax is: { 80 =&gt; 8080 }, auto correction is enabled by default.</span>
<span style="color:#75715e"># 4001 is the default etcd port, we need this if we want to run fleetctl locally on the host</span>
$forwarded_ports <span style="color:#f92672">=</span> {<span style="color:#ae81ff">4001</span> <span style="color:#f92672">=&gt;</span> <span style="color:#ae81ff">4001</span>}</code></pre></div>

<p>The file is pretty self-explanatory. You see that we define the size of our
cluster (6 instances) and we give it some extra memory and cpus to run on.
Lastly we forward port 4001 which is the default port used by etcd. We&rsquo;ll see
why we want to do this in a bit.</p>

<p>Then we have the <code>user-data</code> file:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-yaml" data-lang="yaml"><span style="color:#75715e">#cloud-config</span>
coreos:
  etcd2:
    <span style="color:#75715e">#generate a new token for each unique cluster from https://discovery.etcd.io/new</span>
    discovery: https://discovery.etcd.io/&lt;token<span style="color:#e6db74">&gt;
</span><span style="color:#e6db74">    # multi-region and multi-cloud deployments need to use $public_ipv4</span>
    advertise-client-urls: http://$public_ipv4:<span style="color:#ae81ff">2379</span>
    initial-advertise-peer-urls: http://$private_ipv4:<span style="color:#ae81ff">2380</span>
    <span style="color:#75715e"># listen on both the official ports and the legacy ports</span>
    <span style="color:#75715e"># legacy ports can be omitted if your application doesn&#39;t depend on them</span>
    listen-client-urls: http://<span style="color:#ae81ff">0.0</span>.<span style="color:#ae81ff">0.0</span>:<span style="color:#ae81ff">2379</span>,http://<span style="color:#ae81ff">0.0</span>.<span style="color:#ae81ff">0.0</span>:<span style="color:#ae81ff">4001</span>
    listen-peer-urls: http://$private_ipv4:<span style="color:#ae81ff">2380</span>,http://$private_ipv4:<span style="color:#ae81ff">7001</span>
  fleet:
    public-ip: $public_ipv4
  flannel:
    interface: $public_ipv4
  units:
    - name: etcd2.service
      command: start
    - name: fleet.service
      command: start
    - name: docker-tcp.socket
      command: start
      enable: <span style="color:#66d9ef">true</span>
      content: <span style="color:#e6db74">|
</span><span style="color:#e6db74">        [Unit]</span>
        Description=Docker Socket for the API

        [Socket]
        ListenStream=<span style="color:#ae81ff">2375</span>
        Service=docker.service
        BindIPv6Only=both

        [Install]
        WantedBy=sockets.target</code></pre></div>

<p>This is the only file you need to modify
before starting the cluster. Go to
<a href="https://discovery.etcd.io/new" target="_blank">https://discovery.etcd.io/new</a> in your browser
and copy the URL that you get as a response there. Now go to <code>user-data</code> and
paste that URL where it says <code>discovery: https://discovery.etcd.io/&lt;token&gt;</code>.</p>

<p>You can now do a <code>vagrant up</code> and wait while your cluster gets created. When
it&rsquo;s done you should be able to run <code>vagrant status</code> and see the 6 nodes
running.</p>

<h1 id="trying-out-etcd">Trying out etcd</h1>

<p>Now that you have a CoreOS cluster up and running, we can start to play around
with the different tools that are shipped with it. Lets start with etcd, the
distributed key/value store.</p>

<p>You&rsquo;ll need 2 open terminals for this (or tabs, or splits or whatever you use).
We&rsquo;ll ssh into core-01 in one of them (with <code>vagrant ssh core-01</code>) and core-02
in the other (<code>vagrant ssh core-02</code>). Which nodes you ssh into is irrelevant, as
long as they are different.</p>

<p>CoreOS comes with a tool to read and write from etcd, called <code>etcdctl</code>. But etcd
also exposes an HTTP API that is really intuitive and easy to use. In fact,
etcdctl is just a facade in front of this API.
We&rsquo;ll see how to use both here.</p>

<p>Lets start by writing a value. From <code>core-01</code> do a <code>etcdctl set /key1 value1</code>.
This command adds a new key/value pair to etcd where the key is <code>key1</code> and the
value is <code>value1</code>. Now from the second node, you can read the value with
<code>etcdctl get /key1</code>. You should see <code>value1</code> as a response.</p>

<p>Note how etcd replicated the value that you wrote on the first node to the
second one almost instantaneously. In fact, it replicated the value to all nodes
in the cluster not just the two you are ssh&rsquo;ed into. This is the power of a
distributed store.</p>

<p>If you wanted to use the HTTP API you could have accomplished the same thing
using <code>curl</code> instead of <code>etcdctl</code>. We can write a second key/value pair in this
way. From <code>core-01</code> you can do <code>curl -L -X PUT
http://127.0.0.1:4001/v2/keys/key2 -d value=&quot;value2&quot;</code>. Now to read the value
from <code>core-02</code> you can do a <code>curl -L http://127.0.0.1:4001/v2/keys/key2</code>.
Admittedly, the <code>etcdctl</code> tool simplifies things a little bit but both options
are there to choose from.</p>

<p>Another really interesting thing that etcd provides are TTL (time to live)
values for each entry. This is quite useful when we use etcd for things like
service discovery, where we don&rsquo;t want to be reading stale values. To use it you
simply pass the <code>--ttl</code> parameter when you set a value.
To see this in action go back to <code>core-01</code> and do a <code>etcdctl set /key3 value3
--ttl 15</code>. This will add the new key with a TTL of 15 seconds. If you go to
<code>core-02</code> now and do a <code>etcdctl get /key3</code> you should see its value (provided it
took you less than 15 seconds to do that). Now wait for a while and run the same
get again. The key is gone!</p>

<p>Finally, if you want to list all the currently stored keys withing etcd you can
use the <code>etcdctl ls</code> command. This will print the keys available at the root
level. Alternatively, if you want to print keys at any level you can pass the
<code>--recursive</code> flag (as in <code>etcdctl ls --recursive</code>).</p>

<p>Etcd provides some other cool functionalities (like atomic test and set updates,
directories, event notifications) that are well documented if you do a <code>etcdctl
help</code>.</p>

<h1 id="starting-your-first-fleet-unit">Starting your first Fleet unit</h1>

<p>As I mentioned in the introduction, CoreOS comes with a cluster manager called
Fleet. You&rsquo;ll use the <code>fleetctl</code> tool to interact with the cluster.
To see this in action ssh into one of the nodes and do a <code>fleetctl list-machines</code> like:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ vagrant ssh core-01

core-01$ fleetctl list-machines

MACHINE         IP              METADATA
0b9fd6f8...     <span style="color:#ae81ff">172</span>.17.8.104    -
128a2e32...     <span style="color:#ae81ff">172</span>.17.8.103    -
2addf739...     <span style="color:#ae81ff">172</span>.17.8.101    -
3f608471...     <span style="color:#ae81ff">172</span>.17.8.106    -
73c0b7fc...     <span style="color:#ae81ff">172</span>.17.8.105    -
eabc97ed...     <span style="color:#ae81ff">172</span>.17.8.102    -</code></pre></div>

<p>We can see that our 6 CoreOS nodes are automatically recognized by Fleet as
being part of the same cluster.</p>

<p>Like I said before, we know only care about our cluster and not our individual
nodes. This nodes are completely ephemeral and we should assume they can come
and go without previous notice. For this reason, it doesn&rsquo;t matter from which
node we run the previous <code>fleetctl</code> command. We could&rsquo;ve ssh into &ldquo;core-06&rdquo; and
the result would&rsquo;ve been exactly the same.</p>

<h2 id="using-fleetctl-from-your-host">Using fleetctl from your host</h2>

<p>Being able to run <code>fleetctl</code> from within any node is great but even better is to
be able to run it from outside the cluster as well. For now our cluster is
running locally on Vagrant but the same setup could be running in AWS and we
would probably like to control it from our laptop without the need to
ssh into individual instances before.</p>

<p>Luckily, we can do this easily using the <code>--tunnel</code> flag. From your laptop run:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ fleetctl --tunnel <span style="color:#ae81ff">127</span>.0.0.1:2222 list-machines

MACHINE         IP              METADATA
0b9fd6f8...     <span style="color:#ae81ff">172</span>.17.8.104    -
128a2e32...     <span style="color:#ae81ff">172</span>.17.8.103    -
2addf739...     <span style="color:#ae81ff">172</span>.17.8.101    -
3f608471...     <span style="color:#ae81ff">172</span>.17.8.106    -
73c0b7fc...     <span style="color:#ae81ff">172</span>.17.8.105    -
eabc97ed...     <span style="color:#ae81ff">172</span>.17.8.102    -</code></pre></div>

<p>This basically tunnels all communication with your cluster over SSH using the IP
and port specified. Port 2222 is the default port that Vagrant uses to SSH into
your VM (you can see this by running <code>vagrant ssh-config</code>).</p>

<p>If you get a message saying something like
<em>Failed initializing SSH client: ssh: handshake failed: ssh: unable to
authenticate, attempted methods [none publickey], no supported methods remain</em>,
make sure that your Vagrant insecure ssh key is added to your ssh-agent by
running <code>ssh-add ~/.vagrant.d/insecure_private_key</code></p>

<p>To make <code>fleetctl</code> commands a bit less verbose we can actually put the tunnel
configuration into an environment variable:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ export FLEETCTL_TUNNEL<span style="color:#f92672">=</span><span style="color:#ae81ff">127</span>.0.0.1:2222</code></pre></div>

<p>Then we&rsquo;ll be able to run Fleet just as we would if we were inside one of our
nodes:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ fleetctl list-machines

MACHINE         IP              METADATA
0b9fd6f8...     <span style="color:#ae81ff">172</span>.17.8.104    -
128a2e32...     <span style="color:#ae81ff">172</span>.17.8.103    -
2addf739...     <span style="color:#ae81ff">172</span>.17.8.101    -
3f608471...     <span style="color:#ae81ff">172</span>.17.8.106    -
73c0b7fc...     <span style="color:#ae81ff">172</span>.17.8.105    -
eabc97ed...     <span style="color:#ae81ff">172</span>.17.8.102    -</code></pre></div>

<h1 id="running-fleet-units">Running Fleet units</h1>

<p>Having our nodes up and running with Fleet is great but it is not doing anything
useful by itself. We want to start telling our cluster to run some services for
us. This is where Fleet Units come into play.</p>

<p>As I mentioned before Fleet can be seen as
<a href="http://www.freedesktop.org/wiki/Software/systemd/" target="_blank">systemd</a> working at the
cluster level instead of at the individual machines level. As such, in order to
run anything with Fleet you need to submit regular systemd units files combined
with some Fleet specific properties.</p>

<p>A unit file defines what process you want to run and gives Fleet some hints to
help it determine how and where that process should be executed. To get started, lets
see what the unit file to run our <a href="https://registry.hub.docker.com/u/jlordiales/python-micro-service/" target="_blank">good old python
service</a>
would look like:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ cat python-test.service

<span style="color:#f92672">[</span>Unit<span style="color:#f92672">]</span>
Description<span style="color:#f92672">=</span>Python service
Requires<span style="color:#f92672">=</span>docker.service
After<span style="color:#f92672">=</span>docker.service

<span style="color:#f92672">[</span>Service<span style="color:#f92672">]</span>
TimeoutStartSec<span style="color:#f92672">=</span><span style="color:#ae81ff">0</span>
Restart<span style="color:#f92672">=</span>on-failure

ExecStartPre<span style="color:#f92672">=</span>-/usr/bin/docker kill python-service
ExecStartPre<span style="color:#f92672">=</span>-/usr/bin/docker rm python-service
ExecStartPre<span style="color:#f92672">=</span>/usr/bin/docker pull jlordiales/python-micro-service

ExecStart<span style="color:#f92672">=</span>/usr/bin/docker run --name python-service -P jlordiales/python-micro-service

ExecStop<span style="color:#f92672">=</span>/usr/bin/docker stop python-service</code></pre></div>

<p>Lets go through the unit file and see what each section is doing. The first line
simply sets a description for our unit, which is helpful when looking at all the
units that are currently running. The following 2 lines <em>Requires</em> and <em>After</em>
specify ordering dependencies between units (the full documentation can be seen
<a href="http://www.freedesktop.org/software/systemd/man/systemd.unit.html" target="_blank">here</a>).
Since we are running a docker container we need the <em>docker</em> process to be
started first. This dependency also means that if the <em>docker</em> unit is
stopped this <em>python-test.service</em> unit will also be stopped.</p>

<p>We then have the <em>[Service]</em>
<a href="http://www.freedesktop.org/software/systemd/man/systemd.service.html" target="_blank">section</a>,
which effectively describes how our
service should run. We first tell systemd not to wait for a completion signal
from our service (with <em>TimeoutStartSec=0</em>). Next, we ask systemd to restart our
container whenever it exits unexpectedly (exit code different than 0). This is
extremely useful if we want to have a self-healing cluster and we&rsquo;ll see how
this works in a moment.</p>

<p>Finally, the <em>Exec*</em> commands telling systemd how to run our container. The
<em>ExecStartPre</em> commands are run before our container is started and are
basically there to setup the environment to ensure that our main process can run
smoothly. In our example, we make sure that no container with the same name is
running by doing a <code>docker kill</code> and <code>docker rm</code>. Note that this 2 lines are
prefixed with a <code>-</code> before the command to run. This is very important because by
default systemd will execute the commands in the order they are specified and
will stop as soon as one of them returns a non-zero exit code. By prefixing the
command with <code>-</code> systemd will ignore the exit code and continue executing the
next one. We need to do that for <code>docker kill</code> and <code>docker rm</code> because those
commands will fail if there is no container named <em>python-service</em>.</p>

<p>The 2 remaining lines are pretty self-explanatory. <em>ExecStart</em> is the command
that will start the main process for our unit. In our case we run our container
as we usually would, specifying a name and the <code>-P</code> to expose its ports. One
important thing to notice here is that we don&rsquo;t pass the <code>-d</code> flag to docker (to
run in detached mode). If we do that the unit would run for a few seconds and
then exit, because the container would not be started as a child of the unit&rsquo;s
PID. Which basically means that from the unit&rsquo;s point of view there is nothing
to run.
The <em>ExecStop</em> command in the last line will do a <code>docker stop</code> whenever we tell
systemd to stop our unit.</p>

<p>So now that we have our unit file, how do we run it? Well, first we need to load
the unit into our cluster because so far this is only a text file that we have
edited in our local environment (outside of any of the CoreOS hosts). We can do
this with <code>fleetctl submit python-test.service</code>. To see that the unit was
actually submitted we can do a <code>fleetctl list-unit-files</code>, which should give us
the list of all units that our cluster knows about. You can even look at the
contents of the unit with <code>fleetctl cat python-test.service</code>.</p>

<p>With the unit file submitted we can now do:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ fleetctl start python-test.service

Unit python-test.service launched on 0b9fd6f8.../172.17.8.104</code></pre></div>

<p>In this case, Fleet decided that the node 172.17.8.104 was good enough to run
our container. If we want to see all the currently running units we can do that
with:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ fleetctl list-units

UNIT                    MACHINE                         ACTIVE  SUB
python-test.service     0b9fd6f8.../172.17.8.104        active  running</code></pre></div>

<p>We can also check the status of any given unit:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ fleetctl status python-test.service

● python-test.service - Python service
   Loaded: loaded <span style="color:#f92672">(</span>/run/fleet/units/python-test.service; linked-runtime; vendor preset: disabled<span style="color:#f92672">)</span>
   Active: active <span style="color:#f92672">(</span>running<span style="color:#f92672">)</span> since Sat <span style="color:#ae81ff">2015</span>-07-04 <span style="color:#ae81ff">1022</span> ; 50s ago
  Process: <span style="color:#ae81ff">1726</span> ExecStartPre<span style="color:#f92672">=</span>/usr/bin/docker pull jlordiales/python-micro-service <span style="color:#f92672">(</span>code<span style="color:#f92672">=</span>exited, status<span style="color:#f92672">=</span><span style="color:#ae81ff">0</span>/SUCCESS<span style="color:#f92672">)</span>
  Process: <span style="color:#ae81ff">1719</span> ExecStartPre<span style="color:#f92672">=</span>/usr/bin/docker rm python-service <span style="color:#f92672">(</span>code<span style="color:#f92672">=</span>exited, status<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span>/FAILURE<span style="color:#f92672">)</span>
  Process: <span style="color:#ae81ff">1655</span> ExecStartPre<span style="color:#f92672">=</span>/usr/bin/docker kill python-service <span style="color:#f92672">(</span>code<span style="color:#f92672">=</span>exited, status<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span>/FAILURE<span style="color:#f92672">)</span>
 Main PID: <span style="color:#ae81ff">1776</span> <span style="color:#f92672">(</span>docker<span style="color:#f92672">)</span>
   Memory: <span style="color:#ae81ff">8</span>.3M
   CGroup: /system.slice/python-test.service
           └─1776 /usr/bin/docker run --name python-service -P jlordiales/python-micro-service

Jul <span style="color:#ae81ff">04</span> <span style="color:#ae81ff">1007</span> core-04 docker<span style="color:#f92672">[</span><span style="color:#ae81ff">1726</span><span style="color:#f92672">]</span>: 595ded12b855: Pulling fs layer
Jul <span style="color:#ae81ff">04</span> <span style="color:#ae81ff">1009</span> core-04 docker<span style="color:#f92672">[</span><span style="color:#ae81ff">1726</span><span style="color:#f92672">]</span>: 595ded12b855: Download complete
Jul <span style="color:#ae81ff">04</span> <span style="color:#ae81ff">1009</span> core-04 docker<span style="color:#f92672">[</span><span style="color:#ae81ff">1726</span><span style="color:#f92672">]</span>: 7e0b582bc16d: Pulling metadata
Jul <span style="color:#ae81ff">04</span> <span style="color:#ae81ff">1010</span> core-04 docker<span style="color:#f92672">[</span><span style="color:#ae81ff">1726</span><span style="color:#f92672">]</span>: 7e0b582bc16d: Pulling fs layer
Jul <span style="color:#ae81ff">04</span> <span style="color:#ae81ff">1022</span> core-04 docker<span style="color:#f92672">[</span><span style="color:#ae81ff">1726</span><span style="color:#f92672">]</span>: 7e0b582bc16d: Download complete
Jul <span style="color:#ae81ff">04</span> <span style="color:#ae81ff">1022</span> core-04 docker<span style="color:#f92672">[</span><span style="color:#ae81ff">1726</span><span style="color:#f92672">]</span>: 7e0b582bc16d: Download complete
Jul <span style="color:#ae81ff">04</span> <span style="color:#ae81ff">1022</span> core-04 docker<span style="color:#f92672">[</span><span style="color:#ae81ff">1726</span><span style="color:#f92672">]</span>: Status: Downloaded newer image <span style="color:#66d9ef">for</span> jlordiales/python-micro-service:latest
Jul <span style="color:#ae81ff">04</span> <span style="color:#ae81ff">1022</span> core-04 systemd<span style="color:#f92672">[</span><span style="color:#ae81ff">1</span><span style="color:#f92672">]</span>: Started Python service.
Jul <span style="color:#ae81ff">04</span> <span style="color:#ae81ff">1022</span> core-04 docker<span style="color:#f92672">[</span><span style="color:#ae81ff">1776</span><span style="color:#f92672">]</span>: * Running on http://0.0.0.0:5000/ <span style="color:#f92672">(</span>Press CTRL+C to quit<span style="color:#f92672">)</span>
Jul <span style="color:#ae81ff">04</span> <span style="color:#ae81ff">1022</span> core-04 docker<span style="color:#f92672">[</span><span style="color:#ae81ff">1776</span><span style="color:#f92672">]</span>: * Restarting with stat</code></pre></div>

<p>There we can see that our process is active and running. We can also see the
exit code of the 3 <em>ExecStartPre</em> instructions we discussed before. Finally, we
can see some of the output from each process.
To make sure that our container is running and responding where Fleet says it is
we can get the <em>Machine Id</em> from the output of <code>fleetctl list-units</code> that we saw
before (0b9fd6f8 in our case) and ssh directly into it with:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ fleetctl list-units

UNIT                    MACHINE                         ACTIVE  SUB
python-test.service     0b9fd6f8.../172.17.8.104        active  running

$ fleetctl ssh 0b9fd6f8

core-03$ docker ps

CONTAINER ID        IMAGE                                    COMMAND             CREATED             STATUS              PORTS                     NAMES
bd6681b7eef3        jlordiales/python-micro-service:latest   <span style="color:#e6db74">&#34;python app.py&#34;</span>     <span style="color:#ae81ff">19</span> minutes ago      Up <span style="color:#ae81ff">19</span> minutes       <span style="color:#ae81ff">0</span>.0.0.0:32768-&gt;5000/tcp   python-service

core-03$ curl localhost:32768

Hello World from bd6681b7eef3</code></pre></div>

<h1 id="self-healing-nodes">Self-healing nodes</h1>

<p>When I was describing the unit file for the python unit, I briefly showed a
property called <code>Restart=on-failure</code>, which means that systemd will
automatically restart the process if it exits with an exit code different than
0. Lets see if this really works in our example. We&rsquo;ll ssh again into the node
running our container and kill it to see what happens:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ fleetctl ssh 0b9fd6f8

core-03$ docker ps

CONTAINER ID        IMAGE                                    COMMAND             CREATED             STATUS              PORTS                     NAMES
bd6681b7eef3        jlordiales/python-micro-service:latest   <span style="color:#e6db74">&#34;python app.py&#34;</span>     <span style="color:#ae81ff">29</span> minutes ago      Up <span style="color:#ae81ff">29</span> minutes       <span style="color:#ae81ff">0</span>.0.0.0:32768-&gt;5000/tcp   python-service

core-03$ docker kill python-service

core-03$ docker ps

CONTAINER ID        IMAGE                                    COMMAND             CREATED             STATUS              PORTS                     NAMES
1da6c1b5cafc        jlordiales/python-micro-service:latest   <span style="color:#e6db74">&#34;python app.py&#34;</span>     <span style="color:#ae81ff">45</span> seconds ago      Up <span style="color:#ae81ff">44</span> seconds       <span style="color:#ae81ff">0</span>.0.0.0:32769-&gt;5000/tcp   python-service</code></pre></div>

<p>Awesome! We killed the first running container and within seconds systemd
started a new one for us. If however we use <code>docker stop</code> instead of <code>docker
kill</code> (therefore stopping the container gracefully) systemd won&rsquo;t try to restart
it.</p>

<p>That is great if the process is killed for some reason but what happens if the
entire node disappears all of the sudden? I won&rsquo;t show it here but you can
easily simulate this by doing a <code>vagrant halt</code> on the VM where your unit was
placed. Fleet will detect that the node is dead and re-distribute all the units
that were running in that node across the rest of cluster.</p>

<h1 id="high-availability-services">High availability services</h1>

<p>One of the main benefits of using Fleet to mange our units is that it becomes
really easy to run a highly available service with multiple instances running in
different nodes. This, combined with the self-healing property we discussed in
the previous section gives you a lot of power to do pretty cool stuff.</p>

<p>This replication of any given service across your nodes is enabled by something
called Template unit files. This basically means that you can write a regular
unit file like the one we wrote before and use this as a template to instantiate
new units. The only difference is in the name of the unit file, that should now
follow the patter <code>&lt;name&gt;@.&lt;suffix&gt;</code>. For example, for our previous
<code>python-test.service</code> we should rename it to <code>python-test@.service</code>.</p>

<p>Lets rename our unit file and see how we can start as many instances of our
python container as we want. But first, remove the unit file we loaded before
with <code>fleetctl destroy python-test.service</code>. Now we can rename our unit and
submit it to our cluster in the same way as we did for the first one:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ mv python-test.service python-test@.service
$ fleetctl submit python-test@.service</code></pre></div>

<p>With our template loaded in the cluster we can now start instances of that
template using the name and some suffix after the <code>@</code>. For instance:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ fleetctl start python-test@1 python-test@2 python-test@random

$ fleetctl list-units

UNIT                            MACHINE                         ACTIVE  SUB
python-test@1.service           0b9fd6f8.../172.17.8.104        active  running
python-test@2.service           128a2e32.../172.17.8.103        active  running
python-test@random.service      3f608471.../172.17.8.106        active  running</code></pre></div>

<p>Here we can see that we started 3 instances of our python container. We can also
use our shell expansion functionality to start multiple instances:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ fleetctl start python-test@<span style="color:#f92672">{</span><span style="color:#ae81ff">3</span>..5<span style="color:#f92672">}</span>

$ fleetctl list-units

UNIT                            MACHINE                         ACTIVE  SUB
python-test@1.service           0b9fd6f8.../172.17.8.104        active  running
python-test@2.service           128a2e32.../172.17.8.103        active  running
python-test@3.service           73c0b7fc.../172.17.8.105        active  running
python-test@4.service           eabc97ed.../172.17.8.102        active  running
python-test@5.service           2addf739.../172.17.8.101        active  running
python-test@random.service      3f608471.../172.17.8.106        active  running</code></pre></div>

<h1 id="telling-fleet-where-to-run-your-containers">Telling Fleet where to run your containers</h1>

<p>By default Fleet makes no guarantees as to where in the cluster your units will
run. In the last example from the previous section we saw that we started 6
different instances of our python unit and it just so happens that Fleet decided
to run one on each node.</p>

<p>So what do we do if we have dependencies between our different units. Imagine
for instance that you have 2 different containers, one running your application
and one running a monitoring agent for that application.
In that case you want to keep those 2 running on the same node always.
Similarly, if you want to run multiple instances
of your service to scale horizontally you want those to run on different
nodes.</p>

<p>To do this, Fleet provides a set of <a href="https://coreos.com/docs/launching-containers/launching/fleet-unit-files/#unit-scheduling" target="_blank">fleet-specific
options</a>
that allows you to control how the scheduling engine of Fleet will work.
We&rsquo;ll see how these work with some examples. But first we&rsquo;ll need another unit
file:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ cat hello-world@.service

<span style="color:#f92672">[</span>Unit<span style="color:#f92672">]</span>
Description<span style="color:#f92672">=</span>MyApp
After<span style="color:#f92672">=</span>docker.service
Requires<span style="color:#f92672">=</span>docker.service

<span style="color:#f92672">[</span>Service<span style="color:#f92672">]</span>
TimeoutStartSec<span style="color:#f92672">=</span><span style="color:#ae81ff">0</span>
ExecStartPre<span style="color:#f92672">=</span>-/usr/bin/docker kill busybox1
ExecStartPre<span style="color:#f92672">=</span>-/usr/bin/docker rm busybox1
ExecStartPre<span style="color:#f92672">=</span>/usr/bin/docker pull busybox
ExecStart<span style="color:#f92672">=</span>/usr/bin/docker run --name busybox1 busybox /bin/sh -c <span style="color:#e6db74">&#34;while true; do echo Hello World; sleep 1; done&#34;</span>
ExecStop<span style="color:#f92672">=</span>/usr/bin/docker stop busybox1</code></pre></div>

<p>This simply runs a container that will keep printing a Hello World message to
stdout.</p>

<h2 id="running-units-together">Running units together</h2>

<p>Now imagine that we want to run this hello-world unit together with our
python-test one but we want to make sure that these 2 always run together in the
same node. We can use the <code>MachineOf</code> Fleet attribute to achieve this.</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ cat python-test@.service

<span style="color:#f92672">[</span>Unit<span style="color:#f92672">]</span>
Description<span style="color:#f92672">=</span>Python service
Requires<span style="color:#f92672">=</span>docker.service
After<span style="color:#f92672">=</span>docker.service

<span style="color:#f92672">[</span>Service<span style="color:#f92672">]</span>
TimeoutStartSec<span style="color:#f92672">=</span><span style="color:#ae81ff">0</span>
Restart<span style="color:#f92672">=</span>on-failure

ExecStartPre<span style="color:#f92672">=</span>-/usr/bin/docker kill python-service
ExecStartPre<span style="color:#f92672">=</span>-/usr/bin/docker rm python-service
ExecStartPre<span style="color:#f92672">=</span>/usr/bin/docker pull jlordiales/python-micro-service

ExecStart<span style="color:#f92672">=</span>/usr/bin/docker run --name python-service -P jlordiales/python-micro-service

ExecStop<span style="color:#f92672">=</span>/usr/bin/docker stop python-service

<span style="color:#f92672">[</span>X-Fleet<span style="color:#f92672">]</span>
MachineOf<span style="color:#f92672">=</span>hello-world@%i.service</code></pre></div>

<p>We added the <code>[X-Fleet]</code> section to our unit file specifying that our unit
should only be placed wherever there&rsquo;s also a <code>hello-world</code> unit running.
Lets see what happens when we submit these 2 units into our cluster:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ fleetctl submit python-test@.service hello-world@.service
$ fleetctl start python-test@1 hello-world@1

$ fleetctl list-units

UNIT                    MACHINE                         ACTIVE  SUB
hello-world@1.service   0b9fd6f8.../172.17.8.104        active  running
python-test@1.service   0b9fd6f8.../172.17.8.104        active  running</code></pre></div>

<p>As we expected, the 2 units were scheduled on the same node. The same thing
would happen if we start multiple instances of each unit at the same time:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ fleetctl start python-test@<span style="color:#f92672">{</span><span style="color:#ae81ff">2</span>..4<span style="color:#f92672">}</span> hello-world@<span style="color:#f92672">{</span><span style="color:#ae81ff">2</span>..4<span style="color:#f92672">}</span>

$ fleetctl list-units

UNIT                    MACHINE                         ACTIVE  SUB
hello-world@1.service   0b9fd6f8.../172.17.8.104        active  running
hello-world@2.service   128a2e32.../172.17.8.103        active  running
hello-world@3.service   2addf739.../172.17.8.101        active  running
hello-world@4.service   3f608471.../172.17.8.106        active  running
python-test@1.service   0b9fd6f8.../172.17.8.104        active  running
python-test@2.service   128a2e32.../172.17.8.103        active  running
python-test@3.service   2addf739.../172.17.8.101        active  running
python-test@4.service   3f608471.../172.17.8.106        active  running</code></pre></div>

<p>This dependency between units also means that if the unit we depend on
(hello-world in our example) is destroyed then all the units that were dependant
on that one (python-test in our example) will also be destroyed. We can see this
if we do:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ fleetctl destroy hello-world@4

$ fleetctl list-units
UNIT                    MACHINE                         ACTIVE  SUB
hello-world@1.service   0b9fd6f8.../172.17.8.104        active  running
hello-world@2.service   128a2e32.../172.17.8.103        active  running
hello-world@3.service   2addf739.../172.17.8.101        active  running
python-test@1.service   0b9fd6f8.../172.17.8.104        active  running
python-test@2.service   128a2e32.../172.17.8.103        active  running
python-test@3.service   2addf739.../172.17.8.101        active  running</code></pre></div>

<p>We removed <code>hello-world@4</code> and Fleet automatically removed <code>python-test@4</code> as
well.</p>

<h2 id="running-units-away-from-each-other">Running units away from each other</h2>

<p>We saw how to run multiple units guaranteeing that they will be put always in
the same node. How about the opposite scenario, running 2 or more units making
sure that they are never put on the same node.
We can use Fleet&rsquo;s <code>Conflicts</code> option to achieve this. Let&rsquo;s change our
<code>python-test@.service</code> unit file to use this new option:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ cat python-test@.service

<span style="color:#f92672">[</span>Unit<span style="color:#f92672">]</span>
Description<span style="color:#f92672">=</span>Python service
Requires<span style="color:#f92672">=</span>docker.service
After<span style="color:#f92672">=</span>docker.service

<span style="color:#f92672">[</span>Service<span style="color:#f92672">]</span>
TimeoutStartSec<span style="color:#f92672">=</span><span style="color:#ae81ff">0</span>
Restart<span style="color:#f92672">=</span>on-failure

ExecStartPre<span style="color:#f92672">=</span>-/usr/bin/docker kill python-service
ExecStartPre<span style="color:#f92672">=</span>-/usr/bin/docker rm python-service
ExecStartPre<span style="color:#f92672">=</span>/usr/bin/docker pull jlordiales/python-micro-service

ExecStart<span style="color:#f92672">=</span>/usr/bin/docker run --name python-service -P jlordiales/python-micro-service

ExecStop<span style="color:#f92672">=</span>/usr/bin/docker stop python-service

<span style="color:#f92672">[</span>X-Fleet<span style="color:#f92672">]</span>
Conflicts<span style="color:#f92672">=</span>hello-world@%i.service</code></pre></div>

<p>If we submit this new unit file and run multiple instances of our 2 services
we&rsquo;ll see that Fleet will place them on different nodes. If Fleet can not find a
distribution that satisfies the constraints specified in the unit files then it
will simply refuse to schedule them.</p>

<h1 id="conclusion">Conclusion</h1>

<p>Container orchestration and scheduling is an exciting and relatively new area
that is under heavy development by different players. CoreOS presents an easy
and lightweight approach using etcd, Fleet and Docker as its backbone.
In this post we saw how easy it is to create a local CoreOS cluster with Vagrant
and run highly available and self-healing services with the help of Fleet.</p>

<p>By combining a few simple configuration values, we can ensure that our services
are distributed across different regions and availability zones. This, combined
with the fact that we can run CoreOS on pretty much any cloud provider or
hardware, enables us to have very complex architectures with pretty much no
manual intervention.</p>
]]></content>
        </item>
        
        <item>
            <title>Accessing docker containers on localhost when using Boot2Docker</title>
            <link>/posts/2015/04/accessing-docker-containers-on-localhost-when-using-boot2docker/</link>
            <pubDate>Thu, 02 Apr 2015 00:00:00 +0000</pubDate>
            
            <guid>/posts/2015/04/accessing-docker-containers-on-localhost-when-using-boot2docker/</guid>
            <description>If you have been following my posts on Docker then you know by now that I usually run on OSX with Boot2Docker. It is definitely a really useful tool if you are not on a native Linux kernel and it makes using Docker on Mac and Windows almost as easy and transparent as if you were on Linux. That is, until you need to expose one or more ports from your containers and then you want to access those from your host.</description>
            <content type="html"><![CDATA[

<p>If you have been following my posts on Docker then you know by now that I
usually run on OSX with
<a href="https://github.com/boot2docker/boot2docker" target="_blank">Boot2Docker</a>. It is definitely a
really useful tool if you are not on a native Linux kernel and it makes using
Docker on Mac and Windows almost as easy and transparent as if you were on Linux.
That is, until you need to expose one or more ports from your containers and
then you want to access those from your host. If you are on Linux then you can
simply go to <code>localhost</code> and the port number and that&rsquo;s it. If you are using
boot2docker however, you need to remember that your docker host is actually the
boot2docker VM and not your laptop, so you first need to know what that VM&rsquo;s IP
is.  In this very short post I want to describe a way in which you can access
your containers on <code>localhost</code> even if you are using boot2docker.</p>

<p>The important thing to know is that boot2docker is a Virtual Machine that runs
on Virtual Box. And as with any other VM you can forward ports between your host
and guest operating system. That means that if we can get Virtual Box to forward
whatever port we expose from our containers, from our host OS to the boot2docker
VM then those ports will be accessible from our <code>localhost</code>.</p>

<p>So how can we do that? I don&rsquo;t really know if this works on Windows (I assume it
does) but on Mac you can use the <code>VBoxManage</code> command line tool to control the
different VMs that Virtual Box manages.
So let&rsquo;s imagine that our Nginx container exposes port 80 and then we map that
to port 8080 on the VM when we do a <code>docker run -p 8080:80</code>. Normally you would
be able to access this by going to <code>http://$DOCKER_IP:8080</code>. But with VBoxManage
you can do: <code>VBoxManage controlvm boot2docker-vm natpf1 &quot;nginx,tcp,127.0.0.1,8080,,8080&quot;</code>.
This basically means: &ldquo;Take the boot2docker-vm and create a new NAT rule called
nginx that will forward all requests on the localhost (127.0.0.1) port 8080 to
port 8080 on the VM&rdquo;.
Now we can access our container on <code>http://localhost:8080</code>. Simple as that! Best
of all is that you can do this while the VM and your containers are running and
doesn&rsquo;t require you to restart anything.
When you are done and you want to delete the NAT rule you can just do
<code>VBoxManage controlvm boot2docker-vm natpf1 delete &quot;nginx&quot;</code>.</p>

<h1 id="but-why-would-you-do-this">But why would you do this?</h1>

<p>Arguably, typing <code>$DOCKER_IP</code> instead of <code>localhost</code> makes little to no
difference. In fact, if you count the time it takes you to do the <code>VBoxManage</code>
stuff then it is probably slower.
In the case when you are just playing around with different containers and want
to test things locally I agree that this makes no sense. But sometimes it can be
quite useful.</p>

<p>Imagine for instance that you are developing a webapp. You run all the backend
services that your app needs as docker containers and then you just run the
frontend part in your laptop, pointing to these containers.
If you are developing on Mac then you would have to point your webapp to
$DOCKER_IP but if then you move to Ubuntu for instance, you would need to change
all places where you were previously using $DOCKER_IP to use localhost instead.
In this scenario, creating a little script that runs the containers and then
uses <code>VBoxManage</code> to forward the exposed ports can give you better portability
between different platforms.</p>

<p>In any case, whether you find a good use case for it or not it is still good to
know that you have that option if you ever need it. The rest is up to you!</p>

<p>Cheers!</p>
]]></content>
        </item>
        
        <item>
            <title>Consul Template for transparent load balancing of containers</title>
            <link>/posts/2015/04/consul-template-for-transparent-load-balancing-of-containers/</link>
            <pubDate>Wed, 01 Apr 2015 00:00:00 +0000</pubDate>
            
            <guid>/posts/2015/04/consul-template-for-transparent-load-balancing-of-containers/</guid>
            <description>In the previous post we talked about Registrator and how, combined with a service discovery backend like Consul, it allows us to have transparent discovery for our containers while still keeping their portability. One thing we didn&amp;rsquo;t talk about though is how are we supposed to access those services registered in Consul from our consumer applications, which could be running as containers themselves.
As an example, imagine we have a service exposing a REST API.</description>
            <content type="html"><![CDATA[

<p>In the <a href="/posts/2015/02/automatic-container-registration-with-consul-and-registrator/" target="_blank">previous post</a> we talked about
Registrator and how, combined with a service discovery backend like Consul, it
allows us to have transparent discovery for our containers while still keeping
their portability.
One thing we didn&rsquo;t talk about though is how are we supposed to access those
services registered in Consul from our consumer applications, which could be
running as containers themselves.</p>

<p>As an example, imagine we have a service exposing a REST API. To provide
horizontal scalability we decide to run 3 instances of that service, all
registered in Consul.
Each container will be listening on a random port assigned by Docker, so how do
we know where to connect to from our consumers?
We can use Consul&rsquo;s own DNS capabilities, as we saw on the last post, but even
though Consul offers the possibility of asking for SRV records (which include
the port information as well as the IP) most client libraries in modern
programming languages don&rsquo;t care about this information and only use the IP
address, leaving the task of specifying the port to the developer.
We could always use Consul&rsquo;s REST API to query for the services we are
interested in and parse the IP and Port from there. But this approach seems
rather complex and it would couple our consumer app to Consul&rsquo;s specific API.</p>

<p>In this post I want to explore one possible approach to solve this problem in a
portable and transparent way, both from the point of view of our services as
from the point of view of our consumers.
It is certainly not the only possible approach nor the best but it is something
that I have seen working quite successfully in the past.</p>

<h1 id="introduction">Introduction</h1>

<p>Lets think about our current problem again. We have 2 or more containers that
expose a REST API and we want to consume that API from another application.
We are using Consul as a service discovery mechanism and Registrator to
transparently register our containers there.
We know that we can get the IP of our service by using Consul&rsquo;s DNS interface
but we don&rsquo;t know which port on that IP to use.
For the purposes of this post, our service container will be the Python service
that we have been using so far (available in the Docker hub as
jlodiales/python-micro-service).
In turn, our consumer will simply be the <code>curl</code> command line tool.</p>

<p>It would be great if there was a proxy running on a well known port that we
could send requests to. That proxy would then pass the request to the correct
service and transmit the response back to us. This sounds a lot like something
that Nginx or HAProxy could do.
But now we have just moved the problem one step further. That is, how does our
proxy know which port our containers are running on?
Luckily for us, the guys from <a href="https://hashicorp.com/" target="_blank">HashiCorp</a> have developed
a little standalone tool to do just this: <a href="https://hashicorp.com/blog/introducing-consul-template.html" target="_blank">Consul
Template</a>.</p>

<h1 id="consul-template">Consul Template</h1>

<p>From the project&rsquo;s <a href="https://github.com/hashicorp/consul-template" target="_blank">Github repo</a>:</p>

<blockquote>
<p>This project provides a convenient way to populate values from Consul into the
filesystem using the consul-template daemon.
The daemon consul-template queries a Consul instance and updates any number of
specified templates on the filesystem. As an added bonus, consul-template can
optionally run arbitrary commands when the update process completes.</p>
</blockquote>

<p>We&rsquo;ll see how this works with a simple example. First, we&rsquo;ll run our Consul
cluster. For simplicity we&rsquo;ll run just one node but exactly the same would apply
on a multi-node setup.</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ docker run -p <span style="color:#ae81ff">8400</span>:8400 -p <span style="color:#ae81ff">8500</span>:8500 -p <span style="color:#ae81ff">8600</span>:53/udp <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-h consul --name consul <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>progrium/consul -server -advertise $DOCKER_IP -bootstrap</code></pre></div>

<p>Notice that we are advertising the $DOCKER_IP as Consul&rsquo;s IP. The reason for
that is that Registrator will always register new containers as accessible in
Consul&rsquo;s advertise IP. We discussed this in the
<a href="/posts/2015/02/automatic-container-registration-with-consul-and-registrator/#advertise" target="_blank">previous post</a>. Also, as a
remainder, the DOCKER_IP variable is simply boot2docker&rsquo;s IP
(<code>export DOCKER_IP=$(boot2docker ip 2&gt; /dev/null)</code>). If you are running on
native Linux then that would be <code>localhost</code>.</p>

<p>Now that we have Consul running, we&rsquo;ll do the same for Registrator:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ docker run -d <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-v /var/run/docker.sock:/tmp/docker.sock <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>--name registrator -h registrator <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>gliderlabs/registrator:latest consul://$DOCKER_IP:8500</code></pre></div>

<p>And finally our Python service. As we said before, lets imagine we want to run 3
instances of it:
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ docker run -d -P --name node1 -h node1 jlordiales/python-micro-service:latest
$ docker run -d -P --name node2 -h node2 jlordiales/python-micro-service:latest
$ docker run -d -P --name node3 -h node3 jlordiales/python-micro-service:latest</code></pre></div></p>

<p>We can query consul to make sure that our new containers are running:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ curl $DOCKER_IP:8500/v1/catalog/service/python-micro-service

<span style="color:#f92672">[</span>
  <span style="color:#f92672">{</span>
    <span style="color:#e6db74">&#34;Address&#34;</span>: <span style="color:#e6db74">&#34;192.168.59.103&#34;</span>,
    <span style="color:#e6db74">&#34;Node&#34;</span>: <span style="color:#e6db74">&#34;node1&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceAddress&#34;</span>: <span style="color:#e6db74">&#34;&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceID&#34;</span>: <span style="color:#e6db74">&#34;registrator5000&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceName&#34;</span>: <span style="color:#e6db74">&#34;python-micro-service&#34;</span>,
    <span style="color:#e6db74">&#34;ServicePort&#34;</span>: <span style="color:#ae81ff">49162</span>,
    <span style="color:#e6db74">&#34;ServiceTags&#34;</span>: null
  <span style="color:#f92672">}</span>,
  <span style="color:#f92672">{</span>
    <span style="color:#e6db74">&#34;Address&#34;</span>: <span style="color:#e6db74">&#34;192.168.59.103&#34;</span>,
    <span style="color:#e6db74">&#34;Node&#34;</span>: <span style="color:#e6db74">&#34;node1&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceAddress&#34;</span>: <span style="color:#e6db74">&#34;&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceID&#34;</span>: <span style="color:#e6db74">&#34;registrator5000&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceName&#34;</span>: <span style="color:#e6db74">&#34;python-micro-service&#34;</span>,
    <span style="color:#e6db74">&#34;ServicePort&#34;</span>: <span style="color:#ae81ff">49163</span>,
    <span style="color:#e6db74">&#34;ServiceTags&#34;</span>: null
  <span style="color:#f92672">}</span>,
  <span style="color:#f92672">{</span>
    <span style="color:#e6db74">&#34;Address&#34;</span>: <span style="color:#e6db74">&#34;192.168.59.103&#34;</span>,
    <span style="color:#e6db74">&#34;Node&#34;</span>: <span style="color:#e6db74">&#34;node1&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceAddress&#34;</span>: <span style="color:#e6db74">&#34;&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceID&#34;</span>: <span style="color:#e6db74">&#34;registrator5000&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceName&#34;</span>: <span style="color:#e6db74">&#34;python-micro-service&#34;</span>,
    <span style="color:#e6db74">&#34;ServicePort&#34;</span>: <span style="color:#ae81ff">49164</span>,
    <span style="color:#e6db74">&#34;ServiceTags&#34;</span>: null
  <span style="color:#f92672">}</span>
<span style="color:#f92672">]</span></code></pre></div>

<p>Now for the fun part. We&rsquo;ll install Consul Template and see what happens when we
run it against our current setup. We can get the latest release from
<a href="https://github.com/hashicorp/consul-template/releases" target="_blank">here</a> for whatever
architecture we are running on. In my case I&rsquo;m running on a Mac so:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ wget https://github.com/hashicorp/consul-template/releases/download/v0.7.0/consul-template_0.7.0_darwin_amd64.tar.gz -O /tmp/consul-template.tar.gz
$ tar -xvzf /tmp/consul-template.tar.gz -C /tmp --strip-components<span style="color:#f92672">=</span><span style="color:#ae81ff">1</span></code></pre></div>

<p>Next, we&rsquo;ll write a simple template and run consul-template to parse it and
generate the result. You can read all about the templates syntax and provided
functions at the project&rsquo;s
<a href="https://github.com/hashicorp/consul-template#templating-language" target="_blank">documentation</a>:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ echo <span style="color:#e6db74">&#39;{{range service &#34;python-micro-service&#34;}}\nserver {{.Address}}:{{.Port}}{{end}}&#39;</span> &gt; /tmp/consul.ctmpl
$ /tmp/consul-template -consul $DOCKER_IP:8500 -template /tmp/consul.ctmpl:/tmp/consul.result -dry -once

&gt; /tmp/consul.result

server <span style="color:#ae81ff">192</span>.168.59.103:49162
server <span style="color:#ae81ff">192</span>.168.59.103:49163
server <span style="color:#ae81ff">192</span>.168.59.103:49164</code></pre></div>

<p>By specifying the <code>-dry</code> parameter we tell consul-template to send the output to
stdout instead of the file specified on the command (<em>/tmp/consul.result</em> in this
case). The <code>-once</code> parameter tells Consul Template to query Consul and generate
the output just once. If we don&rsquo;t do this then the app will keep running in the
foreground polling Consul at regular intervals (which is what we would want in a
typical scenario).  You can see that the result includes the 3 instances of the
service with their respective ports.</p>

<p>To see what happens when we change the information registered in Consul, we are
going to run consul-template again but this time we won&rsquo;t specify the <code>-once</code>
parameter in order to leave the daemon running:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ /tmp/consul-template -consul $DOCKER_IP:8500 -template /tmp/consul.ctmpl:/tmp/consul.result -dry</code></pre></div>

<p>With that running, we&rsquo;ll go to a new terminal and stop one of the running python
containers:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ docker stop node3</code></pre></div>

<p>You should almost instantly see the refreshed output in the terminal running
consul-template that now only shows 2 entries. Conversely, if we run a new
container:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ docker run -d -P --name node4 -h node4 jlordiales/python-micro-service:latest</code></pre></div>

<p>The consul-template output gets updated again with the new service.</p>

<h1 id="combining-consul-template-and-a-reverse-proxy">Combining Consul Template and a reverse proxy</h1>

<p>So we saw that we can use Consul Template to parse a template file and produce a
new file with the information read from Consul. How can we use this from our
consumer applications in order to have transparent service location and load
balance?
Well, one option is to front our services with Nginx or HAProxy, creating the
config files for these with Consul Template.
We&rsquo;ll how this would work for Nginx. All the files that I&rsquo;ll describe in the
following section can be found <a href="https://github.com/jlordiales/docker-nginx-consul" target="_blank">in this
repo</a> if you just want to
clone from it.</p>

<p>I&rsquo;ll first show the Dockerfile that we&rsquo;ll use for the Nginx image and then
explain each section of it:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-docker" data-lang="docker"><span style="color:#66d9ef">FROM</span><span style="color:#e6db74"> nginx:latest</span><span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">ENTRYPOINT</span><span style="color:#e6db74"> [&#34;/bin/start.sh&#34;]</span><span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">EXPOSE</span><span style="color:#e6db74"> 80</span><span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">VOLUME</span><span style="color:#e6db74"> /templates</span><span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">ENV</span><span style="color:#e6db74"> CONSUL_URL consul:8500</span><span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">ADD</span><span style="color:#e6db74"> start.sh /bin/start.sh</span><span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">RUN</span> rm -v /etc/nginx/conf.d/<span style="color:#ae81ff">\*</span>.conf<span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">ADD</span><span style="color:#e6db74"> https://github.com/hashicorp/consul-template/releases/download/v0.7.0/consul-template_0.7.0_linux_amd64.tar.gz /usr/bin/</span><span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">RUN</span> tar -C /usr/local/bin --strip-components <span style="color:#ae81ff">1</span> -zxf /usr/bin/consul-template_0.7.0_linux_amd64.tar.gz</code></pre></div>

<p>We are basing our image from the official Nginx image, available
<a href="https://registry.hub.docker.com/_/nginx/" target="_blank">here</a>.
This gives us a ready to use, default Nginx installation. Then we say that the
entrypoint will be the /bin/start.sh (will see that one in a bit) and that our
container will expose port 80, where Nginx will be listening for new
connections.
Next we define a volume <em>/templates</em>, which is where we will mount our template
files from the host. This way we can reuse the same image for different services
and templates.
In the following step we define and environment variable with the location of
our Consul cluster. By default, it will try to resolve to <em>consul:8500</em> which
would be the behavior if we have Consul running as a container in the same host
and we link it to this Nginx container (with the alias consul, of course). But
this environment variable can also be overridden when we run the container if we
want to point somewhere else.
We then add the start up script (which is used as the entrypoint to our
containers) and remove all default configurations from Nginx.
On the last 2 lines we download the latest version of Consul Template
(0.7.0 at the time of writing this) and we put it on /usr/local/bin.</p>

<p>The start.sh script is very simple:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#75715e">#!/bin/bash
</span><span style="color:#75715e"></span>service nginx start
consul-template -consul<span style="color:#f92672">=</span>$CONSUL_URL -template<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;/templates/service.ctmpl:/etc/nginx/conf.d/service.conf:service nginx reload&#34;</span></code></pre></div>

<p>We just start the nginx service and then leave consul-template running on the
foreground. Here we use the CONSUL_URL environment variable that we defined
before. Consul template expects to find a <code>service.ctmpl</code> file in <code>/templates</code>.
This is the template that we would mount as a volume from our host. The result
is then placed in <code>/etc/nginx/conf.d/service.conf</code> where Nginx will be able to
read from. Finally, every time the template is re-rendered we do a <code>service
nginx reload</code> in order to read the new configuration.</p>

<p>Time to see this in action. If you still have the Consul, Registrator and Python
containers running from the first part of this post then you only need to run
the Nginx container (otherwise start them again).</p>

<p>The only thing you&rsquo;ll need is a template file like the following, save it as
<code>/tmp/service.ctmpl</code> for convenience:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-text" data-lang="text">upstream python-service {
  least_conn;
  {% raw %}{{range service &#34;python-micro-service&#34;}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1;
  {{else}}server 127.0.0.1:65535; # force a 502{{end}}{% endraw %}
}

server {
  listen 80 default_server;

  charset utf-8;

  location ~ ^/python-micro-service/(.\*)$ {
    proxy_pass http://python-service/$1$is_args$args;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }
}</code></pre></div>

<p>Now run the nginx container with:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ docker run -p <span style="color:#ae81ff">8080</span>:80 -d --name nginx --volume /tmp/service.ctmpl:/templates/service.ctmpl --link consul:consul jlordiales/nginx-consul</code></pre></div>

<p>We can <code>curl</code> the service multiple times:
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ curl $DOCKER_IP:8080/python-micro-service/
$ curl $DOCKER_IP:8080/python-micro-service/
$ curl $DOCKER_IP:8080/python-micro-service/
$ curl $DOCKER_IP:8080/python-micro-service/</code></pre></div></p>

<p>You should see a &ldquo;Hello World from nodeX&rdquo; where X alternates between 1, 2 and 3.
We are effectively load balancing between the 3 nodes. But there&rsquo;s something
even cooler that you can try.
Leave this running on a terminal:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ <span style="color:#66d9ef">while</span> true; <span style="color:#66d9ef">do</span> curl $DOCKER_IP:8080/python-micro-service/; echo -----; sleep <span style="color:#ae81ff">1</span>; <span style="color:#66d9ef">done</span>;</code></pre></div>

<p>That will keep calling nginx every second, which in turn will send the request
to one of the 3 nodes. Now from another terminal, stop <code>node1</code> with:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ docker stop node1</code></pre></div>

<p>If you check the terminal running the <code>while</code> loop you&rsquo;ll notice that the
requests are now going to node2 and node3 only. You can play around with this
(starting and stopping nodes) to see the configuration updated almost
instantaneous and nginx adjusting which nodes it sends requests to.
And, more importantly, all of this while keeping our service containers and our
nginx container completely ignorant about the fact that we are using Consul as a
service discovery mechanism!</p>

<h1 id="conclusion">Conclusion</h1>

<p>This post completes the subject of transparent service discovery in Docker. We
saw how we can use a reverse proxy sitting in front of our containers,
accessible through a well known port. The proxy, in turn is kept updated with
the information available in our Consul cluster thanks to a small and handy tool
called Consul Template.</p>

<p>Combined with Registrator and Consul this gives us extreme flexibility and
portability. Of course, as with almost everything else, there are other
alternatives and approaches. I would be glad to hear other people&rsquo;s experiences
around this area.</p>
]]></content>
        </item>
        
        <item>
            <title>Automatic container registration with Consul and Registrator</title>
            <link>/posts/2015/02/automatic-container-registration-with-consul-and-registrator/</link>
            <pubDate>Tue, 03 Feb 2015 00:00:00 +0000</pubDate>
            
            <guid>/posts/2015/02/automatic-container-registration-with-consul-and-registrator/</guid>
            <description>In the previous post we talked about Consul and how it can help us towards a highly available and efficient service discovery. We saw how to run a Consul cluster, register services, query through its HTTP API as well as its DNS interface and use the distributed key/value store. One thing we missed though was how to register the different services we run as docker containers with the Cluster. In this post I&amp;rsquo;m going to talk about Registrator, an amazing tool that we can run as a docker container whose responsibility is to make sure that new containers are registered and deregistered automatically from our service discovery tool.</description>
            <content type="html"><![CDATA[

<p>In the <a href="/posts/2015/01/where-are-my-containers-dockerized-service-discovery-with-consul/" target="_blank">previous post</a> we talked about
Consul and how it can help us towards a highly available and efficient service
discovery. We saw how to run a Consul cluster, register services, query through
its HTTP API as well as its DNS interface and use the distributed key/value
store.  One thing we missed though was how to register the different services we
run as docker containers with the Cluster. In this post I&rsquo;m going to talk about
<a href="https://github.com/progrium/registrator" target="_blank">Registrator</a>, an amazing tool that we
can run as a docker container whose responsibility is to make sure that new
containers are registered and deregistered automatically from our service
discovery tool.</p>

<h1 id="introduction">Introduction</h1>

<p>We&rsquo;ve seen how to run a Consul cluster and we&rsquo;ve also seen how to register
services in that cluster. With this in place we could, in principle, start
running other Docker containers with our services and register those containers
with Consul.
However, who should be responsible for registering those new containers?</p>

<p>You could let each container know how to register itself. There are some
problems with this approach. First, you give up one of the main benefits of
using containers: portability. If the logic of how the container needs to join
the cluster is inside of it then suddenly you can not run that same container if
you decide to use a different service discovery mechanism or if you decide to
use no service discovery at all.  Another potential issue is that containers are
supposed to do just one thing and do that well. The container that runs your
user service should not care about how that service will be discovered by
others.  The last problem is that you will not always be in control of all the
containers you use. One of the strong points of Docker is the huge amount of
already dockerized applications and services available in their
<a href="https://hub.docker.com/" target="_blank">registry</a>. Those containers will have no idea about
your Consul cluster.</p>

<h1 id="registrator">Registrator</h1>

<p>To solve these problems meet
<a href="https://github.com/progrium/registrator" target="_blank">registrator</a>. It is designed to be run
as an independent Docker container. It will sit there quietly, watching for new
containers that are started on the same host where it is currently running,
extracting information from them and then registering those containers with your
service discovery solution. It will also watch for containers that are stopped
(or simply die) and will deregister them.
Additionally, it supports pluggable service discovery mechanisms so you are not
restricted to any particular solution.</p>

<p>Lets quickly see how we can run registrator together with our Consul cluster.</p>

<h2 id="setting-up-our-hosts">Setting up our hosts</h2>

<p>So far we have always run our Consul cluster and all our services in just one
host (the boot2docker VM). In this post I&rsquo;ll try to simulate a more
&ldquo;production-like&rdquo; environment were we might have several hosts, each running one
or more docker containers with our services and each running a Consul agent.</p>

<p>In order to do this, we&rsquo;ll use Vagrant to create 3 CoreOS VMS running
locally.
The Vagrantfile will look like this:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-ruby" data-lang="ruby"><span style="color:#66d9ef">Vagrant</span><span style="color:#f92672">.</span>configure(<span style="color:#66d9ef">VAGRANTFILE_API_VERSION</span>) <span style="color:#66d9ef">do</span> <span style="color:#f92672">|</span>config<span style="color:#f92672">|</span>
  config<span style="color:#f92672">.</span>vm<span style="color:#f92672">.</span>box <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;yungsang/coreos&#34;</span>
  config<span style="color:#f92672">.</span>vm<span style="color:#f92672">.</span>network <span style="color:#e6db74">&#34;private_network&#34;</span>, <span style="color:#e6db74">type</span>: <span style="color:#e6db74">&#34;dhcp&#34;</span>

  number_of_instances <span style="color:#f92672">=</span> <span style="color:#ae81ff">3</span>
  (<span style="color:#ae81ff">1</span><span style="color:#f92672">..</span>number_of_instances)<span style="color:#f92672">.</span>each <span style="color:#66d9ef">do</span> <span style="color:#f92672">|</span>instance_number<span style="color:#f92672">|</span>
    config<span style="color:#f92672">.</span>vm<span style="color:#f92672">.</span>define <span style="color:#e6db74">&#34;host-</span><span style="color:#e6db74">#{</span>instance_number<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span> <span style="color:#66d9ef">do</span> <span style="color:#f92672">|</span>host<span style="color:#f92672">|</span>
      host<span style="color:#f92672">.</span>vm<span style="color:#f92672">.</span>hostname <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;host-</span><span style="color:#e6db74">#{</span>instance_number<span style="color:#e6db74">}</span><span style="color:#e6db74">&#34;</span>
    <span style="color:#66d9ef">end</span>
  <span style="color:#66d9ef">end</span>
<span style="color:#66d9ef">end</span></code></pre></div>

<p>After you save the Vagrantfile you can start the 3 VMs with <code>vagrant up</code>.  It
might take a while the first time while it downloads the CoreOS image. At this
point you should be able to see the 3 VMs running:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ vagrant status

Current machine states:

host-1             running <span style="color:#f92672">(</span>virtualbox<span style="color:#f92672">)</span>
host-2             running <span style="color:#f92672">(</span>virtualbox<span style="color:#f92672">)</span>
host-3             running <span style="color:#f92672">(</span>virtualbox<span style="color:#f92672">)</span>

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run vagrant status NAME.</code></pre></div>

<p>We&rsquo;ll now ssh into the first host and check that docker is installed and running
(which happens by default when you use the CoreOS image):</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ vagrant ssh host-1

host-1$ docker info
Containers: <span style="color:#ae81ff">0</span>
Images: <span style="color:#ae81ff">0</span>
Storage Driver: btrfs
Execution Driver: native-0.2
Kernel Version: <span style="color:#ae81ff">3</span>.17.2
Operating System: CoreOS <span style="color:#ae81ff">494</span>.5.0</code></pre></div>

<p>Similarly for the second host:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ vagrant ssh host-2

host-2$ docker info
Containers: <span style="color:#ae81ff">0</span>
Images: <span style="color:#ae81ff">0</span>
Storage Driver: btrfs
Execution Driver: native-0.2
Kernel Version: <span style="color:#ae81ff">3</span>.17.2
Operating System: CoreOS <span style="color:#ae81ff">494</span>.5.0</code></pre></div>

<p>And the third:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ vagrant ssh host-3

host-3$ docker info
Containers: <span style="color:#ae81ff">0</span>
Images: <span style="color:#ae81ff">0</span>
Storage Driver: btrfs
Execution Driver: native-0.2
Kernel Version: <span style="color:#ae81ff">3</span>.17.2
Operating System: CoreOS <span style="color:#ae81ff">494</span>.5.0</code></pre></div>

<p>Now, before we start running all our different containers I wanted to show how
our hosts look like from a networking point of view. Notice that we specified a
&ldquo;private_network&rdquo; interface for our VMs in our Vagrantfile. This basically means
that our VMs will be able to communicate with each other as if they were inside
the same local network. We can see this if we check the network configuration on
each one:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-1$ ifconfig enp0s8 | grep <span style="color:#e6db74">&#39;inet &#39;</span> | awk <span style="color:#e6db74">&#39;{ print $2 }&#39;</span>

<span style="color:#ae81ff">172</span>.28.128.3</code></pre></div>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-2$ ifconfig enp0s8 | grep <span style="color:#e6db74">&#39;inet &#39;</span> | awk <span style="color:#e6db74">&#39;{ print $2 }&#39;</span>

<span style="color:#ae81ff">172</span>.28.128.4</code></pre></div>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-3$ ifconfig enp0s8 | grep <span style="color:#e6db74">&#39;inet &#39;</span> | awk <span style="color:#e6db74">&#39;{ print $2 }&#39;</span>

<span style="color:#ae81ff">172</span>.28.128.5</code></pre></div>

<p>Each VM has other network adapters, but for now we&rsquo;ll focus on this particular
one. We can see that all 3 machines are part of the 172.28.128.0/24 network. On
a production setup the different machines are probably not going to be on the
same private network but we can still achieve this using virtual networks most
of the time (VPC on AWS for instance). This is usually a very good idea because
the public facing IP shoud be firewalled but we don&rsquo;t need that while we
communicate between our internal services.</p>

<h2 id="starting-the-consul-cluster">Starting the Consul cluster</h2>

<p>The first thing we&rsquo;ll do is to start our Consul cluster. We are going to use a 3
node cluster, similarly to how we did it in our <a href="/posts/2015/01/where-are-my-containers-dockerized-service-discovery-with-consul/" target="_blank">previous post</a>.
I&rsquo;ll show the full docker run commands here, but don&rsquo;t run those yet. I&rsquo;ll show
a more concise form later on:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-1$ docker run -d -h node1 -v /mnt:/data <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.38300 <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.38301 <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.38301/udp <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.38302 <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.38302/udp <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.38400 <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.38500 <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.17.42.153/udp <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>progrium/consul -server -advertise <span style="color:#ae81ff">172</span>.28.128.3 -bootstrap-expect <span style="color:#ae81ff">3</span></code></pre></div>

<p>In this docker run command, we are binding all Consul&rsquo;s internal ports to the
private IP address of our first host, except for the DNS port (53) which is
exposed only on the <code>docker0</code> interface (172.17.42.1 by default).
The reason why we use the docker bridge interface for the DNS server is that we
want all the containers running on the same host to query this DNS interface,
but we don&rsquo;t need anyone from outside doing the same. Since each host will be
running a Consul agent, each container can query its own host.
We also added the <code>-advertise</code> flag to tell Consul that it should use the
host&rsquo;s IP instead of the docker container&rsquo;s IP.</p>

<p>On the second host, we&rsquo;d run the same thing, but passing a <code>-join</code> to the first
node&rsquo;s IP:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-2$ docker run -d -h node2 -v /mnt:/data <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.48300 <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.48301 <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.48301/udp <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.48302 <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.48302/udp <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.48400 <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.48500 <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.17.42.153/udp <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>progrium/consul -server -advertise <span style="color:#ae81ff">172</span>.28.128.4 -join <span style="color:#ae81ff">172</span>.28.128.3</code></pre></div>

<p>Same for the third one:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-3$ docker run -d -h node3 -v /mnt:/data <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.58300 <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.58301 <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.58301/udp <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.58302 <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.58302/udp <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.58400 <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.58500 <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.17.42.153/udp <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>progrium/consul -server -advertise <span style="color:#ae81ff">172</span>.28.128.5 -join <span style="color:#ae81ff">172</span>.28.128.3</code></pre></div>

<p>Since the docker run command for each host can be quite large and error prone to
type in manually, the <strong>progrium/consul</strong> image comes with a convenient command
to generate this for you. You can try this on any of the 3 hosts:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ docker run --rm progrium/consul cmd:run <span style="color:#ae81ff">172</span>.28.128.3 -d -v /mnt:/data

eval docker run --name consul -h $HOSTNAME  <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.38300   <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.38301   <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.38301/udp <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.38302 <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.38302/udp       <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.38400  <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.38500<span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.17.42.153/udp <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-d -v /mnt:/data  progrium/consul -server -advertise <span style="color:#ae81ff">172</span>.28.128.3 -bootstrap-expect <span style="color:#ae81ff">3</span></code></pre></div>

<p>Note that this is the exact command we ran on our first host to bootstrap the
cluster. You can also try the following:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ docker run --rm progrium/consul cmd:run <span style="color:#ae81ff">172</span>.28.128.4:172.28.128.3 -d -v /mnt:/data

eval docker run --name consul -h $HOSTNAME      <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.48300 <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.48301       <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.48301/udp   <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.48302      <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.48302/udp   <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.48400       <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.28.128.48500       <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-p <span style="color:#ae81ff">172</span>.17.42.153/udp      <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-d -v /mnt:/data progrium/consul -server -advertise <span style="color:#ae81ff">172</span>.28.128.4 -join <span style="color:#ae81ff">172</span>.28.128.3</code></pre></div>

<p>Here we passed 2 IPs to the cmd:run command, first the node&rsquo;s own address (the
one that will be used for the <code>-advertise</code>) and the second the IP of one of the
nodes that is already in the cluster (the IP in the <code>-join</code> part).
Note also that by specifying a second IP the cmd:run command now removed the
<code>-bootstrap-expect</code> parameter, which makes sense because otherwise each node
would start a different cluster.</p>

<p>We can use the 2 forms of the &ldquo;cmd:run&rdquo; command above to bootstrap our cluster with a
lot less typing. First, stop and remove all running containers on each host with
the following command:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ docker rm -f <span style="color:#66d9ef">$(</span>docker ps -aq<span style="color:#66d9ef">)</span></code></pre></div>

<p>Now, on the first host:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-1$ <span style="color:#66d9ef">$(</span>docker run --rm progrium/consul cmd:run <span style="color:#ae81ff">172</span>.28.128.3 -d -v /mnt:/data<span style="color:#66d9ef">)</span> </code></pre></div>

<p>For the second node:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-2$ <span style="color:#66d9ef">$(</span>docker run --rm progrium/consul cmd:run <span style="color:#ae81ff">172</span>.28.128.4:172.28.128.3 -d -v /mnt:/data<span style="color:#66d9ef">)</span> </code></pre></div>

<p>And the third node:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-3$ <span style="color:#66d9ef">$(</span>docker run --rm progrium/consul cmd:run <span style="color:#ae81ff">172</span>.28.128.5:172.28.128.3 -d -v /mnt:/data<span style="color:#66d9ef">)</span> </code></pre></div>

<p>If you take a look at the logs in host-1 with <code>docker logs consul</code> you would see
both nodes joining and finally Consul starting the cluster and setting the 3
nodes as healthy.</p>

<h2 id="working-with-registrator">Working with Registrator</h2>

<p>Now that we have our Consul cluster up and running we can start the registrator container with:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-1$  export HOST_IP<span style="color:#f92672">=</span><span style="color:#66d9ef">$(</span>ifconfig enp0s8 | grep <span style="color:#e6db74">&#39;inet &#39;</span> | awk <span style="color:#e6db74">&#39;{ print $2  }&#39;</span><span style="color:#66d9ef">)</span>
host-1$  docker run -d <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-v /var/run/docker.sock:/tmp/docker.sock <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>--name registrator -h registrator <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>progrium/registrator:latest consul://$HOST_IP:8500</code></pre></div>

<p>Notice that we are mounting our &ldquo;/var/run/docker.sock&rdquo; file to the container.
This file is a <a href="http://en.wikipedia.org/wiki/Unix_domain_socket" target="_blank">Unix socket</a>,
where the docker daemon listens for events. This is actually how the docker
client (the docker command that you usually use) and the docker daemon
communicate, through a REST API accessible from this socket. If you want to
learn more about how you can interact with the docker daemon through this socket
take a look
<a href="http://blog.trifork.com/2013/12/24/docker-from-a-distance-the-remote-api/" target="_blank">here</a>.
The important thing to know is that by listening on the same port as Docker,
Registrator is able to know everything that happens with Docker on that host.</p>

<p>If you check the logs of the &ldquo;registrator&rdquo; container you&rsquo;ll see a bunch of stuff
and a message in the end indicating that it is waiting for new events. You
should run the same commands on the other 2 containers to start registrator on
those.</p>

<p>To summarize what we have done so far, we have 3 different hosts each running a
Consul agent and a registrator container. The registrator instance on each host
watches for changes in docker containers for that host and talks to the local
Consul agent.</p>

<h2 id="starting-our-containers">Starting our containers</h2>

<p>Let&rsquo;s see what happens when we run our python service from
<a href="/posts/2014/12/running-docker-in-aws-with-elastic-beanstalk/" target="_blank">the first post</a> in this Docker series.
You can do this following the step by step guide on that post, getting the code
from <a href="https://github.com/jlordiales/docker-python-service" target="_blank">this repo</a> and
building the docker image yourself or using the image that is already on the
public registry <code>jlordiales/python-micro-service</code>. I will go with the latter
option here.
We&rsquo;ll first run our python container on host-1:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-1$ docker run -d --name service1 -P jlordiales/python-micro-service</code></pre></div>

<p>Lets see what happened in our registrator container:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-1$ docker logs registrator

<span style="color:#ae81ff">2015</span>/02/02 <span style="color:#ae81ff">1826</span> registrator: added: a8dc2b849d99 registrator5000</code></pre></div>

<p>Registrator saw that a new container (service1) was started, exposing port 5000
and it registered it with our Consul cluster.
We&rsquo;ll query our cluster now to see if the service was really added there:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-1$ curl <span style="color:#ae81ff">172</span>.28.128.3:8500/v1/catalog/services

<span style="color:#f92672">{</span>
  <span style="color:#e6db74">&#34;consul&#34;</span>:<span style="color:#f92672">[]</span>,
  <span style="color:#e6db74">&#34;consul-53&#34;</span>:<span style="color:#f92672">[</span><span style="color:#e6db74">&#34;udp&#34;</span><span style="color:#f92672">]</span>,
  <span style="color:#e6db74">&#34;consul-8300&#34;</span>:<span style="color:#f92672">[]</span>,
  <span style="color:#e6db74">&#34;consul-8301&#34;</span>:<span style="color:#f92672">[</span><span style="color:#e6db74">&#34;udp&#34;</span><span style="color:#f92672">]</span>,
  <span style="color:#e6db74">&#34;consul-8302&#34;</span>:<span style="color:#f92672">[</span><span style="color:#e6db74">&#34;udp&#34;</span><span style="color:#f92672">]</span>,
  <span style="color:#e6db74">&#34;consul-8400&#34;</span>:<span style="color:#f92672">[]</span>,
  <span style="color:#e6db74">&#34;consul-8500&#34;</span>:<span style="color:#f92672">[]</span>,
  <span style="color:#e6db74">&#34;python-micro-service&#34;</span>:<span style="color:#f92672">[]</span>
<span style="color:#f92672">}</span></code></pre></div>

<p>There it is! Lets get some more details about it:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-1$ curl <span style="color:#ae81ff">172</span>.28.128.3:8500/v1/catalog/service/python-micro-service

<span style="color:#f92672">[</span>
  <span style="color:#f92672">{</span>
    <span style="color:#e6db74">&#34;Node&#34;</span>:<span style="color:#e6db74">&#34;host-1&#34;</span>,
    <span style="color:#e6db74">&#34;Address&#34;</span>:<span style="color:#e6db74">&#34;172.28.128.3&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceID&#34;</span>:<span style="color:#e6db74">&#34;registrator5000&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceName&#34;</span>:<span style="color:#e6db74">&#34;python-micro-service&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceTags&#34;</span>:null,
    <span style="color:#e6db74">&#34;ServicePort&#34;</span>:49154
  <span style="color:#f92672">}</span>
<span style="color:#f92672">]</span></code></pre></div>

<p><a name="advertise"/>
One important thing to notice here, as it caused a lot of
<a href="https://github.com/progrium/registrator/issues/68" target="_blank">frustration</a> to people
before. You can see that Registrator used the IP of the host as the service IP
rather than the IP address of the container. The reason for that is explained in
<a href="https://github.com/bryanlarsen/registrator/commit/0182dd4bdb4cc6b98aa2b80103fd591f65132f46" target="_blank">this</a>
pull request to update the FAQ (which should be merged IMHO).</p>

<p>In a nutshell, registrator will always use the IP you specified when you run
your consul agent with the <code>-advertise</code> flag. At first, this seems wrong,
but it is usually what you want.
A service in a Docker based production cluster typically has 3 IP addresses.
The service itself is running in a Docker container, which has an IP address
assigned by Docker. The host that it&rsquo;s running on will have 3 IP addresses:
one for the Docker network, an internal private IP address for all hosts in the
cluster, and a public address on the Internet. Unless you&rsquo;ve bridged your
docker networks, the IP address of the service container is not accessible from
other hosts in the cluster. Instead you use the &ldquo;-P&rdquo; or &ldquo;-p&rdquo; option to Docker
to map the service port onto the host.  You then advertise a Host IP as the
service IP. The public IP address should be firewalled, so you want the
internal private IP to be advertised.</p>

<p>Going back to the output of our last curl, we get the private IP of our &ldquo;host-1&rdquo;
which is where our docker container is running with an exposed port (49154 in
this case). With that information we could call our service from any other node
in any host, as long as they are able to reach &ldquo;host-1&rdquo; through its private IP
that is.</p>

<p>So what would happen now if we run a second &ldquo;python-micro-service&rdquo; container
from our second host?</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-2$ docker run -d --name service2 -P jlordiales/python-micro-service</code></pre></div>

<p>As we saw on the <a href="/posts/2015/01/where-are-my-containers-dockerized-service-discovery-with-consul/" target="_blank">last post</a>, whenever
we have a Consul cluster running we can query any node (client or server) and
the response should always be the same.  Since we are running our containers in
host-1 and host-2, lets query the Consul node on host-3:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-3$ curl <span style="color:#ae81ff">172</span>.28.128.5:8500/v1/catalog/service/python-micro-service

<span style="color:#f92672">[</span>
  <span style="color:#f92672">{</span>
    <span style="color:#e6db74">&#34;Node&#34;</span>:<span style="color:#e6db74">&#34;host-1&#34;</span>,
    <span style="color:#e6db74">&#34;Address&#34;</span>:<span style="color:#e6db74">&#34;172.28.128.3&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceID&#34;</span>:<span style="color:#e6db74">&#34;registrator5000&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceName&#34;</span>:<span style="color:#e6db74">&#34;python-micro-service&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceTags&#34;</span>:null,
    <span style="color:#e6db74">&#34;ServicePort&#34;</span>:49154
  <span style="color:#f92672">}</span>,
  <span style="color:#f92672">{</span>
    <span style="color:#e6db74">&#34;Node&#34;</span>:<span style="color:#e6db74">&#34;host-2&#34;</span>,
    <span style="color:#e6db74">&#34;Address&#34;</span>:<span style="color:#e6db74">&#34;172.28.128.4&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceID&#34;</span>:<span style="color:#e6db74">&#34;registrator5000&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceName&#34;</span>:<span style="color:#e6db74">&#34;python-micro-service&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceTags&#34;</span>:null,
    <span style="color:#e6db74">&#34;ServicePort&#34;</span>:49153
  <span style="color:#f92672">}</span>
<span style="color:#f92672">]</span></code></pre></div>

<p>We now have two containers offering the same service. Using this information we
could call either one from host-3:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-3$ curl <span style="color:#ae81ff">172</span>.28.128.3:49154

Hello World from a8dc2b849d99

host-3$ curl <span style="color:#ae81ff">172</span>.28.128.4:49153

Hello World from c9ca6addfdb0</code></pre></div>

<h2 id="integrating-our-containers-with-consul-s-dns">Integrating our containers with Consul&rsquo;s DNS</h2>

<p>Lets try one more thing: using Consul&rsquo;s DNS interface from a different container
to ping our service. We&rsquo;ll run a simple busybox container in host-3:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-3$  docker run --dns <span style="color:#ae81ff">172</span>.17.42.1 --dns <span style="color:#ae81ff">8</span>.8.8.8 --dns-search service.consul
--rm --name ping_test -it busybox </code></pre></div>

<p>The &ldquo;&ndash;dns&rdquo; parameter allows us to use a custom DNS server for our container. By
default the container will use the same DNS servers as its host. In our case we
want it to use the docker bridge interface (172.17.42.1) first and then, if it
can not find the host there go to Google&rsquo;s DNS (8.8.8.8).
Finally, the &ldquo;dns-search&rdquo; option makes it easier to query for our services. For
instance, instead of querying for &ldquo;python-micro-service.service.consul&rdquo; we can
just query for &ldquo;python-micro-service&rdquo;.
Let&rsquo;s try to ping our service from the new busybox container:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ ping -qc <span style="color:#ae81ff">1</span> python-micro-service

PING python-micro-service <span style="color:#f92672">(</span><span style="color:#ae81ff">172</span>.28.128.4<span style="color:#f92672">)</span>: <span style="color:#ae81ff">56</span> data bytes

--- python-micro-service ping statistics ---
<span style="color:#ae81ff">1</span> packets transmitted, <span style="color:#ae81ff">1</span> packets received, <span style="color:#ae81ff">0</span>% packet loss
round-trip min/avg/max <span style="color:#f92672">=</span> <span style="color:#ae81ff">2</span>.391/2.391/2.391 ms</code></pre></div>

<p>It effectively resolved our service name to one of the hosts where it is
currently running. If we keep running the same &ldquo;ping&rdquo; command multiple times we
will eventually see that it will resolve the hostname to 172.28.128.3, which is
the other host where our service is running.
This is well explained in the documentation but Consul will load balance between
all nodes running the same service as long as they are healthy.</p>

<p>Of course, if we stop a running container Registrator will notice it and also
remove the service from Consul. We can see that if we stop the container running
in host-1:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-1$ docker stop service1</code></pre></div>

<p>And then query again from host-3 like we did before (you can do the same from
host-1, it doesn&rsquo;t matter):</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">host-3$ curl <span style="color:#ae81ff">172</span>.28.128.5:8500/v1/catalog/service/python-micro-service

<span style="color:#f92672">[</span>
  <span style="color:#f92672">{</span>
    <span style="color:#e6db74">&#34;Node&#34;</span>:<span style="color:#e6db74">&#34;host-2&#34;</span>,
    <span style="color:#e6db74">&#34;Address&#34;</span>:<span style="color:#e6db74">&#34;172.28.128.4&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceID&#34;</span>:<span style="color:#e6db74">&#34;registrator5000&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceName&#34;</span>:<span style="color:#e6db74">&#34;python-micro-service&#34;</span>,
    <span style="color:#e6db74">&#34;ServiceTags&#34;</span>:null,
    <span style="color:#e6db74">&#34;ServicePort&#34;</span>:49153
  <span style="color:#f92672">}</span>
<span style="color:#f92672">]</span></code></pre></div>

<h1 id="conclusion">Conclusion</h1>

<p>In this post we have seen an approach that allows to have our containers
registered with the service discovery solution of our choice without the need to
couple both. Instead, an intermediary tool called Registrator manages this for
all the containers running on a particular host.</p>

<p>We used Vagrant to create 3 different virtual hosts all under the same private
network. We started our 3 nodes Consul cluster, one consul container running on
each host. We did the same thing for Registrator, one container running on each
host pointing to its local consul container.
Then we ran the container with our python endpoint. This container had no idea
about Consul or registrator. We used exactly the same <code>docker run</code> command that
we would&rsquo;ve used if we were running that container alone.
And yet registrator was notified about this new container and automatically
registered it with the correct IP and port information on Consul. Moreover, when
we ran another container in another host from the same docker image Consul saw
that it was the same service and started to load balance between them.
When we stopped our container registrator also saw that and automatically
deregistered it from the cluster.</p>

<p>This is amazing because we can keep our containers completely ignorant about how
they will be discovered or any other piece of infrastructure information. We can
keep them portable and we move the logic of registration to a separate component
running in a separate container.</p>

<p>The capability to run multiple containers of the same service and have Consul
automatically load balancing between them, together with its health-checks and
its DNS interface allow us to deploy and run really complex configurations of
services in an extremely transparent and simplified way.</p>
]]></content>
        </item>
        
        <item>
            <title>Where are my containers? Dockerized service discovery with Consul</title>
            <link>/posts/2015/01/where-are-my-containers-dockerized-service-discovery-with-consul/</link>
            <pubDate>Fri, 23 Jan 2015 00:00:00 +0000</pubDate>
            
            <guid>/posts/2015/01/where-are-my-containers-dockerized-service-discovery-with-consul/</guid>
            <description>In the previous post I talked a bit about Docker and the main benefits you can get from running your applications as isolated, loosely coupled containers. We then saw how to &amp;ldquo;dockerize&amp;rdquo; a small python web service and how to run this container in AWS, first manually and then using Elastic Beanstalk to quickly deploy changes to it. This was really good from an introduction to Docker point of view but in real life one single container running on a host will not cut it.</description>
            <content type="html"><![CDATA[

<p>In the <a href="/posts/2014/12/running-docker-in-aws-with-elastic-beanstalk/" target="_blank">previous post</a> I talked a bit
about Docker and the main benefits you can get from running your applications as
isolated, loosely coupled containers. We then saw how to &ldquo;dockerize&rdquo; a small
python web service and how to run this container in AWS, first manually and then
using Elastic Beanstalk to quickly deploy changes to it.
This was really good from an introduction to Docker point of view but in real
life one single container running on a host will not cut it.  You will need a
set of related containers running together and collaborating, each with the
ability to be deployed independently. This also means that you need a way to
know which container is running what and where.  In this post I wanted to talk a
bit about service discovery. Particularly, I&rsquo;m going to show how you can use
Consul running as a container to achieve this goal in a robust and scalable way.</p>

<h1 id="consul">Consul</h1>

<p>Consul came out of <a href="https://hashicorp.com/" target="_blank">Hashicorp</a>, the same company behind
popular tools like <a href="https://www.vagrantup.com/" target="_blank">Vagrant</a> and
<a href="https://www.packer.io/" target="_blank">Packer</a>. They are pretty good at creating DevOps
friendly tools so I take some time to play around with anything they come up
with. Consul has several components that provide different functionalities but
in a nutshell is a highly distributed and highly available tool for service
discovery. Clients can register new services with Consul, specifying a name and
additional information in the form of tags and then query Consul for services
that match their criteria using either HTTP or DNS. We&rsquo;ll see an example later
on.</p>

<p>In addition to clients specifying the services they want to register they can
also specify any number of health checks. The health check can be made against
your application (e.g., the REST endpoint is listening to connections on port X)
or on the physical node itself (e.g., the CPU utilization is above 90%). Consul
will use these health checks to know which nodes it should exclude when a client
queries for a specific service.</p>

<p>Finally, Consul also provides a highly scalable and fault tolerant Key/Value
store, which your services can use for anything they want: dynamic
configuration, feature flags, etc.</p>

<p>So how does it work? The main thing you need is a Consul agent running as a
server. This Consul server is responsible for storing data and replicating it to
other servers. You can have a fully functioning Consul system with just 1 server
but that is usually a bad idea for a production deployment. Your server becomes
your <a href="http://en.wikipedia.org/wiki/Single_point_of_failure" target="_blank">single point of
failure</a> and you can not
discover your services if that server goes down. The Consul documentation
recommends setting up a cluster with 3 or 5 Consul servers running to avoid data
loss. More than that and the communication starts to suffer from progressively
increasing overhead. In addition to running as a server, an agent can also run
in client mode. These agents have a lot less responsibilities than servers and
are pretty much stateless components.</p>

<p>Usually, nodes wanting to register services running on them with Consul do so by
registering them with their local running Consul agent. However, you can also
register <a href="http://www.consul.io/docs/guides/external.html" target="_blank">external services</a> so
you don&rsquo;t need to run a Consul agent on every node that is hosting your
services.</p>

<p>Queries can be made against any type of Consul
agent, either running as a server or as a client. Unlike servers, you can have
thousands or tens of of thousands of Consul clients without any significant
impact on performance or network overhead.<br />
I would strongly suggest taking a look at its
<a href="https://www.consul.io/docs/index.html" target="_blank">documentation</a> to get a more detailed
explanation of how all of this works.</p>

<h1 id="running-a-single-node-cluster">Running a single node cluster</h1>

<p>And now, the fun part! Lets see how we can bootstrap a Consul cluster using
Docker containers. We&rsquo;ll first run a Consul cluster consisting of a single
server to see how it works. We&rsquo;ll use the amazing image built by
<a href="https://github.com/progrium/docker-consul" target="_blank">Jeff Lindsay</a>:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ docker run -p <span style="color:#ae81ff">8400</span>:8400 -p <span style="color:#ae81ff">8500</span>:8500 -p <span style="color:#ae81ff">8600</span>:53/udp <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>-h node1 progrium/consul -server -bootstrap</code></pre></div>

<p>You should see something like:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-text" data-lang="text">==&gt; WARNING: bootstrap mode enabled! do not enable unless necessary
==&gt; WARNING: It is highly recommended to set GOMAXPROCS higher than 1
==&gt; Starting Consul agent...
==&gt; Starting Consul agent RPC...
==&gt; Consul agent running!
         Node name: &#39;node1&#39;
        Datacenter: &#39;dc1&#39;
            Server: true (bootstrap: true)
       Client Addr: 0.0.0.0 (HTTP: 8500, DNS: 53, RPC: 8400)
      Cluster Addr: 172.17.0.66 (LAN: 8301, WAN: 8302)
    Gossip encrypt: false, RPC-TLS: false, TLS-Incoming: false

==&gt; Log data will now stream in as it occurs:

    2014/12/04 1930 [INFO] serf: EventMemberJoin: node1 172.17.0.66
    2014/12/04 1930 [INFO] serf: EventMemberJoin: node1.dc1 172.17.0.66
    2014/12/04 1930 [INFO] raft: Node at 172.17.0.66:8300 [Follower] entering Follower state
    2014/12/04 1930 [INFO] consul: adding server node1 (Addr: 172.17.0.66:8300) (DC: dc1)
    2014/12/04 1930 [INFO] consul: adding server node1.dc1 (Addr: 172.17.0.66:8300) (DC: dc1)
    2014/12/04 1930 [ERR] agent: failed to sync remote state: No cluster leader
    2014/12/04 1931 [WARN] raft: Heartbeat timeout reached, starting election
    2014/12/04 1931 [INFO] raft: Node at 172.17.0.66:8300 [Candidate] entering Candidate state
    2014/12/04 1931 [INFO] raft: Election won. Tally: 1
    2014/12/04 1931 [INFO] raft: Node at 172.17.0.66:8300 [Leader] entering Leader state
    2014/12/04 1931 [INFO] consul: cluster leadership acquired
    2014/12/04 1931 [INFO] consul: New leader elected: node1
    2014/12/04 1931 [INFO] raft: Disabling EnableSingleNode (bootstrap)
    2014/12/04 1931 [INFO] consul: member &#39;node1&#39; joined, marking health alive
    2014/12/04 1933 [INFO] agent: Synced service &#39;consul&#39;</code></pre></div>

<p>The <code>-server -bootstrap</code> tells Consul to start this agent in server mode and not
wait for any other instances to join. Notice how Consul actually warns you about
this when you start the server: <strong>bootstrap mode enabled! do not enable unless
necessary</strong>.</p>

<p>We can now query Consul through its REST API. Since I&rsquo;m running
<a href="http://boot2docker.io/" target="_blank">boot2docker</a> I need to get the VM IP first:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ export DOCKER_IP<span style="color:#f92672">=</span><span style="color:#66d9ef">$(</span>boot2docker ip<span style="color:#66d9ef">)</span>
$ curl $DOCKER_IP:8500/v1/catalog/nodes

<span style="color:#f92672">[{</span><span style="color:#e6db74">&#34;Node&#34;</span>:<span style="color:#e6db74">&#34;node1&#34;</span>,<span style="color:#e6db74">&#34;Address&#34;</span>:<span style="color:#e6db74">&#34;172.17.0.66&#34;</span><span style="color:#f92672">}]</span></code></pre></div>

<p>You get a JSON response specifying the nodes that are currently part of the
Consul cluster, which in our case so far is just one. You can also go to
<a href="http://192.168.59.103:8500/" target="_blank">http://192.168.59.103:8500/</a> (replace the IP by whatever your Docker host IP is)
in your browser to see a nice UI with information about the currently registered
services and nodes.</p>

<p>Lets now add a new service. We usually want to register all the services that
are under our control. But what about the external ones? It is seldom the case
where we don&rsquo;t use any third party services. It would certainly be nice to treat
both types equally from a service discovery point of view.
We&rsquo;ll start by adding an external service, following
the example given in the documentation:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ curl -X PUT -d <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span><span style="color:#e6db74">&#39;{&#34;Datacenter&#34;: &#34;dc1&#34;, &#34;Node&#34;: &#34;google&#34;, &#34;Address&#34;: &#34;www.google.com&#34;, &#34;Service&#34;: {&#34;Service&#34;: &#34;search&#34;, &#34;Port&#34;: 80}}&#39;</span> <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>http://$DOCKER_IP:8500/v1/catalog/register</code></pre></div>

<p>Here we registered the &ldquo;google&rdquo; node as offering the &ldquo;search&rdquo; service. But what
if google is down for some reason? (can that happen?). We can register multiple
search services:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ curl -X PUT -d <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span><span style="color:#e6db74">&#39;{&#34;Datacenter&#34;: &#34;dc1&#34;, &#34;Node&#34;: &#34;bing&#34;, &#34;Address&#34;: &#34;www.bing.com&#34;, &#34;Service&#34;: {&#34;Service&#34;: &#34;search&#34;, &#34;Port&#34;: 80}}&#39;</span> <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>http://$DOCKER_IP:8500/v1/catalog/register</code></pre></div>

<p>We can now query Consul through its HTTP API to see all the services that are
currently registered with it:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ curl $DOCKER_IP:8500/v1/catalog/services

<span style="color:#f92672">{</span><span style="color:#e6db74">&#34;consul&#34;</span>:<span style="color:#f92672">[]</span>,<span style="color:#e6db74">&#34;search&#34;</span>:<span style="color:#f92672">[]}</span></code></pre></div>

<p>We can see that the &ldquo;search&rdquo; service that we added before is registered. Note
that we don&rsquo;t see any mention about the 2 specific services we added. If we want
to get more information about any particular service we can also do that:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ curl $DOCKER_IP:8500/v1/catalog/service/search

<span style="color:#f92672">[</span>
  <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;Node&#34;</span>:<span style="color:#e6db74">&#34;google&#34;</span>,<span style="color:#e6db74">&#34;Address&#34;</span>:<span style="color:#e6db74">&#34;www.google.com&#34;</span>,<span style="color:#e6db74">&#34;ServiceID&#34;</span>:<span style="color:#e6db74">&#34;search&#34;</span>,<span style="color:#e6db74">&#34;ServiceName&#34;</span>:<span style="color:#e6db74">&#34;search&#34;</span>,<span style="color:#e6db74">&#34;ServiceTags&#34;</span>:null,<span style="color:#e6db74">&#34;ServicePort&#34;</span>:80<span style="color:#f92672">}</span>,
  <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;Node&#34;</span>:<span style="color:#e6db74">&#34;bing&#34;</span>,<span style="color:#e6db74">&#34;Address&#34;</span>:<span style="color:#e6db74">&#34;www.bing.com&#34;</span>,<span style="color:#e6db74">&#34;ServiceID&#34;</span>:<span style="color:#e6db74">&#34;search&#34;</span>,<span style="color:#e6db74">&#34;ServiceName&#34;</span>:<span style="color:#e6db74">&#34;search&#34;</span>,<span style="color:#e6db74">&#34;ServiceTags&#34;</span>:null,<span style="color:#e6db74">&#34;ServicePort&#34;</span>:80<span style="color:#f92672">}</span>
<span style="color:#f92672">]</span></code></pre></div>

<p>We can also use the DNS interface to query for services:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">dig @$DOCKER_IP -p <span style="color:#ae81ff">8600</span> search.service.consul.

; &lt;&lt;&gt;&gt; DiG <span style="color:#ae81ff">9</span>.8.3-P1 &lt;&lt;&gt;&gt; @192.168.59.103 -p <span style="color:#ae81ff">8600</span> search.service.consul.
; <span style="color:#f92672">(</span><span style="color:#ae81ff">1</span> server found<span style="color:#f92672">)</span>
;; global options: +cmd
;; Got answer:
;; -&gt;&gt;HEADER<span style="color:#e6db74">&lt;&lt;- opco</span>de: QUERY, status: NOERROR, id: <span style="color:#ae81ff">1330</span>
;; flags: qr aa rd ra; QUERY: <span style="color:#ae81ff">1</span>, ANSWER: <span style="color:#ae81ff">6</span>, AUTHORITY: <span style="color:#ae81ff">0</span>, ADDITIONAL: <span style="color:#ae81ff">0</span>

;; QUESTION SECTION:
;search.service.consul.         IN      A

;; ANSWER SECTION:
search.service.consul.  <span style="color:#ae81ff">0</span>       IN      CNAME   www.google.com.
www.google.com.         <span style="color:#ae81ff">255</span>     IN      A       <span style="color:#ae81ff">173</span>.194.42.243
www.google.com.         <span style="color:#ae81ff">255</span>     IN      A       <span style="color:#ae81ff">173</span>.194.42.242
www.google.com.         <span style="color:#ae81ff">255</span>     IN      A       <span style="color:#ae81ff">173</span>.194.42.241
search.service.consul.  <span style="color:#ae81ff">0</span>       IN      CNAME   www.bing.com.
any.edge.bing.com.      <span style="color:#ae81ff">375</span>     IN      A       <span style="color:#ae81ff">204</span>.79.197.200

;; Query time: <span style="color:#ae81ff">133</span> msec
;; SERVER: <span style="color:#ae81ff">192</span>.168.59.103#8600<span style="color:#f92672">(</span><span style="color:#ae81ff">192</span>.168.59.103<span style="color:#f92672">)</span>
;; WHEN: Thu Jan <span style="color:#ae81ff">22</span> <span style="color:#ae81ff">1728</span> <span style="color:#ae81ff">2015</span>
;; MSG SIZE  rcvd: <span style="color:#ae81ff">258</span></code></pre></div>

<h1 id="running-a-consul-cluster">Running a Consul cluster</h1>

<p>Ok, so we were able to run a single Consul agent in server mode and register an
external service. But, as I mentioned before, this is usually a very bad idea
for availability reasons. So lets see how we could run a cluster with 3 servers,
all of them running locally on different Docker containers.</p>

<p>We&rsquo;ll start the first node similarly to the way we did it before:
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ docker run --name node1 -h node1 progrium/consul -server -bootstrap-expect 3

<span style="color:#f92672">==</span>&gt; WARNING: Expect Mode enabled, expecting <span style="color:#ae81ff">3</span> servers
<span style="color:#f92672">==</span>&gt; WARNING: It is highly recommended to set GOMAXPROCS higher than 1
<span style="color:#f92672">==</span>&gt; Starting Consul agent...
<span style="color:#f92672">==</span>&gt; Starting Consul agent RPC...
<span style="color:#f92672">==</span>&gt; Consul agent running!
         Node name: <span style="color:#e6db74">&#39;node1&#39;</span>
        Datacenter: <span style="color:#e6db74">&#39;dc1&#39;</span>
            Server: true <span style="color:#f92672">(</span>bootstrap: false<span style="color:#f92672">)</span>
       Client Addr: <span style="color:#ae81ff">0</span>.0.0.0 <span style="color:#f92672">(</span>HTTP: <span style="color:#ae81ff">8500</span>, DNS: <span style="color:#ae81ff">53</span>, RPC: <span style="color:#ae81ff">8400</span><span style="color:#f92672">)</span>
      Cluster Addr: <span style="color:#ae81ff">172</span>.17.0.75 <span style="color:#f92672">(</span>LAN: <span style="color:#ae81ff">8301</span>, WAN: <span style="color:#ae81ff">8302</span><span style="color:#f92672">)</span>
    Gossip encrypt: false, RPC-TLS: false, TLS-Incoming: false</code></pre></div></p>

<p>Note here that instead of passing the <code>-bootstrap</code> flag we are passing a
<code>-bootstrap-expect 3</code> flag, which tells Consul that it should wait until 3
servers join to actually start the cluster.
In order to join the cluster a node only needs to know the location of 1 node
that is already part of it. So to join the second node we will need the IP of
the first one (the only node we know of so far). We can get this IP using
<code>docker inspect</code> and looking for the <code>IPAddress</code> field. Or you can just export
that to an environment variable with:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ JOIN_IP<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;</span><span style="color:#66d9ef">$(</span>docker inspect -f <span style="color:#e6db74">&#39;{{.NetworkSettings.IPAddress}}&#39;</span> node1<span style="color:#66d9ef">)</span><span style="color:#e6db74">&#34;</span></code></pre></div>

<p>We can now start our 2 remaining servers and join them with the first one:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ docker run -d --name node2 -h node2 progrium/consul -server -join $JOIN_IP
$ docker run -d --name node3 -h node3 progrium/consul -server -join $JOIN_IP</code></pre></div>

<p>After doing that you should see something like this on the <code>node1</code> logs:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash"><span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0854</span> <span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> serf: EventMemberJoin: node2 <span style="color:#ae81ff">172</span>.17.0.76
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0854</span> <span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> consul: adding server node2 <span style="color:#f92672">(</span>Addr: <span style="color:#ae81ff">172</span>.17.0.76:8300<span style="color:#f92672">)</span> <span style="color:#f92672">(</span>DC: dc1<span style="color:#f92672">)</span>
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0858</span> <span style="color:#f92672">[</span>ERR<span style="color:#f92672">]</span> agent: failed to sync remote state: No cluster leader
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0815</span> <span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> serf: EventMemberJoin: node3 <span style="color:#ae81ff">172</span>.17.0.77
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0815</span> <span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> consul: adding server node3 <span style="color:#f92672">(</span>Addr: <span style="color:#ae81ff">172</span>.17.0.77:8300<span style="color:#f92672">)</span> <span style="color:#f92672">(</span>DC: dc1<span style="color:#f92672">)</span>
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0815</span> <span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> consul: Attempting bootstrap with nodes: <span style="color:#f92672">[</span><span style="color:#ae81ff">172</span>.17.0.75:8300 <span style="color:#ae81ff">172</span>.17.0.76:8300 <span style="color:#ae81ff">172</span>.17.0.77:8300<span style="color:#f92672">]</span>
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0816</span> <span style="color:#f92672">[</span>WARN<span style="color:#f92672">]</span> raft: Heartbeat timeout reached, starting election
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0816</span> <span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> raft: Node at <span style="color:#ae81ff">172</span>.17.0.75:8300 <span style="color:#f92672">[</span>Candidate<span style="color:#f92672">]</span> entering Candidate state
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0816</span> <span style="color:#f92672">[</span>WARN<span style="color:#f92672">]</span> raft: Remote peer <span style="color:#ae81ff">172</span>.17.0.77:8300 does not have local node <span style="color:#ae81ff">172</span>.17.0.75:8300 as a peer
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0816</span> <span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> raft: Election won. Tally: <span style="color:#ae81ff">2</span>
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0816</span> <span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> raft: Node at <span style="color:#ae81ff">172</span>.17.0.75:8300 <span style="color:#f92672">[</span>Leader<span style="color:#f92672">]</span> entering Leader state
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0816</span> <span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> consul: cluster leadership acquired
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0816</span> <span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> raft: pipelining replication to peer <span style="color:#ae81ff">172</span>.17.0.77:8300
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0816</span> <span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> consul: New leader elected: node1
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0816</span> <span style="color:#f92672">[</span>WARN<span style="color:#f92672">]</span> raft: Remote peer <span style="color:#ae81ff">172</span>.17.0.76:8300 does not have local node <span style="color:#ae81ff">172</span>.17.0.75:8300 as a peer
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0816</span> <span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> raft: pipelining replication to peer <span style="color:#ae81ff">172</span>.17.0.76:8300
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0816</span> <span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> consul: member <span style="color:#e6db74">&#39;node3&#39;</span> joined, marking health alive
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0816</span> <span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> consul: member <span style="color:#e6db74">&#39;node1&#39;</span> joined, marking health alive
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0816</span> <span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> consul: member <span style="color:#e6db74">&#39;node2&#39;</span> joined, marking health alive
<span style="color:#ae81ff">2014</span>/12/06 <span style="color:#ae81ff">0818</span> <span style="color:#f92672">[</span>INFO<span style="color:#f92672">]</span> agent: Synced service <span style="color:#e6db74">&#39;consul&#39;</span></code></pre></div>

<p>Basically, after joining the second node Consul tells us that it can not yet
start the cluster. But after joining the third node, it tries to bootstrap the
cluster, elects a <a href="https://www.consul.io/docs/internals/architecture.html" target="_blank">leader
node</a> and marks the 3
nodes as healthy.</p>

<p>So now we have our 3 servers cluster up and running. Note however, that we did
not specify any port mapping information on any of the three nodes. This means
that we would have no way of accessing the cluster from outside.
Luckily this is not a problem because with our cluster running we can now join
any number of nodes in client mode and interact with the cluster through those
clients. Lets join the first client node with:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ docker run -d -p <span style="color:#ae81ff">8400</span>:8400 -p <span style="color:#ae81ff">8500</span>:8500 -p <span style="color:#ae81ff">8600</span>:53/udp <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>--name node4 -h node4 progrium/consul -join $JOIN_IP</code></pre></div>

<p>Note that we didn&rsquo;t pass the <code>-server</code> parameter this time and we added the port
mapping information.
We can now interact with the cluster through our client node. We could, for
instance, use the REST API to see all the nodes that are currently part of the
cluster:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ curl $DOCKER_IP:8500/v1/catalog/nodes

<span style="color:#f92672">[</span>
  <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;Node&#34;</span>:<span style="color:#e6db74">&#34;node1&#34;</span>,<span style="color:#e6db74">&#34;Address&#34;</span>:<span style="color:#e6db74">&#34;172.17.0.7&#34;</span><span style="color:#f92672">}</span>,
  <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;Node&#34;</span>:<span style="color:#e6db74">&#34;node2&#34;</span>,<span style="color:#e6db74">&#34;Address&#34;</span>:<span style="color:#e6db74">&#34;172.17.0.8&#34;</span><span style="color:#f92672">}</span>,
  <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;Node&#34;</span>:<span style="color:#e6db74">&#34;node3&#34;</span>,<span style="color:#e6db74">&#34;Address&#34;</span>:<span style="color:#e6db74">&#34;172.17.0.9&#34;</span><span style="color:#f92672">}</span>,
  <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;Node&#34;</span>:<span style="color:#e6db74">&#34;node4&#34;</span>,<span style="color:#e6db74">&#34;Address&#34;</span>:<span style="color:#e6db74">&#34;172.17.0.10&#34;</span><span style="color:#f92672">}</span>
<span style="color:#f92672">]</span></code></pre></div>

<p>It is important to understand that we only need to know the address of 1 of the
nodes (either server or client) to join. Until now we have used the <code>JOIN_IP</code>
variable which contains the IP of <strong>node1</strong> but we could just as easily add a
new node using the IP of <strong>node4</strong> for instance, which is a client:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ docker run -d -p <span style="color:#ae81ff">8401</span>:8400 -p <span style="color:#ae81ff">8501</span>:8500 -p <span style="color:#ae81ff">8601</span>:53/udp <span style="color:#ae81ff">\
</span><span style="color:#ae81ff"></span>--name node5 -h node5 progrium/consul -join <span style="color:#ae81ff">172</span>.17.0.10</code></pre></div>

<p>Similarly, we can send our queries to any node in the cluster and the answer
will be always the same thanks to Consul&rsquo;s replication algorithms. Here we&rsquo;ll
use port 8501, which is the port exposed by the last client we joined:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ curl $DOCKER_IP:8501/v1/catalog/nodes

<span style="color:#f92672">[</span>
  <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;Node&#34;</span>:<span style="color:#e6db74">&#34;node1&#34;</span>,<span style="color:#e6db74">&#34;Address&#34;</span>:<span style="color:#e6db74">&#34;172.17.0.7&#34;</span><span style="color:#f92672">}</span>,
  <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;Node&#34;</span>:<span style="color:#e6db74">&#34;node2&#34;</span>,<span style="color:#e6db74">&#34;Address&#34;</span>:<span style="color:#e6db74">&#34;172.17.0.8&#34;</span><span style="color:#f92672">}</span>,
  <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;Node&#34;</span>:<span style="color:#e6db74">&#34;node3&#34;</span>,<span style="color:#e6db74">&#34;Address&#34;</span>:<span style="color:#e6db74">&#34;172.17.0.9&#34;</span><span style="color:#f92672">}</span>,
  <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;Node&#34;</span>:<span style="color:#e6db74">&#34;node4&#34;</span>,<span style="color:#e6db74">&#34;Address&#34;</span>:<span style="color:#e6db74">&#34;172.17.0.10&#34;</span><span style="color:#f92672">}</span>,
  <span style="color:#f92672">{</span><span style="color:#e6db74">&#34;Node&#34;</span>:<span style="color:#e6db74">&#34;node5&#34;</span>,<span style="color:#e6db74">&#34;Address&#34;</span>:<span style="color:#e6db74">&#34;172.17.0.11&#34;</span><span style="color:#f92672">}</span>
<span style="color:#f92672">]</span> </code></pre></div>

<p>This combined with the fact that we can have thousands of clients in the cluster
without any performance impact makes Consul an extremely highly available
service discovery solution.</p>

<h1 id="key-value-store">Key/Value store</h1>

<p>In addition to its service discovery and health check capabilities, Consul
offers a key/value store for whatever you may need. We can easily access it
through its REST API. We&rsquo;ll keep using the 5 node cluster we got running before.
First, lets make sure that there is nothing currently saved there:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ curl -v  $DOCKER_IP:8500/v1/kv/key1

 About to connect<span style="color:#f92672">()</span> to <span style="color:#ae81ff">192</span>.168.59.103 port <span style="color:#ae81ff">8500</span> <span style="color:#f92672">(</span><span style="color:#75715e">#0)</span>
   Trying <span style="color:#ae81ff">192</span>.168.59.103...
 Adding handle: conn: 0x7fa72b811a00
 Adding handle: send: <span style="color:#ae81ff">0</span>
 Adding handle: recv: <span style="color:#ae81ff">0</span>
 Curl_addHandleToPipeline: length: <span style="color:#ae81ff">1</span>
 - Conn <span style="color:#ae81ff">0</span> <span style="color:#f92672">(</span>0x7fa72b811a00<span style="color:#f92672">)</span> send_pipe: <span style="color:#ae81ff">1</span>, recv_pipe: <span style="color:#ae81ff">0</span>
 Connected to <span style="color:#ae81ff">192</span>.168.59.103 <span style="color:#f92672">(</span><span style="color:#ae81ff">192</span>.168.59.103<span style="color:#f92672">)</span> port <span style="color:#ae81ff">8500</span> <span style="color:#f92672">(</span><span style="color:#75715e">#0)</span>
&gt; GET /v1/kv/key1 HTTP/1.1
&gt; User-Agent: curl/7.30.0
&gt; Host: <span style="color:#ae81ff">192</span>.168.59.103:8500
&gt; Accept: */*
&gt;
&lt; HTTP/1.1 <span style="color:#ae81ff">404</span> Not Found
&lt; X-Consul-Index: <span style="color:#ae81ff">50</span>
&lt; X-Consul-Knownleader: true
&lt; X-Consul-Lastcontact: <span style="color:#ae81ff">0</span>
&lt; Date: Tue, <span style="color:#ae81ff">20</span> Jan <span style="color:#ae81ff">2015</span> <span style="color:#ae81ff">0607</span> GMT
&lt; Content-Length: <span style="color:#ae81ff">0</span>
&lt; Content-Type: text/plain; charset<span style="color:#f92672">=</span>utf-8
&lt;
 Connection <span style="color:#75715e">#0 to host 192.168.59.103 left intact</span></code></pre></div>

<p>We got back a 404 because the key doesn&rsquo;t exist yet, great! Let&rsquo;s now add a
value for <strong>key1</strong> and query again:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ curl -X PUT -d <span style="color:#e6db74">&#39;test&#39;</span> http://$DOCKER_IP:8500/v1/kv/key1

$ curl -v  $DOCKER_IP:8500/v1/kv/key1

 About to connect<span style="color:#f92672">()</span> to <span style="color:#ae81ff">192</span>.168.59.103 port <span style="color:#ae81ff">8500</span> <span style="color:#f92672">(</span><span style="color:#75715e">#0)</span>
   Trying <span style="color:#ae81ff">192</span>.168.59.103...
 Adding handle: conn: 0x7fb9a3817e00
 Adding handle: send: <span style="color:#ae81ff">0</span>
 Adding handle: recv: <span style="color:#ae81ff">0</span>
 Curl_addHandleToPipeline: length: <span style="color:#ae81ff">1</span>
 - Conn <span style="color:#ae81ff">0</span> <span style="color:#f92672">(</span>0x7fb9a3817e00<span style="color:#f92672">)</span> send_pipe: <span style="color:#ae81ff">1</span>, recv_pipe: <span style="color:#ae81ff">0</span>
 Connected to <span style="color:#ae81ff">192</span>.168.59.103 <span style="color:#f92672">(</span><span style="color:#ae81ff">192</span>.168.59.103<span style="color:#f92672">)</span> port <span style="color:#ae81ff">8500</span> <span style="color:#f92672">(</span><span style="color:#75715e">#0)</span>
&gt; GET /v1/kv/key1 HTTP/1.1
&gt; User-Agent: curl/7.30.0
&gt; Host: <span style="color:#ae81ff">192</span>.168.59.103:8500
&gt; Accept: */*
&gt;
&lt; HTTP/1.1 <span style="color:#ae81ff">200</span> OK
&lt; Content-Type: application/json
&lt; X-Consul-Index: <span style="color:#ae81ff">55</span>
&lt; X-Consul-Knownleader: true
&lt; X-Consul-Lastcontact: <span style="color:#ae81ff">0</span>
&lt; Date: Tue, <span style="color:#ae81ff">20</span> Jan <span style="color:#ae81ff">2015</span> <span style="color:#ae81ff">0631</span> GMT
&lt; Content-Length: <span style="color:#ae81ff">93</span>
&lt;
 Connection <span style="color:#75715e">#0 to host 192.168.59.103 left intact</span>
<span style="color:#f92672">[{</span><span style="color:#e6db74">&#34;CreateIndex&#34;</span>:50,<span style="color:#e6db74">&#34;ModifyIndex&#34;</span>:55,<span style="color:#e6db74">&#34;LockIndex&#34;</span>:0,<span style="color:#e6db74">&#34;Key&#34;</span>:<span style="color:#e6db74">&#34;key1&#34;</span>,<span style="color:#e6db74">&#34;Flags&#34;</span>:0,<span style="color:#e6db74">&#34;Value&#34;</span>:<span style="color:#e6db74">&#34;dGVzdA==&#34;</span><span style="color:#f92672">}]</span>%</code></pre></div>

<p>Note that the <code>Value</code> field is base64 encoded. According to the
<a href="http://www.consul.io/intro/getting-started/kv.html" target="_blank">documentation</a> this is to
allow non UTF-8 characters.</p>

<p>Before we saw that we could query any node in the cluster for registered
services or a list of nodes and the answer would be the same.
It&rsquo;s no surprise that this also applies to the key/value store. We can add a key
and query for one from any node. In our example, we could use <code>curl -v
$DOCKER_IP:8501/v1/kv/key1</code> (changing the port to 8501 to query a different node
that the one we used on the PUT) and we would get exactly the same answer from
Consul.</p>

<h1 id="conclusion">Conclusion</h1>

<p>In the <a href="/posts/2014/12/running-docker-in-aws-with-elastic-beanstalk/" target="_blank">last post</a> we saw an overview of
Docker and its benefits. This is really easy to see when you consider a service
running on a single container. But when you start to throw in hundreds or
thousands of containers things start to get a bit more complicated. One of the
first things you need is to know where each container lives and what services it
offers. You also need some basic form of health-check to be sure that you don&rsquo;t
try to send requests to containers that are either not able to reply or
are not there anymore.
Consul, a highly scalable and efficient service discovery tool, solves these
problems in a very elegant way. Of course, there are many other alternatives out
there with different capabilities like <a href="https://github.com/coreos/etcd" target="_blank">etcd</a> or
<a href="https://github.com/skynetservices/skydns/" target="_blank">SkyDns</a>. I haven&rsquo;t had a chance to
play around with those yet so I don&rsquo;t have an informed opinion about them.</p>

<p>One thing that we haven&rsquo;t talked about yet is how would you go about registering
your containers. By this I don&rsquo;t mean the Consul-specific way of registering
services but rather a more general question: who is responsible for doing this?
Should the container know how to register itself with the cluster? Should the
operator running the container do this? Someone else? All these approaches have
pros and cons. In the next post I&rsquo;ll discuss these options as well as showing a
really amazing tool from Jeff Lindsay that makes it incredibly easy and
transparent to deal with container registration.</p>
]]></content>
        </item>
        
        <item>
            <title>Running Docker in AWS with Elastic Beanstalk</title>
            <link>/posts/2014/12/running-docker-in-aws-with-elastic-beanstalk/</link>
            <pubDate>Sun, 07 Dec 2014 00:00:00 +0000</pubDate>
            
            <guid>/posts/2014/12/running-docker-in-aws-with-elastic-beanstalk/</guid>
            <description>By now I would image that Docker needs no introduction, given that is one of the hottest technologies and indeed buzzwords in the industry today. But just in case, we&amp;rsquo;ll see the basics of it. We&amp;rsquo;ll also see how you can quickly run a Docker container in AWS and how you can easily deploy your changes to it.
Introduction The official documentation defines Docker as &amp;ldquo;an open platform for developing, shipping, and running applications&amp;rdquo;.</description>
            <content type="html"><![CDATA[

<p>By now I would image that <a href="http://www.docker.com/" target="_blank">Docker</a> needs no
introduction, given that is one of the hottest technologies and indeed buzzwords
in the industry today. But just in case, we&rsquo;ll see the basics of it. We&rsquo;ll also
see how you can quickly run a Docker container in AWS and how you can easily
deploy your changes to it.</p>

<h1 id="introduction">Introduction</h1>

<p>The <a href="https://docs.docker.com" target="_blank">official documentation</a> defines Docker as &ldquo;an open
platform for developing, shipping, and running applications&rdquo;.
What does that really mean? In simple terms it means that instead of thinking
about your application as only the code that you write and then somehow gets
deployed into some server in the &ldquo;cloud&rdquo;, you can start thinking about your
application and those things that it needs to run as a single isolated container
that you can just throw at any server and it will work, regardless of what
that server already had installed or not.</p>

<p>When you hear about isolation the first thing that probably comes to mind are
Virtual Machines. The problem with VMs is that they are usually a bit
heavyweight. Even on a pretty decent laptop it usually takes a few minutes for a
VM to start. A Docker container, on the other hand, starts in the order of
seconds.
On a very simplified view of the world, you can see Docker containers as
lightweight VMs (although in reality they are much much more than that). Each
container can run its own OS, have its own files, run its own processes and so
on. Also, unlike VMs where you can probably run just a few of them on a regular
piece of hardware, you can easily run dozens of Docker containers on your
laptop.</p>

<p>The benefits from using containers for your applications are varied and people
are still finding new and innovative ways to put them to good use. Perhaps one
of the main benefits is related to deployment and portability. You know the
dreaded &ldquo;It works in my machine&rdquo; phrase, don&rsquo;t you? Imagine the following
workflow:</p>

<ul>
<li>You develop and test in your local box running your application and all the
services it requires on their own isolated environment.</li>
<li>Once you are happy with your code you push your changes and the same set of
containers that you were running locally are now running in a testing
environment.</li>
<li>Once you validate your changes in this testing environment you push the same
container to be run in Production.</li>
</ul>

<p>Because of the underlying principles of Docker you are guaranteed that
regardless of the differences in environment between your local box, the testing
environment and the production environment, your containers (and therefore your
application) will run exactly in the same way.</p>

<p>What happens if you decide to move to a different provider for your production
environment? Say you were running in AWS and suddenly all your company migrates
to OpenStack. As long as the new server is able to run Docker containers, it
doesn&rsquo;t matter. Your containers will still run exactly in the same way as
before.</p>

<p>Another huge benefit that I see in Docker is the fact that not only your code
runs in a container but also the infrastructure that your code needs, usually in
different containers. This, combined with the fact that the community has
already created thousands of Docker images for all sort of popular applications
(publicly available in <a href="https://hub.docker.com/" target="_blank">Docker Hub</a>) means that you can
save yourself a lot of trouble.
Say your application needs to use <a href="http://redis.io/" target="_blank">Redis</a> as its backing
store. Do you install Redis locally in your box to test while you develop and
then make sure that the same version of Redis with the same configuration is
installed in each and every new environment? Or do you get an <a href="https://registry.hub.docker.com/_/redis/" target="_blank">official Redis
image</a> and run that same image on
every environment with just one command?</p>

<h1 id="a-really-simple-docker-app">A really simple Docker app</h1>

<p>Due to the way that Docker works, it needs a Linux kernel to run on. This is
obviously not a problem if you are actually using a Linux distribution but it
can be an issue if you are on Windows or Mac.
The official documentation covers Docker
<a href="https://docs.docker.com/installation/" target="_blank">installation</a> on a lot of different
platforms.
Personally, since I use a Mac mostly these days, I really recommend the
<a href="http://boot2docker.io/" target="_blank">boot2docker</a>. It provides a very tiny VM (literally, is
based in <a href="http://tinycorelinux.net/" target="_blank">Tiny Core Linux</a>) where you can run Docker
from your Mac terminal (almost) as if you were running it locally.</p>

<p>Enough introductions, lets see an example. We are going to develop a really
simple REST service and run it inside a Docker container.
We are going to use Python with <a href="http://flask.pocoo.org/" target="_blank">Flask</a> for this,
simply because it&rsquo;s really easy to get up an running in no time but the
language and framework of choice are not really important for this. We could
have used Java with Dropwizard or Ruby with Sinatra and the result would be the
same. If you don&rsquo;t want to write the code you can just clone the app from
<a href="https://github.com/jlordiales/docker-python-service.git" target="_blank">here</a>.</p>

<p>So our application will consist of one <code>app.py</code> file that looks like the
following:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-python" data-lang="python"><span style="color:#f92672">from</span> flask <span style="color:#f92672">import</span> Flask
<span style="color:#f92672">import</span> os
<span style="color:#f92672">import</span> socket
app <span style="color:#f92672">=</span> Flask(__name__)

<span style="color:#a6e22e">@app.route</span>(<span style="color:#e6db74">&#39;/&#39;</span>)
<span style="color:#66d9ef">def</span> <span style="color:#a6e22e">hello</span>():
    <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#39;Hello World from </span><span style="color:#e6db74">%s</span><span style="color:#e6db74">&#39;</span> <span style="color:#f92672">%</span> socket<span style="color:#f92672">.</span>gethostname()

<span style="color:#66d9ef">if</span> __name__ <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;__main__&#34;</span>:
    app<span style="color:#f92672">.</span>run(host<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;0.0.0.0&#34;</span>, debug<span style="color:#f92672">=</span>True)</code></pre></div>

<p>In order to get the dependencies we need for our app (just flask in this case)
and comply with the <a href="http://12factor.net/" target="_blank">12 factor app</a> we&rsquo;ll also create a
<code>requirements.txt</code> file with just one line:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-text" data-lang="text">flask</code></pre></div>

<p>With these 2 files we can already run our application with:
<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-bash" data-lang="bash">$ pip install -r requirements.txt
$ python app.py</code></pre></div></p>

<p>The application will start a server listening in port 5000. If you run <code>curl
localhost:5000</code> from a different shell you should see a hello world message as a
response.</p>

<p>Lets now &ldquo;dockerize&rdquo; our application. The easiest way to this is to write a
Dockerfile with the steps we want to take. I won&rsquo;t go into a lot of details
about Dockerfiles but you can read about them
<a href="https://docs.docker.com/reference/builder/" target="_blank">here</a>. I&rsquo;m rather going to show you
the Dockerfile that we&rsquo;ll use and describe what each step is doing:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-dockerfile" data-lang="dockerfile"><span style="color:#66d9ef">FROM</span><span style="color:#e6db74"> python:2.7</span><span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">EXPOSE</span><span style="color:#e6db74"> 5000</span><span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">ADD</span><span style="color:#e6db74"> . /code</span><span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">WORKDIR</span><span style="color:#e6db74"> /code</span><span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">RUN</span> pip install -r requirements.txt<span style="color:#960050;background-color:#1e0010">
</span><span style="color:#960050;background-color:#1e0010"></span><span style="color:#66d9ef">CMD</span><span style="color:#e6db74"> [&#34;python&#34;, &#34;app.py&#34;]</span></code></pre></div>

<p>On the first line we are saying that our new image will use the <code>python</code>
<a href="https://registry.hub.docker.com/_/python/" target="_blank">official image</a> as a base image. The
2.7 part is called a TAG and in this case represents the version of python that
we want installed in our image.
Next we tell Docker that the container will expose port 5000 to the external
world (which is the port where our endpoint will be listening). We&rsquo;ll see how
this is useful in a moment.
The third instruction tells Docker that it needs to copy the current directory
(where the Dockerfile is placed) and copy it to <code>/code</code> inside the new
container.
Then, in the following step we tell Docker that we want to <code>cd</code> to that <code>/code</code>
directory so that all commands we run after that are executed from within that path.
Next we run <code>pip install</code> to install our dependencies into the container and
finally we tell Docker that the default command to run should be <code>python
app.py</code>.</p>

<p>Now that we have our Dockerfile, we can build an image from it using the <code>docker
build</code> command: <code>docker build -t python_service .</code>. This step can take a while
the first time you run it because it will need to download the python base image
first (which is currently around 850 MB, a bit too much if you ask me).
When the command finishes you should be able to see your new shiny image after
running <code>docker images</code>.</p>

<p>So far you have an image, but not a running container. To run this new image
you&rsquo;ll have to do a <code>docker run --rm --name service1 -P python_service</code>. The
<code>--rm</code> parameter tells Docker to delete the container after it has stopped
running, which is useful for cases where you are creating lots of different
containers to do quick tests because it will save you quite a bit of disk space.
Next, we give our container a name. This is completely optional and if we don&rsquo;t
specify a name then Docker will assign the container one by default. The <code>-P</code>
parameter means that we want to map every port exposed by the container (in our
case just port 5000) into a port in our host. By not specifying any specific
port on the host Docker will randomly assign one. Another alternative, if we
want to explicitly tell Docker which port to use would be to pass the parameter
<code>-p $HOST_PORT:$CONTAINER_PORT</code>. But it is usually a good idea not to do that
because we might want to run multiple instances of the same container and they
all have to map to different ports. So its usually better to let Docker decide.</p>

<p>After running the <code>docker run</code> command the container will start and you&rsquo;ll see
that it will run our app which is going to be waiting for connections to it.
If you now run <code>docker ps</code> on a different shell you&rsquo;ll see something like this:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-text" data-lang="text">CONTAINER ID        IMAGE                     COMMAND             CREATED             STATUS              PORTS                     NAMES
86b331209845        python_service:latest   &#34;python app.py&#34;     2 days ago          Up 12 hours         0.0.0.0:49162-&gt;5000/tcp   python1</code></pre></div>

<p>Pay special attention to the PORTS part. In your Dockerfile you told Docker that
you were exposing port 5000. But remember that when you ran the container with
<code>docker run</code> you specified the -P, which meant that the ports exposed by the
container would be mapped to randomly high ports on the host. In our case, the
49162-&gt;5000/tcp part is telling us that port 49162 on the host will map to port
5000 on the container.</p>

<p>So how do we curl our service now? If we were running Docker natively on a Linux
machine we could just do a <code>curl localhost:49162</code>. But since I&rsquo;m running on
boot2docker, I need to get the IP of the boot2docker VM first. This can be
easily done with <code>boot2docker ip</code>. Unless you&rsquo;ve done something to change the
default values this IP will be 192.168.59.103.
So if we now run <code>curl 192.168.59.103:49162</code> we get back our awesome hello world
message from our running container.</p>

<h1 id="running-manually-in-aws">Running manually in AWS</h1>

<p>By now you have an independent Docker image with your python service which you
can easily run and query with a simple curl. But so far we have only run the
container locally, which doesn&rsquo;t seem like a big improvement over just running
the application directly. And indeed it wouldn&rsquo;t make a lot of sense to do all
this work if we are only going to run things locally.
So lets see what happens when we want to run the same container somewhere else,
like AWS for instance given that they give us a free year with their <a href="http://aws.amazon.com/free/" target="_blank">free
tier</a>. This AWS server could be a QA environment
for instance.</p>

<p>Before we go into AWS we are going to use the <a href="https://registry.hub.docker.com/" target="_blank">Docker
registry</a> to push the image we created before,
which is based off the <code>python</code> image and has our app and dependencies all
bundled together. The
<a href="http://docs.docker.com/userguide/dockerrepos/" target="_blank">documentation</a> is pretty clear
about how you work with the registry so I&rsquo;ll skip that part (hint: you should
use the <code>docker push</code> command).</p>

<p>Now that our image is on the public Docker registry, lets create a micro
instance on EC2. Create a new account if you don&rsquo;t have one yet, go to your EC2
dashboard, instances and click on Launch instance.
Choose the Amazon Linux AMI that shows up on the first step, select t2.micro for
the instance type, leave all the default options on the next steps until Step 6
where you&rsquo;ll create a security group for your instance specifying which ports
you are going to leave open to the internet. In our case we want port 22 to be
able to ssh into our instance. We also want to add a new custom rule to open the
high ports that Docker usually uses. So we&rsquo;ll create a new TCP rule with Port
Range between 30000-50000. Finally review your instance and Launch!</p>

<p>Once the instance is running, ssh into it using its public IP, install Docker
with <code>sudo yum install -y docker</code> and start it with <code>sudo service docker start</code>.
Now that we have Docker installed in our new instance we can use it in exactly
the same way that we did locally.
Since we pushed our image into the Docker registry before, we can do a <code>sudo docker
pull your_user/repo_name</code> and then run our container similarly to how we did
before with <code>sudo docker run --rm --name service1 -p 45000:5000
your_image_name</code>.
Our container is now running and the host (the EC2 instance in this case) will
map its port 45000 to the container&rsquo;s port 5000 thanks to the <code>-p</code> argument.
You can now go to your local shell, run <code>curl your_ec2_public_ip:45000</code> and&hellip;
get a &ldquo;Hello World&rdquo; message back.</p>

<p>Lets take a moment to think about what just happened. We first created a Docker
image and ran it locally to test our app. We then pushed that image into the
public registry, pulled it from a freshly created EC2 instance and ran it in
exactly the same way. Since all the dependencies were already included in the
image, we didn&rsquo;t need to do anything on the server apart from installing Docker.
Same application, same Docker image, same version, same behavior and two completely
different environments.
What would happen now if we wanted to run the application on a different server?
Maybe an OpenStack server, or DigitalOcean or an old laptop at home that is not
doing anything else. It would be exactly the same! The only thing that we need
in every case is a Linux kernel and the Docker daemon running.</p>

<p>This is certainly great progress but what would happen if we want to make some
changes to our code and then redeploy the container again? We would have to push
the image again into the public repository, ssh into our instance, stop the
running container, pull the new image and finally run it again.
 Wouldn&rsquo;t it be great if Amazon could handle all of this for us? Meet Elastic
 Beanstalk!</p>

<h1 id="using-elastic-beanstalk">Using Elastic Beanstalk</h1>

<p><a href="http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/Welcome.html" target="_blank">Elastic
Beanstalk</a>
is a service provided by Amazon to quickly deploy and manage your applications.
You don&rsquo;t need to worry about creating instances or things like load balancing
and auto scaling. It can be used to run Web Applications in a variety of
languages and, of course, Docker containers.</p>

<p>We are going to use Elastic Beanstalk to run our app and see how we can deploy
new versions of it. We&rsquo;ll first need the <code>eb</code> tool, which can be installed using
brew with <code>brew install aws-elasticbeanstalk</code>. Next we&rsquo;ll need to initialize a
git repository with the app code (<code>git init .</code>) and commit what we have so far
(<code>git commit -a -m &quot;Initial commit&quot;</code>).
Now we can run <code>eb init</code> to configure Elastic Beanstalk. This will be a one time
process that will tell EB how to deploy our application. The steps are pretty
self-explanatory. Just make sure that you select the &ldquo;64bit Amazon Linux
2014.09 v1.0.10 running Docker&rdquo; when you are asked for the solution stack.</p>

<p>Once that is done you can run <code>eb start</code>. It will ask you if you want to deploy
the last commit of your app, to which you&rsquo;ll respond yes. You can then follow
the logs shown on the console to get an idea of what eb is doing. This will
include creating a S3 bucket, creating an Elastic IP address, a security group
for your instance and finally launching your instance. In the end, you will see
a message indicating that your application was deployed and is ready to be
accessed. Something like: &ldquo;Application is available at &hellip;&rdquo; an some URL.
Go to that URL and see the glorious Hello World message once again.</p>

<p>Now, let change the message on our app to say something different. Edit the
<code>app.py</code> file and change the return line for <code>return 'Hello Docker World from
%s' % socket.gethostname()</code>. Save and commit your changes to git. Now we&rsquo;ll use
eb to deploy our app once again. Run <code>eb push</code> and Elastic Beanstalk will deploy
the new version of your app. When that finishes you go back to the same URL as
before and see the updated message.</p>

<p>Interestingly, if you go to your AWS Dashboard and then to Elastic Beanstalk you
will be able to see, among other things, all the different versions of your app
that you have ever deployed so rollbacks are trivial. And this is all thanks to
the fact that EB created a new Docker image every time you deployed a new
version.
When you are done you can do a <code>eb delete</code> to clean up all the resources that
were created.</p>

<p>And that is all there is to it. Your changes get easily deployed with just one
command and, as an added bonus, you get to keep a record of all the different
versions of your app for easy rollback.</p>

<h1 id="conclusion">Conclusion</h1>

<p>Docker is revolutionizing the way we think about development and deployment.
Specially at a time were loosely coupled and small services are the way more and
more applications are getting architected. This is still a pretty new area with
lots of exciting tools under heavy development and increasing support from big
players in the industry. Amazon, for instance, announced its <a href="http://aws.amazon.com/ecs/" target="_blank">EC2 Container
Service</a> in the last re:invent conference to offer
easy support for Docker containers, treating them as first class citizens inside
the AWS ecosystem. Similarly, in the last <a href="http://europe.dockercon.com/" target="_blank">DockerCon Europe
2014</a> they announced, among other things, support
for <a href="https://blog.docker.com/2014/12/docker-announces-docker-hub-enterprise/" target="_blank">Docker hub in the
enterprise</a>
and a set of <a href="https://blog.docker.com/2014/12/announcing-docker-machine-swarm-and-compose-for-orchestrating-distributed-apps/" target="_blank">Alpha
tools</a>
to support easy Docker host provisioning, clustering and orchestration.
As well as Docker, other <a href="https://coreos.com/blog/rocket/" target="_blank">container runtime
technologies</a> are making their way to the
scene. Where all these technologies and tools will end no one knows but one
thing is for sure, containers are here to stay and they will have a bigger and
bigger impact in the future. So start playing around with them!</p>
]]></content>
        </item>
        
        <item>
            <title>Lambdas and Functional interfaces in Java 8</title>
            <link>/posts/2014/11/lambdas-and-functional-interfaces-in-java-8/</link>
            <pubDate>Tue, 18 Nov 2014 00:00:00 +0000</pubDate>
            
            <guid>/posts/2014/11/lambdas-and-functional-interfaces-in-java-8/</guid>
            <description>In the previous post we saw an overview of what functional programming is and how the new features of Java 8 allow developers to write their applications using a more functional style. One of the main points in this new version of the language was the introduction of lambdas. Together with lambdas came the use of functional interfaces and methods references. This post will explore these features in more detail, showing when to use them, the restrictions around them and how you can use them to make your code more readable and concise.</description>
            <content type="html"><![CDATA[

<p>In the
<a href="/posts/2014/11/an-overview-of-functional-style-programming-in-java-8/" target="_blank">previous post</a> we saw an
overview of what functional programming is and how the new features of Java 8
allow developers to write their applications using a more functional style. One
of the main points in this new version of the language was the introduction of
lambdas. Together with lambdas came the use of functional interfaces and methods
references. This post will explore these features in more detail, showing
when to use them, the restrictions around them and how you can use them
to make your code more readable and concise.</p>

<h1 id="lambdas">Lambdas</h1>

<p>First things first, what is a lambda (or lambda expression)? A lambda is an
anonymous method that doesn&rsquo;t have a name but it has a list of parameters, a
body, a return type and potentially a list of exception that the lambda can
throw. Unlike regular class methods, lambdas are not actually associated with
any class. They can also be assigned to variables or passed as arguments to
other methods. The name <em>lambda expression</em> comes from the field of
<a href="http://en.wikipedia.org/wiki/Lambda_calculus" target="_blank">mathematics</a>.</p>

<p>We saw an example of a lambda expression in the
<a href="/posts/2014/11/an-overview-of-functional-style-programming-in-java-8/" target="_blank">previous post</a>, using an example
from the <code>File</code> class to list <code>csv</code> files:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java">File<span style="color:#f92672">[]</span> csvFiles <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> File<span style="color:#f92672">(</span><span style="color:#e6db74">&#34;.&#34;</span><span style="color:#f92672">)</span>
                    <span style="color:#f92672">.</span><span style="color:#a6e22e">listFiles</span><span style="color:#f92672">(</span>pathname <span style="color:#f92672">-&gt;</span> pathname<span style="color:#f92672">.</span><span style="color:#a6e22e">getAbsolutePath</span><span style="color:#f92672">().</span><span style="color:#a6e22e">endsWith</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;csv&#34;</span><span style="color:#f92672">));</span></code></pre></div>

<p>Here, we are passing a lambda expression to the <code>listFiles</code> method that takes
one input parameter and returns a boolean value. I also mentioned that you can
assign lambdas to variables, so the previous code is functionally equivalent to:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java">FileFilter csvFilter <span style="color:#f92672">=</span> pathname <span style="color:#f92672">-&gt;</span> pathname<span style="color:#f92672">.</span><span style="color:#a6e22e">getAbsolutePath</span><span style="color:#f92672">().</span><span style="color:#a6e22e">endsWith</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;csv&#34;</span><span style="color:#f92672">);</span>
File<span style="color:#f92672">[]</span> csvFiles <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> File<span style="color:#f92672">(</span><span style="color:#e6db74">&#34;.&#34;</span><span style="color:#f92672">).</span><span style="color:#a6e22e">listFiles</span><span style="color:#f92672">(</span>csvFilter<span style="color:#f92672">);</span></code></pre></div>

<p>How did we use to do that before Java 8? Like this:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java">File<span style="color:#f92672">[]</span> csvFiles <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> File<span style="color:#f92672">(</span><span style="color:#e6db74">&#34;.&#34;</span><span style="color:#f92672">).</span><span style="color:#a6e22e">listFiles</span><span style="color:#f92672">(</span><span style="color:#66d9ef">new</span> FileFilter<span style="color:#f92672">()</span> <span style="color:#f92672">{</span>
    <span style="color:#a6e22e">@Override</span>
    <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">boolean</span> <span style="color:#a6e22e">accept</span><span style="color:#f92672">(</span>File pathname<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
      <span style="color:#66d9ef">return</span> pathname<span style="color:#f92672">.</span><span style="color:#a6e22e">getAbsolutePath</span><span style="color:#f92672">().</span><span style="color:#a6e22e">endsWith</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;csv&#34;</span><span style="color:#f92672">);</span>
    <span style="color:#f92672">}</span>
<span style="color:#f92672">});</span></code></pre></div>

<p>You have to admit that the snippet using a lambda expression looks much more
concise and cleaner. In the last snippet we have to create an anonymous class
with an <code>accept</code> method (with all the verbosity that it implies). In the first
one, we just need to specify our logic.</p>

<p>This brings an interesting question, if the <code>listFiles</code> method takes a parameter
of <code>FileFilter</code> type (which is an interface), how come we can pass a lambda
instead? We can do this because the <code>FileFilter</code> interface is a functional
interface.</p>

<h1 id="functional-interfaces">Functional interfaces</h1>

<p>In a nutshell, a functional interface is an interface that specifies exactly
<strong>one</strong> abstract method. So the <code>FileFilter</code> interface we saw before is
specified as:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java"><span style="color:#a6e22e">@FunctionalInterface</span>
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">FileFilter</span> <span style="color:#f92672">{</span>
  <span style="color:#66d9ef">boolean</span> <span style="color:#a6e22e">accept</span><span style="color:#f92672">(</span>File pathname<span style="color:#f92672">);</span>
<span style="color:#f92672">}</span></code></pre></div>

<p>Another example, is the <code>Runnable</code> interface:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java"><span style="color:#a6e22e">@FunctionalInterface</span>
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">Runnable</span> <span style="color:#f92672">{</span>
  <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">abstract</span> <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">run</span><span style="color:#f92672">();</span>
<span style="color:#f92672">}</span></code></pre></div>

<p>You can see that both of these interfaces have a <code>@FunctionalInterface</code>
annotation. So what does that do? First it informs people who look at that
interface that it is intended to be a functional interface and that they can use
lambdas and method references wherever they are expected. Second, it works as a
compile-time check to make sure that the interface is indeed functional. If you
add this annotation to your interface and it is not in fact functional then you
will get a nice compile error letting you know this. It is worth noting that the
annotation is not actually required but it is usually a good idea to have it
there for the reasons I mentioned before.</p>

<p>There&rsquo;s one small caveat here. We briefly discussed default
methods in the <a href="/posts/2014/11/an-overview-of-functional-style-programming-in-java-8/" target="_blank">previous post</a>, which
are methods whose implementation code can be written in an interface. Default
methods do not count for the &ldquo;exactly one abstract method&rdquo; rule of functional
interfaces so you can effectively have a functional interface with one abstract
method and one or more default methods.</p>

<h1 id="some-useful-functional-interfaces">Some useful functional interfaces</h1>

<p>Now that we know what a functional interface is and how it can be used, lets
look at some pretty useful interfaces provided by Java in its
<code>java.function.util</code> package</p>

<h2 id="predicate">Predicate</h2>

<p>The predicate interface defines a simple <code>test</code> method that takes an object and
returns a boolean. It looks something like:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java"><span style="color:#a6e22e">@FunctionalInterface</span>
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">Predicate</span><span style="color:#f92672">&lt;</span>T<span style="color:#f92672">&gt;</span> <span style="color:#f92672">{</span>
    <span style="color:#66d9ef">boolean</span> <span style="color:#a6e22e">test</span><span style="color:#f92672">(</span>T t<span style="color:#f92672">);</span>
<span style="color:#f92672">}</span></code></pre></div>

<p>This is pretty useful for things like filtering. You could have a generic method
to filter a list (this is just an example, you don&rsquo;t need to write this logic
and we&rsquo;ll see why when we go into streams):</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java"><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">static</span> <span style="color:#f92672">&lt;</span>T<span style="color:#f92672">&gt;</span> List<span style="color:#f92672">&lt;</span>T<span style="color:#f92672">&gt;</span> <span style="color:#a6e22e">filter</span><span style="color:#f92672">(</span>List<span style="color:#f92672">&lt;</span>T<span style="color:#f92672">&gt;</span> list<span style="color:#f92672">,</span> Predicate<span style="color:#f92672">&lt;</span>T<span style="color:#f92672">&gt;</span> predicate<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
  List<span style="color:#f92672">&lt;</span>T<span style="color:#f92672">&gt;</span> result <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> ArrayList<span style="color:#f92672">&lt;&gt;();</span>
  <span style="color:#66d9ef">for</span> <span style="color:#f92672">(</span>T elem <span style="color:#f92672">:</span> list<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
    <span style="color:#66d9ef">if</span> <span style="color:#f92672">(</span>predicate<span style="color:#f92672">.</span><span style="color:#a6e22e">test</span><span style="color:#f92672">(</span>elem<span style="color:#f92672">))</span> <span style="color:#f92672">{</span>
      result<span style="color:#f92672">.</span><span style="color:#a6e22e">add</span><span style="color:#f92672">(</span>elem<span style="color:#f92672">);</span>
    <span style="color:#f92672">}</span>
  <span style="color:#f92672">}</span>
  <span style="color:#66d9ef">return</span> result<span style="color:#f92672">;</span>
<span style="color:#f92672">}</span></code></pre></div>

<p>And then create a predicate for your particular object. For example, a predicate
that given a <code>User</code> returns true if his age is greater than or equal to 18:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java"><span style="color:#66d9ef">public</span> <span style="color:#66d9ef">enum</span> Sex <span style="color:#f92672">{</span>
  MALE<span style="color:#f92672">,</span> FEMALE
<span style="color:#f92672">}</span>

<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">class</span> <span style="color:#a6e22e">User</span> <span style="color:#f92672">{</span>
  <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">final</span> <span style="color:#66d9ef">int</span> age<span style="color:#f92672">;</span>
  <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">final</span> String name<span style="color:#f92672">;</span>
  <span style="color:#66d9ef">private</span> <span style="color:#66d9ef">final</span> Sex sex<span style="color:#f92672">;</span>

  <span style="color:#66d9ef">public</span> <span style="color:#a6e22e">User</span><span style="color:#f92672">(</span><span style="color:#66d9ef">int</span> age<span style="color:#f92672">,</span> String name<span style="color:#f92672">,</span> Sex sex<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
    <span style="color:#66d9ef">this</span><span style="color:#f92672">.</span><span style="color:#a6e22e">age</span> <span style="color:#f92672">=</span> age<span style="color:#f92672">;</span>
    <span style="color:#66d9ef">this</span><span style="color:#f92672">.</span><span style="color:#a6e22e">name</span> <span style="color:#f92672">=</span> name<span style="color:#f92672">;</span>
    <span style="color:#66d9ef">this</span><span style="color:#f92672">.</span><span style="color:#a6e22e">sex</span> <span style="color:#f92672">=</span> sex<span style="color:#f92672">;</span>
  <span style="color:#f92672">}</span>

  <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">int</span> <span style="color:#a6e22e">getAge</span><span style="color:#f92672">()</span> <span style="color:#f92672">{</span>
    <span style="color:#66d9ef">return</span> age<span style="color:#f92672">;</span>
  <span style="color:#f92672">}</span>

  <span style="color:#66d9ef">public</span> <span style="color:#66d9ef">boolean</span> <span style="color:#a6e22e">isMale</span><span style="color:#f92672">()</span> <span style="color:#f92672">{</span>
    <span style="color:#66d9ef">return</span> MALE<span style="color:#f92672">.</span><span style="color:#a6e22e">equals</span><span style="color:#f92672">(</span>sex<span style="color:#f92672">);</span>
  <span style="color:#f92672">}</span>
<span style="color:#f92672">}</span>

Predicate<span style="color:#f92672">&lt;</span>User<span style="color:#f92672">&gt;</span> predicate <span style="color:#f92672">=</span> user <span style="color:#f92672">-&gt;</span> user<span style="color:#f92672">.</span><span style="color:#a6e22e">getAge</span><span style="color:#f92672">()</span> <span style="color:#f92672">&gt;=</span> 18<span style="color:#f92672">;</span></code></pre></div>

<p>A pretty useful functionality about predicates is that they can be composed
together to form more complex ones. For instance, what do you do if suddenly you
want a new <code>User</code> predicate that returns true for all users who are less than
18? Do you create a new predicate like the previous one but changing the <code>&gt;=</code> by
<code>&lt;</code>? Luckily, you don&rsquo;t have to because the <code>Predicate</code> interface provides 3
methods to compose several predicates: <code>and</code>, <code>or</code> and <code>negate</code>. So the previous
example could be written as:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java">Predicate<span style="color:#f92672">&lt;</span>User<span style="color:#f92672">&gt;</span> older <span style="color:#f92672">=</span> user <span style="color:#f92672">-&gt;</span> user<span style="color:#f92672">.</span><span style="color:#a6e22e">getAge</span><span style="color:#f92672">()</span> <span style="color:#f92672">&gt;=</span> 18<span style="color:#f92672">;</span>
Predicate<span style="color:#f92672">&lt;</span>User<span style="color:#f92672">&gt;</span> younger <span style="color:#f92672">=</span> older<span style="color:#f92672">.</span><span style="color:#a6e22e">negate</span><span style="color:#f92672">();</span></code></pre></div>

<p>Similarly, if we want a predicate that returns true for all the male users older
or equal to 18, we could write it as:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java">Predicate<span style="color:#f92672">&lt;</span>User<span style="color:#f92672">&gt;</span> older <span style="color:#f92672">=</span> user <span style="color:#f92672">-&gt;</span> user<span style="color:#f92672">.</span><span style="color:#a6e22e">getAge</span><span style="color:#f92672">()</span> <span style="color:#f92672">&gt;=</span> 18<span style="color:#f92672">;</span>
Predicate<span style="color:#f92672">&lt;</span>User<span style="color:#f92672">&gt;</span> adultMales <span style="color:#f92672">=</span> older<span style="color:#f92672">.</span><span style="color:#a6e22e">and</span><span style="color:#f92672">(</span>User:<span style="color:#f92672">:</span>isMale<span style="color:#f92672">);</span></code></pre></div>

<p>That last example shows that we can use method references where a <code>Predicate</code> is
expected. In fact, we can use a method reference wherever a functional interface
is expected. We quickly saw method references in the
<a href="/posts/2014/11/an-overview-of-functional-style-programming-in-java-8/" target="_blank">previous post</a> but we&rsquo;ll discuss more
about them later on.</p>

<h2 id="function">Function</h2>

<p>The java.util.function.Function interface is defined as:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java"><span style="color:#a6e22e">@FunctionalInterface</span>
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">Function</span><span style="color:#f92672">&lt;</span>T<span style="color:#f92672">,</span> R<span style="color:#f92672">&gt;</span> <span style="color:#f92672">{</span>
  R <span style="color:#a6e22e">apply</span><span style="color:#f92672">(</span>T t<span style="color:#f92672">);</span>
<span style="color:#f92672">}</span></code></pre></div>

<p>What this basically does is take an input of type <code>T</code> and transform it somehow
to return an object of type <code>R</code>. Note that the <code>Predicate</code> interface can be seen
as a special case of a <code>Function</code> where <code>R</code> is always a boolean value. Following
our <code>User</code> examples, imagine we want a function that given an <code>User</code> instance it
returns that user&rsquo;s name length. We could write this function like this:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java">Function<span style="color:#f92672">&lt;</span>User<span style="color:#f92672">,</span>Integer<span style="color:#f92672">&gt;</span> nameLength <span style="color:#f92672">=</span> user <span style="color:#f92672">-&gt;</span> user<span style="color:#f92672">.</span><span style="color:#a6e22e">getName</span><span style="color:#f92672">().</span><span style="color:#a6e22e">length</span><span style="color:#f92672">();</span></code></pre></div>

<p>Like predicates, the <code>Function</code> interface also has some useful methods to
compose several functions. The two methods offered are <code>compose</code> and <code>andThen</code>.
The difference between them is subtle but important. To understand this better,
imagine we have the following 2 functions:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java">Function<span style="color:#f92672">&lt;</span>Integer<span style="color:#f92672">,</span>Integer<span style="color:#f92672">&gt;</span> sumOne <span style="color:#f92672">=</span> number <span style="color:#f92672">-&gt;</span> number <span style="color:#f92672">+</span> 1<span style="color:#f92672">;</span>
Function<span style="color:#f92672">&lt;</span>Integer<span style="color:#f92672">,</span>Integer<span style="color:#f92672">&gt;</span> duplicate <span style="color:#f92672">=</span> number <span style="color:#f92672">-&gt;</span> number <span style="color:#f92672">*</span> 2<span style="color:#f92672">;</span></code></pre></div>

<p>We can then create 2 new functions in the following way:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java">Function<span style="color:#f92672">&lt;</span>Integer<span style="color:#f92672">,</span> Integer<span style="color:#f92672">&gt;</span> composed <span style="color:#f92672">=</span> sumOne<span style="color:#f92672">.</span><span style="color:#a6e22e">compose</span><span style="color:#f92672">(</span>duplicate<span style="color:#f92672">);</span>
Function<span style="color:#f92672">&lt;</span>Integer<span style="color:#f92672">,</span> Integer<span style="color:#f92672">&gt;</span> andThen <span style="color:#f92672">=</span> sumOne<span style="color:#f92672">.</span><span style="color:#a6e22e">andThen</span><span style="color:#f92672">(</span>duplicate<span style="color:#f92672">);</span>

System<span style="color:#f92672">.</span><span style="color:#a6e22e">out</span><span style="color:#f92672">.</span><span style="color:#a6e22e">println</span><span style="color:#f92672">(</span>composed<span style="color:#f92672">.</span><span style="color:#a6e22e">apply</span><span style="color:#f92672">(</span>2<span style="color:#f92672">));</span>
System<span style="color:#f92672">.</span><span style="color:#a6e22e">out</span><span style="color:#f92672">.</span><span style="color:#a6e22e">println</span><span style="color:#f92672">(</span>andThen<span style="color:#f92672">.</span><span style="color:#a6e22e">apply</span><span style="color:#f92672">(</span>2<span style="color:#f92672">));</span></code></pre></div>

<p>The <code>composed</code> function will first apply <code>duplicate</code> and then apply <code>sumOne</code> on
the result. In other words, composing <code>sumOne</code> with <code>duplicate</code> will result in
<code>sumOne(duplicate(x))</code> and the first System.out will print 5. The <code>andThen</code>
function will do exactly the opposite, it will first apply <code>sumOne</code> and then
apply <code>duplicate</code> on the result. In this case the second System.out will print
6.</p>

<h2 id="consumer">Consumer</h2>

<p>The java.util.function.Consumer interface defines an <code>accept</code> method that takes
a paramter of type <code>T</code> and returns no value. In other words:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java"><span style="color:#a6e22e">@FunctionalInterface</span>
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">Consumer</span><span style="color:#f92672">&lt;</span>T<span style="color:#f92672">&gt;</span> <span style="color:#f92672">{</span>
    <span style="color:#66d9ef">void</span> <span style="color:#a6e22e">accept</span><span style="color:#f92672">(</span>T t<span style="color:#f92672">);</span>
<span style="color:#f92672">}</span></code></pre></div>

<p>This interface is useful when you want to access an element and perform some
operation on it. For instance, starting with Java 8, lists have a <code>forEach</code>
method where you can pass a <code>Consumer&lt;T&gt;</code> and this function will be applied to
each element on the list.</p>

<p>So imagine that you want to print to <code>System.out</code> each element on a list. You
could do that in the following way:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java">List<span style="color:#f92672">&lt;</span>String<span style="color:#f92672">&gt;</span> users <span style="color:#f92672">=</span> Arrays<span style="color:#f92672">.</span><span style="color:#a6e22e">asList</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;java&#34;</span><span style="color:#f92672">,</span><span style="color:#e6db74">&#34;8&#34;</span><span style="color:#f92672">,</span><span style="color:#e6db74">&#34;rocks&#34;</span><span style="color:#f92672">);</span>
users<span style="color:#f92672">.</span><span style="color:#a6e22e">forEach</span><span style="color:#f92672">(</span>elem <span style="color:#f92672">-&gt;</span> System<span style="color:#f92672">.</span><span style="color:#a6e22e">out</span><span style="color:#f92672">.</span><span style="color:#a6e22e">println</span><span style="color:#f92672">(</span>elem<span style="color:#f92672">));</span></code></pre></div>

<p>The implementation of the <code>forEach</code> method is actually quite straightforward:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java"><span style="color:#66d9ef">void</span> <span style="color:#a6e22e">forEach</span><span style="color:#f92672">(</span>Consumer<span style="color:#f92672">&lt;?</span> <span style="color:#66d9ef">super</span> T<span style="color:#f92672">&gt;</span> action<span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
  <span style="color:#66d9ef">for</span> <span style="color:#f92672">(</span>T t <span style="color:#f92672">:</span> <span style="color:#66d9ef">this</span><span style="color:#f92672">)</span> <span style="color:#f92672">{</span>
    action<span style="color:#f92672">.</span><span style="color:#a6e22e">accept</span><span style="color:#f92672">(</span>t<span style="color:#f92672">);</span>
  <span style="color:#f92672">}</span>
<span style="color:#f92672">}</span></code></pre></div>

<h1 id="primitive-functional-interfaces">Primitive functional interfaces</h1>

<p>We saw a couple of generic, quite useful functional interfaces provided by the
language: <code>Predicate&lt;T&gt;</code>, <code>Function&lt;T,R&gt;</code> and <code>Consumer&lt;T&gt;</code>. This is great for most
cases where you want to use this interfaces for your own classes. But what
happens when you need something like this for primitive types: <code>int</code>, <code>double</code>
or <code>boolean</code> for instance?</p>

<p>In Java, each primitive type has a corresponding <a href="https://docs.oracle.com/javase/tutorial/java/data/numberclasses.html" target="_blank">wrapper
class</a>. So
<code>int</code> has an <code>Integer</code> class and <code>boolean</code> has a <code>Boolean</code>. Additionally, Java
can handle conversions between these types for you automatically. This concept,
known as
<a href="https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html" target="_blank">autoboxing/unboxing</a>
is what allows you to write code like this:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java">List<span style="color:#f92672">&lt;</span>Integer<span style="color:#f92672">&gt;</span> numbers <span style="color:#f92672">=</span> <span style="color:#66d9ef">new</span> ArrayList<span style="color:#f92672">&lt;&gt;();</span>
<span style="color:#66d9ef">for</span> <span style="color:#f92672">(</span><span style="color:#66d9ef">int</span> i <span style="color:#f92672">=</span> 0<span style="color:#f92672">;</span> i <span style="color:#f92672">&lt;</span> 10<span style="color:#f92672">;</span> i<span style="color:#f92672">++)</span> <span style="color:#f92672">{</span>
  numbers<span style="color:#f92672">.</span><span style="color:#a6e22e">add</span><span style="color:#f92672">(</span>i<span style="color:#f92672">);</span>
<span style="color:#f92672">}</span></code></pre></div>

<p>This lets the developer write less code because he doesn&rsquo;t need to worry about
explicitly converting one type to the other. However, there is a performance
impact involved. Is probably not a big deal if you do it occasionally here and
there but when you are doing a boxing or unboxing on every iteration in a big
list you will see a difference.</p>

<p>Going back to our functional interfaces, say you want to define a predicate that
takes an <code>int</code> and returns a <code>boolean</code> telling us whether the number is odd or
not. You can not define a <code>Predicate&lt;int&gt;</code> because <code>int</code> is not a class but you
could do something like this:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java">Predicate<span style="color:#f92672">&lt;</span>Integer<span style="color:#f92672">&gt;</span> isOdd <span style="color:#f92672">=</span> i <span style="color:#f92672">-&gt;</span> i <span style="color:#f92672">%</span> 2 <span style="color:#f92672">==</span> 1<span style="color:#f92672">;</span>
isOdd<span style="color:#f92672">.</span><span style="color:#a6e22e">test</span><span style="color:#f92672">(</span>15<span style="color:#f92672">);</span></code></pre></div>

<p>What happens when you call this predicate with an <code>int</code> is that this parameter
gets autoboxed into an <code>Integer</code>. Again, this might not really be an issue if
you are not using this <code>Predicate</code> in critical areas of your application or
inside big loops.</p>

<p>If you don&rsquo;t want your parameters boxed automatically for you and want to really
use primitive types instead, Java 8 provides primitive specializations of its
functional interfaces. In our example, we could use the <code>IntPredicate</code>
interface, whose <code>accept</code> method only takes <code>int</code> parameters:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java"><span style="color:#a6e22e">@FunctionalInterface</span>
<span style="color:#66d9ef">public</span> <span style="color:#66d9ef">interface</span> <span style="color:#a6e22e">IntPredicate</span> <span style="color:#f92672">{</span>
  <span style="color:#66d9ef">boolean</span> <span style="color:#a6e22e">test</span><span style="color:#f92672">(</span><span style="color:#66d9ef">int</span> value<span style="color:#f92672">);</span>
<span style="color:#f92672">}</span></code></pre></div>

<p>Therefore, our previous example could be rewritten as:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java">IntPredicate isOdd <span style="color:#f92672">=</span> i <span style="color:#f92672">-&gt;</span> i <span style="color:#f92672">%</span> 2 <span style="color:#f92672">==</span> 1<span style="color:#f92672">;</span>
isOdd<span style="color:#f92672">.</span><span style="color:#a6e22e">test</span><span style="color:#f92672">(</span>15<span style="color:#f92672">);</span></code></pre></div>

<p>Now, the parameter to the <code>test</code> method is treated as a primitive <code>int</code> all the
way avoiding boxing and unboxing operations.</p>

<p>This primitive specializations extend to other types with similar names. So you
are going to find <code>DoublePredicate</code>, <code>IntFunction</code>, <code>LongConsumer</code> and so on.</p>

<h1 id="method-references">Method references</h1>

<p>Lambda expressions are undoubtedly a great construct to make your code more
compact. However, some times all you do in your lambda is to call an individual
method potentially passing some parameter to it. In these cases you can often
replace your lambda expression by a method reference.</p>

<p>Method references are compact ways to create lambda expressions for methods that
already have a name. For instance, in the previous section we saw an example of
the <code>forEach</code> method:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java">List<span style="color:#f92672">&lt;</span>String<span style="color:#f92672">&gt;</span> users <span style="color:#f92672">=</span> Arrays<span style="color:#f92672">.</span><span style="color:#a6e22e">asList</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;java&#34;</span><span style="color:#f92672">,</span><span style="color:#e6db74">&#34;8&#34;</span><span style="color:#f92672">,</span><span style="color:#e6db74">&#34;rocks&#34;</span><span style="color:#f92672">);</span>
users<span style="color:#f92672">.</span><span style="color:#a6e22e">forEach</span><span style="color:#f92672">(</span>elem <span style="color:#f92672">-&gt;</span> System<span style="color:#f92672">.</span><span style="color:#a6e22e">out</span><span style="color:#f92672">.</span><span style="color:#a6e22e">println</span><span style="color:#f92672">(</span>elem<span style="color:#f92672">));</span></code></pre></div>

<p>Here, our lambda expression is only calling the <code>System.out.println</code> method.
Therefore, we could rewrite it like this:</p>

<div class="highlight"><pre style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4"><code class="language-java" data-lang="java">List<span style="color:#f92672">&lt;</span>String<span style="color:#f92672">&gt;</span> users <span style="color:#f92672">=</span> Arrays<span style="color:#f92672">.</span><span style="color:#a6e22e">asList</span><span style="color:#f92672">(</span><span style="color:#e6db74">&#34;java&#34;</span><span style="color:#f92672">,</span><span style="color:#e6db74">&#34;8&#34;</span><span style="color:#f92672">,</span><span style="color:#e6db74">&#34;rocks&#34;</span><span style="color:#f92672">);</span>
users<span style="color:#f92672">.</span><span style="color:#a6e22e">forEach</span><span style="color:#f92672">(</span>System<span style="color:#f92672">.</span><span style="color:#a6e22e">out</span><span style="color:#f92672">::</span>println<span style="color:#f92672">);</span></code></pre></div>

<h1 id="conclusion">Conclusion</h1>

<p>Lambdas are one of the main additions to Java 8. And while you can still write
code the way you used to do it before (using anonymous classes) chances are that
you will start to see more and more lambdas going around other people code. So
you should at least know they exist and how they can be used effectively.</p>

<p>Functional interfaces are not a small addition to the language but the fact that
you can use a lambda expression or method reference every time you expect an
interface is a huge deal. Is not only the fact that you remove a lot of
boilerplate code but also that by doing that you are actually making your code
easier to read and maintain. Having this concept applied to a lot of the
existing language interfaces will also help a lot.</p>

<p>Take advantage of the interfaces defined for you in <code>java.util.function</code>. They
are abstractions that come up quite frequently in practice and are very powerful
given the way you can combine them. If you need to use them for primitive types
like int or double remember that you have the option to use primitive
specializations of these interfaces to avoid the performance cost of autoboxing.</p>
]]></content>
        </item>
        
    </channel>
</rss>
