Docker
1.摘要
本篇博客参考了《微服务架构基础》和一些其他教程,对Docker进行了较为全面的总结,以便加深理解和记忆。
2.概述
1)来源
Docker是一个开源的应用容器引擎,基于go语言开发,诞生于2013年,包括Community Edition(CE社区版,免费)和Enterprise Edition(EE企业版,付费),遵从Apache2.0开源协议。
2)功能
Docker可以让应用及其依赖封装到一个可移植的镜像中,发布到任意Linux机器上,也可也实现虚拟化。Docker完全使用沙箱机制,相互隔离,保证了容器之间的安全性。
3)特点
特点 | 解释 |
---|---|
快速交付和部署 | 镜像简化了容器环境的搭建过程,轻量且启动速度快 |
更高效的虚拟化 | 运行时无需额外的虚拟机程序支持,属于内核级的虚拟化,因而可以具有更高的性能与效率 |
更轻松的迁移与扩展 | Docker容器几乎可以在任何平台上运行,包括物理机、虚拟机、公有云、私有有、PC机和服务器等。这种良好的兼容性有利于应用的迁移和扩展 |
更简单的管理 | 所有修改可以以增量的方式被分发和更新,从而实现自动化并高效的管理 |
4)Docker与虚拟机的区别
①虚拟机:运行在每个应用层级的客户端操作系统上,是资源密集型。由于磁盘的镜像和应用程序的操作系统相互交叉,所以导致虚拟机对操作系统的依赖性很强,一旦系统出现问题,虚拟机依赖的文件都可能存在丢失的情况。
②Docker容器:进程级的隔离,多个容器可以共享单个内核,且创建Docker容器的镜像所需要的配置不依赖于宿主机器。正是由于容器间配置的隔离性,容器之间没有配置交叉,因而Docker拥有很好的可移植性。

5)运行机制
- Docker引擎
Docker Engine是Docker的核心部分,使用的CS架构,其主要组成部分如下:
名称 | 功能 |
---|---|
docker CLI(command line interface) | Docker的命令接口(客户端组件),开发者可以在命令行中使用Docker相关指令与Docker守护进程交互,从而进行一些操作 |
REST API | Docker应用程序接口,开发者可以通过API接口与Docker的守护进程交互,从而执行相应的操作 |
docker daemon | Docker的服务端组件,它是Docker架构中在后台运行的一个守护进程,负责接收由命令行和API接口的指令,然后执行相应的后台操作 |

- Docker架构
名称 | 功能 |
---|---|
Client客户端 | 可认为是Docker CLI,开发者通过该命令接口与后台守护进程交互以执行相应指令 |
DOCKER_HOST Docker主机 | Docker内部引擎运行的主机,主要指Docker daemon。可以与客户端和Docker镜像仓库交互,以实现本地-远程镜像/容器的管理 |
Registry注册中心 | Docker镜像仓库,默认使用Docker官方远程注册仓库Docker Hub |

