Docker

Dockerfile 阅读更多

Docker原理 阅读更多

init-system 阅读更多

Package 阅读更多

Registry 阅读更多

Docker命令 阅读更多

启动 docker 守护进程 # systemctl start docker docker 命令介绍 # docker --help 管理命令: container 管理容器 image 管理镜像 network 管理网络 命令: attach 介入到一个正在运行的容器 build 根据 Dockerfile 构建一个镜像 commit 根据容器的更改创建一个新的镜像 cp 在本地文件系统与容器中复制 文件/文件夹 create 创建一个新容器 exec 在容器中执行一条命令 images 列出镜像 kill 杀死一个或多个正在运行的容器 logs 取得容器的日志 pause 暂停一个或多个容器的所有进程 ps 列出所有容器 pull 拉取一个镜像或仓库到 registry push 推送一个镜像或仓库到 registry rename 重命名一个容器 restart 重新启动一个或多个容器 rm 删除一个或多个容器 rmi 删除一个或多个镜像 run 在一个新的容器中执行一条命令 search 在 Docker Hub 中搜索镜像 start 启动一个或多个已经停止运行的容器 stats 显示一个容器的实时资源占用 stop 停止一个或多个正在运行的容器 tag 为镜像创建一个新的标签 top 显示一个容器内的所有进程 unpause 恢复一个或多个容器内所有被暂停的进程 在子命令中还有更多丰富的选项,可以使用 docker COMMAND --help 查看。例如: docker run --help

Docker安装 阅读更多

卸载旧版本 旧版本中Docker的名字叫 docker 或者 docker-engine sudo apt-get remove docker docker-engine docker.io /var/lib/docker 目录中的内容包括: images containers volumes networks 新版的Docker CE名字叫 docker-ce。 存储驱动 在Ubuntu下,Docker CE 支持overlay2和aufs。 Linux kernel 4 以上版本overlay2比aufs更好。 Linux kernel 3 版本只有aufs,overlay和overlay2不支持这个内核。 安装新版本 下载Docker的存储仓库,然后进行下载安装,这样也便于卸载和升级。(推荐方式) 在脱机离线的环境下,下载Deb安装包,手动安装和配置 在测试或者开发环境中使用自动化脚本安装 以Docker存储仓库的形式安装 配置存储仓库 更新apt安装包的索引信息 $ sudo apt-get update 安装必要的工具使得apt能够通过HTTPS来使用存储仓库 sudo apt-get install apt-transport-https ca-certificates curl software-properties-common 添加Docker官方的GPG 密钥 $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 或者从阿里云开源镜像仓库下载GPG和密钥 curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add - 通过搜索指纹的最后8个字符,确认现在拥有指纹9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88的密钥。 $ sudo apt-key fingerprint 0EBFCD88 pub 4096R/0EBFCD88 2017-02-22 Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 uid Docker Release (CE deb) <docker@docker.com> sub 4096R/F273FCD8 2017-02-22 设置稳定版存储仓库 $ sudo add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs)\ stable" 如果需要测试版,把stable修改好edge或test,docker 17.06开始稳定版也会被放在测试版的仓库中。 使用阿里云这里也需要修改 sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs)stable" lsb_release -cs 命令会获取Ubuntu的发行版代号,如果使用的是一些子发行版(如Linux Mint Rafaela,需要将这个命令的返回值修改为trusty,即对应的父发行版代号) 安装Docker ce 更新apt安装包的索引信息 sudo apt-get update 安装最新版的docker-ce sudo apt-get install docker-ce apt-get install 和 apt-get update 通常安装和升级最新版。 安装指定版本的docker-ce apt-cache madison docker-ce //列出存储仓库中所有版本 docker-ce | 18.09.0~ce-0~ubuntu | https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages sudo apt-get install docker-ce=<VERSION> //使用全名安装对应版本 Docker daemon会自动运行。 验证docker-ce是否安装成功 sudo docker run hello-world 安装完成后,docker组被创建但是其中并没有用户,所以需要使用sudo来运行docker的命令 以非root用户管理Docker Docker 守护进程绑定在Unix套接字而不是TCP端口。默认情况下,Unix套接字由用户root拥有,而其他用户只能使用sudo访问它。Docker守护程序始终以root用户身份运行。 如果不想在docker命令前加上sudo,请创建一个名为docker的Unix组并向其添加用户。当Docker守护程序启动时,它会创建一个可由docker组成员访问的Unix套接字。 注意,docker组被授予的是和root用户一样的权限。有关这将如何影响系统安全性的详细信息,查看这边 https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface 创建docker用户组 $ sudo groupadd docker 添加用户到docker用户组 $ sudo usermod -aG docker $USER 登出并重新登录,来重新更新组成员关系 如果在虚拟机上进行测试,则可能需要重新启动虚拟机才能使更改生效。 在桌面Linux环境(如X Windows)上,完全注销会话,然后重新登录。 验证是否可以运行docker命令,而不需要sudo $ docker run hello-world 如果在创建docker组并向其中添加用户之前,已经使用sudo运行过docker命令的话,那么会看到如下报错信息: WARNING: Error loading config file: /home/user/.docker/config.json - stat /home/user/.docker/config.json: permission denied 这是因为执行sudo命令而创建的〜/.docker/目录的权限不正确。 要解决此问题, 删除〜/.docker/目录(它会自动重新创建,但任何自定义设置都会丢失) 使用以下命令更改其所有权和权限: $ sudo chown "$USER":"$USER" /home/"$USER"/.docker -R $ sudo chmod g+rwx "$HOME/.docker" -R 升级docker-ce sudo apt-get update 找到对应版本进行升级。 卸载docker-ce 卸载docker-ce软件包 $ sudo apt-get purge docker-ce 删除images,volumes,containers,自定义配置文件 $ sudo rm -rf /var/lib/docker 配置Docker开机自启 大多数主流的Linux发行版(RHEL, CentOS, Fedora, Ubuntu 16.04及以上版本)使用 systemd来管理系统启动时启动的服务。Ubuntu 14.10及以下版本使用 upstart。 systemd $ sudo systemctl enable docker $ sudo systemctl disable docker 如果需要添加HTTP代理,为Docker运行时文件设置不同的目录或分区,或进行其他自定义,请参阅自定义systemd Docker守护程序。 upstart $ echo manual | sudo tee /etc/init/docker.override //取消开机自启 chkconfig $ sudo chkconfig docker on 使用不容的存储引擎 查看这里 https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/

