Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了。
容器(Container):基于镜像创建的轻量化的运行实例,包含应用代码、运行时环境和依赖库。
镜像(Image):只读模板,定义了容器的运行环境。
Dockerfile:文本文件,描述如何自动构建镜像(例如指定基础镜像、安装软件、复制文件等)。
仓库(Registry):存储和分发镜像的平台,可以包含一个镜像的多个版本。如 Docker Hub(官方公共仓库)或私有仓库(如 Harbor)。
容器共享主机内核,轻量、隔离且高效,不像虚拟机需要完整的操作系统。

| 特性 | 虚拟机 | Docker容器 |
|---|---|---|
| 隔离级别 | 硬件级别虚拟化 | 操作系统级别虚拟化 |
| 操作系统 | 每个VM需要完整OS | 共享宿主机OS内核 |
| 资源占用 | 重量级,占用较多资源 | 轻量级,资源占用少 |
| 启动时间 | 分钟级别 | 秒级别 |
| 性能开销 | 较大 | 接近原生性能 |
| 镜像大小 | GB级别 | MB级别 |

虚拟机适用场景:需要完全隔离的环境、运行不同操作系统的应用、需要硬件级别的安全隔离
Docker容器适用场景:微服务架构、CI/CD流水线、应用快速部署和扩展、开发环境标准化
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程 API 来管理和创建 Docker 容器。

Docker Client(客户端):用户与Docker交互的主要方式,接收用户命令并发送给Docker Daemon,可以与远程Docker Daemon通信
Docker Daemon(守护进程):Docker的核心服务进程,管理镜像、容器、网络和存储卷,监听Docker API请求并处理
Docker Engine(引擎):是Docker的核心组件
组成:Docker Client + Docker Daemon + REST API
Docker Registry(仓库):存储和分发Docker镜像,提供镜像的版本管理,支持公有和私有仓库
Docker 架构工作流程:

Docker Compose:一个用于定义和运行多容器 Docker 应用的工具。用户可以使用一个 docker-compose.yml 配置文件定义多个容器(服务),并可以通过一个命令启动这些容器。
Docker Compose 主要用于开发、测试和部署多容器应用。
创建一个简单的 docker-compose.yml 文件来配置一个包含 Web 服务和数据库服务的应用:
yml
version: '3'
services:
web:
image: nginx
ports:
- "8080:80"
db:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: example
启动 Compose 定义的所有服务:
docker-compose up
Docker Swarm: Docker 提供的集群管理和调度工具。允许将多个 Docker 主机(节点)组织成一个集群,并通过 Swarm 集群管理工具来调度和管理容器。
初始化 Swarm 集群:
docker swarm init
Docker Networks(网络):允许容器之间相互通信,并与外部世界进行连接。Docker 提供了多种网络模式来满足不同的需求,如 bridge 网络(默认)、host 网络和 overlay 网络等。
创建一个自定义网络并将容器连接到该网络:
docker network create my_network
docker run -d --network my_network ubuntu
Docker Volumes(卷): 一种数据持久化机制,允许数据在容器之间共享。与容器文件系统不同,卷的内容不会随着容器的销毁而丢失,适用于数据库等需要持久存储的应用。
创建并挂载卷:
docker volume create my_volume
docker run -d -v my_volume:/data ubuntu
Docker 的工作流程
Docker 并非是一个通用的容器工具,它依赖于已存在并运行的 Linux 内核环境。
Docker 实质上是在已经运行的 Linux 下制造了一个隔离的文件环境,因此它执行的效率几乎等同于所部署的 Linux 主机。
因此,Docker 必须部署在 Linux 内核的系统上。如果其他系统想部署 Docker 就必须安装一个虚拟 Linux 环境。
国内从 DockerHub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。
Docker 官方和国内很多云服务商都提供了国内加速器服务,例如:
当配置某一个加速器地址之后,若发现拉取不到镜像,请切换到另一个加速器地址。
国内各大云服务商均提供了 Docker 镜像加速服务,建议根据运行 Docker 的云平台选择对应的镜像加速服务。
阿里云镜像获取地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors 登陆后,左侧菜单选中镜像加速器就可以看到你的专属地址了:

在系统右下角托盘 Docker 图标内右键菜单选择 Settings,打开配置窗口后左侧导航菜单选择 Daemon。
在 Registrymirrors 一栏中填写加速器地址 https://docker.mirrors.ustc.edu.cn/ ,之后点击 Apply 保存后 Docker 就会重启并应用配置的镜像地址了。

