One place for hosting & domains

      How To Deploy and Manage Your DNS using DNSControl on Ubuntu 18.04


      The author selected the Electronic Frontier Foundation Inc to receive a donation as part of the Write for DOnations program.

      Introduction

      DNSControl is an infrastructure-as-code tool that allows you to deploy and manage your DNS zones using standard software development principles, including version control, testing, and automated deployment. DNSControl was created by Stack Exchange and is written in Go.

      Using DNSControl eliminates many of the pitfalls of manual DNS management, as zone files are stored in a programmable format. This allows you to deploy zones to multiple DNS providers simultaneously, identify syntax errors, and push out your DNS configuration automatically, reducing the risk of human error. Another common usage of DNSControl is to quickly migrate your DNS to a different provider; for example, in the event of a DDoS attack or system outage.

      In this tutorial, you’ll install and configure DNSControl, create a basic DNS configuration, and begin deploying DNS records to a live provider. As part of this tutorial, we will use DigitalOcean as the example DNS provider. If you wish to use a different provider, the setup is very similar. When you’re finished, you’ll be able to manage and test your DNS configuration in a safe, offline environment, and then automatically deploy it to production.

      Prerequisites

      Before you begin this guide you’ll need the following:

      • One Ubuntu 18.04 server set up by following the Initial Server Setup with Ubuntu 18.04, including a sudo non-root user and enabled firewall to block non-essential ports. your-server-ip refers to the IP address of the server where you’re hosting your website or domain.
      • A fully registered domain name with DNS hosted by a supported provider. This tutorial will use example.com throughout and DigitalOcean as the service provider.
      • A DigitalOcean API key (Personal Access Token) with read and write permissions. To create one, visit How to Create a Personal Access Token.

      Once you have these ready, log in to your server as your non-root user to begin.

      Step 1 — Installing DNSControl

      DNSControl is written in Go, so you’ll start this step by installing Go to your server and setting your GOPATH.

      Go is available within Ubuntu’s default software repositories, making it possible to install using conventional package management tools.

      Begin by updating the local package index to reflect any new upstream changes:

      Then, install the golang-go package:

      • sudo apt install golang-go

      After confirming the installation, apt will download and install Go and all of its required dependencies.

      Next, you'll configure the required path environment variables for Go. If you would like to know more about this, you can read this tutorial on Understanding the GOPATH. Start by editing the ~/.profile file:

      Add the following lines to the very end of your file:

      ~/.profile

      ...
      export GOPATH="$HOME/go"
      export PATH="$PATH:$GOPATH/bin"
      

      Once you have added these lines to the bottom of the file, save and close it. Then reload your profile by either logging out and back in, or sourcing the file again:

      Now you've installed and configured Go, you can install DNSControl.

      The go get command can be used to fetch a copy of the code, automatically compile it and install it into your Go directory:

      • go get github.com/StackExchange/dnscontrol

      Once this is complete, you can check the installed version to make sure that everything is working:

      Your output will look similar to the following:

      Output

      dnscontrol 0.2.8-dev

      If you see a dnscontrol: command not found error, double-check your Go path setup.

      Now that you've installed DNSControl, you can create a configuration directory and connect DNSControl to your DNS provider in order to allow it to make changes to your DNS records.

      Step 2 — Configuring DNSControl

      In this step, you'll create the required configuration directories for DNSControl, and connect it to your DNS provider so that it can begin to make live changes to your DNS records.

      Firstly, create a new directory in which you can store your DNSControl configuration, and then move into it:

      • mkdir ~/dnscontrol
      • cd ~/dnscontrol

      Note: This tutorial will focus on the initial set up of DNSControl; however for production use it is recommended to store your DNSControl configuration in a version control system (VCS) such as Git. The advantages of this include full version control, integration with CI/CD for testing, seamlessly rolling-back deployments, and so on.

      If you plan to use DNSControl to write BIND zone files, you should also create the zones directory:

      BIND zone files are a raw, standardized method for storing DNS zones/records in plain text format. They were originally used for the BIND DNS server software, but are now widely adopted as the standard method for storing DNS zones. BIND zone files produced by DNSControl are useful if you want to import them to a custom or self-hosted DNS server, or for auditing purposes.

      However, if you just want to use DNSControl to push DNS changes to a managed provider, the zones directory will not be needed.

      Next, you need to configure the creds.json file, which is what will allow DNSControl to authenticate to your DNS provider and make changes. The format of creds.json differs slightly depending on the DNS provider that you are using. Please see the Service Providers list in the official DNSControl documentation to find the configuration for your own provider.

      Create the file creds.json in the ~/dnscontrol directory:

      • cd ~/dnscontrol
      • nano creds.json

      Add the sample creds.json configuration for your DNS provider to the file. If you're using DigitalOcean as your DNS provider, you can use the following:

      ~/dnscontrol/creds.json

      {
        "digitalocean": {
          "token": "your-digitalocean-oauth-token"
        }
      }
      

      This file tells DNSControl to which DNS providers you want it to connect.

      You'll need to provide some form of authentication for your DNS provider. This is usually an API key or OAuth token, but some providers require extra information, as documented in the Service Providers list in the official DNSControl documentation.

      Warning: This token will grant access to your DNS provider account, so you should protect it as you would a password. Also, ensure that if you're using a version control system, either the file containing the token is excluded (e.g. using .gitignore), or is securely encrypted in some way.

      If you're using DigitalOcean as your DNS provider, you can use the required OAuth token in your DigitalOcean account settings that you generated as part of the prerequisites.

      If you have multiple different DNS providers—for example, for multiple domain names, or delegated DNS zones—you can define these all in the same creds.json file.

      You've set up the initial DNSControl configuration directories, and configured creds.json to allow DNSControl to authenticate to your DNS provider and make changes. Next you'll create the configuration for your DNS zones.

      Step 3 — Creating a DNS Configuration File

      In this step, you'll create an initial DNS configuration file, which will contain the DNS records for your domain name or delegated DNS zone.

      dnsconfig.js is the main DNS configuration file for DNSControl. In this file, DNS zones and their corresponding records are defined using JavaScript syntax. This is known as a DSL, or Domain Specific Language. The JavaScript DSL page in the official DNSControl documentation provides further details.

      To begin, create the DNS configuration file in the ~/dnscontrol directory:

      • cd ~/dnscontrol
      • nano dnsconfig.js

      Then, add the following sample configuration to the file:

      ~/dnscontrol/dnsconfig.js

      // Providers:
      
      var REG_NONE = NewRegistrar('none', 'NONE');
      var DNS_DIGITALOCEAN = NewDnsProvider('digitalocean', 'DIGITALOCEAN');
      
      // Domains:
      
      D('example.com', REG_NONE, DnsProvider(DNS_DIGITALOCEAN),
          A('@', 'your-server-ip')
      );
      

      This sample file defines a domain name or DNS zone at a particular provider, which in this case is example.com hosted by DigitalOcean. An example A record is also defined for the zone root (@), pointing to the IP of the server that you're hosting your domain/website on.

      There are three main functions that make up a basic DNSControl configuration file:

      • NewRegistrar(name, type, metadata): defines the domain registrar for your domain name. DNSControl can use this to make required changes, such as modifying the authoritative nameservers. If you only want to use DNSControl to manage your DNS zones, this can generally be left as NONE.

      • NewDnsProvider(name, type, metadata): defines a DNS service provider for your domain name or delegated zone. This is where DNSControl will push the DNS changes that you make.

      • D(name, registrar, modifiers): defines a domain name or delegated DNS zone for DNSControl to manage, as well as the DNS records present in the zone.

      You should configure NewRegistrar(), NewDnsProvider(), and D() accordingly using the Service Providers list in the official DNSControl documentation.

      If you're using DigitalOcean as your DNS provider, and only need to be able to make DNS changes (rather than authoritative nameservers as well), the sample in the preceding code block is already correct.

      Once complete, save and close the file.

      In this step, you set up a DNS configuration file for DNSControl, with the relevant providers defined. Next, you'll populate the file with some useful DNS records.

      Step 4 — Populating Your DNS Configuration File

      Next, you can populate the DNS configuration file with useful DNS records for your website or service, using the DNSControl syntax.

      Unlike traditional BIND zone files, where DNS records are written in a raw, line-by-line format, DNS records within DNSControl are defined as a function parameter (domain modifier) to the D() function, as shown briefly in Step 3.

      A domain modifier exists for each of the standard DNS record types, including A, AAAA, MX, TXT, NS, CAA, and so on. A full list of available record types is available in the Domain Modifiers section of the DNSControl documentation.

      Modifiers for individual records are also available (record modifiers). Currently these are primarily used for setting the TTL (time to live) of individual records. A full list of available record modifiers is available in the Record Modifiers section of the DNSControl documentation. Record modifiers are optional, and in most basic use cases can be left out.

      The syntax for setting DNS records varies slightly for each record type. Following are some examples for the most common record types:

      • A records:

        • Purpose: To point to an IPv4 address.
        • Syntax: A('name', 'address', optional record modifiers)
        • Example: A('@', 'your-server-ip', TTL(30))
      • AAAA records:

        • Purpose: To point to an IPv6 address.
        • Syntax: AAAA('name', 'address', optional record modifiers)
        • Example: AAAA('@', '2001:db8::1') (record modifier left out, so default TTL will be used)
      • CNAME records:

        • Purpose: To make your domain/subdomain an alias of another.
        • Syntax: CNAME('name', 'target', optional record modifiers)
        • Example: CNAME('subdomain1', 'example.org.') (note that a trailing . must be included if there are any dots in the value)
      • MX records:

        • Purpose: To direct email to specific servers/addresses.
        • Syntax: MX('name', 'priority', 'target', optional record modifiers)
        • Example: MX('@', 10, 'mail.example.net') (note that a trailing . must be included if there are any dots in the value)
      • TXT records:

        • Purpose: To add arbitrary plain text, often used for configurations without their own dedicated record type.
        • Syntax: TXT('name', 'content', optional record modifiers)
        • Example: TXT('@', 'This is a TXT record.')
      • CAA records:

        • Purpose: To restrict and report on Certificate Authorities (CAs) who can issue TLS certificates for your domain/subdomains.
        • Syntax: CAA('name', 'tag', 'value', optional record modifiers)
        • Example: CAA('@', 'issue', 'letsencrypt.org')

      In order to begin adding DNS records for your domain or delegated DNS zone, edit your DNS configuration file:

      • cd ~/dnscontrol
      • nano dnsconfig.js

      Next, you can begin populating the parameters for the existing D() function using the syntax described in the previous list, as well as the Domain Modifiers section of the official DNSControl documentation. A comma (,) must be used in-between each record.

      For reference, the code block here contains a full sample configuration for a basic, initial DNS setup:

      ~/dnscontrol/dnsconfig.js

      ...
      
      D('example.com', REG_NONE, DnsProvider(DNS_DIGITALOCEAN),
          A('@', 'your-server-ip'),
          A('www', 'your-server-ip'),
          A('mail', 'your-server-ip'),
          AAAA('@', '2001:db8::1'),
          AAAA('www', '2001:db8::1'),
          AAAA('mail', '2001:db8::1'),
          MX('@', 10, 'mail.example.com.'),
          TXT('@', 'v=spf1 -all'),
          TXT('_dmarc', 'v=DMARC1; p=reject; rua=mailto:abuse@example.com; aspf=s; adkim=s;')
      );
      

      Once you have completed your initial DNS configuration, save and close the file.

      In this step, you set up the initial DNS configuration file, containing your DNS records. Next, you will test the configuration and deploy it.

      Step 5 — Testing and Deploying Your DNS Configuration

      In this step, you will run a local syntax check on your DNS configuration, and then deploy the changes to the live DNS server/provider.

      Firstly, move into your dnscontrol directory:

      Next, use the preview function of DNSControl to check the syntax of your file, and output what changes it will make (without actually making them):

      If the syntax of your DNS configuration file is correct, DNSControl will output an overview of the changes that it will make. This should look similar to the following:

      Output

      ******************** Domain: example.com ----- Getting nameservers from: digitalocean ----- DNS Provider: digitalocean...8 corrections #1: CREATE A example.com your-server-ip ttl=300 #2: CREATE A www.example.com your-server-ip ttl=300 #3: CREATE A mail.example.com your-server-ip ttl=300 #4: CREATE AAAA example.com 2001:db8::1 ttl=300 #5: CREATE TXT _dmarc.example.com "v=DMARC1; p=reject; rua=mailto:abuse@example.com; aspf=s; adkim=s;" ttl=300 #6: CREATE AAAA www.example.com 2001:db8::1 ttl=300 #7: CREATE AAAA mail.example.com 2001:db8::1 ttl=300 #8: CREATE MX example.com 10 mail.example.com. ttl=300 ----- Registrar: none...0 corrections Done. 8 corrections.

      If you see an error warning in your output, DNSControl will provide details on what and where the error is located within your file.

      Warning: The next command will make live changes to your DNS records and possibly other settings. Please ensure that you are prepared for this, including taking a backup of your existing DNS configuration, as well as ensuring that you have the means to roll back if needed.

      Finally, you can push out the changes to your live DNS provider:

      You'll see an output similar to the following:

      Output

      ******************** Domain: example.com ----- Getting nameservers from: digitalocean ----- DNS Provider: digitalocean...8 corrections #1: CREATE TXT _dmarc.example.com "v=DMARC1; p=reject; rua=mailto:abuse@example.com; aspf=s; adkim=s;" ttl=300 SUCCESS! #2: CREATE A example.com your-server-ip ttl=300 SUCCESS! #3: CREATE AAAA example.com 2001:db8::1 ttl=300 SUCCESS! #4: CREATE AAAA www.example.com 2001:db8::1 ttl=300 SUCCESS! #5: CREATE AAAA mail.example.com 2001:db8::1 ttl=300 SUCCESS! #6: CREATE A www.example.com your-server-ip ttl=300 SUCCESS! #7: CREATE A mail.example.com your-server-ip ttl=300 SUCCESS! #8: CREATE MX example.com 10 mail.example.com. ttl=300 SUCCESS! ----- Registrar: none...0 corrections Done. 8 corrections.

      Now, if you check the DNS settings for your domain in the DigitalOcean control panel, you'll see the changes.

      A screenshot of the DigitalOcean control panel, showing some of the DNS changes that DNSControl has made.

      You can also check the record creation by running a DNS query for your domain/delegated zone. You'll see that the records have been updated accordingly:

      You'll see output showing the IP address and relevant DNS record from your zone that was deployed using DNSControl. DNS records can take some time to propagate, so you may need to wait and run this command again.

      In this final step, you ran a local syntax check of the DNS configuration file, then deployed it to your live DNS provider, and tested that the changes were made successfully.

      Conclusion

      In this article you set up DNSControl and deployed a DNS configuration to a live provider. Now you can manage and test your DNS configuration changes in a safe, offline environment before deploying them to production.

      If you wish to explore this subject further, DNSControl is designed to be integrated into your CI/CD pipeline, allowing you to run in-depth tests and have more control over your deployment to production. You could also look into integrating DNSControl into your infrastructure build/deployment processes, allowing you to deploy servers and add them to DNS completely automatically.

      If you wish to go further with DNSControl, the following DigitalOcean articles provide some interesting next steps to help integrate DNSControl into your change management and infrastructure deployment workflows:



      Source link

      How To Automatically Manage DNS Records From DigitalOcean Kubernetes Using ExternalDNS


      The author selected the Free and Open Source Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      When deploying web apps to Kubernetes, you usually use Services and Ingresses to expose apps beyond the cluster at your desired domain. This involves manually configuring not only the Ingress, but also the DNS records at your provider, which can be a time-consuming and error-prone process. This can become an obstacle as your application grows in complexity; when the external IP changes, it is necessary to update the DNS records accordingly.

      To overcome this, the Kubernetes sig-network team created ExternalDNS for the purpose of automatically managing external DNS records from within a Kubernetes cluster. Once deployed, ExternalDNS works in the background and requires almost no additional configuration. Whenever a Service or Ingress is created or changed, ExternalDNS will update the records right away.

      In this tutorial, you will install ExternalDNS to your DigitalOcean Kubernetes cluster via Helm and configure it to use DigitalOcean as your DNS provider. Then, you will deploy a sample web app with an Ingress and use ExternalDNS to point it to your domain name. In the end, you will have an automated DNS record managing system in place for both Services and Ingresses.

      Prerequisites

      • A DigitalOcean Kubernetes cluster with your connection configured as the kubectl default. Instructions on how to configure kubectl are shown under the Connect to your Cluster step when you create your cluster. To create a Kubernetes cluster on DigitalOcean, see Kubernetes Quickstart.

      • The Helm package manager installed on your local machine, and Tiller installed on your cluster. To do this, complete Steps 1 and 2 of the How To Install Software on Kubernetes Clusters with the Helm Package Manager tutorial.

      • The Nginx Ingress Controller installed on your cluster using Helm in order to use ExternalDNS with Ingress Resources. To do this, follow How to Set Up an Nginx Ingress on DigitalOcean Kubernetes Using Helm. You’ll need to set the publishService property to true as per the instructions in Step 2.

      • A DigitalOcean API key (Personal Access Token) with read and write permissions. To create one, visit How to Create a Personal Access Token.

      • A fully registered domain name. This tutorial will use echo.example.com throughout. You can purchase a domain name on Namecheap, get one for free on Freenom, or use the domain registrar of your choice.

      Step 1 — Installing ExternalDNS Using Helm

      In this section, you will install ExternalDNS to your cluster using Helm and configure it to work with the DigitalOcean DNS service.

      In order to override some of the default settings of the ExternalDNS Helm chart, you’ll need to create a values.yaml file that you’ll pass in to Helm during installation. On the machine you use to access your cluster in the prerequisites, create the file by running:

      • nano externaldns-values.yaml

      Add the following lines:

      externaldns-values.yaml

      rbac:
        create: true
      
      provider: digitalocean
      
      digitalocean:
        apiToken: your_api_token
      
      interval: "1m"
      
      policy: sync # or upsert-only
      
      # domainFilters: [ 'example.com' ]
      

      In the first block, you enable RBAC (Role Based Access Control) manifest creation, which must be enabled on RBAC-enabled Kubernetes clusters like DigitalOcean. In the next line, you set the DNS service provider to DigitalOcean. Then, in the next block, you’ll add your DigitalOcean API token by replacing your_api_token.

      The next line sets the interval at which ExternalDNS will poll for changes to Ingresses and Services. You can set it to a lower value to propogate changes to your DNS faster.

      The policy setting determines whether ExternalDNS will only insert DNS records (upsert-only) or create and delete them as needed (sync). Fortunately, since version 0.3, ExternalDNS supports the concept of ownership by creating accompanying TXT records in which it stores information about the domains it creates, limiting its scope of action to only those it created.

      The domainFilters parameter is used for limiting the domains that ExternalDNS can manage. You can uncomment it and enter your domains in the form of a string array, but this isn’t necessary.

      When you’ve finished editing, save and close the file.

      Now, install ExternalDNS to your cluster by running the following command:

      • helm install stable/external-dns --name external-dns -f externaldns-values.yaml

      The output will look similar to the following:

      Output

      NAME: external-dns LAST DEPLOYED: ... NAMESPACE: default STATUS: DEPLOYED RESOURCES: ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE external-dns-69c545655f-xqjjf 0/1 ContainerCreating 0 0s ==> v1/Secret NAME TYPE DATA AGE external-dns Opaque 1 0s ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE external-dns ClusterIP 10.245.47.69 <none> 7979/TCP 0s ==> v1/ServiceAccount NAME SECRETS AGE external-dns 1 0s ==> v1beta1/ClusterRole NAME AGE external-dns 0s ==> v1beta1/ClusterRoleBinding NAME AGE external-dns 0s ==> v1beta1/Deployment NAME READY UP-TO-DATE AVAILABLE AGE external-dns 0/1 1 0 0s NOTES: ...

      You can verify the ExternalDNS creation by running the following command:

      • kubectl --namespace=default get pods -l "app=external-dns,release=external-dns" -w

      Output

      NAME READY STATUS RESTARTS AGE external-dns-69bfcf8ccb-7j4hp 0/1 ContainerCreating 0 3s

      You’ve installed ExternalDNS to your Kubernetes cluster. Next, you will deploy an example web app, expose it using an Nginx Ingress, and let ExternalDNS automatically point your domain name to the appropriate Load Balancer.

      Step 2 — Deploying and Exposing an Example Web App

      In this section, you will deploy a dummy web app to your cluster in order to expose it using your Ingress. Then you’ll set up ExternalDNS to automatically configure DNS records for you. In the end, you will have DNS records for your domain pointed to the Load Balancer of the Ingress.

      The dummy web app you’ll deploy is http-echo by Hashicorp. It is an in-memory web server that echoes back the message you give it. You’ll store its Kubernetes manifests in a file named echo.yaml. Create it and open it for editing:

      Add the following lines to your file:

      echo.yaml

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
        name: echo-ingress
      spec:
        rules:
        - host: echo.example.com
          http:
            paths:
            - backend:
                serviceName: echo
                servicePort: 80
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: echo
      spec:
        ports:
        - port: 80
          targetPort: 5678
        selector:
          app: echo
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: echo
      spec:
        selector:
          matchLabels:
            app: echo
        replicas: 3
        template:
          metadata:
            labels:
              app: echo
          spec:
            containers:
            - name: echo
              image: hashicorp/http-echo
              args:
              - "-text=Echo!"
              ports:
              - containerPort: 5678
      

      In this configuration, you define a Deployment, an Ingress, and a Service. The Deployment consists of three replicas of the http-echo app, with a custom message (Echo!) passed in. The Service is defined to allow access to the Pods in the Deployment via port 80. The Ingress is configured to expose the Service at your domain.

      Replace echo.example.com with your domain, then save and close the file.

      Now there is no need for you to configure the DNS records for the domain manually. ExternalDNS will do so automatically, as soon as you apply the configuration to Kubernetes.

      To apply the configuration, run the following command:

      • kubectl create -f echo.yaml

      You'll see the following output:

      Output

      ingress.extensions/echo-ingress created service/echo created deployment.apps/echo created

      You'll need to wait a short amount of time for ExternalDNS to notice the changes and create the appropriate DNS records. The interval setting in the Helm chart governs the length of time you'll need to wait for your DNS record creation. In values.yaml, the interval length is set to 1 minute by default.

      You can visit your DigitalOcean Control Panel to see an A and TXT record.

      Control Panel - Generated DNS Records

      Once the specified time interval has passed, access your domain using curl:

      You'll see the following output:

      Output

      Echo!

      This message confirms you've configured ExternalDNS and created the necessary DNS records to point to the Load Balancer of the Nginx Ingress Controller. If you see an error message, give it some time. Or, you can try accessing your domain from your browser where you'll see Echo!.

      You've tested ExternalDNS by deploying an example app with an Ingress. You can also observe the new DNS records in your DigitalOcean Control Panel. In the next step, you'll expose the Service at your domain name.

      Step 3 — (Optional) Exposing the App Using a Service

      In this optional section, you'll use Services with ExternalDNS instead of Ingresses. ExternalDNS allows you to make different Kubernetes resources available to DNS servers. Using Services is a similar process to Ingresses with the configuration modified for this alternate resource.

      Note: Following this step will delete the DNS records you've just created.

      Since you'll be customizing the Service contained in echo.yaml, you won't need the echo-ingress anymore. Delete it using the following command:

      • kubectl delete ing echo-ingress

      The output will be:

      Output

      ingress.extensions/echo-ingress deleted

      ExternalDNS will delete the existing DNS records it created in the previous step. In the remainder of the step, you can use the same domain you have used before.

      Next, open the echo.yaml file for editing:

      Replace the file contents with the following lines:

      echo.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: echo
        annotations:
          external-dns.alpha.kubernetes.io/hostname: echo.example.com
      spec:
        type: LoadBalancer
        ports:
        - port: 80
          targetPort: 5678
        selector:
          app: echo
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: echo
      spec:
        selector:
          matchLabels:
            app: echo
        replicas: 3
        template:
          metadata:
            labels:
              app: echo
          spec:
            containers:
            - name: echo
              image: hashicorp/http-echo
              args:
              - "-text=Echo!"
              ports:
              - containerPort: 5678
      

      You've removed Ingress from the file for the previous set up and changed the Service type to LoadBalancer. Furthermore, you've added an annotation specifying the domain name for ExternalDNS.

      Apply the changes to your cluster by running the following command:

      • kubectl apply -f echo.yaml

      The output will be:

      Output

      service/echo configured deployment.apps/echo configured

      You can watch the Service's Load Balancer become available by running:

      You will see output similar to the following:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE echo LoadBalancer 10.245.81.235 <pending> 80:31814/TCP 8s ...

      As in the previous step, you'll need to wait some time for the DNS records to be created and propagated. Once that is done, curl the domain you specified:

      The output will be the same as the previous step:

      Output

      Echo!

      If you get an error, wait a little longer, or you can try a different domain. Since DNS records are cached on client systems, it may take a long time for the changes to actually propagate.

      In this step, you created a Service (of type LoadBalancer) and pointed it to your domain name using ExternalDNS.

      Conclusion

      ExternalDNS works silently in the background and provides a friction-free experience. Your Kubernetes cluster has just become the central source of truth regarding the domains. You won't have to manually update DNS records anymore.

      The real power of ExternalDNS will become apparent when creating testing environments from a Continuous Delivery system. If you want to set up one such system on your Kubernetes cluster, visit How To Set Up a CD Pipeline with Spinnaker on DigitalOcean Kubernetes.



      Source link

      Uma Introdução ao Serviço de DNS do Kubernetes


      Introdução

      O Domain Name System ou Sistema de Nomes de Domínio (DNS) é um sistema para associar vários tipos de informação – como endereços IP – com nomes fáceis de lembrar. Por padrão, a maioria dos clusters de Kubernetes configura automaticamente um serviço de DNS interno para fornecer um mecanismo leve para a descoberta de serviços. O serviço de descoberta integrado torna fácil para as aplicações encontrar e se comunicar umas com as outras nos clusters de Kubernetes, mesmo quando os pods e serviços estão sendo criados, excluídos, e deslocados entre os nodes.

      Os detalhes de implementação do serviço de DNS do Kubernetes mudaram nas versões recentes do Kubernetes. Neste artigo vamos dar uma olhada nas versões kube-dns e CoreDNS do serviço de DNS do Kubernetes. Vamos rever como eles operam e os registros DNS que o Kubernetes gera.

      Para obter uma compreensão mais completa do DNS antes de começar, por favor leia Uma Introdução à Terminologia, Componentes e Conceitos do DNS. Para qualquer tópico do Kubernetes com o qual você não esteja familiarizado, leia Uma Introdução ao Kubernetes.

      O que o serviço DNS do Kubernetes fornece?

      Antes da versão 1.11 do Kubernetes, o serviço de DNS do Kubernetes era baseado no kube-dns. A versão 1.11 introduziu o CoreDNS para resolver algumas preocupações de segurança e estabilidade com o kube-dns.

      Independentemente do software que manipula os registros de DNS reais, as duas implementações funcionam de maneira semelhante:

      • Um serviço chamado kube-dns e um ou mais pods são criados.

      • O serviço kube-dns escuta por eventos service e endpoint da API do Kubernetes e atualiza seus registros DNS quando necessário. Esses eventos são disparados quando você cria, atualiza ou exclui serviços do Kubernetes e seus pods associados.

      • O kubelet define a opção nameserver do /etc/resolv.conf de cada novo pod para o IP do cluster do serviço kube-dns, com opções apropriadas de search para permitir que nomes de host mais curtos sejam usados:

      resolv.conf

      
      nameserver 10.32.0.10
      search namespace.svc.cluster.local svc.cluster.local cluster.local
      options ndots:5
      
      • Aplicações executando em containers podem então resolver nomes de hosts como example-service.namespace nos endereços IP corretos do cluster.

      Exemplo de registros DNS do Kubernetes

      O registro de DNS A completo de um serviço do Kubernetes será semelhante ao seguinte exemplo:

      service.namespace.svc.cluster.local
      

      Um pod teria um registro nesse formato, refletindo o endereço IP real do pod:

      10.32.0.125.namespace.pod.cluster.local
      

      Além disso, os registros SRV são criados para as portas nomeadas do serviço Kubernetes:

      _port-name._protocol.service.namespace.svc.cluster.local
      

      O resultado de tudo isso é um mecanismo de descoberta de serviço interno baseado em DNS, onde seu aplicativo ou microsserviço pode referenciar um nome de host simples e consistente para acessar outros serviços ou pods no cluster.

      Pesquisar Domínios e Resolver Nomes de Host Mais Curtos

      Por causa dos sufixos de busca de domínio listados no arquivo resolv.conf, muitas vezes você não precisará usar o nome do host completo para entrar em contato com outro serviço. Se você estiver referenciando um serviço no mesmo namespace, poderá usar apenas o nome do serviço para contatá-lo:

      outro-service
      

      Se o serviço estiver em um namespace diferente, adicione-o à consulta:

      outro-service.outro-namespace
      

      Se você estiver referenciando um pod, precisará usar pelo menos o seguinte:

      pod-ip.outro-namespace.pod
      

      Como vimos no arquivo resolv.conf padrão, apenas os sufixos .svc são automaticamente completados, então certifique-se de que você especificou tudo até o .pod.

      Agora que sabemos os usos práticos do serviço DNS do Kubernetes, vamos analisar alguns detalhes sobre as duas diferentes implementações.

      Detalhes de implementação do DNS do Kubernetes

      Como observado na seção anterior, a versão 1.11 do Kubernetes introduziu um novo software para lidar com o serviço kube-dns. A motivação para a mudança era aumentar o desempenho e a segurança do serviço. Vamos dar uma olhada na implementação original do kube-dns primeiro.

      kube-dns

      O serviço kube-dns antes do Kubernetes 1.11 é composto de três containers executando em um pod kube-dns no namespace kube-system. Os três containers são:

      • kube-dns: um container que executa o SkyDNS, que realiza a resolução de consultas DNS

      • dnsmasq: um resolvedor e cache de DNS leve e popular que armazena em cache as respostas do SkyDNS

      • sidecar: um container sidecar que lida com relatórios de métricas e responde a verificações de integridade do serviço

      As vulnerabilidades de segurança no Dnsmasq, e os problemas com desempenho ao escalar com o SkyDNS levaram à criação de um sistema substituto, o CoreDNS.

      CoreDNS

      A partir do Kubernetes 1.11, um novo serviço de DNS do Kubernetes, o CoreDNS foi promovido à Disponibilidade Geral. Isso significa que ele está pronto para uso em produção e será o serviço DNS de cluster padrão para muitas ferramentas de instalação e provedores gerenciados do Kubernetes.

      O CoreDNS é um processo único, escrito em Go, que cobre todas as funcionalidades do sistema anterior. Um único container resolve e armazena em cache as consultas DNS, responde a verificações de integridade e fornece métricas.

      Além de abordar problemas relacionados a desempenho e segurança, o CoreDNS corrige alguns outros pequenos bugs e adiciona alguns novos recursos:

      • Alguns problemas com incompatibilidades entre o uso de stubDomains e serviços externos foram corrigidos

      • O CoreDNS pode melhorar o balanceamento de carga round-robin baseado em DNS ao randomizar a ordem na qual ele retorna determinados registros

      • Um recurso chamado autopath pode melhorar os tempos de resposta do DNS ao resolver nomes de host externos, sendo mais inteligente ao iterar através de cada um dos sufixos de domínio de busca listados em resolv.conf

      • Com o kube-dns 10.32.0.125.namespace.pod.cluster.local sempre resolveria para 10.32.0.125, mesmo que o pod não existisse realmente. O CoreDNS tem um modo “pods verificados” que somente resolverá com sucesso se o pod existir com o IP correto e no namespace correto.

      Para mais informações sobre o CoreDNS e com ele se diferencia do kube-dns, você pode ler o anúncio do Kubernetes CoreDNS GA.

      Opções de Configuração Adicionais

      Os operadores do Kubernetes geralmente desejam personalizar como seus pods e containers resolvem determinados domínios personalizados, ou precisam ajustar os servidores de nomes upstream ou os sufixos de domínio de busca configurados em resolv.conf. Você pode fazer isso com a opção dnsConfig na especificação do seu pod:

      example_pod.yaml

      
      apiVersion: v1
      kind: Pod
      metadata:
        namespace: example
        name: custom-dns
      spec:
        containers:
          - name: example
            image: nginx
        dnsPolicy: "None"
        dnsConfig:
          nameservers:
            - 203.0.113.44
          searches:
            - custom.dns.local
      

      A atualização dessa configuração irá reescrever o resolv.conf do pod para ativar as alterações. A configuração mapeia diretamente para as opções padrão do resolv.conf, assim a configuração acima criaria um arquivo com as linhas nameserver 203.0.113.44 e search custom.dns.local

      Conclusão

      Neste artigo, cobrimos as noções básicas sobre o que o serviço de DNS do Kubernetes fornece aos desenvolvedores, mostramos alguns exemplos de registros DNS para serviços e pods, discutimos como o sistema é implementado em diferentes versões do Kubernetes, e destacamos algumas opções de configuração adicionais disponíveis para personalizar como seus pods resolvem as consultas DNS.

      Para mais informações sobre o serviço e DNS do Kubernetes, por favor, consulte a documentação oficial do DNS do Kubernetes para Serviços e Pods.

      Por Brian Boucheron



      Source link