Jeżeli kiedykolwiek korzystałeś z Dockera metodą Kopiego-Pasty, być może spotkałeś się już z następującym argumentem: -v /var/run/docker.sock:/var/run/docker.sock
Co to jest i jaką pełni rolę? Dlaczego czasami jest wykorzystywany, a czasami nie – oraz w jakich przypadkach warto wiedzieć, o co w tym wszystkim chodzi?
TLDR;
Chcąc ująć to w jednym zdaniu: “Jest to Unix Socket, na którym domyślnie nasłuchuje Docker Daemon.”

Wystarczy zerknąć na powyższy diagram i w zasadzie wszystko powinno być już jasne ; -)
Dzięki podmontowaniu pliku /var/run/docker.sock
(znajdującego się na hoście), kontener może komunikować się z Docker Deamonem – czyli jednym z komponentów wchodzących w skład architektury Dockera. Docker Daemon odpowiada za przyjmowanie “rozkazów” i przekazanie ich w dół, do warstwy OCI (container runtime).
Porównując to do architektury klient-serwer, kontener może stać się klientem, a Docker Deamon – serwerem.
Docker API
Jeżeli kiedykolwiek wpisałeś w terminalu docker container run
(bądź też docker run
) to na 99% “pod spodem” wykorzystałeś Docker Daemon Socket.
Jest to domyślny typ komunikacji pomiędzy Docker CLI a Docker Daemonem. Domyślny nie oznacza, że nie można go zmienić, ale tym za chwilę.
Gdy korzystamy z Docker CLI, np. docker image ls
– automatycznie (w tle) dorzucany jest parametr -H unix:///var/run/docker.sock
.
Parametr -H
to informacja dla Docker CLI, z jakim Docker Daemonem ma się skomunikować. Inaczej mówiąc, gdzie polecenie ma zostać wykonane.
Warto podkreślić, że do parametru-H
można przekazać również inną wartość. Na przykład adres hosta i port TCP lub inny unix socket.
WAŻNE: Jeżeli chcemy by Docker CLI komunikował się z Docker Daemonem po protokole TCP – zamiast Unix Sockets, należy pamiętać by najpierw “włączyć” ten typ komunikacji w ustawieniach Docker Daemon’a.
Jeżeli to, co do tej pory przeczytałeś odnośnie komunikacji na lini Docker CLI => Docker Daemon – nie jest dla Ciebie do końca zrozumiałe, to koniecznie zerknij TUTAJ, gdzie jakiś czasu temu opisywałem, w jaki sposób komunikować się ze zdalnym Docker Hostem z wykorzystaniem Docker Contexts.
Portainer – pierwszy przykład zastosowania
Wykorzystanie pliku /var/run/docker.sock
możemy spotkać na przykład przy uruchamianiu Portainera – narzędzia do zarządzania Dockerem z poziomu przeglądarki.
$ docker container run -d \ -p 9000:9000 \ -v /var/run/docker.sock:/var/run/docker.sock \ portainer/portainer
Portainer to aplikacja webowa, która umożliwia zarządzanie poszczególnymi obiektami w Dockerze (obrazy, kontenery, volumeny itd.)
Zamiast wpisywania docker container stop <moj_kontener>
czy też innych poleceń – możesz to “wyklikać”. Ale nie o tym dzisiaj.
Dzięki podmontowaniu pliku /var/run/docker.sock
– Portainer uruchomiony w kontenerze może komunikować się z Docker Daemonem. Inaczej mówiąc, kontener Portainera otrzymuje dostęp do głównego Dockera, na którym został uruchomiony.
Szukasz wiedzy z zakresu konteneryzacji?
Sprawdź koniecznie mój autorski program DOCKER MAESTRO