检查加速器是否生效
效配置加速器之后,如果拉取镜像仍然十分缓慢,请手动检查加速器配置是否生效,在命令行执行 docker info,如果从结果中看到了如下内容,说明配置成功。
$ docker info
Registry Mirrors:
https://reg-mirror.qiniu.com
Docker 客户端是与Docker Daemon交互的命令行工具。
可以直接输入 docker 命令来查看到 Docker 客户端的所有命令选项。
$ docker
可以通过命令 docker command --help 更深入的了解指定的 Docker 命令使用方法。
例如我们要查看 docker stats 指令的具体使用方法:
$ docker stats --help
| 命令 | 功能 | 示例 |
|---|---|---|
| docker run | 启动一个新的容器并运行命令 | docker run -d ubuntu |
| docker ps | 列出当前正在运行的容器 | docker ps |
| docker ps -a | 列出所有容器(包括已停止的容器) | docker ps -a |
| docker build | 使用 Dockerfile 构建镜像 | docker build -t my-image . |
| docker images | 列出本地存储的所有镜像 | docker images |
| docker pull | 从 Docker 仓库拉取镜像 | docker pull ubuntu |
| docker push | 将镜像推送到 Docker 仓库 | docker push my-image |
| docker exec | 在运行的容器中执行命令 | docker exec -it container_name bash |
| docker stop | 停止一个或多个容器 | docker stop container_name |
| docker start | 启动已停止的容器 | docker start container_name |
| docker restart | 重启一个容器 | docker restart container_name |
| docker rm | 删除一个或多个容器 | docker rm container_name |
| docker rmi | 删除一个或多个镜像 | docker rmi my-image |
| docker logs | 查看容器的日志 | docker logs container_name |
| docker inspect | 获取容器或镜像的详细信息 | docker inspect container_name |
| docker exec -it | 进入容器的交互式终端 | docker exec -it container_name /bin/bash |
| docker network ls | 列出所有 Docker 网络 | docker network ls |
| docker volume ls | 列出所有 Docker 卷 | docker volume ls |
| docker-compose up | 启动多容器应用(从 docker-compose.yml 文件) | docker-compose up |
| docker-compose down | 停止并删除由 docker-compose 启动的容器、网络等 | docker-compose down |
| docker info | 显示 Docker 系统的详细信息 | docker info |
| docker version | 显示 Docker 客户端和守护进程的版本信息 | docker version |
| docker stats | 显示容器的实时资源使用情况 | docker stats |
| docker login | 登录 Docker 仓库 | docker login |
| docker logout | 登出 Docker 仓库 | docker logout |
常用选项说明 | 选项 | 说明 | 示例 | | ---- | ---- | ---- | | -d | 后台运行容器 | docker run -d ubuntu | | -it | 以交互式终端运行容器 | docker exec -it container_name bash | | -t | 为镜像指定标签 | docker build -t my-image . |

