Unix Domain Socket nedir ve ne işe yarar?

Bu flood’da Linux ve Unix bazlı sistemlerde prosesler arası iletişim kurma metotlarından biri olan Unix Domain Socket'lerden bahsedeceğim.

İşletim sistemleri, aynı host üzerinde koşan proseslerin birbirleri ile haberleşmesi gerektiği durumlarda kullanılmak üzere IPC - Inter-Process Communication adı verilen mekanizmaları kullanıma sunarlar. Bu mekanizmalardan biri Unix Domain Socket'lerdir.

Unix Domain Socket'lerin sundukları API bakımından internet soketlerine benzerler fakat internet soketlerinden farklı olarak sadece aynı host üzerinden erişilebilirler. İnternet soketleri iletişim kurmak için ağ altyapısını kullanırken Domain Socket'ler işletim sisteminin çekirdeği üzerinden haberleşirler. "Linux'ta her şey birer dosyadır" prensibinden hareketle Domain Socket'ler de birer dosyadır ve dosya sistemi üzerinden erişilirler.

Unix Domain Socket'lerin en fazla kullanıldığı alanlardan biri istemci-sunucu mantığında tasarlanmış yazılımların ayrı prosesler tarafından koşturulduğu fakat bir komut seti aracılığıyla haberleştiği durumlardır. Bu prosesler aynı host üzerinde koşturulduğu zaman birbirleri ile Unix Domain Socket'ler aracılığıyla haberleşebilirler. Domain Socket'ler internet soketlerinin aksine işletim sisteminin IP katmanını kullanmadıkları için internet soketlerine göre hız avantajı sağlamaktadır.

Hızlı olmalarına ek olarak host dışından erişime olanak tanımadıkları için Unix Domain Socket'lerin güvenlik anlamında doğal izolasyon sağladıkları da söylenebilir. Aynı izolasyon internet soketlerinde ilgili port sadece localhost - 127.0.0.1'dan dinlenerek sağlanır.

Daemon olarak çalışan hemen bütün servisler Unix Domain Socket arayüzü sunmaktadır. Bu servislere MySQL, Postgres, Redis, Memcached ve Docker örnek olarak verilebilir.

Docker CLI varsayılan olarak /var/run/docker.sock adresinde bulunan Unix Domain Socket üzerinden Docker Daemon ile iletişime geçmeye çalışır. Docker Daemon da varsayılan olarak sadece Domain Socket üzerinden istekleri kabul eder.

Birçok karşılaştırmalı hız testinde yukarıda verilen servislerle internet soket yerine Unix Domain Socket'şe iletişim kurmanın %25-35 arasında performans artışı sağladığı görülmektedir fakat tekrar belirtmekte fayda var ki bu performans artışını sağlamak için istemci ve sunucunun aynı host üzerinde olması gerekmektedir. Aynı host üzerinde bulunma zorunluluğu ölçeklenme ihtiyacı bulunan uygulamalarda Unix Domain Socket kullanımını imkansız hale getirir. Yine de ölçekleme ve yedeklilik ihtiyacı duyulmayan uygulamalarda rahatlıkla kullanılabilir.

Unix Domain Socket'lerin anlamlı olduğu güncel bir kullanım alanı host'ta başlatılan Docker konteynerlera soketi mount ederek konteyner içerisinden Docker Daemon'a erişim sağlanabilmesi ve dolayısıyla konteyner içinde yeni konteynerler oluşturulmasına olanak tanınmasıdır.

Aşağıdaki örnekte host üzerindeki Unix Domain Socket (/var/run/docker.sock) başlatılan konteynere volume olarak mount edilmiş ve konteyner içerisine girilerek yeni bir konteyner oluşturulmuştur.

Unix Domain Socket'lerin sunduğu API internet soketleri ile aynı olduğu için (aynı sistem çağrıları ile erişildiğinden) kullanımları esnek olmaktadır. Örnek olarak geliştirme sırasında unix:///var/run/docker.sock ile erişilen Docker Daemon'a üretim ortamında tcp://172.22.44.110:2375 olarak erişebiliriz. Bunun için tek yapmamız gereken istemcinin sunucuya bağlantı ayarının yapıldığı konfigürasyon dosyasında veya ortam değişkeninde ilgili adresi değiştirmektir.