* minimum 13 godzin materiału (nowe materiału w produkcji)
* dożywotni dostęp do materiałów & aktualizacji
* certyfikat Docker Maestro
* gwarancja satysfakcji
(masz 14 dni na zwrot kasy, licząc od dnia zakupu, jeśli COKOLWIEK Ci się nie spodoba)
Portainer & Docker API – jak to działa?
Najczęściej stosowanym typem komunikacji po HTTP jest protokoł TCP.
W przypadku Portainera – żądania HTTP do Docker Daemona nie są jednak wysyłane po TCP, ale właśnie przez Unix Socket.
Jeżeli wyklikamy w Portainerze utworzenie kontenera na podstawie obrazu wordpress
, to pod spodem zostanie wykonane zbliżone polecenie:
curl -XPOST --unix-socket /var/run/docker.sock -d '{"Image":"wordpress"}' \ -H 'Content-Type: application/json' http://localhost/containers/create {"Id":"fcb65c6147efb862d5ea3a2ef20e793c52f0fafa3eb04e4292cb4784c5777d65","Warnings":null}
Istnieje możliwość skonfigurowania Docker Daemona tak, by oprócz Unix Socket, dodatkowo nasłuchiwał po protokole TCP.
Z perspektywy bezpieczeństwa jest to jednak niezalecane.
Trzeba wiedzieć co się robi, i jak to działa. W przeciwnym wypadku – może to zostać wykorzystane przeciwko nam (przez osoby trzecie). Przykład takiego “włamania” do Docker Daemona można znaleźć TUTAJ.
Narzędzia do CI/CD w kontenerze (Gitlab, Jenkins)
Od dłuższego czasu, narzędzia takie jak GitLab czy Jenkins możemy uruchomić z poziomu Dockera. Obydwa narzędzia mogą być z powodzeniem wykorzystane do skonfigurowania procesów automatycznego budowania i publikowania obrazów w Docker Registry.
Swego czasu w takich zastosowaniach modne było podejście Docker-in-Docker. To podejście miało jednak sporo wad i szybko zostały uznane jako “anti-pattern”.
Aby mieć możliwość dostępu do “głównego” Dockera, bądź też – aby móc budować obrazy w skonteneryzowanym Gitlabie czy Jenkinsie – wystarczy podmontować Docker Socket.
Przykład – Gitlab Runner
Jak wspominałem wcześniej, istnieje możliwość uruchomienia lokalnej instancji GitLaba z poziomu Dockera. Gdy już to zrobimy, chcemy mieć możliwość automatycznego budowania obrazów.
Aby zbudować docker image, kontener gitlab-runner
potrzebuje działającej instancji Dockera. (pamiętajmy, że kontener Gitlab Runnera to tak naprawdę tylko linuxowy proces!)
version: '3.5' services: gitlab: image: gitlab/gitlab-ce:latest container_name: gitlab restart: always ... ... gitlab-runner: image: gitlab/gitlab-runner:alpine container_name: gitlab-runner restart: always volumes: - /var/run/docker.sock:/var/run/docker.sock - /srv/gitlab-runner/config:/etc/gitlab-runner depends_on: - gitlab
Obecnie rekomendowanym podejściem jest podmontowanie /var/run/docker.sock:/var/run/docker.sock
– dzięki czemu budowanie obrazów odbywa się na “głównym” Dockerze (pomimo tego, że cały GitLab jest uruchomionyjako kontener).
Benefitem tego rozwiązania jest przede wszystkim pełne wykorzystanie cache podczas budowania obrazów — gdyż cały proces wykonywany jest ZAWSZE na tej samej (i jedynej) instancji Dockera.
Podsumowanie
Mam nadzieję, że ten post pozwolił Ci na zrozumienie, w jakim celu wykorzystywany jest Docker Socket.
Podmontowanie pliku /var/run/docker.sock
może pozwalać na zarządzanie Dockerem z poziomu kontenera. Daje nam to ogrom możliwości i może mieć zastosowanie w narzędziach integrujących się z Dockerem, czy procesach CI/CD.
PS. Jeżeli ten wpis był dla Ciebie wartościowy – będę BARDZO wdzięczny jeśli udostępnisz go/podzielisz się nim ze znajomym.