Docker常见错误汇总 阅读更多

1. certificate has expired or is not yet valid 一般是因为本地系统时间错误导致证书过期。 解决方法: 同步服务器之间的时间。 2. dial unix /var/run/docker.sock: permission denied 在 Linux 环境下,一些新装了 docker 的用户,特别是使用了 sudo 命令安装好了 Docker 后,发现当前用户一执行 docker 命令,就会报没权限的错误。 解决方式: sudo usermod -aG docker $USER 将用户添加到docker组 这里说的权限问题,是指使用 docker 命令操作本机 dockerd 引擎,也就是通过 /var/run/docker.sock 来操作 dockerd 引擎,只有这种有之前说的权限类的问题。 而 docker 命令还可以操作远程 dockerd 的引擎,也就是 -H参数,或者 DOCKER_HOST 环境变量所指定的 Docker 主机。这种情况通讯走的是网络、HTTP,不会有权限问题。所以,如果不打算操作本机的 dockerd 引擎,则不需要将用户加入 docker 组,也是可以操作远程服务器的。

下载海外镜像 阅读更多

0.1. 常用镜像下载地址 0.2. 操作方式 0.2.1. 配置docker代理 0.2.2. 第一步登录阿里云 0.2.3. 第二步登录Google Cloud Platfrom 0.2.4. 从阿里云Docker Registry中拉取镜像 0.3. 附加 0.1. 常用镜像下载地址 Docker Hub QUAY Google Cloud Platfrom <https://console.cloud.google.com/gcr/images/<所要下载的镜像的仓库名称>: 如果是goolge的仓库就是goolge-containers 如果是linkerd的仓库就是linkerd-io 以此类推 通常需要的镜像可以在以上两个仓库下载到,但是,在国内直接通过docker命令下载海外镜像通常情况下都是无法下载的。 比如执行如下命令,拉去Google的镜像: docker pull gcr.io/google-containers/kubernetes-dashboard:v0.1.0 因此需要采取一个迂回操作,共三个步骤。 0.2. 操作方式 首先需要有个梯子。 0.2.1. 配置docker代理 最快捷的方式。 为docker服务创建一个内嵌的systemd目录mkdir -p /etc/systemd/system/docker.service.d 创建/etc/systemd/system/docker.service.d/http-proxy.conf文件 添加HTTP_PROXY环境变量 [Service]Environment="HTTP_PROXY=socks5://127.0.0.1:1080" "HTTPS_PROXY=socks5://127.0.0.1:1080" 更新配置 systemctl daemon-reload 重启Docker服务 systemctl restart docker 0.2.2. 第一步登录阿里云 另一种方式。 国内提供容器仓库服务的公有云都可以。 点击阿里云免费提供的容器镜像服务 选择一个距离自己比较近的节点,大陆主要有一下几个选择: 华东1(杭州) 华东2(上海) 华北1(青岛) 华北2(北京) 华北3(张家口) 华北4(呼和浩特) 华南1(深圳) 新建一个命名空间,命名空间可以分为公开(其他人也可以拉取)和私有两种 在命名空间下新建需要的镜像仓库 一个镜像就是一个仓库,同一个镜像的不同版本通过Tag区分 点击创建好的仓库后可以看到仓库的基本信息、操作指南和镜像描述 第二步中的操作,就主要参考这里的操作指南。 0.2.3. 第二步登录Google Cloud Platfrom 访问地址:https://console.cloud.google.com/getting-started Google提供了免费的Cloud Shell: 默认就已经预装了docker,查看版本为18.03.1-ce,以后可能会继续升级吧 Cloud Shell 有5G的存储空间,基本够用 登录Google账号,点击右侧头像旁边的激活Cloud Shell 在Cloud Shell中登录阿里云Docker Registry docker login --username=<你的阿里云账号> registry.cn-shanghai.aliyuncs.com # 用于登录的用户名为阿里云账号全名,密码为开通服务时设置的密码。 # 您可以在产品控制台首页修改登录密码。 登录一次之后,以后都不需要在重新登录。 下载需要的海外镜像到Cloud Shell中,如: docker pull gcr.io/google-containers/kubernetes-dashboard:v0.1.0 将镜像push到阿里云Docker Registry中 docker tag gcr.io/google-containers/kubernetes-dashboard:v0.1.0 registry.cn-shanghai.aliyuncs.com/promacanthus/kubernetes-dashboard:v0.1.0 docker push registry.cn-shanghai.aliyuncs.com/promacanthus/kubernetes-dashboard:v0.1.0 # docker client对镜像进行push时,根据镜像名字中包含的registry地址进行传输 以上操作,在阿里云的容器镜像服务的每个仓库的操作指南中有详细说明。 0.2.4. 从阿里云Docker Registry中拉取镜像 docker pull registry.cn-shanghai.aliyuncs.com/promacanthus/kubernetes-dashboard:v0.1.0 0.3. 附加 阿里云的容器镜像服务还有一个很好用的功能,镜像加速器。 虽然Docker Hub的镜像我们可以直接拉取,很多时候pull的非常慢,这时候镜像加速器就很好用了。 登录阿里云容器镜像服务 点击左侧导航栏中的镜像中心,选择镜像加速器 首先是一个加速器地址,每个用户都会有一个不同的加速器地址 具体在自己电脑上的配置查看操作文档的说明