如果我们本地没有 ubuntu 镜像,我们可以使用 docker pull 命令来载入 ubuntu 镜像:
$ docker pull ubuntu
以下命令使用 ubuntu 镜像启动一个容器,参数为以命令行模式进入该容器:
$ docker run -it ubuntu /bin/bash
# 或
$ docker run -i -t ubuntu /bin/bash
# 后台运行
$ docker run -d ubuntu /bin/bash
# 注:加了 -d 参数默认不会进入容器,想要进入容器需要使用指令 docker exec
参数说明:
-i: 交互式操作。
-t: 终端。
-d: 后台运行容器。
ubuntu: ubuntu 镜像。
/bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。
要退出终端,直接输入 exit。
查看所有的容器:
$ docker ps -a
停止容器:
$ docker stop 容器id
容器之前通过 docker stop 或正常退出后,需要重新启动
$ docker start 容器id
重启一个正在运行或已停止的容器
$ docker restart 容器id
在使用 -d 参数时启动容器时,容器会运行在后台,这时如果要进入容器,可以通过以下命令进入:
docker attach:允许你与容器的标准输入(stdin)、输出(stdout)和标准错误(stderr)进行交互。
docker exec:推荐大家使用 docker exec 命令,因为此命令会退出容器终端,但不会导致容器的停止。
$ docker attach 容器id
# 注意: 如果从这个容器退出,会导致容器停止。
$ docker exec -it 容器id /bin/bash
# 注意: 如果从这个容器退出,容器不会停止。
# 更多参数说明请使用 docker exec --help 命令查看。
如果要导出本地某个容器,可以使用 docker export 命令。
$ docker export 1e560fca3906 > ubuntu.tar
# 导出容器 1e560fca3906 快照到本地文件 ubuntu.tar
可以使用 docker import 从容器快照文件中再导入为镜像,以下实例将快照文件 ubuntu.tar 导入到镜像 test/ubuntu:v1:
$ cat docker/ubuntu.tar | docker import - test/ubuntu:v1
此外,也可以通过指定 URL 或者某个目录来导入,例如:
$ docker import http://example.com/exampleimage.tgz example/imagerepo
删除一个容器,可以使用 docker rm 命令。
$ docker rm 容器id
删除已停止的容器,可以使用 -f 参数:
$ docker rm -f 容器id
清理掉所有处于终止状态的容器。
$ docker container prune
接下来让我们尝试使用 docker 构建一个 web 应用程序。
我们将在docker容器中运行一个 Python Flask 应用来运行一个web应用。
docker pull training/webapp # 载入镜像
docker run -d -P training/webapp python app.py
运行成功后,我们可以通过 docker ps 命令查看容器的运行状态。
docker ps
CONTAINER ID IMAGE COMMAND ... PORTS
d3d5e39ed9d3 training/webapp "python app.py" ... 0.0.0.0:32769->5000/tcp
Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 32769 上。
我们可以通过浏览器访问WEB应用:
http://localhost:32769
访问成功后,可以看到如下页面:

也可以通过 -p 参数明确指定端口:
docker run -d -p 5000:5000 training/webapp python app.py
使用 docker port 可以查看指定 (ID 或者名字)容器的某个确定端口映射到宿主机的端口号。
docker port <container_id>
# 或
docker port <container_name>
# 结果
5000/tcp -> 0.0.0.0:5000
docker logs [ID或者名字]
$ docker logs -f bf08b7f2cd89
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
192.168.239.1 - - [09/May/2016 16:30:37] "GET / HTTP/1.1" 200 -
192.168.239.1 - - [09/May/2016 16:30:37] "GET /favicon.ico HTTP/1.1" 404 -
从上面,我们可以看到应用程序使用的是 5000 端口并且能够查看到应用程序的访问日志。
docker top [ID或者名字]
$ docker top bf08b7f2cd89
UID PID PPID C STIME TTY TIME CMD
root 1580 1535 0 08:30 ? 00:00:00 python app.py
docker inspect [ID或者名字]
docker stop [ID或者名字]
docker start [ID或者名字]
docker restart [ID或者名字]
docker rm [ID或者名字]
删除容器时,容器必须是停止状态。
docker rm -f [ID或者名字]
强制删除容器时,容器可以运行。
当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu 14.04 90d5884b1ee0 5 days ago 188 MB
php 5.6 f40e9e0f10c8 9 days ago 444.8 MB
nginx latest 6f8d099c3adc 12 days ago 182.7 MB
mysql 5.6 f2e8d6c772c0 3 weeks ago 324.6 MB
httpd latest 02ef73cf1bc0 3 weeks ago 194.4 MB
ubuntu 15.10 4e3b13c8a266 4 weeks ago 136.3 MB
hello-world latest 690ed74de00f 6 months ago 960 B
training/webapp latest 6fae60ef3446 11 months ago 348.8 MB
REPOSITORY:表示镜像的仓库源
同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本,如 ubuntu 仓库源里,有 15.10、14.04 等多个不同的版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。
例如要使用版本为15.10的ubuntu系统镜像来运行容器时,命令如下:
$ docker run -t -i ubuntu:15.10 /bin/bash
# 只使用 ubuntu,docker 将默认使用 ubuntu:latest 镜像。
我们可以从 Docker Hub 网站来搜索镜像,Docker Hub 网址为: https://hub.docker.com/
我们也可以使用 docker search 命令来搜索镜像。比如我们需要一个 httpd 的镜像来作为我们的 web 服务
docker search httpd

