Nasza strona używa cookies. Korzystając ze strony, wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki. Rozumiem

Dobre praktyki w Dockerze: /var/run/docker.sock

Luc Juggery Freelance Docker & Kubernetes trainer
Poznaj plik /var/run/docker.sock w Dockerze i dowiedz się, jak możesz wykorzystywać go do tworzenia bind mount w kontenerze.
Dobre praktyki w Dockerze: /var/run/docker.sock

Podczas odpalania kontenerów z Docker Hub, niektóre z nich wymagają zamontowania pliku /var/run/docker.sock. Co to za plik i dlaczego jest czasami używany przez kontenery? Krótka odpowiedź: jest to gniazdo Unix, na którym domyślnie nasłuchuje deamon Dockera i które może być używane do komunikacji z demonem z poziomu kontenera.

Sprawdźmy Portainer, interfejs open source do zarządzania hostem Dockera lub klastrem Swarm. Jeśli jest używany do zarządzania lokalnym hostem Dockera, Portainer można uruchomić za pomocą następującego polecenia, które zamontuje socket Dockera z hosta.

$ docker container run -d \
  -p 9000:9000 \
  -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer


Interfejs jest wtedy dostępny na porcie 9000 i umożliwia zarządzanie kontenerami, obrazami, woluminami itp.

Aby wykonać wszystkie te czynności związane z zarządzaniem, Portainer komunikuje się z lokalnym demonem Dockera za pośrednictwem pliku /var/run/docker.sock, do którego ma dostęp, bo został on zamontowany przez tzw. bind mount.


API demona Dockera

Gdy Docker jest zainstalowany na hoście, demon domyślnie nasłuchuje na gnieździe /var/run/docker.sock Unixa. Widać to na podstawie opcji dostarczanych do demona. Powinien zostać zawarty następujący wpis:

-H unix:///var/run/docker.sock


Disclaimer: Dodatkowe opcje -H mogą być dostarczone demonowi, aby nasłuchiwał również na hoście/porcie tcp lub na innych gniazdach unixowych.

Wszystkie endpointy HTTP zdefiniowane w API silnika Dockera w wersji 1.27 (ostatnia wersja) mogą być zatem wykorzystywane przez to gniazdo unix.


Tworzenie kontenerów

Możemy łatwo uruchamiać kontenery, korzystając z UI Portainera. Żądania HTTP wysyłane są w tle do demona Dockera za pośrednictwem docker.sock. Zilustrujemy to i utworzymy kontener NGINX za pomocą curl.

Disclaimer: Korzystając z API HTTP, do uruchomienia kontenera potrzebne są 2 kroki: najpierw należy go utworzyć, a dopiero potem uruchomić.

Tworzenie kontenera NGINX

Curl używa następujących poleceń do wysłania {“Image”:”nginx”} do endpointa /containers/create demona Dockera przez gniazdo unixowe. Spowoduje to utworzenie kontenera z obrazu NGINX i zwrócenie jego identyfikatora.

$ curl -XPOST --unix-socket /var/run/docker.sock -d '{"Image":"nginx"}' -H 'Content-Type: application/json' http://localhost/containers/create

{"Id":"fcb65c6147efb862d5ea3a2ef20e793c52f0fafa3eb04e4292cb4784c5777d65","Warnings":null}


Uruchamianie kontenera

Korzystając z identyfikatora podanego powyżej, możemy wybrać /containers/<ID>/start, aby uruchomić nowo utworzony kontener.

$ curl -XPOST --unix-socket /var/run/docker.sock http://localhost/containers/fcb6...7d65/start


Możemy teraz sprawdzić, czy kontener nginx jest uruchomiony i działa poprawnie.

$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fcb65c6147ef nginx “nginx -g ‘daemon …” 5 minutes ago Up 5 seconds 80/tcp, 443/tcp ecstatic_kirch
...


To ilustruje, jak łatwo można tworzyć kontenery w tle we wnętrzu kontenera za pomocą gniazda Dockera. Oczywiście kontener nie zostanie utworzony za pomocą curla, ale masz tu ciekawą inspirację.


Streaming zdarzeń z demona Dockera