加速器 阅读更多

Docker官方加速器 官网地址:https://www.docker-cn.com/registry-mirror Docker 中国官方镜像加速可通过 registry.docker-cn.com 访问。该镜像库只包含流行的公有镜像。私有镜像仍需要从美国镜像库中拉取。 手动拉取 使用以下命令直接从该镜像加速地址进行拉取: docker pull registry.docker-cn.com/myname/myrepo:mytag docker pull registry.docker-cn.com/library/ubuntu:16.04 注: 除非修改了 Docker 守护进程的 --registry-mirror 参数 (见下文), 否则需要完整地指定官方镜像的名称。例如,library/ubuntu、library/redis、library/nginx。 参数配置 使用 --registry-mirror配置 Docker 守护进程默认使用 Docker 官方镜像加速。这样可以默认通过官方镜像加速拉取镜像,而无需在每次拉取时指定 registry.docker-cn.com。 可以在 Docker 守护进程启动时传入 --registry-mirror 参数: bash docker --registry-mirror=https://registry.docker-cn.com daemon 为了永久性保留更改,修改 /etc/docker/daemon.json文件并添加上 registry-mirrors 键值。 json { "registry-mirrors": ["https://registry.docker-cn.com"] } 注: 可以使用适用于 Mac 的 Docker 和适用于 Windows 的 Docker 来进行设置。 或者修改这里:(保证服务已经enable) sudo vim /etc/systemd/system/multi-user.target.wants/docker.service # 在行尾添加这些信息 ExecStart=/usr/bin/dockerd --registry-mirror=https://registry.docker-cn.com 修改保存后重启 Docker 以使配置生效: sudo systemctl daemon-reload sudo systemctl restart docker docker进程重启或升级,容器是否会被重启 在 1.12 以前的版本确实如此,但是从 1.12 开始,Docker 引擎加入了 --live-restore 参数,使用该参数可以避免引擎升级、重启导致容器停止服务的情况。 默认情况该功能不会被启动,如需启动,需要配置 docker 服务配置文件。比如 Ubuntu 16.04 这类 systemd 的系统,可以修改 /etc/systemd/system/multi-user.target.wants/docker.service 文件,在 ExecStart= 后面配置上 --live-restore,如下所示: ExecStart=/usr/bin/dockerd \ --registry-mirror=https://registry.docker-cn.com \ --live-restore 需要注意的是,--live-restore 和 Swarm Mode 不兼容,所以在集群环境中不要使用。实际上集群环境也不用担心某个服务器重启的问题,因为其上的服务都会被调度到别的节点上,因此服务并不会被中断。 执行命令,查看是否生效: docker info 阿里加速器 阿里云容器Hub服务提供了官方的镜像站点加速官方镜像的下载速度。 使用镜像加速器 在不同的系统下面,配置加速器的方式有一些不同,所以我们介绍主要的几个操作系统的配置方法。 关于加速器的地址,你只需要登录容器Hub服务的控制台,左侧的加速器帮助页面就会显示为你独立分配的加速地址。 具体配置 当你下载安装的Docker Version不低于1.10时,建议直接通过daemon config进行配置。 使用配置文件 /etc/docker/daemon.json(没有时新建该文件) { "registry-mirrors": ["<your accelerate address>"] }sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://******.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker 重启Docker Daemon就可以了。