docker commit从已经创建的容器中更新镜像,并且提交这个镜像
$ docker commit -m "update" -a "yourname" 5a0c7b4d5a0c myapp:v2
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myapp v2 5a0c7b4d5a0c 7 minutes ago 348.8 MB
-m参数指定镜像的描述,-a参数指定镜像的作者。5a0c7b4d5a0c是容器的ID,myapp:v2是镜像名称和标签。
docker build 命令用于创建镜像。为此,我们需要创建一个 Dockerfile 文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像。
创建一个 Dockerfile 文件,内容如下:
$ cat Dockerfile
FROM ubuntu:15.10
RUN apt-get update
RUN apt-get install -y nginx
EXPOSE 80
CMD ["nginx"]
每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。
FROM 指定使用哪个镜像源
RUN 指令告诉docker 在镜像内执行命令,安装了什么。
EXPOSE,指定nginx的端口号
CMD,指定nginx的启动命令
然后,我们使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像。
$ docker build -t mynginx .
镜像构建完成后,我们可以使用 docker images 命令查看镜像。
$ docker tag mynginx mynginx:v1
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mynginx v1 5a0c7b4d5a0c 7 minutes ago 348.8 MB
mynginx latest 5a0c7b4d5a0c 7 minutes ago 348.8 MB
前面实现了通过网络端口来访问运行在 docker 容器内的服务。
容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P 或 -p 参数来指定端口映射。
$ docker run -d -P training/webapp python app.py
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fce072cc88ce training/webapp "python app.py" 7 seconds ago Up 6 seconds 0.0.0.0:49153->5000/tcp naughty_poitras
$ docker run -d -p 5000:5000 training/webapp python app.py
$ docker ps
CONTAINER ID IMAGE COMMAND ... PORTS NAMES
33e4523d30aa training/webapp "python app.py" ... 0.0.0.0:5000->5000/tcp berserk_bartik
fce072cc88ce training/webapp "python app.py" ... 0.0.0.0:32768->5000/tcp grave_hopper
可以指定容器绑定的网络地址,比如绑定 127.0.0.1
$ docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
$ docker ps
CONTAINER ID IMAGE COMMAND ... PORTS NAMES
95c6ceef88ca training/webapp "python app.py" ... 5000/tcp, 127.0.0.1:5001->5000/tcp adoring_stonebraker
33e4523d30aa training/webapp "python app.py" ... 0.0.0.0:5000->5000/tcp berserk_bartik
fce072cc88ce training/webapp "python app.py" ... 0.0.0.0:32768->5000/tcp grave_hopper
默认都是绑定 tcp 端口,如果要绑定 UDP 端口,可以在端口后面加上 /udp
$ docker run -d -p 127.0.0.1:5001:5000/udp training/webapp python app.py
$ docker ps
CONTAINER ID IMAGE COMMAND ... PORTS NAMES
95c6ceef88ca training/webapp "python app.py" ... 5000/tcp, 5000/udp, 127.0.0.1:5001->5000/tcp
$ docker port adoring_stonebraker 5000
127.0.0.1:5001
端口映射并不是唯一把 docker 连接到另一个容器的方法。
docker 有一个连接系统允许将多个容器连接在一起,共享连接信息。
docker 连接会创建一个父子关系,其中父容器可以看到子容器的信息。
# 先创建一个新的 Docker 网络,并列出所有网络:
# -d:参数指定 Docker 网络类型,有 bridge、overlay。
$ docker network create -d bridge test-net
$ docker network ls
# 运行一个容器并连接到新建的 test-net 网络:
$ docker run -itd --name test1 --network test-net ubuntu /bin/bash
# 打开新的终端,再运行一个容器并加入到 test-net 网络:
$ docker run -itd --name test2 --network test-net ubuntu /bin/bash
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0c0f0c5c0c0f ubuntu "/bin/bash" 2 seconds ago Up 1 second test2
9c0f0c5c0c0f ubuntu "/bin/bash" 2 seconds ago Up 1 second test1
# 下面通过 ping 来证明 test1 容器和 test2 容器建立了互联关系。
# 如果 test1、test2 容器内中无 ping 命令,则在容器内执行以下命令安装 ping(可以在一个容器里安装好,提交容器到镜像,在以新的镜像重新运行以上俩个容器)。
$ apt-get update
$ apt install iputils-ping
$ docker exec -it test1 /bin/bash
# 在 test1 容器输入以下命令:
$ ping test2
如果你有多个容器之间需要互相连接,推荐使用 Docker Compose,后面会介绍。
在宿主机的 /etc/docker/daemon.json 文件中增加以下内容来设置全部容器的 DNS:
{
"dns" : [
"114.114.114.114",
"8.8.8.8"
]
}
设置后,启动容器的 DNS 会自动配置为 114.114.114.114 和 8.8.8.8。
配置完,需要重启 docker 才能生效。
查看容器的 DNS 是否生效可以使用以下命令,它会输出容器的 DNS 信息:
$ docker run -it --rm ubuntu cat etc/resolv.conf
nameserver 114.114.114.114
nameserver 8.8.8.8
如果只想在指定的容器设置 DNS,则可以使用以下命令:
$ docker run -it --rm -h host_ubuntu --dns=114.114.114.114 --dns-search=test.com ubuntu
# --rm:容器退出时自动清理容器内部的文件系统。
# -h HOSTNAME 或者 --hostname=HOSTNAME: 设定容器的主机名,它会被写到容器内的 /etc/hostname 和 /etc/hosts。
# --dns=IP_ADDRESS: 添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名。
# --dns-search=DOMAIN: 设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的主机时,DNS 不仅搜索 host,还会搜索 host.example.com。
如果在容器启动时没有指定 --dns 和 --dns-search,Docker 会默认用宿主主机上的 /etc/resolv.conf 来配置容器的 DNS。
在Windows中运行docker,实际上还是在Windows下先安装了一个Linux环境,然后在这个系统中运行的docker。也就是说,服务中使用的localhost指的是这个Linux环境的地址,而不是我们的宿主环境Windows。
通过命令:
docker-machine ip default
# 其中,default 是docker-machine的name,可以通过docker-machine -ls 查看找到这个Linux的ip地址,
# 一般情况下这个地址是192.168.99.100,然后在Windows的浏览器中,输入这个地址,加上服务的端口即可启用了。
比如,首先运行一个docker 容器:
docker run -it -p 8888:8888 conda:v1
# 其中,conda:v1是我的容器名称。然后在容器中开启jupyter notebook 服务:
jupyter notebook --no-browser --port=8888 --ip=172.17.0.2 --allow-root
# 其中的ip参数为我的容器的ip地址,可以通过如下命令获得:
docker inspect container_id
# 最后在windows浏览器中测试结果:
http://192.168.99.100:8888
Docker 官方维护了一个公共仓库 Docker Hub。
免费注册一个 Docker 账号登录就可以从 docker hub 上拉取自己账号下的全部镜像。
$ docker login
Username: <username>
Password: <password>
Login Succeeded
$ docker search ubuntu # 以 ubuntu 为关键词搜索镜像
$ docker pull ubuntu
$ docker tag ubuntu:18.04 username/ubuntu:18.04 # username 请替换为你的 Docker 账号用户名
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED ...
ubuntu 18.04 275d79972a86 6 days ago ...
username/ubuntu 18.04 275d79972a86 6 days ago ...
$ docker push username/ubuntu:18.04 # 推送镜像
$ docker search username/ubuntu
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
username/ubuntu
$ docker logout # 注销
Dockerfile 是一个文本文件,包含了构建 Docker 镜像的所有指令
下面以定制一个 nginx 镜像为例(构建好的镜像内会有一个 /usr/share/nginx/html/index.html 文件)
在一个空目录下,新建一个名为 Dockerfile 文件,并在文件内添加以下内容:
$ mkdir Dockerfile
$ cd Dockerfile/
$ vim Dockerfile
$ cat Dockerfile
FROM nginx
# FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。
RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html
# RUN:用于执行后面跟着的命令行命令。有以下俩种格式:1. RUN <命令> 2. RUN [<可执行文件>, <参数1>, <参数2>...]
# 例如:RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。 例如:
FROM centos
RUN yum -y install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz
以上执行会创建 3 层镜像。可简化为以下格式:
FROM centos
RUN yum -y install wget \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gz
在 Dockerfile 文件的存放目录下,执行构建动作。
以下示例,通过目录下的 Dockerfile 构建一个 nginx:v3(镜像名称:镜像标签)。
$ docker build -t nginx:v3 .
Sending build context to Docker daemon
Step 1/3 : FROM nginx
---> 9e05c5c0c0c1
Step 2/3 : RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html
---> Running in 0c0d0c0d0c0d
Removing intermediate container 0c0c0c0c0c0c
---> 0c0c0c0c0c0c
Successfully built 0c0c0c0c0c0c
Successfully tagged nginx:v3
# 镜像构建成功后,可以通过 docker images 命令查看镜像列表。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v3 0c0c0c0c0c0c 2 minutes ago 109MB
指令最后一个.是上下文路径的结束符。
上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。
解析:
由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。
实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。
如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。
注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢。
| 指令 | 描述 |
|---|---|
| FROM | 指定基础镜像,用于后续的指令构建 |
| RUN | 执行命令,并生成镜像 |
| CMD | 指定容器启动时运行的命令 |
| LABEL | 为镜像添加标签 |
| EXPOSE | 指定容器的端口号 |
| ADD | 将文件或目录添加到镜像中 |
| COPY | 将文件或目录添加到镜像中 |
| ENTRYPOINT | 指定容器启动时运行的命令 |
| VOLUME | 创建一个挂载点,用于数据卷的挂载 |
| WORKDIR | 设置工作目录 |
| ENV | 设置环境变量 |
| USER | 指定用户 |
| ARG | 定义构建参数 |
| ONBUILD | 在FROM指令之后,指定当镜像被用作其他镜像的基镜像时,会自动执行的指令 |
| STOPSIGNAL | 指定容器停止的信号 |
| HEALTHCHECK | 指定容器健康检查的指令 |
| SHELL | 指定Shell |
Compose 是用于定义和运行多容器 Docker 应用程序的工具。
通过 Compose 可以使用 YML 文件来配置应用程序需要的所有服务。
然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
Compose 使用的三个步骤:
docker-compose.yml
yml
# yaml 配置实例
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
volumes:
logvolume01: {}
...
...
Docker Swarm 是 Docker 的集群管理工具。它将 Docker 主机池转变为单个虚拟 Docker 主机。
Docker Swarm 提供了标准的 Docker API,所有任何已经与 Docker 守护程序通信的工具都可以使用 Swarm 轻松地扩展到多个主机。
如下图所示,swarm 集群由管理节点(manager)和工作节点(work node)构成。

