svg

Expose Docker Internal DNS with CoreDNS

docker linux

Aku mau akses service yg jalan pakai docker compose dari host hanya dengan memanggil nama service-nya dengan suffix .docker, ala K8S. Misalnya, ada service my-service yg jalan di docker compose, aku bisa akses dari host dengan curl http://my-service.docker:8080 tanpa harus tahu IP container-nya. Dan aku tidak mau edit file /etc/hosts di host, karena repot.

Solusinya adalah sama seperti K8S, yaitu dengan menambahkan CoreDNS yg akan resolve nama service ke IP container-nya. Dengan rule sederhana, CoreDNS bisa resolve nama service yg diakhiri dengan .docker ke IP container-nya.

Langsung saja ke Working dir-nya:

docker/services/coredns
├── compose.yaml
└── Corefile

0 directories, 2 files

Corefile

# Forward *.docker to Docker internal DNS
docker:53 {
    log
    errors
    cancel

    rewrite stop {
        name suffix .docker . answer auto
    }

    # Forward to Docker internal DNS
    forward . 127.0.0.11
}

# Forward selected domain to mikrotik DNS
# *.google.com
# *.gstatic.com
# *.googleapis.com
# *.intranet.tld
# *.googleusercontent.com
google.com:53 {
    log
    errors
    cancel
    cache 3600
    forward . 172.16.0.1
}

gstatic.com:53 {
    log
    errors
    cancel
    cache 3600
    forward . 172.16.0.1
}


googleapis.com:53 {
    log
    errors
    cancel
    cache 3600
    forward . 172.16.0.1
}


intranet.tld:53 {
    log
    errors
    cancel
    cache 3600
    forward . 172.16.0.1
}

googleusercontent.com:53 {
    log
    errors
    cancel
    cache 3600
    forward . 172.16.0.1
}

# Forward any other queries to AdGuard DNS
. {
  log
  errors
  cancel
  cache 3600

  # Forward to AdGuard DNS with TLS
  forward . tls://94.140.14.14 tls://94.140.15.15 {
    tls_servername dns.adguard-dns.com
    health_check 5s
  }
}

compose.yaml

networks:
  database:
    external: true
  logging:
    external: true
  proxy:
    external: true

services:
  coredns:
    image: coredns/coredns
    restart: unless-stopped
    command: -conf /Corefile
    ports:
      - '127.0.0.99:53:53/udp'
      - '127.0.0.99:53:53/tcp'
    volumes:
      - './Corefile:/Corefile'
    networks:
      - logging
      - database
      - proxy

Config-nya cukup self explanatory, jadi aku skip penjelasan lebih lanjut.

Selanjutnya, aku tinggal jalankan docker compose-nya:

docker compose up -d

Test dengan dig:

 > dig @127.0.0.99 grafana.docker

; <<>> DiG 9.18.28-0ubuntu0.22.04.1-Ubuntu <<>> @127.0.0.99 grafana.docker
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31140
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: b4fa539d5f820d2e (echoed)
;; QUESTION SECTION:
;grafana.docker.			IN	A

;; ANSWER SECTION:
grafana.docker.		600	IN	A	172.20.0.6

;; Query time: 0 msec
;; SERVER: 127.0.0.99#53(127.0.0.99) (UDP)
;; WHEN: Tue Oct 29 09:55:15 WIB 2024
;; MSG SIZE  rcvd: 85

Kemudian atur network manager supaya memakai DNS yg baru saja aku buat yaitu 127.0.0.99, dan test lagi dengan dig:

 > dig grafana.docker

; <<>> DiG 9.18.28-0ubuntu0.22.04.1-Ubuntu <<>> grafana.docker
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34470
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;grafana.docker.			IN	A

;; ANSWER SECTION:
grafana.docker.		600	IN	A	172.20.0.6

;; Query time: 0 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Tue Oct 29 09:54:45 WIB 2024
;; MSG SIZE  rcvd: 59