6)Docker底层技术
名称 | 功能 |
---|---|
Namespace 命名空间 | Docker通过命名空间来提供隔离的工作空间,当一个容器运行时,Docker会为该容器创建一系列的命名空间,并为命名空间提供一层隔离。每个容器运行在相对隔离的环境下,对其他命名空间是相对受限的 |
Control groups 控制组 | Linux系统的Docker Engine依赖于Control groups的技术,控制组可以对程序进行资源限定,并允许Docker引擎在容器间进行硬件资源共享以及随时进行限制和约束 |
Union file systems 联合文件系统 | UnionFS是一种分层、轻量级且高性能的文件系统,它支持将文件系统的修改作为一次提交来一层层的叠加,同时还可以将不同目录挂载到同一虚拟文件系统下。不同Docker容器可以共享一些基础的文件系统层,与自己独有的改动层一起使用,大大地提高了存储效率。Docker支持的UnionFS包括:AUFS、btrfs、vfs和DeviceMapper |
Container format 容器格式 | Docker Engine将命名空间、控制组和联合文件系统组合成一个叫容器格式的整体,当前默认的容器格式是libcontainer,未来Docker可能与其他技术(如BSD Jails、Solaris Zones等)的集成使用来开发其他容器格式 |
3.安装
1)安装要求
Docker支持多种平台,但由于Docker是基于Ubuntu发布的,因而官方更推荐在Ubuntu上使用Docker。以Ubuntu系统为例,Docker安装需要满足:
①Ubuntu版本的支持(Ubuntu Trusty 14.04(LTS)、Ubuntu Xenial 14.04(LTS)、Ubuntu Zesty 17.04、其他更高版本)
②Ubuntu的内核支持:Docker需要在64位Ubuntu上安装,其内核版本不能低于3.10(可以通过 uname -r
查看)
2)安装方式
- 在线安装
# 使用国内镜像源一键安装
curl -sSL https://get.daocloud.io/docker | sh
# 启动docker服务
sudo systemctl start docker
# 测试安装是否成功,运行内置的hello-world镜像
sudo docker run hello-world
# 删除docker安装包
yum remove docker-ce
# 删除镜像、容器、配置文件等
rm -rf /var/lib/docker
- 离线安装
在docker官网的下载页下载对应系统、对应版本、对应机器架构的安装包,如Ubuntu下的.deb文件,上传至Ubuntu系统中,进行安装
sudo dpkg -i {path}/package.deb
# 检验安装
- 通过脚本文件安装
4.使用
4.1服务管理
# 启动docker守护线程
systemctl daemon-reload
# 启动docker
systemctl start docker
# 配置Docker开机启动
sudo systemctl enable docker
# 配置当前用户执行Docker权限
sudo usermod -aG docker {username}
# 查看docker服务是否启动
ps -ef |grep docker
# 重启docker服务
systemctl restart docker
# 停止docker服务
systemctl stop docker
4.2Dockerfile构建镜像
Dockerfile文件用于构建Docker镜像,其命令包含了构建镜像的配置信息。
1)基本结构
Dockerfile的结构包括4个基本部分:
# 1.基础镜像信息:用于定义基础镜像,构建时从本地或DockerHub中拉取
FROM ubuntu
# 2.定义镜像维护者的信息:一般为 系统用户名+邮箱
MAINTAINER {docker_user} {email}
# 3.镜像操作指令:构建镜像时要执行的指令,可以有多条
RUN echo "deb https://archive.ubuntu.com/ubuntu/" raring main universe >> /etc/apt/source.list
RUN apt-get update && apt-get install -y nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
# 4.容器启动时指令:容器在每次启动时执行的指令,通常是运行某个应用,只能有一条,多条时只有最后一条生效
CMD /user/sbin/nginx
2)常用指令
# 1.FROM
FROM <image>
FROM <image>:<tag>
# 2.MAINTAINER
MAINTAINER "lincat"<2596874177@qq.com>
# 3.RUN
# 每条RUN指令都会在当前基础镜像上执行并提交为新的镜像,多条RUN指令合并为一条可以减小镜像构建时的体积
RUN <command> # 在shell终端(/bin/sh -c)中执行
RUN ["executable","param1","param2"] RUN ["/bin/bash","-c","echo hello"] # exec执行方式,使用其他终端时使用这种方式
# 4.CMD
CMD ["executable","param1","param2"] # exec执行方式,推荐方式
CMD command param1 param2 # /bin/sh 中执行,提供给需要交互的应用
CMD ["param1","param2"] # 提供给ENTRYPOINT的默认参数
# 5.EXPOSE:声明容器内部暴露的端口号,供容器访问连接使用
EXPOSE <port> [<port>...]
# 6.ENV:用于为下文设置一个环境变量,该变量在后续指令和内联文件中都可以使用
ENV <key> <value> # 设置单一k-v对,第一个空格后的所有字符会被认为是value的内容
ENV <key>=<value> <key>=<value> ... # 设置多个k-v对,引号、反斜杠等会被拆解
# 7.ADD:用于复制指定路径的文件、目录或URL资源到容器的指定目录下,其中压缩包复制后会被自动解压
ADD <src>... <container path>
# 8.COPY:与ADD指令类似,但不能用于URL资源,也不会自动解压压缩包
COPY <src> ... <container path>
# 9.ENTRYPOINT:配置容器启动后执行的命令,每个Dockerfile中只能有一个,多条只有最后一条生效
ENTRYPOINT ["executable","param1","param2"] # exec格式,推荐
ENTRYPOINT command param1 param2 # shell格式
# 10.WORKDIR:为后续的指令指定工作目录,可以多次使用
WORKDIR /path/to/workdir
###### 示例 ######
# 涉及到两个外部文件requirements.txt和app.py
# sudo vim Dockerfile
# 使用Docker官方的Python作为一个基础镜像
FROM python:2.7-slim
# 设置容器的工作目录/app
WORKDIR /app
# 复制当前目录下的所有内容到容器的/app目录下
ADD . /app
# 安装在requirements.txt中声明的文件包
RUN pip install -r requirements.txt
# 设置容器暴露的端口号
EXPOSE 80
# 定义环境变量
ENV NAME World
# 当容器启动后立即允许app.py
CMD {"python","app.py"}
4)通过Dockerfile文件构建镜像
# 创建镜像
docker build -t {image_name}
5).dockerignore文件
Docker读取应用上下文中的Dockerfile之前会先将.dockerignore文件中声明的文件或目录排除,再读Dockerfile构建镜像,它有助于在进行文件复制时避免向进程中加入过大或敏感无用的文件和目录
4.3镜像管理
# 列出本机所有镜像
docker images 或 docker image ls
# 从远程仓库拉镜像
docker pull ubuntu:13.10
docker pull ubunto:lastest
# 更新镜像 在容器中使用
apt-get update
# 删除镜像
docker rmi imageName/imageId
# 强制删除镜像
docker rmi -f/-force imageName/imageId
# 为镜像添加标签(软链接)
docker tag imageName dockerUserName/imageName:version
4.4容器管理
# 创建容器并运行
# -i 交互式操作
# -t 终端
# -d 运行模式:后台运行
# -p 端口映射,将服务器的端口80映射到容器的8080端口
# /bin/bash 创建并运行容器时要求给出一个容器执行的操作,这里即是启动命令行
docker run -p 80:8080 --name containerName -itd imageName /bin/bash
# 列出运行的容器
docker ps
# 列出所有包括已经停止运行的容器
docker ps -a
# 启动一个停止的容器
docker start containerName/containerId
# 停止一个容器
docker stop containerName/containerId
# 重启一个容器
docker restart containerName/containerId
# 删除容器:需要是停止状态
docker rm -f containerName/containerId
# 进入一个容器:进入容器退出后,容器会自动停止,不推荐
docker attach containerName/containerId
# 进入一个容器:进入容器退出后,容器不会自动停止,推荐
docker exec -it containerName/containerId /bin/bash
# 退出容器
docker exit
# 查看容器的端口映射情况
docker port containerName/containerId
# 查看容器的配置和状态信息:返回json数据,可以在inspect后加上{{'attributeName'}}单独看某一
字段
docker inspect containerName/containerId
# 将服务器上的文件复制到容器中
docker cp severAbsoluteFilePath
containerName/containerLongId:containerAbsoluteFilePath
# 查看容器日志
docker logs -f containerName/containerId
# 查看容器进程
docker top containerName/containerId
# 将一个容器变保存为镜像
docker commit containerId imagesName
# 导出容器
docker export containerName/containerId > container.tar
# 导入一个容器:将container.tar导入到 dockerUserName/imageName:version镜像中
cat docker/container.tar | docker import - dockerUserName/imageName:version
4.5仓库管理
# 登录:密码模式,token模式
docker login
# 搜索镜像
docker search imageName
# 搜索自己的镜像
docker search userName/imageName
# 推送镜像:注意推送镜像必须先给镜像打带有自己用户名前缀的tag才能推送
docker push username/imageNanem:version
2)Docker Registry
Docker Registry相比于Docker官方提供的开放的镜像仓库,Docker Registry是用户私人搭建的镜像仓库。
在想严格控制镜像的存储位置,完全拥有自己的镜像分配渠道,或想将镜像存储和分布紧密嵌入到自己开发的程序中,可以使用Docker Registry。
下面给出通过命令行搭建和访问Docker Registry的方法,除此以外,还可以通过Portus等第三方可视化私有仓库工具来简化操作
①Docker Registry仓库搭建
# 1.生成签名证书:访问权限验证
mkdir registry && cd registry && mkdir certs && certs
openssl req # 使用openssl生成自签名证书
-x509 # 自签名证书的格式
-days 3650 # 证书有效期
-subj '/CN={ip}:port/' # 具体部署Docker Registry本地仓库的地址和端口
-nodes
-newkey rsa:2048 # 证书算法长度
# 以下两个是证书文件
-keyout domain.key
-out domain.crt
# 2.生成账户密码
cd .. && mkdir auth
docker run --entrypoint htpasswd registry:2 -Btn {username} {password} > auth/htpasswd
# 3.启动Docker Registry
docker run -d # 后台运行该容器
-p 5000:5000
--restart=always # 本地私有镜像仓库宕机后始终自动重启
--name registry # 生成的容器名为registry
# 将容器内的默认存储位置/var/lib/registry中的数据挂在到宿主机的/mnt/resgitry目录下
# 这样以来,当容器销毁后,容器中/var/lib/registry下的数据会自动被分到宿主机指定位置
# Dock Registry 有 v1、v2版本,v1基于python开发,v2基于go开发,v1容器的默认挂载点为/tmp/registry,下面的v2的
-v /mnt/registry:/var/lib/registry \
# 配置账户和证书的位置
-v `pwd` /auth:/auth \
-v `pwd` /certs:/certs
# 配置用户连接信息
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key
registry:2
# 4.配置docker registry访问接口:创建证书目录,并将证书复制到创建的证书目录下
sudo mkdir -p /etc/docker/certs.d/{ip}:{port}
sudo cp certs/domain.crt /etc/docker/certs.d/{ip}:{port}
②私有Docker Registry仓库访问
# 1.私有仓库登记
sudo vim /etc/docker/daemon.json
{"insecure-registries":["{ip}:{port}"]}
# 2.重启Docker
sudo /etc/init.d/docker restart
# 3.镜像推送
## 2.1 登录私有Docker Registry仓库
docker login {ip}:{port}
## 2.2镜像重命名:必须符合:{仓库ip}:{port}/{repository_name}的格式
docker tag {local_image_name}:{version/lastest} {remote_ip}:{port}/{repository_name}
## 2.3推送镜像
docker push {remote_ip}:{port}/{repository_name}
## 在宿主机的浏览器上输入:http://{ip}:{port}/v2/{repository_name}/tag/list验证
## 在本地磁盘的/mnt/registry/docker/registry/v2/repositories中可以查看映射到数据盘的数据
4.6数据管理
1)数据存储机制
①通过Dockerfile文件创建的镜像,会在某个基础镜像之上层层提交修改(对应每一条指令)
②通过某一镜像构建容器时,会在镜像层之上增加一个容器层。不同容器进行的(数据)修改由各自保存,共享底层的镜像层。当容器层被删除时,容器层包括其存储的数据也会被一同删除,底层的镜像层保持不变

