Video: using Triton Container Name Service with Docker

January 17, 2017 - by Alexandra White

Triton Container Name Service (CNS) is a service that adds automatic, global DNS to your containers and VMs on Triton. Triton CNS is ideal for making applications discoverable on the internet.

If you've previously managed the process of mapping DNS names to IP numbers, you know what a hassle it can be. It's one of the reasons some servers turn into pets. And, when scaling your application up or down, you need to re-update all your DNS to IP mappings. Triton CNS knows when containers are running. DNS names are automatically updated as containers start and stop so that requests are only sent to running containers. You can learn all about how Triton CNS works by watching our introduction to Triton CNS.

Below you'll learn how to create Triton CNS-powered Docker applications and you can even watch a video of how to use Triton CNS with Docker. For more information, read about Triton CNS and Docker in our documentation.

Video: learn how to use Triton CNS with Docker

For those in need of a visual reference, this screencast will go over how to use Triton CNS with your Docker instances.

You can also read the transcript below.

Run a container with Triton CNS

Creating a new instance with Triton CNS is as simple as adding a CNS service label to docker run:

docker run -d -p 80 --label triton.cns.services= /

Let's break down this command step by step:

  • docker run creates a container.
  • -d detaches the container, which means it's running in the background. You can continue to run commands from outside of the container so you don't have to login to the container or start/stop it.
  • -p 80 tells Triton to use port 80. This declaration ensures your container will receive an external IP address that is reachable over the public internet.
  • --label triton.cns.services= tells Triton CNS to give your application a specific title, which will be used in the DNS string.
  • / is the format for a Docker Hub image that is being pulled. If you're using a different registry, it may be formatted differently.

The most important part of that command is triton.cns.services=. Use any DNS-safe name that has meaning for what the container does in your application. For example, if you were to create your personal portfolio you could use triton.cns.services=myportfolio.

Using Triton CNS with Docker Compose

Docker Compose makes it easy to start a number of Docker containers all at once. For example, the Autopilot Pattern WordPress application uses CNS for all services—Nginx, MySQL, Memcached, PHP, and others, each running in separate containers. Instead of having to use multiple docker run commands, starting the application is as easy as docker-compose up -d.

The docker-compose.yml file includes Docker labels that set the CNS service name for each of the different containers. Here's the CNS services label set for the Nginx container:

  labels:
    - triton.cns.services=nginx

That Docker Compose syntax has the same effect as setting a label with docker run as described above.

Using Triton CNS on preexisting instances

If you already have an instance up and running that you'd like to add Triton CNS power to, never fear. Run the following command:

triton instance tag set -w  triton.cns.services=</code></pre>
<p>Your container now has Triton CNS enabled and you can carry on to the next step.</p>
<h2 id='finding-your-dns-name'>Finding your DNS name</h2>
<p>To find out the important details for your Triton CNS-powered instance, use <code>docker ps</code> to list all of your Docker containers or <code>triton instances</code> to list all of your instances running on Triton.</p>
<p>Once you know your container's name, get a list of details about your instance including CNS-generated DNS names:</p>
<pre><code class="language-sh">triton instance get <container name></code></pre>
<p>Triton will tell you a lot of information about your instance. The last section, <code>dns_names</code>, lists several options:</p>
<pre><code class="language-sh">{
    "id": "a216675d-acf9-42b4-a3bf-3079f7cfc92e",
    "name": "wordpress_nginx_1",
    "type": "smartmachine",
    [...]
    "dns_names": [
        "a216675d-acf9-42b4-a3bf-3079f7cfc92e.inst.d9a01feb-be7d-6a32-b58d-ec4a2bf4ba7d.us-east-1.cns.joyent.com",
        "wordpress-nginx-1.inst.d9a01feb-be7d-6a32-b58d-ec4a2bf4ba7d.us-east-1.cns.joyent.com",
        "nginx.svc.d9a01feb-be7d-6a32-b58d-ec4a2bf4ba7d.us-east-1.cns.joyent.com",
        "a216675d-acf9-42b4-a3bf-3079f7cfc92e.inst.d9a01feb-be7d-6a32-b58d-ec4a2bf4ba7d.us-east-1.triton.zone",
        "spacewordpress-nginx-1.inst.d9a01feb-be7d-6a32-b58d-ec4a2bf4ba7d.us-east-1.triton.zone",
        "nginx.svc.d9a01feb-be7d-6a32-b58d-ec4a2bf4ba7d.us-east-1.triton.zone"
    ]
}</code></pre>
<p>Some of the DNS names point to a public network interface (ending with <code>.triton.zone</code>) and some point to a private network interface (ending with <code>.joyent.com</code>). The DNS structure for a public Triton CNS powered instance is as follows:</p>
<pre><code><service name>.svc.<account uuid>.<data center name>.triton.zone</code></pre>
<p>Each DNS name structure has a different use case:</p>
<ul>
<li>Names beginning with <code>*.svc...</code> are service names. All containers by the same user in the same data center sharing the same service tag will be part of the service name, and will be round-robin load-balanced.</li>
<li>Names beginning with <code>*.inst...</code> are instance names. Only one container by the same user in the same data center can have a given instance name. CNS automatically generates instance names using the container name and UUID.</li>
<li>Names ending with <code>*.cns.joyent.com</code> point to a private network interface for the instance or service. These names can only be used inside the Triton data center, since the IP addresses are not internet-routable.</li>
<li>Names ending with <code>*.triton.zone</code> point to public network interface for the instance or service. These names will only be provided if the container has a public IP address</li>
</ul>
<p>The CNS-powered DNS name for my WordPress Nginx instance is <code>nginx.svc.d9a01feb-be7d-6a32-b58d-ec4a2bf4ba7d.us-east-1.triton.zone</code>. No matter how many times I redeploy my WordPress application or you redeploy your Triton CNS powered application, Triton CNS will keep that DNS information the same and up-to-date.</p>
<h2 id='look-up-your-dns'>Look up your DNS</h2>
<p>It may take a while for your domain to propagate the new CNAME. You can check in on it by running <code>dig <your DNS name></code>. This will reveal the record information about your domain, including where it is pointing and its TTL i.e. time to live (the timespan for which the record will be cached).</p>
<pre><code class="language-sh">; <<>> DiG 9.8.3-P1 <<>> nginx.svc.d9a01feb-be7d-6a32-b58d-ec4a2bf4ba7d.us-east-1.triton.zone
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25534
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;nginx.svc.d9a01feb-be7d-6a32-b58d-ec4a2bf4ba7d.us-east-1.triton.zone. IN A

;; ANSWER SECTION:
nginx.svc.d9a01feb-be7d-6a32-b58d-ec4a2bf4ba7d.us-east-1.triton.zone. 29 IN A 165.225.139.145