容器执行宿主机命令 阅读更多

容器中执行docker命令 把docker相关的命令和依赖使用-v挂载到容器中 docker run -it -d \ --restart=always -u root \ -v /usr/bin/docker:/usr/bin/docker \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/lib64/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7 镜像名称 参数说明: --restart=always #Docker重启后该容器也为随之重启 -u root #以root的身份去运行镜像(避免在容器中调用Docker命令没有权限) #最好使用docker用户去运行 --privileged #或者使用这个参数,表示该容器真正使用root权限 -v /usr/bin/docker:/usr/bin/docker #将宿主机的docker命令挂载到容器中 #可以使用which docker命令查看具体位置 #或者把挂载的参数改为: -v $(which docker):/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock #容器中的进程可以通过它与Docker守护进程进行通信 -v /usr/lib64/libltdl.so.7:/usr/lib/x86_64-linux-gnu/libltdl.so.7 #libltdl.so.7是Docker命令执行所依赖的函数库 #容器中library的默认目录是 /usr/lib/x86_64-linux-gnu/ #把宿主机的libltdl.so.7 函数库挂载到该目录即可 #可以通过whereis libltdl.so.7命令查看具体位置 #centos7位置/usr/lib64/libltdl.so.7 #ubuntu位置/usr/lib/x86_64-linux-gnu/libltdl.so.7 为当前用户赋予执行docker命令的权限 如果之前为docker创建过用户,则需要执行以下命令,没有的话直接跳过 #则需要把将当前用户加入docker组 sudo gpasswd -a ${USER} docker #或者将当前用户直接加到文件中 sudo echo "`docker:x:994:${USER}``" >> /etc/group #查看docker用户组成员 cat /etc/group |grep docker #重新启动docker服务 sudo systemctl restart docker #当前用户退出系统重新登陆 Pod中执行kubernetes命令 使用kubectl 在Dockerfile中添加如下命令: RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl RUN chmod +x ./kubectl RUN sudo mv ./kubectl /usr/local/bin/kubectl 使用上述Dockerfile创建的容器中执行命令报错如下: The connection to the server : was refused - did you specify the right host or port? 使用restful API 在api-server上运行如下命令, curl http://localhost:8080/api/v1/namespaces/default/pods #localhost修改为IP或DNS 根据配置,需要使用安全相关的证书 使用如下命令找到api的endpoint: kubectl get pods --v=8 需要配置基于角色的权限访问控制,为pod创建一个service account并运行它。这个service account应该具有所需namespace中pod列表的权限。需要创建一个角色,并且绑定到刚才创建的service account上。 集群中的每一个容器都需要有一个可以向API server发起认证的token。在容器中执行如下命令: cat /var/run/secrets/kubernetes.io/serviceaccount/token 要向apiserver发出请求,在容器中运行如下命令: curl -ik \ -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ https://kubernetes.default.svc.cluster.local/api/v1/namespaces/default/pods https相关安全问题,执行如下命令: curl https://ip:8443/api/v1/namespaces/default/pods --cacert ca.pem --insecure --key client-key.pem --cert client.pem /usr/local/bin/kubectl: cannot execute binary file kubectl执行命令需要能够访问apiserver,也就是说: apiserver的主机名和端口保存在环境变量中KUBERNETES_SERVICE_HOST和KUBERNETES_SERVICE_PORT access token被挂载在var/run/secrets/kubernetes.io/serviceaccount/token 服务证书被挂载在/var/run/secrets/kubernetes.io/serviceaccount/ca.crt 这是kubectl连接到apiserver时需要知道的所有数据。 以上配置不能运行的一些思考: 容器没有运行在kubernetes集群中,即容器需要以pod的形式运行 访问被认证插件限制了(不是默认的插件) service account 中证书的被pod 的定义覆盖了(spec.serviceAccountName) kubectl 比 api 简单 在容器中下载并编译kubectl 编译应用,拷贝kubectl到容器中 可以了 一种认证更严格 更方便的 pod访问api 的方式: 为pod创建service account,然后配置pod使用这个service account 配置一个rolebinding或者clusterrolebinding来运行服务有权限和kubernetes api通信 直接访问api 或者使用客户端来管理api的访问,推荐使用客户端的方式,它具有pod的自动配置,删除正常请求所需的身份验证令牌步骤。 部署完成需要有以下对象:serviceaccount clusterrolebinding deployment

