Docker Engine 受管外掛程式系統

Docker Engine 的外掛程式系統允許您使用 Docker Engine 安裝、啟動、停止和移除外掛程式。

有關傳統(非受管)外掛程式的資訊,請參閱 瞭解傳統 Docker Engine 外掛程式

**注意**

Windows daemon 目前不支援 Docker Engine 受管外掛程式。

安裝和使用外掛程式

外掛程式以 Docker 映像檔的形式發佈,可以託管在 Docker Hub 或私有 Registry 上。

要安裝外掛程式,請使用 `docker plugin install` 命令,該命令會從 Docker Hub 或您的私有 Registry 中提取外掛程式,在必要時提示您授予權限或功能,並啟用外掛程式。

要檢查已安裝外掛程式的狀態,請使用 `docker plugin ls` 命令。成功啟動的外掛程式在輸出中會列為已啟用。

安裝外掛程式後,您可以將其作為另一個 Docker 操作的選項使用,例如建立磁碟區。

在以下範例中,您將安裝 `sshfs` 外掛程式,驗證它是否已啟用,並使用它來建立磁碟區。

**注意**

此範例僅供教學用途。建立磁碟區後,當您檢查磁碟區時,您到遠端主機的 SSH 密碼將以純文字形式公開。範例完成後立即刪除磁碟區。

  1. 安裝 `sshfs` 外掛程式。

    $ docker plugin install vieux/sshfs
    
    Plugin "vieux/sshfs" is requesting the following privileges:
    - network: [host]
    - capabilities: [CAP_SYS_ADMIN]
    Do you grant the above permissions? [y/N] y
    
    vieux/sshfs
    

    外掛程式請求 2 個權限

    • 它需要存取 `host` 網路。
    • 它需要 `CAP_SYS_ADMIN` 功能,允許外掛程式執行 `mount` 命令。
  2. 檢查外掛程式是否在 `docker plugin ls` 的輸出中啟用。

    $ docker plugin ls
    
    ID                    NAME                  TAG                 DESCRIPTION                   ENABLED
    69553ca1d789          vieux/sshfs           latest              the `sshfs` plugin            true
    
  3. 使用外掛程式建立磁碟區。此範例將主機 `1.2.3.4` 上的 `/remote` 目錄掛載到名為 `sshvolume` 的磁碟區中。

    此磁碟區現在可以掛載到容器中。

    $ docker volume create \
      -d vieux/sshfs \
      --name sshvolume \
      -o sshcmd=user@1.2.3.4:/remote \
      -o password=$(cat file_containing_password_for_remote_host)
    
    sshvolume
    
  4. 驗證磁碟區是否已成功建立。

    $ docker volume ls
    
    DRIVER              NAME
    vieux/sshfs         sshvolume
    
  5. 啟動使用 `sshvolume` 磁碟區的容器。

    $ docker run --rm -v sshvolume:/data busybox ls /data
    
    <content of /remote on machine 1.2.3.4>
    
  6. 移除磁碟區 `sshvolume`

    $ docker volume rm sshvolume
    
    sshvolume
    

要停用外掛程式,請使用 `docker plugin disable` 命令。要完全移除它,請使用 `docker plugin remove` 命令。有關其他可用命令和選項,請參閱 命令列參考

開發外掛程式

rootfs 目錄

`rootfs` 目錄代表外掛程式的根檔案系統。在本例中,它是從 Dockerfile 建立的

**注意**

`/run/docker/plugins` 目錄在外掛程式的檔案系統中是強制性的,以便 Docker 與外掛程式進行通訊。

$ git clone https://github.com/vieux/docker-volume-sshfs
$ cd docker-volume-sshfs
$ docker build -t rootfsimage .
$ id=$(docker create rootfsimage true) # id was cd851ce43a403 when the image was created
$ sudo mkdir -p myplugin/rootfs
$ sudo docker export "$id" | sudo tar -x -C myplugin/rootfs
$ docker rm -vf "$id"
$ docker rmi rootfsimage

config.json 檔案

`config.json` 檔案描述外掛程式。請參閱 外掛程式設定參考

考慮以下 `config.json` 檔案。

{
  "description": "sshFS plugin for Docker",
  "documentation": "https://docker-docs.dev.org.tw/engine/extend/plugins/",
  "entrypoint": ["/docker-volume-sshfs"],
  "network": {
    "type": "host"
  },
  "interface": {
    "types": ["docker.volumedriver/1.0"],
    "socket": "sshfs.sock"
  },
  "linux": {
    "capabilities": ["CAP_SYS_ADMIN"]
  }
}

