<p>I have a Kubernetes v1.4 cluster running in AWS with auto-scaling nodes.
I also have a Mongo Replica Set cluster with SSL-only connections (FQDN common-name) and public DNS entries:</p>

<ul>
<li>node1.mongo.example.com -> 1.1.1.1</li>
<li>node2.mongo.example.com -> 1.1.1.2</li>
<li>node3.mongo.example.com -> 1.1.1.3</li>
</ul>

<p>The Kubernetes nodes are part of a security group that allows access to the mongo cluster, but only via their private IPs.</p>

<p>Is there a way of creating A records in the Kubernetes DNS with the private IPs when the public FQDN is queried?</p>

<p>The first thing I tried was a script &amp; ConfigMap combination to update /etc/hosts on startup (ref. <a href="https://stackoverflow.com/questions/37166822/is-it-a-way-to-add-arbitrary-record-to-kube-dns">Is it a way to add arbitrary record to kube-dns?</a>), but that is problematic as other Kubernetes services may also update the hosts file at different times.</p>

<p>I also tried a Services &amp; Enpoints configuration:</p>

<pre><code>---
apiVersion: v1
kind: Service
metadata:
  name: node1.mongo.example.com
spec:
  ports:
    - protocol: TCP
      port: 27017
      targetPort: 27017
---
apiVersion: v1
kind: Endpoints
metadata:
  name: node1.mongo.example.com
subsets:
  - addresses:
      - ip: 192.168.0.1
    ports:
      - port: 27017
</code></pre>

<p>But this fails as the Service name cannot be a FQDN...</p>

<p>While not so obvious at first, the solution is quite simple. kube-dns image in recent versions includes <code>dnsmasq</code> as one of it's components. If you look into its man page, you will see some usefull options. Following that lecture you can choose a path similar to this :</p>

<p>Create a ConfigMap to store your dns mappings :</p>

<pre><code>apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-dns
  namespace: kube-system
data:
  myhosts: |
    10.0.0.1 foo.bar.baz
</code></pre>

<p>Having that ConfigMap applied in your cluster you can now make some changes to <code>kube-dns-vXX</code> deployment you use in your kubernetes.</p>

<p>Define volume that will expose your CM to <code>dnsmasq</code></p>

<pre><code>  volumes:
  - name: hosts
    configMap:
      name: kube-dns
</code></pre>

<p>and mount is in your <code>dnsmasq</code> container of <code>kube-dns</code> deployment/rc template</p>

<pre><code>    volumeMounts:
    - name: hosts
      mountPath: /etc/hosts.d
</code></pre>

<p>and finally, add a small config flag to your dnsmasq arguments :</p>

<pre><code>    args:
    - --hostsdir=/etc/hosts.d
</code></pre>

<p>now, as you apply these changes to the <code>kube-dns-vXX</code> deployment in your cluster it will mount the configmap and use files mounted in /etc/hosts.d/ (with typical hosts file format) as a source of knowledge for <code>dnsmasq</code>. Hence if you now query for foo.bar.baz in your pods, they will resolve to respective IP. These entries take precedence over public DNS, so it should perfectly fit your case.</p>

<p>Mind that <code>dnsmasq</code> is not watching for changes in ConfigMap so it has to be restarted manually if it changes.</p>

<p>Tested and validated this on a live cluster just few minutes ago.</p>