;; Query time: 58 msec
;; SERVER: 10.32.200.16#53(10.32.200.16)
;; WHEN: Tue Jan 14 08:24:33 2017
;; MSG SIZE  rcvd: 102</code></pre>
<p>We care most of all about <code>ANSWER SECTION</code>. This tells me that my domain has 1799 seconds left before the cache expires and is pointing to the instance IP 165.225.139.145. If I were to make changes right now to the CNS service name assigned to the instance, or if I spun up new instances with the same CNS service name, it would take at least 1799 seconds to propogate.</p>
<h2 id='where-to-be-cautious-about-using-dns'>Where to be cautious about using DNS</h2>
<p>DNS isn't the perfect solution for every application. DNS client problems are surprisingly common, including clients that refuse to respect TTLs and clients that don’t recognize multiple IPs in an A record. These problems are frustrating in a web browser (though modern browsers now have advanced DNS implementations that avoid these problems), but they can lead to applications failures when they occur inside the data center between the components of an application. </p>
<p>One way around those problems is using <a href="http://containersummit.io/articles/active-vs-passive-discovery">active discovery</a> where possible. If you can't modify your app or runtime environment to ensure good DNS client behavior, then you should consider using an alternative to DNS for discovery of application components. <a href="https://www.joyent.com/containerpilot">ContainerPilot</a> automates the processes of service registration, health checking, and discovery for this purpose.</p>
<h2 id='video-transcript'>Video transcript</h2>
<p>Welcome to this tutorial for using Triton CNS with Docker. To learn more about Container Name Service, watch our introduction to Triton CNS video.</p>
<p>Triton CNS works hand-in-hand with your Docker instances on Triton. It can be added to any application, whether it’s made of a single service or many different services, and makes DNS mapping simple.</p>
<p>There are three ways to implement Triton CNS with Docker: set a tag to an existing instance with <code>triton instance tag label</code>; add a label to <code>docker run -d --label</code> at the start of a container; or add Triton CNS to the Docker Compose file within your application. Docker Compose allows you to start and scale many containers with a consistent configuration, instead of running individual <code>docker run</code> commands.</p>
<p>To get started, be sure Triton CNS is enabled with the <code>triton account</code> command. To add Triton CNS to a pre-existing Docker container, add a Triton CNS service name with <code>triton instance tag set</code> to any existing instance. You can check the DNS name by running <code>triton instance get</code> with your container’s name or ID.</p>
<p>Your container’s DNS name will contain your CNS service name, your account ID number, the data center name, and various other bits of information. You can investigate your DNS name further to see which IP address is behind it at any given moment. Check the IP address by running <code>dig</code>.</p>
<p>When you want to start a new Docker container,  you’ll be adding a label to your <code>docker run</code> command.  The CNS service name will form the DNS name which follow your service, no matter how many times you scale up or down or redeploy containers spun up from that service. If you give your Nginx container the CNS service name <code>hellonginx</code>, that means the automatically generated domain name for your application will begin with <code>hellonginx</code>.</p>
<p>When you scale up services either with multiple <code>docker run</code> commands with the same image and configuration or with <code>docker-compose scale</code>, the additional instances will carry the same CNS service name as the original service and therefore have the same DNS name.</p>
<p>Check the IP address associated with your <code>hellonginx</code> DNS name by running <code>dig</code>.</p>
<p>If you’re creating a new application, it’s simple to add Triton CNS to your Docker Compose configuration file. This is the easiest way to consistently execute numerous Docker commands.</p>
<p>Docker Compose makes it easy to start a number of Docker containers all at once. We’ve implemented it for our Autopilot Pattern WordPress application to make starting WordPress services as easy as docker-compose up. The <code>docker-compose.yml</code> file includes labels that set the CNS service name for each of the different containers.</p>
<p>That Docker Compose syntax has the same effect as setting a CNS service name with docker run.</p>
<p>Once you’ve added Triton CNS to your Docker container, you can scale up and down without thinking twice about DNS management. For a larger applications, like WordPress, the DNS names for each of your services will remain the same no matter how many instances of each service exist.</p>
<p>Run <code>triton instance get</code> on your scaled services. For <code>wordpress_nginx_1</code>, I can see that the DNS name starts with <code>nginx</code>. It’s the same for <code>wordpress_nginx_2</code> and any future scaled up instances. No matter how many times I deploy or redeploy this application, the DNS names will remain  the same.</p>
<p>If you have multiple instances, multiple A records will be reflected when you <code>dig</code> the DNS name.</p>
<p>Using Triton CNS with Docker is easy to do, be it with a new or pre-existing application. Make DNS management, scalability, and application updates hassle free.</p>                    
                    <div class="clearfix"></div>
                    <p class="share"><span>Share: </span> <a href="https://twitter.com/intent/tweet?source=Joyent%20Blog&text=Video%3A+using+Triton+Container+Name+Service+with+Docker&url=https%3A%2F%2Fwww.joyent.com%2Fblog%2Ftritoncns-and-docker&via=joyent" class="twitter"></a><a href="http://www.facebook.com/share.php?u=https%3A%2F%2Fwww.joyent.com%2Fblog%2Ftritoncns-and-docker" class="facebook"></a><a href="http://www.linkedin.com/shareArticle?url=https%3A%2F%2Fwww.joyent.com%2Fblog%2Ftritoncns-and-docker&title=Video%3A+using+Triton+Container+Name+Service+with+Docker&summary=Triton+Container+Name+Service+%28CNS%29+is+a+service+that+adds+automatic%2C+global+DNS+to+your+containers+and+VMs+on+Triton.+Triton+CNS+is+ideal+for+making+applications+discoverable+on+the+internet.+If+you%27ve+previously+managed+the+process+of+mapping+DNS+names+to+IP+numbers%2C+you+know+what+a+hassle+it+can%E2%80%A6" class="linkedin"></a><a href="mailto:?subject=Video: using Triton Container Name Service with Docker&body=Learn how to add Triton CNS, a free and automated DNS solution which offers consistent and predictable addresses for changing infrastructure, to your Docker instances on Triton.%0D%0A%0D%0Ahttps://www.joyent.com/blog/tritoncns-and-docker" class="mail"></a></p>
                                                    <div class="clearfix"></div>
                </div>
        </div>
        <div class="col-sm-4">
            <div class="sidebar first gartner">
    <img src="/assets/img/node-support/cta-logo.181005.svg">
    <div class="content">
        <p class="logo-text">Triton</p>
        <p class="header">Node.js<sup>®</sup> Enterprise Support</p>
        <p>New comprehensive plans available</p>
        <a href="/node-js/support" class="getstarted">Learn More</a>
    </div>