這個插件是一個磁碟區驅動程式。它需要一個 host 網路和 CAP_SYS_ADMIN 權限。它依賴於 /docker-volume-sshfs 進入點,並使用 /run/docker/plugins/sshfs.sock 通訊端與 Docker 引擎通訊。這個插件沒有運行時參數。

建立插件

可以透過執行 docker plugin create <插件名稱> ./path/to/plugin/data 來建立新的插件,其中插件資料包含一個插件設定檔 config.json 和一個位於子目錄 rootfs 的根檔案系統。

之後,插件 <插件名稱> 將會顯示在 docker plugin ls 中。插件可以使用 docker plugin push <插件名稱> 推送到遠端倉庫。

除錯外掛程式

插件的標準輸出會被重新導向到 dockerd 的日誌。這些條目會有一個 plugin=<ID> 的後綴。以下是一些針對 pluginID 為 f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62 的指令範例,以及它們在 Docker Daemon 日誌中對應的日誌條目。

$ docker plugin install tiborvass/sample-volume-plugin

INFO[0036] Starting...       Found 0 volumes on startup  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
$ docker volume create -d tiborvass/sample-volume-plugin samplevol

INFO[0193] Create Called...  Ensuring directory /data/samplevol exists on host...  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0193] open /var/lib/docker/plugin-data/local-persist.json: no such file or directory  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0193]                   Created volume samplevol with mountpoint /data/samplevol  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0193] Path Called...    Returned path /data/samplevol  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
$ docker run -v samplevol:/tmp busybox sh

INFO[0421] Get Called...     Found samplevol                plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0421] Mount Called...   Mounted samplevol              plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0421] Path Called...    Returned path /data/samplevol  plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62
INFO[0421] Unmount Called... Unmounted samplevol            plugin=f52a3df433b9aceee436eaada0752f5797aab1de47e5485f1690a073b860ff62

使用 runc 來取得日誌檔並進入插件的 shell。

使用 runc(預設的 Docker 容器運行環境)來除錯插件,方法是將插件日誌重新導向到一個檔案中。

$ sudo runc --root /run/docker/runtime-runc/plugins.moby list

ID                                                                 PID         STATUS      BUNDLE                                                                                                                                       CREATED                          OWNER
93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25   15806       running     /run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby-plugins/93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25   2018-02-08T21:40:08.621358213Z   root
9b4606d84e06b56df84fadf054a21374b247941c94ce405b0a261499d689d9c9   14992       running     /run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby-plugins/9b4606d84e06b56df84fadf054a21374b247941c94ce405b0a261499d689d9c9   2018-02-08T21:35:12.321325872Z   root
c5bb4b90941efcaccca999439ed06d6a6affdde7081bb34dc84126b57b3e793d   14984       running     /run/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby-plugins/c5bb4b90941efcaccca999439ed06d6a6affdde7081bb34dc84126b57b3e793d   2018-02-08T21:35:12.321288966Z   root
$ sudo runc --root /run/docker/runtime-runc/plugins.moby exec 93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25 cat /var/log/plugin.log

如果插件有內建的 shell,則可以透過以下方式進入插件的 shell

$ sudo runc --root /run/docker/runtime-runc/plugins.moby exec -t 93f1e7dbfe11c938782c2993628c895cf28e2274072c4a346a6002446c949b25 sh

使用 curl 來除錯插件通訊端問題。

要驗證 Docker Daemon 與之通訊的插件 API 通訊端是否有回應,請使用 curl。在本例中,我們將使用 curl 7.47.0 從 Docker 主機對磁碟區和網路插件進行 API 呼叫,以確保插件正在監聽所述的通訊端。對於功能正常的插件,這些基本請求應該可以正常運作。請注意,插件通訊端位於主機上的 /var/run/docker/plugins/<pluginID> 路徑下。

$ curl -H "Content-Type: application/json" -XPOST -d '{}' --unix-socket /var/run/docker/plugins/e8a37ba56fc879c991f7d7921901723c64df6b42b87e6a0b055771ecf8477a6d/plugin.sock http:/VolumeDriver.List

{"Mountpoint":"","Err":"","Volumes":[{"Name":"myvol1","Mountpoint":"/data/myvol1"},{"Name":"myvol2","Mountpoint":"/data/myvol2"}],"Volume":null}
$ curl -H "Content-Type: application/json" -XPOST -d '{}' --unix-socket /var/run/docker/plugins/45e00a7ce6185d6e365904c8bcf62eb724b1fe307e0d4e7ecc9f6c1eb7bcdb70/plugin.sock http:/NetworkDriver.GetCapabilities

{"Scope":"local"}

當使用 curl 7.5 及更高版本時,URL 應採用 http://hostname/APICall 的形式,其中 hostname 是安裝插件的有效主機名稱,而 APICall 是對插件 API 的呼叫。

例如,http://localhost/VolumeDriver.List