API Dockera udostępnia również endpoint /events, który można użyć do pobrania strumienia wszystkich zdarzeń generowanych przez demona. Przykładowo load balancer może wykorzystać go do pobierania zdarzeń o utworzeniu czy usunięciu kontenerów, dzięki czemu może dynamicznie aktualizować swoją konfigurację.

Uruchomimy teraz prosty kontener i sprawdzimy, jak możemy wykorzystać zdarzenia demona Dockera.


Uruchomienie kontenera Alpine

Kontener Alpine uruchamia następujące polecenie w trybie interaktywnym i stworzy bind mount (pochylonym) do docker.sock:

$ docker run -v /var/run/docker.sock:/var/run/docker.sock -ti alpine sh


Nasłuchiwanie zdarzeń z demona Dockera

Z poziomu kontenera Alpine najpierw instalujemy curl za pomocą menedżera pakietów apk.

# apk update && apk add curl


Następnie możemy wysłać żądanie HTTP do endpointa /events przez gniazdo Dockera. Polecenie zawiesi się, czekając na nowe zdarzenia od demona. Każde nowe zdarzenie będzie następnie streamowane z demona.

$ curl --unix-socket /var/run/docker.sock http://localhost/events


Obserwowanie zdarzeń

Następnie tworzymy nowy kontener na podstawie obrazu NGINX i obserwujemy zdarzenia generowane przez demona Dockera, poprzez standardowe wyjście kontenera Alpine.

$ docker container run -p 8080:80 -d nginx


Możemy zauważyć, że ostatnie żądanie otrzymało kilka zdarzeń.

$ curl --unix-socket /var/run/docker.sock http://localhost/events
{
  "status": "create",
  "id": "277786a066994b4d842dc097c4544e2ddcf50ffe0b6aa8352812ca0aadec4078",
  "from": "nginx",
  "Type": "container",
  "Action": "create",
  "Actor": {
    "ID": "277786a066994b4d842dc097c4544e2ddcf50ffe0b6aa8352812ca0aadec4078",
    "Attributes": {
      "image": "nginx",
      "name": "hardcore_carson"
    }
  },
  "time": 1491683503,
  "timeNano": 1491683503003280100
}
{
  "Type": "network",
  "Action": "connect",
  "Actor": {
    "ID": "18147ed9f4510d0149a0810916434df19b3d03f30e17ac4effcbcc1d2371ba97",
    "Attributes": {
      "container": "277786a066994b4d842dc097c4544e2ddcf50ffe0b6aa8352812ca0aadec4078",
      "name": "bridge",
      "type": "bridge"
    }
  },
  "time": 1491683503,
  "timeNano": 1491683503061245700
}
{
  "status": "start",
  "id": "277786a066994b4d842dc097c4544e2ddcf50ffe0b6aa8352812ca0aadec4078",
  "from": "nginx",
  "Type": "container",
  "Action": "start",
  "Actor": {
    "ID": "277786a066994b4d842dc097c4544e2ddcf50ffe0b6aa8352812ca0aadec4078",
    "Attributes": {
      "image": "nginx",
      "name": "hardcore_carson"
    }
  },
  "time": 1491683503,
  "timeNano": 1491683503389984300
}


Miały miejsce trzy zdarzenia:

  • stworzenie kontenera
  • połączenie z domyślnym network bridge
  • uruchomienie kontenera


Podsumowanie

Mam nadzieję, że to krótkie wyjaśnienie pozwoli Ci lepiej zrozumieć plik /var/run/docker.sock i to, jak możesz wykorzystywać go, gdy stworzysz do niego bind mount w kontenerze. Oczywiście aplikacje korzystające z tego gniazda nie będą używać curl, ale będą wykorzystywały dedykowane biblioteki do wysyłania żądania HTTP do demona.

Uwaga: Montowanie gniazda demona Dockera daje kontenerowi duże uprawnienia, ponieważ może on kontrolować demona. Należy go jednak używać ostrożnie i tylko w przypadku zaufanych kontenerów.



Oryginał tekstu w języku angielskim przeczytasz
tutaj.

Rozpocznij dyskusję

Lubisz dzielić się wiedzą i chcesz zostać autorem?

Podziel się wiedzą z 160 tysiącami naszych czytelników

Dowiedz się więcej