</div>
            <div class="sidebar second hidden-xs">
                <ul class="social clearfix">
    <li><a href="http://www.linkedin.com/company/joyent" class="linkedin" target="_blank"></a></li>
    <li><a href="https://www.facebook.com/joyentcloud" class="facebook" target="_blank"></a></li>
    <li><a href="http://twitter.com/joyent" class="twitter" target="_blank"></a></li>
    <li><a href="https://www.instagram.com/joyenttriton/" class="instagram" target="_blank"></a></li>
    <li><a href="/blog/feed" class="rss"></a></li>
</ul>
                                                <h4>More From CNS</h4>
                <ul class="events">
                                                      <li><a href="https://www.joyent.com/blog/triton-cns-and-vanity-domains">Using custom domains with Triton Container Name Service</a></li>
                                    <li><a href="https://www.joyent.com/blog/video-introducing-tritoncns">Video: introducing Triton CNS</a></li>
                                    <li><a href="https://www.joyent.com/blog/using-triton-cns">Using Triton Container Name Service with Docker and vanity domain names</a></li>
                                    <li><a href="https://www.joyent.com/blog/introducing-triton-container-name-service">Introducing Triton Container Name Service</a></li>
                                    <li><a href="https://www.joyent.com/blog/docker-nodejs-nginx-nosql-autopilot">Modern application blueprint: Node.js + Docker + NoSQL</a></li>
                                </ul>
            </div>
        </div>
    </div>
</div>
<script type="text/javascript">
  $(document).ready(function() {
    $('table').each(function() {
        $(this).addClass('table').addClass('table-bordered').addClass('table-striped');
    });
   });
</script>
</div>
    <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700|Inconsolata" rel="stylesheet">
    <script src="https://www.joyent.com/assets/js/bootstrap.min.1551196802.js"></script>    <script src="https://www.joyent.com/assets/js/combined.1505409704.js"></script>    
<footer class="footer" id="footer">
    <div class="container hidden-print">
        <div class="foot-logo row">
            <div class="col-sm-12">
                <p><img src="/assets/img/triton-logo.170828.svg" alt="Triton Logo" class="footer-logo"></p>
            </div>
            <div class="col-sm-8">
                <p class="foot-tag">Hybrid, Modern and Open, Triton is engineered to run the world’s largest cloud native applications</p>
            </div>
            <div class="col-sm-3 col-sm-offset-1">
                <p>Connect with Joyent</p>
                <ul class="social clearfix">
    <li><a href="http://www.linkedin.com/company/joyent" class="linkedin" target="_blank"></a></li>
    <li><a href="https://www.facebook.com/joyentcloud" class="facebook" target="_blank"></a></li>
    <li><a href="http://twitter.com/joyent" class="twitter" target="_blank"></a></li>
    <li><a href="https://www.instagram.com/joyenttriton/" class="instagram" target="_blank"></a></li>
    <li><a href="/blog/feed" class="rss"></a></li>
