|
| 1 | + |
| 2 | +[Xiaowei's Note](https://xiaoweiqian.github.io/note/) |
| 3 | +## Introduction |
| 4 | + |
| 5 | +Docker pluginV2 管理机制可以使得第三方插件以镜像的方式管理起来,插件不再需要独立部署和维护,而是由docker统一维护,各个节点可以方便的从镜像仓库安装、升级和删除插件。 |
| 6 | + |
| 7 | +## Prepare |
| 8 | + |
| 9 | +- 网络插件开发参考 |
| 10 | + |
| 11 | +[网络插件开发](https://xiaoweiqian.github.io/note/docker-network-remote-driver/) |
| 12 | + |
| 13 | +## Configration |
| 14 | + |
| 15 | +推荐使用alpine基础镜像(4M)作为plugin的运行环境,插件制作过程分为如下几个步骤。 |
| 16 | + |
| 17 | +- 插件编译 |
| 18 | + |
| 19 | + 插件编译和插件运行环境必须一致,因此使用alpine作为编译环境。 |
| 20 | + |
| 21 | + 1. 编写Dockerfile.dev |
| 22 | + |
| 23 | + 若插件基于golang开发,使用golang:1.7.5-alpine3.5基础镜像作为插件编译环境 |
| 24 | + |
| 25 | + ``` |
| 26 | + FROM golang:1.7.5-alpine3.5 |
| 27 | +
|
| 28 | + COPY . /go/src/github.com/XiaoweiQian/macvlan-driver |
| 29 | + WORKDIR /go/src/github.com/XiaoweiQian/macvlan-driver |
| 30 | +
|
| 31 | + RUN set -ex \ |
| 32 | + && apk add --no-cache --virtual .build-deps \ |
| 33 | + gcc libc-dev linux-headers \ |
| 34 | + && go install --ldflags '-extldflags "-static"' \ |
| 35 | + && apk del .build-deps |
| 36 | +
|
| 37 | + CMD ["/go/bin/macvlan-driver"] |
| 38 | + ``` |
| 39 | +
|
| 40 | +
|
| 41 | + ``` |
| 42 | +
|
| 43 | + 2. 编写Makefile |
| 44 | +
|
| 45 | + 启动插件编译容器,把编译成功的插件二进制文件拷贝到本地 |
| 46 | +
|
| 47 | + ``` |
| 48 | + compile: |
| 49 | + @echo "### compile docker-macvlan plugin" |
| 50 | + @docker build -q -t builder -f Dockerfile.dev . |
| 51 | + @echo "### extract docker-macvlan" |
| 52 | + @docker create --name tmp builder |
| 53 | + @docker cp tmp:/go/bin/macvlan-driver ./docker-macvlan |
| 54 | + @docker rm -vf tmp |
| 55 | + @docker rmi builder |
| 56 | +
|
| 57 | + ``` |
| 58 | +
|
| 59 | +- 插件打包 |
| 60 | +
|
| 61 | + 一个标准的docker第三方插件必须包含config.json文件和rootfs文件系统。 |
| 62 | +
|
| 63 | + 1. 编写Dockerfile |
| 64 | +
|
| 65 | + 以alpine镜像为基础运行环境,把插件可执行文件打包到镜像中 |
| 66 | +
|
| 67 | + ``` |
| 68 | + FROM alpine |
| 69 | +
|
| 70 | + RUN mkdir -p /run/docker/plugins |
| 71 | +
|
| 72 | + COPY docker-macvlan /usr/bin/docker-macvlan |
| 73 | +
|
| 74 | + CMD ["/usr/bin/docker-macvlan"] |
| 75 | +
|
| 76 | + ``` |
| 77 | +
|
| 78 | + 2. 编写config.json |
| 79 | +
|
| 80 | + 配置插件基本参数 |
| 81 | +
|
| 82 | + ``` |
| 83 | + { |
| 84 | + "description": "macvlan Net plugin for Docker swarm", |
| 85 | + "documentation": "", |
| 86 | + "entrypoint": [ |
| 87 | + "docker-macvlan" |
| 88 | + ], |
| 89 | + "interface": { |
| 90 | + "socket": "macvlan_swarm.sock", |
| 91 | + "types": [ |
| 92 | + "docker.networkdriver/1.0" |
| 93 | + ] |
| 94 | + }, |
| 95 | + "linux": { |
| 96 | + "capabilities": [ |
| 97 | + "CAP_SYS_ADMIN", |
| 98 | + "CAP_NET_ADMIN" |
| 99 | + ] |
| 100 | + }, |
| 101 | + "mounts": null, |
| 102 | + "env": [ |
| 103 | + { |
| 104 | + "description": "Extra args to `macvlan_swarm` and `plugin`", |
| 105 | + "name": "EXTRA_ARGS", |
| 106 | + "settable": [ |
| 107 | + "value" |
| 108 | + ], |
| 109 | + "value": "" |
| 110 | + } |
| 111 | + ], |
| 112 | + "network": { |
| 113 | + "type": "host" |
| 114 | + }, |
| 115 | + "workdir": "" |
| 116 | + } |
| 117 | +
|
| 118 | + ``` |
| 119 | +
|
| 120 | + 3. 编写Makefile |
| 121 | +
|
| 122 | + 生成插件文件系统rootfs,和config.json拷贝到插件目录plugin |
| 123 | +
|
| 124 | + ``` |
| 125 | + rootfs: |
| 126 | + @echo "### docker build: rootfs image with docker-macvlan" |
| 127 | + @docker build -q -t ${PLUGIN_NAME}:rootfs . |
| 128 | + @echo "### create rootfs directory in ./plugin/rootfs" |
| 129 | + @mkdir -p ./plugin/rootfs |
| 130 | + @docker create --name tmp ${PLUGIN_NAME}:rootfs |
| 131 | + @docker export tmp | tar -x -C ./plugin/rootfs |
| 132 | + @echo "### copy config.json to ./plugin/" |
| 133 | + @cp config.json ./plugin/ |
| 134 | + @docker rm -vf tmp |
| 135 | + @docker rmi ${PLUGIN_NAME}:rootfs |
| 136 | +
|
| 137 | + ``` |
| 138 | +
|
| 139 | +- 插件上传 |
| 140 | +
|
| 141 | + 插件可以上传到hub公共仓库,也可以上传到本地私有仓库,如果要上传本地私有库,插件的名字必须按照此格式192.168.1.2:5000/plugin_name,才能上传成功。 |
| 142 | +
|
| 143 | + 1. 编写Makefile |
| 144 | +
|
| 145 | + 通过指定插件目录plugin创建本地插件,启用插件并上传到镜像仓库 |
| 146 | +
|
| 147 | + ``` |
| 148 | + create: |
| 149 | + @echo "### remove existing plugin ${PLUGIN_NAME} if exists" |
| 150 | + @docker plugin rm -f ${PLUGIN_NAME} || true |
| 151 | + @echo "### create new plugin ${PLUGIN_NAME} from ./plugin" |
| 152 | + @docker plugin create ${PLUGIN_NAME} ./plugin |
| 153 | +
|
| 154 | + enable: |
| 155 | + @echo "### enable plugin ${PLUGIN_NAME}" |
| 156 | + @docker plugin enable ${PLUGIN_NAME} |
| 157 | +
|
| 158 | + push: clean compile rootfs create enable |
| 159 | + @echo "### push plugin ${PLUGIN_NAME}" |
| 160 | + @docker plugin push ${PLUGIN_NAME} |
| 161 | +
|
| 162 | + ``` |
| 163 | +
|
| 164 | +- 插件安装 |
| 165 | +
|
| 166 | + 所有docker节点通过docker plugin install命令安装插件 |
| 167 | +
|
| 168 | + ``` |
| 169 | + docker plugin install ${PLUGIN_NAME} --grant-all-permissions |
| 170 | + |
| 171 | + ``` |
0 commit comments