容器访问宿主机网络 阅读更多

单机环境 如果是单机环境,很简单,不必琢磨怎么突破命名空间限制,直接用环境变量送进去即可。 docker run -d -e HOST_IP=<宿主的IP地址> nginx 然后容器内直接读取 HOST_IP 环境变量即可。 集群环境 进程运行在容器中,如果通过localhost访问的是容器的localhost,而不是宿主机的localhost。 如何从容器中访问到宿主机的网络? 使用宿主机IP 使用host网络 使用宿主机IP 安装Docker的时候,会在宿主机上安装一个虚拟网关docker0,可以使用宿主机在docker0上的IP地址来替代localhost。 sugoi@thinkpad:~$ ifconfig docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 inet6 fe80::42:c3ff:fed9:32c0 prefixlen 64 scopeid 0x20<link> ether 02:42:c3:d9:32:c0 txqueuelen 0 (以太网) RX packets 654034 bytes 35089343 (35.0 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 757538 bytes 15529486900 (15.5 GB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 docker0的宿主机IP地址为172.17.0.1,直接使用这个IP地址,可以实现容器访问宿主机网络。 注意,不同系统下,docker0可能是不一样的,通过这个IP地址访问不通用。 使用host网络 容器运行的时候有host、bridge、none,三种网络可以配置。 默认使用bridge,即桥接网络,以桥接的模式连接到宿主机 host,直接使用宿主机网络,即容器与宿主机共用网络 none,表示无网络,这种情况下,容器将无法联网 docker 运行时,使用如下参数设置容器的网络: --network string Connect a container to a network (default "default") --network-alias list Add network-scoped alias for the container 当--network 设置参数为host时,可以不用-p参数来进行容器和宿主机端口的映射,因为容器本身就与宿主机共享了网络,因此容器中暴露的端口就是宿主机上暴露的端口 优势:使用host的方式,不需要修改IP地址,容器运行在不同的系统中都可以,很通用。 不足:host直接使用宿主机的网络,没有bridge的隔离性好,安全性不高

手动实现一个容器 阅读更多

容器 实现一个资源隔离的容器: 文件系统:chroot命令切换根目录挂载点 网络:在分布式环境下进行通信和定位,需要有独立的IP、端口、路由等,还需要有独立的主机名以便在网络中标识自己 通信:有了网络自然需要通信,进程键通信需要隔离开 权限:对用户和用户组的隔离实现用户权限的隔离 进程:运行在容器中的应用需要有进程号,容器需要有PID进行隔离 一个容器所需要的6项隔离: namespace 系统调用参数 隔离内容 UTC CLONE_NEWUTC 主机名和域名 IPC CLONE_NEWIPC 信号量、消息队列、共享内存 PID CLONE_NEWPID 进程编号 Network CLONE_NEWNET 网络设备、网络栈、端口等 Mount CLONE_NEWNS 挂载点(文件系统) User CLONE_NEWUSER 用户和用户组 Linux内核实现namespace的目的:实现轻量级虚拟化(容器)服务。 镜像 Docker 通过distribution、registry、layer、image、reference等模块实现了Docker镜像的管理。在Docker1.10以前的版本中这一功能通过graph组件来完成。 distribution:负责与Docker Registry交互,上传下载镜像以及存储与v2 registry有关的元数据 registry:负责与Docker Registry有关的身份验证、镜像查找、镜像验证以及管理registry mirror等交互操作 image:负责与镜像元数据有关的存储、查找、镜像层的索引、查找以及镜像tar包有关的导入、导出等操作 reference:负责存储本地所有镜像的repository和tag名,并维护与镜像ID之间的映射关系 layer:负责与镜像层和容器层元数据有关的增删改查,并负责将镜像层的增删改查操作映射到实际存储镜像层文件系统的graphdriver模块

通过socket与docker通信 阅读更多

运行过Docker Hub的Docker镜像的话,会发现其中一些容器时需要挂载/var/run/docker.sock文件。 这个文件是什么呢?为什么有些容器需要使用它? 简单地说,它是Docker守护进程(Docker daemon)默认监听的Unix域套接字(Unix domain socket),容器中的进程可以通过它与Docker守护进程进行通信。 如下图所示: 举个例子 不妨看一下 Portainer,它提供了图形化界面用于管理Docker主机和Swarm集群。如果使用Portainer管理本地Docker主机的话,需要绑定/var/run/docker.sock: docker volume create portainer_data docker run --name portainer \ -d -p 9000:9000 \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/dat \ portainer/portainer:1.20.1 访问9000端口可以查看图形化界面,可以管理容器(container),镜像(image),数据卷(volume)… Portainer通过绑定的/var/run/docker.sock文件与Docker守护进程通信,执行各种管理操作。 Docker守护进程的API 安装Docker之后,Docker守护进程会监听Unix域套接字:/var/run/docker.sock。这一点可以通过Docker daemon的配置选项看出来(在ubuntu上执行cat /etc/default/docker ): -H unix:///var/run/docker.sock 注: 监听网络TCP套接字或者其他套接字需要配置相应的-H选项。 运行容器 使用Portainer的UI,可以轻松创建容器。实际上,HTTP请求是通过docker.sock发送给Docker守护进程的。可以通过curl创建容器来说明这一点。使用HTTP接口运行容器需要两个步骤,先创建容器,然后启动容器。 1. 创建nginx容器 curl命令通过Unix套接字发送{“Image”:”nginx”}到Docker守护进程的/containers/create接口,这个将会基于Nginx镜像创建容器并返回容器的ID。 curl -XPOST --unix-socket /var/run/docker.sock \ -d '{"Image":"nginx"}' \ -H 'Content-Type: application/json' \ http://localhost/containers/create `` # 输出返回了容器ID: {"Id":"fcb65c6147efb862d5ea3a2ef20e793c52f0fafa3eb04e4292cb4784c5777d65","Warnings":null} 2. 启动nginx容器 使用返回的容器ID,调用/containers/start接口,即可启动新创建的容器。 curl -XPOST --unix-socket /var/run/docker.sock http://localhost/containers/fcb6...7d65/start 查看已启动的容器: docker 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.sock运行容器其实非常简单。 Docker守护进程的事件流 Docker的API提供了/events接口,可以用于获取Docker守护进程产生的所有事件流。负载均衡组件(load balancer)组件可以通过它获取容器的创建/删除事件,从而动态地更新配置。 通过创建一个简单的容器,我们可以了解如何利用Docker守护进程的事件。 1. 运行alpine容器 下面的命令用于运行容器,并采用交互模式(interactive mode,该模式下会直接进入容器内),同时绑定docker.sock。 docker run -v /var/run/docker.sock:/var/run/docker.sock -ti alpine sh 2. 监听Docker守护进程的事件流 在alpine容器内,可以通过Docker套接字发送HTTP请求到/events接口。这个命令会一直等待Docker daemon的事件。当新的事件发生时(例如创建了新的容器),会看到输出信息。 curl --unix-socket /var/run/docker.sock http://localhost/events 3. 观察事件 基于Nginx镜像运行容器之后,通过aplpine容器的标准输出可以观察到Docker daemon生成的事件。 docker run -p 8080:80 -d nginx 可以观察到3个事件: 创建容器 连接默认的桥接网络(bridge network) 启动容器 总结 注意: 绑定Docker套接字之后,容器的权限会很高,可以控制Docker守护进程。因此,这一点必须谨慎使用,只能用于足够信任的容器。