</ul>
            </div>
        </div>
    </div>
    <div class="container hidden-xs" id="footer">
        <div class="row hidden-xs hidden-print">
            <div class="col-sm-3 col-md-2 column">
                <h4>Open Source</h4>
                <ul>
                    <li><a href="http://github.com/joyent" id="foot-github">Github/joyent</a></li>
                    <li><a href="/triton/compute" id="foot-triton-open-source">Triton Compute Service</a></li>
                    <li><a href="/smartos" id="foot-smartos-open-source">SmartOS</a></li>
                    <li><a href="/triton/object-storage" id="foot-triton-object-storage">Object Storage</a></li>
                    <li><a href="http://github.com/autopilotpattern" id="foot-github-autopilotpattern">Github/autopilotpattern</a></li>
                    <li><a href="/containerpilot" id="foot-containerpilot-open-source">ContainerPilot</a></li>
                    <li><a href="/node-js" id="foot-node-open-source">Node.js</a></li>
                </ul>
            </div>
            <div class="col-sm-2 col-md-2 column">
                <h4>Documentation</h4>
                <ul>
                    <li><a href="/blog" id="foot-blog">Joyent Blog</a></li>
                    <li><a href="/getting-started" id="foot-triton-getting-started">Triton Getting Started</a></li>
                    <li><a href="https://docs.joyent.com/public-cloud" id="foot-triton-compute-docs">Triton Compute</a></li>
                    <li><a href="https://wiki.smartos.org" id="foot-triton-smartos-docs">Triton SmartOS</a></li>
                    <li><a href="https://apidocs.joyent.com/manta/index.html" id="foot-object-storage-docs">Object Storage</a></li>
                    <li><a href="/containerpilot/docs" id="foot-containerpilot-docs">ContainerPilot</a></li>
                    <li><a href="/node-js/production" id="foot-node-docs">Node.js Production Practices</a></li>
                </ul>
            </div>
            <div class="col-sm-2 col-md-2 column">
                <h4>About</h4>
                <ul>
                    <li><a href="/about/press" id="foot-press">Press Room</a></li>
                    <li><a href="/about/events" id="foot-events">Events</a></li>
                    <li><a href="/about/management" id="foot-management">Management</a></li>
                    <li><a href="/about/careers" id="foot-careers">Careers</a></li>
                    <li><a href="/contact" id="foot-contact">Contact Us</a></li>
                </ul>
            </div>
            <div class="col-sm-2 column">
                <h4>Support</h4>
                <ul>
                    <li><a href="https://help.joyent.com/home" id="footer-help-desk">Support Center</a></li>
                    <li><a href="https://status.joyent.com" id="footer-system-status">System Status</a></li>
                    <li><a href="#" id="footer-feedback" data-toggle="modal" data-target="#feedback">Site Feedback</a></li>
                    <li><a href="/search" id="footer-search">Site Search</a></li>
                </ul>
            </div>
        </div>
        <div class="row copyright">
            <div class="col-sm-6 logorow">
                <p>© 2019 Joyent, Inc. | <a href="https://www.joyent.com/about/policies">Policies</a></p>            </div>
        </div>
    </div>


<!-- Marketo Munchkin -->
<script type="text/plain" src="//munchkin.marketo.net/munchkin.js" class="optanon-category-2"></script>
<script type="text/plain" class="optanon-category-2">try { mktoMunchkin("993-RJQ-253"); } catch(err) { }</script>
<!-- End Marketo Munchkin -->
<link rel="stylesheet" href="https://www.joyent.com/assets/css/MyFontsWebfontsKit.1505409704.css"></footer>
</div>
<div class="modal" id="feedback">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                <h2>Joyent.com Feedback</h2>
            </div>
            <div class="modal-body">
              <div class="thankyou alert-success" style="display: none;">
                  <h4>Thank You</h4>
                  <p>Thank you for helping us improve joyent.com.</p>
              </div>
                <div class="alert-danger feedback" style="display: none;">
                    <h4>Forms are blocked</h4>
                    <p>It appears you have an ad or script blocker that won't allow us to load our feedback form from <code>app-sjf.marketo.com</code>. To submit feedback, you can either temporarily unblock that domain, or email <a href="mailto:marketing@joyent.com">marketing@joyent.com</a>. Email may take longer to get to the relevant people.</p>
                </div>
              <form id="mktoForm_1244"></form>
              <script>
                try {
                MktoForms2.loadForm("//app-sjf.marketo.com", "993-RJQ-253", 1244, function(form){
                    form.onSuccess(function(values, followUpUrl){
                      //get the form's jQuery element and hide it
                      form.getFormElem().hide();
                      //return false to prevent the submission handler from taking the lead to the follow up url.
                      $('.thankyou').show();
                      return false;
                    });
                  });
                } catch(err) {
                    $('.alert-danger.feedback').show();
                }
              </script>
            </div>
        </div>
    </div>
</div>
<!-- Twitter universal website tag code -->
<script type="text/plain" class="optanon-category-4">
!function(e,n,u,a){e.twq||(a=e.twq=function(){a.exe?a.exe.apply(a,arguments):
a.queue.push(arguments);},a.version='1',a.queue=[],t=n.createElement(u),
t.async=!0,t.src='//static.ads-twitter.com/uwt.js',s=n.getElementsByTagName(u)[0],
s.parentNode.insertBefore(t,s))}(window,document,'script');
// Insert Twitter Pixel ID and Standard Event data below
twq('init','nvay1');
twq('track','PageView');
</script>
<!-- End Twitter universal website tag code -->
</body>
</html>