原文:medium.com/better-prog…nginx
你keneng1已經運行過docker hub上的container而且注意到其中的一些須要綁定掛載(mount)/var/run/docker.sock
文件。這個文件是什麼呢,爲何有些時候會被container所用到?剪短的回答:這個是Unix socket,Docker進程默認監聽文件,爲進行container進程間通訊所用。docker
咱們先來看看Portainer,是一個用於管理docker host或者Swarm集羣的開源工具。若是用來管理本地Docker host Protaner能夠用如下命令運行,綁定掛載到本地的docker的Unix socket上json
$ docker container run -d \
-p 9000:9000 \
-v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
複製代碼
而後咱們能夠經過本地9000端口來訪問圖形界面,能夠管理咱們的container,images,volumes等等api
爲了作到以上全部的管理功能,Portainer與本地Docker進程進行通訊就是經過掛載/var/run/docker.sock
文件來實現的。bash
當Docker在主機上安裝之後,Docker守護進程監聽默認監聽/var/run/docker.sock
文件。固然這個路徑是能夠設置的,經過-H
參數app
-H unix:///var/run/docker.sock
複製代碼
Notes: 因爲-H參數的提供,Docker守護進程還能夠監聽tcp 主機/端口或者其餘的Unix socketscurl
全部HTTP接口定義在 Docker engine API v1.27。全部接口的底層通訊都是經過Unix socket。socket
經過Portainer界面,咱們能夠輕鬆的運行container。在引擎後面,Http請求經過docker.socket發送到Docker進程。tcp
下面來演示一下這個以及經過curl建立一個Nginx containue工具
Notes: 當使用HTTP API,運行container須要兩步,首先要先建立conatiner而後啓動。
下面命令使用curl發送{「Image」:」nginx」}
請求體經過Unix socket發送到到Docker進程的接口/containers/create
。最終會建立一個Nginx的container而且會返回他的ID。
$ curl -XPOST --unix-socket /var/run/docker.sock -d '{"Image":"nginx"}' -H 'Content-Type: application/json' http://localhost/containers/create
{"Id":"fcb65c6147efb862d5ea3a2ef20e793c52f0fafa3eb04e4292cb4784c5777d65","Warnings":null}
複製代碼
經過返回的ID,咱們能夠經過 /containers/<ID>/start
來運行剛剛新建立的container
$ curl -XPOST --unix-socket /var/run/docker.sock http://localhost/containers/fcb6...7d65/start
複製代碼
咱們能夠看到Nginx container就被啓起來而且正在運行狀態
$ 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
複製代碼
這說明了如何使用Docker套接字輕鬆地從容器內部建立容器。 顯然,他實際並非經過curl建立容易的,只是我這麼演示能更方便讀者理解。
Docker API暴露一個/events
的接口,能夠用來獲取全部Docker進程生成的事件流,舉個例子,他能夠用來經過負載勻衡去建立或者刪除container的事件,以便動態地更新他的配置。
跑一個簡單的container而且檢查一下咱們如何使用docker進程事件
下面命令會以交互模式啓動一個Apline container並綁定docker.sock
$ docker run -v /var/run/docker.sock:/var/run/docker.sock -ti alpine sh
複製代碼
在Apline container內部,咱們首先經過apk安裝curl
$ apk update && apk add curl
複製代碼
如今能夠經過docker socket發送HTTP請求到/events
接口。命令會被掛起,等待新的事件從進程中進來。每一個新的事件都會是一個來自docker進程的事件流。
curl --unix-socket /var/run/docker.sock http://localhost/events
複製代碼
咱們建立了一個新的基於Nginx的container,而後監聽他,經過Apline container的標準輸出,這個事件由Docker進程生成。
docker container run -p 8080:80 -d nginx
複製代碼
咱們能夠觀察到以前的請求會接收到一系列的事件
$ 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
}
複製代碼
基本上,三個事件發生:
我但願快速解釋能讓你給/var/run/docker.sock
文件有更好的理解以及他是如何被用來綁定container的。很明顯,應用經過socket鏈接並非經過curl可是會用其餘庫來進行HTTP請求傳輸給Docker進程。
注意:Docker進程socket的綁定掛載給了container很大的力量去控制Docker進程。因此必須謹慎使用而且只在咱們能夠信任的container上使用。