...
可参考 ROS/
docker run -d --name my-redis -p 6379:6379 redis
参数解释:
-d :后台运行
--name :指定容器名称
-p :端口映射
-i :交互式运行
-t :分配一个伪输入终端
$ docker run -i -t ubuntu:15.10 /bin/bash
root@0123ce188bd8:/#
docker: Docker 的二进制执行文件。 run: 与前面的 docker 组合来运行一个容器。 ubuntu:15.10 指定要运行的镜像,Docker 首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像。 /bin/bash: 在启动的容器里执行的命令 第二行 root@0123ce188bd8:/#,此时我们已进入一个 ubuntu15.10 系统的容器
通过运行 exit 命令或者使用 CTRL+D 来退出容器。
root@0123ce188bd8:/# exit exit root@runoob:~#
第三行中 root@runoob:~# 表明我们已经退出了当前的容器,返回到当前的主机中。
启动容器(后台模式) 使用以下命令创建一个以进程方式运行的容器
runoob@runoob:~$ docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done" 2b1b7a428627c51ab8810d541d759f072b4fc75487eed05812646b8534a2fe63 在输出中,我们没有看到期望的 "hello world",而是一串长字符
2b1b7a428627c51ab8810d541d759f072b4fc75487eed05812646b8534a2fe63
这个长字符串叫做容器 ID,对每个容器来说都是唯一的,我们可以通过容器 ID 来查看对应的容器发生了什么。
首先,我们需要确认容器有在运行,可以通过 docker ps 来查看:
runoob@runoob:~$ docker ps
CONTAINER ID IMAGE COMMAND ...
5917eac21c36 ubuntu:15.10 "/bin/sh -c 'while t…" ...
输出详情介绍:
CONTAINER ID: 容器 ID。
IMAGE: 使用的镜像。
COMMAND: 启动容器时运行的命令。
CREATED: 容器的创建时间。
STATUS: 容器状态。
状态有7种:
created(已创建) restarting(重启中) running 或 Up(运行中) removing(迁移中) paused(暂停) exited(停止) dead(死亡) PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。
NAMES: 自动分配的容器名称。
在宿主主机内使用 docker logs 命令,查看容器内的标准输出:
runoob@runoob:~$ docker logs 2b1b7a428627
runoob@runoob:~$ docker logs amazing_cori
停止容器 我们使用 docker stop 命令来停止容器:
通过 docker ps 查看,容器已经停止工作:
runoob@runoob:~$ docker ps 可以看到容器已经不在了。
也可以用下面的命令来停止:
runoob@runoob:~$ docker stop amazing_cori