Topik ini membahas service discovery pada Docker, yaitu cara sebuah layanan menemukan layanan lain hanya dari namanya tanpa mencatat alamat IP. Pembahasan mencakup server DNS tertanam Docker, yaitu penerjemah nama menjadi alamat IP di dalam jaringan. Selanjutnya dibahas peragaan resolusi nama pada umumnya, pola klien-server antara aplikasi web dan basis datanya, serta kegagalan resolusi yang paling sering ditemui. Setelah membacanya, dua container dapat saling dihubungi dengan nama yang tetap meskipun alamat IP-nya berganti.
Server DNS tertanam Docker#
Setiap jaringan kustom dilengkapi server DNS tertanam yang melayani container pada alamat tetap 127.0.0.11. Server ini menerjemahkan nama container menjadi alamat IP container tersebut, sehingga koneksi antar container dapat ditulis dengan nama alih-alih angka. Daftar nama yang dikenalnya berasal dari anggota jaringan itu sendiri, dan jawabannya diperbarui setiap kali container dibuat, dihentikan, atau dipasang-lepas dari jaringan. Alamat 127.0.0.11 tetap sama di setiap container, karena yang berbeda hanyalah daftar nama yang dikenal server tersebut.
Mekanisme ini hanya tersedia pada jaringan buatan pengguna. Jaringan bridge default tidak menyediakan server DNS sama sekali, sehingga nama container tidak dikenal di sana. Karena itu, langkah pertama pola klien-server adalah memastikan kedua container menjadi anggota jaringan kustom yang sama, sebagaimana perintah berikut. Nama db pada contoh dipilih karena pendek dan menggambarkan perannya sebagai basis data.
# tidak-dijalankan: daemon Docker tidak tersedia di sandbox
# jaringan kustom sebagai wadah kedua container
docker network create jaringan-catatan
# basis data PostgreSQL dengan nama container db
docker run -d --name db --network jaringan-catatan -e POSTGRES_PASSWORD=rahasia-db postgres:18-alpine
# aplikasi catatan pada jaringan yang sama
docker run -d --name catatan-web --network jaringan-catatan -p 8000:8000 catatanResolusi nama pada umumnya#
Penerjemahan nama menjadi alamat sebenarnya adalah mekanisme umum pada sistem Linux, bukan penemuan Docker. Sebuah resolver, yaitu bagian pustaka jaringan yang menerjemahkan nama menjadi alamat IP, membaca berkas /etc/resolv.conf untuk mengetahui server DNS yang harus ditanya. Perintah berikut menampilkan isi berkas tersebut pada mesin lingkungan uji modul ini, beserta hasil penerjemahan nama localhost melalui dua cara.
# isi berkas konfigurasi resolver pada mesin lingkungan uji
cat /etc/resolv.conf
# penerjemahan nama localhost menjadi alamat IP
getent hosts localhost
# penerjemahan yang sama melalui pustaka soket Python
python3 -c "import socket; print(socket.gethostbyname('localhost'))"nameserver 100.100.2.136
nameserver 100.100.2.138
::1 localhost ip6-localhost ip6-loopback
127.0.0.1Keluaran tersebut memperlihatkan pola yang sama pada tiga lapisan. Berkas /etc/resolv.conf menyebut alamat server DNS yang harus ditanya, perintah getent menerjemahkan localhost menjadi ::1 melalui berkas hosts milik sistem, dan pustaka soket Python menghasilkan 127.0.0.1 untuk nama yang sama. Docker menggunakan mekanisme yang serupa di dalam container, hanya berbeda isi berkas konfigurasinya. Pada container anggota jaringan kustom, /etc/resolv.conf milik container menunjuk ke 127.0.0.11, yaitu server DNS tertanam Docker, sehingga pertanyaan tentang nama container dijawab tanpa konfigurasi tambahan apa pun.
Pola klien-server dengan nama host#
Aplikasi catatan yang membutuhkan PostgreSQL menghubungi basis datanya melalui nama host db, yaitu nama yang diselesaikan menjadi alamat IP container basis data. Alamat IP tersebut tidak pernah ditulis langsung pada konfigurasi aplikasi. Nilai koneksi pun berbentuk seperti postgres://catatan:rahasia-db@db:5432/catatan, dan bagian db di tengahnya diselesaikan oleh server DNS tertanam menjadi alamat container basis data. Karena nama db ditetapkan pada setiap pembuatan container basis data, konfigurasi aplikasi tidak pernah berubah meskipun alamat IP container tersebut ditetapkan ulang.
Penggunaan nama sebagai alamat juga mengubah urutan penyiapan yang aman. Alamat IP container baru diketahui setelah container berjalan, sedangkan nama db dapat ditulis pada konfigurasi aplikasi jauh sebelum basis data dihidupkan. Ketika container basis data dihentikan dan dibuat ulang dengan nama yang sama, server DNS memperbarui jawabannya tanpa perubahan apa pun pada sisi aplikasi. Perilaku inilah yang menjadi dasar urutan startup pada aplikasi multi-container.
Sebuah container juga dapat memiliki lebih dari satu nama pada satu jaringan. Opsi --network-alias menambahkan alias, yaitu nama tambahan yang diselesaikan menjadi alamat container yang sama, sehingga layanan dapat dijangkau dengan nama perannya. Alias berguna ketika nama container dan nama peran layanannya berbeda, misalnya container db yang juga dijangkau sebagai basisdata.
# tidak-dijalankan: daemon Docker tidak tersedia di sandbox
# container basis data dengan nama tambahan basisdata
docker run -d --name db --network jaringan-catatan --network-alias basisdata -e POSTGRES_PASSWORD=rahasia-db postgres:18-alpine
# kedua nama menunjuk container yang sama
docker exec catatan-web getent hosts db
docker exec catatan-web getent hosts basisdataMekanisme yang sama digunakan Docker Compose, alat yang menghidupkan aplikasi multi-container dari satu berkas YAML. Nama service pada berkas compose.yaml menjadi nama yang dapat dihubungi container lain, sehingga pola klien-server ini berlaku apa adanya pada Compose. Perbedaannya hanya pada letak penamaan, karena Compose menamai container otomatis mengikuti nama service yang tertulis.
Kesalahan umum#
Nama container tidak dikenal padahal container berjalan. Aplikasi menampilkan error penyelesaian nama karena container yang dihubungi dan container yang menghubungi tidak berada pada jaringan kustom yang sama. Perbaikannya dengan memasang keduanya ke satu jaringan melalui
docker network connect, lalu memverifikasinya melaluidocker network inspect.Menulis nama yang tidak sesuai. Server DNS hanya menjawab nama yang terdaftar pada jaringannya, sehingga salah eja pada nama container atau menggunakan nama container yang belum dibuat menghasilkan kegagalan yang sama. Perbaikannya dengan mencocokkan nama pada
docker psdengan nama yang dipanggil aplikasi.Menghubungkan container melalui jaringan default. Koneksi berbasis nama selalu gagal pada bridge default karena jaringan tersebut tidak memiliki server DNS. Perbaikannya dengan membuat jaringan kustom dan menjadikan kedua container sebagai anggotanya.
Ringkasan#
- Setiap jaringan kustom memiliki server DNS tertanam pada 127.0.0.11 yang menerjemahkan nama container menjadi alamat IP-nya.
- Aplikasi klien menghubungi layanan melalui nama host, misalnya
db, sehingga konfigurasi tidak berubah meskipun alamat IP container berganti. - Opsi
--network-aliasmenambahkan nama lain bagi satu container pada jaringan yang sama. - Docker Compose menggunakan mekanisme yang sama, dengan nama service pada
compose.yamlsebagai nama yang dihubungi.
Referensi#
- Bridge network driver — Docker Docs — Memuat perbedaan jaringan kustom dengan bridge default, termasuk DNS otomatis antar container.
- Standalone networking tutorial — Docker Docs — Memperagakan service discovery berbasis nama container pada jaringan kustom.