2)数据存储方式
① 存储在容器层
默认情况下,数据都是存储在容器层的,这样会有很多缺陷:
缺陷 |
---|
容器停止后数据无法持久化保存 |
容器中的数据难以被其他数据共享,想共享则需要容器提供专门的机制(如搭建资源访问系统) |
容器机与运行的主机紧密耦合,难以轻易地移动数据 |
容器层需要一个存储驱动程序来管理文件系统,存储驱动程序提供了一个使用Linux内核的联合文件系统,这种额外的抽象降低了性能 |
②数据外挂
由数据存储在容器中的缺陷,我们通常不会将数据直接存放于容器中,而是采用Docker volume数据外挂机制,将数据映射到宿主机中,有如下三种方式:
名称 | 解释 |
---|---|
volumes 数据卷 | 存储在宿主机的特定位置(Linux下为/var/lib/Docker/volumes/)并由Docker管理,非Docker进程无法修改文件系统的这个部分 |
bind mounts 绑定挂载 | 可存储在宿主机的任意位置,Docker进程和非Docker进程都可以对它们任意修改 |
tmpfs mouts | 只存储在宿主机的内存中,不进行持久化 |

下面着重对volumes数据卷方式进行介绍
3)volumes 数据卷
Volumes数据卷比bind mounts更容易备份和迁移,可以使用Docker CLI或API进行管理,跨平台性更好,更加安全,允许加密和云存储,是持久化容器数据、数据共享的很好选择
# 创建数据卷
docker volume create {volume_name}
# 查看数据卷
docker volume ls
# 查看某一数据卷详情
docker volume inspect {volume_name}
# 删除数据卷
docker volume rm {volume_name}
# 启动容器并挂载数据卷:容器挂载数据卷后,可以在/var/lib/docker/目录下的containers/和volumes/中查看绑定的容器和数据卷
docker run -itd --name {container_name}
# 以下是两种挂载方式(bind mount和tmpfs方式的参数顺序有所不同)
# mount在Docker早期版本适用于集群中,但后来也适用于单机,参数顺序可变,以key=value形式
# source为数据卷名称,target或其他替代参数为容器内映射的路径,type为类型,readonly为只读
-mount source={volume_name},target/dst/destination={mount_path},type={volume|bind|tmpfs},readonly
# -v应用于单机模式,参数顺序不可变,参数之间以逗号分割,ro为readonly,可省略
-v {volume_name}:{mount_path}:[ro]
4.7网络管理与容器互联
Docker默认使用bridge(单主机互联)和overlay(跨主机互联)两种网络驱动来进行容器的网络管理,用户还可自定义网络驱动插件来进行Docker容器的网络管理。
- 单机互联
1)单机下的默认网络
单机下Docker自带三种网络:bridge(容器的默认网络驱动,配置后可以与宿主机实现通信)、host、none(后两者属于无网络,容器无法与外界通信)
# 查看docker支持的网络类型
docker network ls
# 查看某一网络的具体详情
docker network inspect bridge
2)单机下的自定义网络
单机下的自定义网络,即是自定义bridge网络,它是基于原有的bridge网络创建的新的网络,可以较好的实现容器隔离
# 创建自定义网络,创建基于bridge网络的名为{self_network_name}的网络,由于bridge是单机下的默认网络,故可省略
docker network create --driver bridge {self_network_name}
# 使用自定义网络启动容器
docker run --network={self_network_name} -itd --name={container_name}
# 为容器添加网络管理,一个容器可以有多个网络驱动
docker network connect {network_name} {container_name}
# 断开容器的网络连接,若一个容器的所有网络连接被断开,容器仍会运行,但外界无法访问
docker network disconnect {network_name} {container_name}
# 删除自定义网络,移除前应该将使用该网络的容器全部断开
docker network rm {self_network_name}
3)单机下的容器互联
①未使用相同网络管理的容器之间不能通信
②使用默认bridge网络管理的容器之间可以通过IP通信,但无法通过容器名称通信
③使用自定义bridge网络管理的容器之间可以通过容器名称通信
# 进入容器,可以通过exit和CTRL + P + Q退出,其中exit会使得容器停止,组合键会让容器保持运行
docker attach {container_name}
# 查看网络ip配置
ipconfig
# 测试网络连通性,-w 4限制响应次数为4次
ping -w {limit_response_time} IP
# 默认网络下,在容器创建时通过容器名进行通信,但是该方式是docker低版本的遗留功能,未来可能弃用
docker run -itd --name={container_name} --link {link_container_name}:{nickname}
- 跨主机互联
见Swarm集群的网络管理
4.8Swarm集群
1)介绍
Docker Swarm是一个用于创建和管理Docker集群的工具,Docker 1.12以后都集成了swarmkit工具,该工具主要用于Docker集群管理和容器编排。因此,开发者可以不用安装额外的工具就可以通过简单的命令创建并管理Swarm集群。
Docker Swarm集群算是微服务等架构推动的产物,此前较为成熟的容器集群工具有谷歌的开源系统架构Kubernetes和Apache的分布式管理框架Mesos等。
2)特点
特点 | 解释 |
---|---|
使用方便 | 可直接使用Docker客户端来创建和管理Docker集群,无需部署第三方工具 |
可扩展 | 集群中的每个服务,都可以声明运行副本任务的数量,向上或向下扩展时,集群管理器将通过增加或删除副本任务来自动适应所需的状态 |
可实现期望的状态调节 | 集群管理器节点不断地监视集群状态,并协调实际状态和期望状态之间的任何差异。如启动某一服务的10个副本,其中两个副本崩溃后,管理器将创建 |
集群中多主机网络自动扩展管理 | 当集群服务的覆盖网络初始化或更新应用时,集群管理器会自动在工作节点创建或更新网络来管理服务 |
提供服务发现功能 | 集群管理器节点为集群中每个服务分配一个唯一的DNS名称,通过Dcoker Swarm提供的负载均衡功能,可以通过嵌入在集群中的DNS服务器查询每一个运行的容器 |
实现负载均衡 | 可以将容器中服务的端口暴露给外部负载均衡器,而在内部允许指定如何在节点之间分配服务器 |
安全性强 | 群中的每个节点强制使用TLS相互认证和加密,以确保自身和其他节点之间的通信安全,还支持使用自定义的签名证书保证安全 |
支持延迟更新和服务回滚 | 进行服务更新时可以将服务逐步延申到各个节点上,集群管理器允许服务部署到不同节点组之间出现延迟;若某个节点出现问题,还可以将服务回滚到之前的版本 |
3)集群搭建
准备多台Linux机器,其中一台作为管理节点,其余作为工作节点。
# 1.创建Docker Swarm集群
# 在管理节点上,创建Swarm集群,并设至当前节点为管理节点
# 注意在创建集群后,会返回当前集群的token凭证,用于其他节点的注册
docker swarm init --advertise-addr {ip}
# 查看集群节点信息
docker node ls
# 2.向Docker Swarm集群添加工作节点
# 在工作节点上,使用创建Swarm集权的token凭证
docker swarm join --token {token} {manager_node_ip}
# 3.向Docker Swarm集群部署服务
# 在工作节点上,部署服务时可以使用Docker Hub上的基础镜像,也可以使用自定义的镜像,但是使用本地的自定义镜像时,需先上传至Docker Hub
# 另外集群中的服务管理与单机的镜像管理类似,只是docker container变为了docker service
docker service create # 创建容器
--replicas {copy_number} # 服务副本数量
--name {service_name} # 服务名称
{remote_image_name} # Docker Hub远程镜像名
{operation} # 服务启动后执行的命令
# e.g.
docker service create --replicas 1 --name helloworld apline ping docker.com
# 4.查看Docker Swarm集群中的服务
# 管理节点上
docker service ls
# 查看某一服务的具体情况
docker service inspect {service_name}
# 查看某一服务在集群上的分配和运行情况
docker service ps {service_name}
# 5.更改服务的副本数量
# 集群环境下,副本是随机均衡分配到不同节点上,运行显示running状态。
# 有时当镜像过大时,拉取镜像可能需要一定时间,服务会显示prepare状态
# 管理节点上
docker service scale {service_name}={number}
# 通过 docker service ps 可以查看具体的分布和运行情况
# 6.删除服务
# 管理节点上,删除时有一定延迟
docker service rm {service_name}
4)网络管理
集群状态下会增加两个网络类型:docker_gwbridge(以bridge驱动)、ingress(以overlay驱动),其中ingress是服务默认的网络类型。
实际中会使用基于overlay驱动的自定义网络
# 1.构建自定义网络
# 管理节点
docker network create
--driver overlay
[--subnet 10.0.0.0/24] # 定义子网段
{self_network_name}
# 2.使用自定义网络部署服务,并向外部暴露端口号以便访问
# 工作节点,在工作节点使用管理节点创建的自定义网络时,工作节点会自动创建对应的自定义网络,并在服务移除时随之移除
docker service create --network {network_name} --name {service_name} --publish {outer_ip:inner:ip} --replicas {copy_number} {remote_image_name} {operation}
5)集群可视化工具visualizer
4.9Docker Compose
Docker Compose,Docker编排工具,是用来定义和运行多容器应用的Docker工具。通过该工具可通过docker-compose.yaml配置文件来配置服务,只需要一条简单的命令就可以创建并启动所有服务,提高了部署效率(否则逐一运行不同参数的dockerfile文件,给部署和维护都带来了很多麻烦)
1)linux下的安装与卸载
# Docker Compose依赖于Docker引擎,因而安装前需确保Docker已经安装
docker -v
# 通过github下载compose的发行版
sudo curl -L https://github.com/docker/compose/releases/download/{version}/docker-compose-`uname` -s-`uname -m` -o /usr/local/bin/docker-compose
# 更改docker compsoe的可执行文件权限
sudo chmod +x /usr/local/bin/docker-compose
# 验证安装
docker-compose --version
# 卸载
sudo rm /usr/local/bin/docker-compose
2)使用方法
①编写Dockerfile文件,定义应用运行的环境,然后构建镜像
②定义docker-compose.yaml文件,对每个应用的执行和参数进行统一定义
# 版本约束
version: '3'
# 网络定义
networks: {network_name}
# 数据卷定义
volumes: {volume_name}
# 容器/服务定义,每一个缩进即是一个服务
web:
# 容器/服务运行的镜像
image: id/imagename:label
# 重启策略:no,always:服务会一直重启,on-failture:容器/服务失败后重启,unless-stop:容器/服务停止后重启
restart: on-failure
# 容器/服务名,若在集群的多实例下,该参数会被忽略
container_name: my-web-container
# 宿主机-容器/服务的端口映射
ports: {port}:{port}
# 容器/服务运行时使用的网络
networks: {network_name}
# 该容器/服务所依赖的容器,被依赖的容器会被先启动,但不意味着被依赖的容器启动后,依赖容器才启动
depends_on: {service_name}
# 设置容器/服务
enviroment:
{key}: {value}
...
# 容器/服务中应用的部署策略,该策略在集群时生效,单机时会被忽略
deploy:
# 副本数
replicas: {copy_number}
# 应用的重启策略
restart_policy: on-failture
# restart_policy:
# condition: on-failture
# delay: 5s
# max_attempts: 3
# 表示等待多久来确定应用是否启动成功
# window: 120s
# 应用部署的位置副本部署的实际机器是随机的,可以限定应用部署在执行机器上
placement:
# 限制应用部署的位置在管理机器上
constraints: [node.role == manager]
# 服务关联,与depents_on的执行规则一致
links:
...
③运行docker-compose部署指令,启动所有应用
# 1.非集群下的部署
# 部署服务
docker-compose up
# 停止服务
docker-compose down
# 2.集群下的部署
# 部署集群服务
docker stack deploy -c docker-compose-swarm.yml [--with-registry-auth] {swarm-service-name}
# 查看集群部署时的具体情况
docker stack ps {swarm-service-name}
# 查看某一服务日志
docker service logs -f {swarm-service-name}-{service-name}