Docker 学习2
Docker 是什么?
我们在理解 Docker 之前,首先得先区分清楚两个概念,容器和虚拟机。
可能很多读者朋友都用过虚拟机,而对容器这个概念比较的陌生。我们用的传统虚拟机如 VMware , VisualBox 之类的需要模拟整台机器包括硬件。
每台虚拟机都需要有自己的操作系统,虚拟机一旦被开启,预分配给它的资源将全部被占用。
每一台虚拟机包括应用,必要的二进制和库,以及一个完整的用户操作系统。
而容器技术是和我们的宿主机共享硬件资源及操作系统,可以实现资源的动态分配。
容器包含应用和其所有的依赖包,但是与其他容器共享内核。容器在宿主机操作系统中,在用户空间以分离的进程运行。
容器技术是实现操作系统虚拟化的一种途径,可以让您在资源受到隔离的进程中运行应用程序及其依赖关系。
通过使用容器,我们可以轻松打包应用程序的代码、配置和依赖关系,将其变成容易使用的构建块,从而实现环境一致性、运营效率、开发人员生产力和版本控制等诸多目标。
容器可以帮助保证应用程序快速、可靠、一致地部署,其间不受部署环境的影响。
容器还赋予我们对资源更多的精细化控制能力,让我们的基础设施效率更高。
通过下面这幅图,我们可以很直观的反映出这两者的区别所在:
Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。
而 Linux 容器是 Linux 发展出的另一种虚拟化技术,简单来讲, Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离,相当于是在正常进程的外面套了一个保护层。
对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。
Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。
程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker ,就不用担心环境问题。
总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。
Docker 的优势
Docker 相比于传统虚拟化方式具有更多的优势:
Docker 启动快速属于秒级别。虚拟机通常需要几分钟去启动。
Docker 需要的资源更少。Docker 在操作系统级别进行虚拟化,Docker 容器和内核交互,几乎没有性能损耗,性能优于通过 Hypervisor 层与内核层的虚拟化。
Docker 更轻量。Docker 的架构可以共用一个内核与共享应用程序库,所占内存极小。同样的硬件环境,Docker 运行的镜像数远多于虚拟机数量,对系统的利用率非常高。
与虚拟机相比,Docker 隔离性更弱。Docker 属于进程之间的隔离,虚拟机可实现系统级别隔离。
安全性。Docker 的安全性也更弱,Docker 的租户 Root 和宿主机 Root 等同,一旦容器内的用户从普通用户权限提升为 Root 权限,它就直接具备了宿主机的 Root 权限,进而可进行无限制的操作。
虚拟机租户 Root 权限和宿主机的 Root 虚拟机权限是分离的,并且虚拟机利用如 Intel 的 VT-d 和 VT-x 的 ring-1 硬件隔离技术。
这种隔离技术可以防止虚拟机突破和彼此交互,而容器至今还没有任何形式的硬件隔离,这使得容器容易受到攻击。
可管理性。Docker 的集中化管理工具还不算成熟。各种虚拟化技术都有成熟的管理工具,例如 VMware vCenter 提供完备的虚拟机管理能力。
高可用和可恢复性。Docker 对业务的高可用支持是通过快速重新部署实现的。
虚拟化具备负载均衡,高可用,容错,迁移和数据保护等经过生产实践检验的成熟保障机制, VMware 可承诺虚拟机 99.999% 高可用,保证业务连续性。
快速创建、删除。虚拟化创建是分钟级别的,Docker 容器创建是秒级别的,Docker 的快速迭代性,决定了无论是开发、测试、部署都可以节约大量时间
交付、部署。虚拟机可以通过镜像实现环境交付的一致性,但镜像分发无法体系化。Docker 在 Dockerfile 中记录了容器构建过程,可在集群中实现快速分发和快速部署。
Docker 的三个基本概念
从上图我们可以看到,Docker 中包括三个基本的概念:
-
Image(镜像)
-
Container(容器)
-
Repository(仓库)
Image(镜像)
那么镜像到底是什么呢?Docker 镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。
镜像不包含任何动态数据,其内容在构建之后也不会被改变。镜像(Image)就是一堆只读层(read-only layer)的统一视角,也许这个定义有些难以理解,下面的这张图能够帮助读者理解镜像的定义:
从左边我们看到了多个只读层,它们重叠在一起。除了最下面一层,其他层都会有一个指针指向下一层。这些层是 Docker 内部的实现细节,并且能够在主机的文件系统上访问到。
统一文件系统(Union File System)技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角。
这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。我们可以在图片的右边看到这个视角的形式。
Container(容器)
容器(Container)的定义和镜像(Image)几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。
由于容器的定义并没有提及是否要运行容器,所以实际上,容器 = 镜像 + 读写层。
Repository(仓库)
Docker 仓库是集中存放镜像文件的场所。镜像构建完成后,可以很容易的在当前宿主上运行。
但是, 如果需要在其他服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry(仓库注册服务器)就是这样的服务。
有时候会把仓库(Repository)和仓库注册服务器(Registry)混为一谈,并不严格区分。
Docker 仓库的概念跟 Git 类似,注册服务器可以理解为 GitHub 这样的托管服务。
实际上,一个 Docker Registry 中可以包含多个仓库(Repository),每个仓库可以包含多个标签(Tag),每个标签对应着一个镜像。
所以说,镜像仓库是 Docker 用来集中存放镜像文件的地方,类似于我们之前常用的代码仓库。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本 。
我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 Latest 作为默认标签。
仓库又可以分为两种形式:
-
Public(公有仓库)
-
Private(私有仓库)
Docker Registry 公有仓库是开放给用户使用、允许用户管理镜像的 Registry 服务。
一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。
除了使用公开服务外,用户还可以在本地搭建私有 Docker Registry。Docker 官方提供了 Docker Registry 镜像,可以直接使用做为私有 Registry 服务。
当用户创建了自己的镜像之后就可以使用 Push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 Pull 下来就可以了。
我们主要把 Docker 的一些常见概念如 Image,Container,Repository 做了详细的阐述,也从传统虚拟化方式的角度阐述了 Docker 的优势。
我们从下图可以直观地看到 Docker 的架构:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-be97XTMf-1583911757815)(])
Docker 使用 C/S 结构,即客户端/服务器体系结构。Docker 客户端与 Docker 服务器进行交互,Docker服务端负责构建、运行和分发 Docker 镜像。
Docker 客户端和服务端可以运行在一台机器上,也可以通过 RESTful 、 Stock 或网络接口与远程 Docker 服务端进行通信。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8TXtnlqC-1583911757819)(])
这张图展示了 Docker 客户端、服务端和 Docker 仓库(即 Docker Hub 和 Docker Cloud ),默认情况下 Docker 会在 Docker 中央仓库寻找镜像文件。
这种利用仓库管理镜像的设计理念类似于 Git ,当然这个仓库是可以通过修改配置来指定的,甚至我们可以创建我们自己的私有仓库。
Docker 的安装和使用
Docker 的安装和使用有一些前提条件,主要体现在体系架构和内核的支持上。
对于体系架构,除了 Docker 一开始就支持的 X86-64 ,其他体系架构的支持则一直在不断地完善和推进中。
Docker 分为 CE 和 EE 两大版本。CE 即社区版,免费支持周期 7 个月;EE 即企业版,强调安全,付费使用,支持周期 24 个月。
我们在安装前可以参看官方文档获取最新的 Docker 支持情况,官方文档在这里:
https://docs.docker.com/install/
Docker 对于内核支持的功能,即内核的配置选项也有一定的要求(比如必须开启 Cgroup 和 Namespace 相关选项,以及其他的网络和存储驱动等)。
Docker 源码中提供了一个检测脚本来检测和指导内核的配置,脚本链接在这里:
https://raw.githubusercontent.com/docker/docker/master/contrib/check-config.sh
在满足前提条件后,安装就变得非常的简单了。
Docker CE 的安装请参考官方文档:
MacOS:https://docs.docker.com/docker-for-mac/install/
Windows:https://docs.docker.com/docker-for-windows/install/
Ubuntu:https://docs.docker.com/install/linux/docker-ce/ubuntu/
Debian:https://docs.docker.com/install/linux/docker-ce/debian/
CentOS:https://docs.docker.com/install/linux/docker-ce/centos/
Fedora:https://docs.docker.com/install/linux/docker-ce/fedora/
其他 Linux 发行版:https://docs.docker.com/install/linux/docker-ce/binaries/
安装 Docker
Docker 软件包已经包括在默认的 CentOS-Extras 软件源里。因此想要安装 Docker,只需要运行下面的 yum 命令:
$ sudo yum install docker
当然在测试或开发环境中 Docker 官方为了简化安装流程,提供了一套便捷的安装脚本,CentOS 系统上可以使用这套脚本安装:
curl -fsSL get.docker.com -o get-docker.sh
sh get-docker.sh
具体可以参看 docker-install 的脚本:
https://github.com/docker/docker-install
执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker CE 的 Edge 版本安装在系统中。
安装完成后,运行下面的命令,验证是否安装成功:
docker version
启动 Docker-CE:
$ sudo systemctl enable docker$ sudo systemctl start docker
Docker 的简单运用 Hello World
我们通过最简单的 Image 文件 Hello World,感受一下 Docker 的魅力吧!
我们直接运行下面的命令,将名为 hello-world 的 image 文件从仓库抓取到本地:
docker pull library/hello-world
docker pull images 是抓取 image 文件,library/hello-world 是 image 文件在仓库里面的位置,其中 library 是 image 文件所在的组,hello-world 是 image 文件的名字。
抓取成功以后,就可以在本机看到这个 image 文件了:
docker images
现在,我们可以运行 hello-world 这个 image 文件:
docker run hello-world
我们可以看到如下结果:
输出这段提示以后,hello world 就会停止运行,容器自动终止。有些容器不会自动终止,因为提供的是服务,比如 MySQL 镜像等。
配置镜像加速器
http://www.itmuch.com/docker/03-docker-mirror/
常见命令
systemctl命令是系统服务管理器指令
启动docker:
systemctl start docker
停止docker:
systemctl stop docker
重启docker:
systemctl restart docker
查看docker状态:
systemctl status docker
开机启动:
systemctl enable docker
查看docker概要信息
docker info
Docker镜像常用命令
搜索镜像
可使用docker search 命令搜索存放在Docker Hub中的镜像。
命令格式:
docker search [OPTIONS] TERM
参数:
Name, shorthand | Default | Description |
---|---|---|
–automated | false | 只列出自动构建的镜像 |
–filter, -f | 根据指定条件过滤结果 | |
–limit | 25 | 搜索结果的最大条数 |
–no-trunc | false | 不截断输出,显示完整的输出 |
–stars, -s | 0 | 只展示Star不低于该数值的结果 (废弃) |
示例:
docker search -filter=stars=10 java
下载镜像[重要]
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
参数:
Name, shorthand | Default | Description |
---|---|---|
–all-tags, -a | false | 下载所有标签的镜像 |
–disable-content-trust | true | 忽略镜像的校验 |
示例:
docker pull reg.itmuch.com/java:7
使用inspect命令查看详细信息
如
docker inspect nginx
列出镜像[重要]
docker images
命令格式:
docker images [OPTIONS] [REPOSITORY[:TAG]]
参数:
Name, shorthand | Default | Description |
---|---|---|
–all, -a | false | 列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层) |
–digests | false | 显示摘要信息 |
–filter, -f | 显示满足条件的镜像 | |
–format | 通过Go语言模板文件展示镜像 | |
–no-trunc | false | 不截断输出,显示完整的镜像信息 |
–quiet, -q | false | 只显示镜像ID |
示例:
docker images
docker images java
docker images java:8
docker images --digests
docker images --filter "dangling=true" # 展示虚悬镜像
删除本地镜像[重要]
命令格式:
docker rmi [OPTIONS] IMAGE [IMAGE...]
参数:
Name, shorthand | Default | Description |
---|---|---|
–force, -f | false | 强制删除 |
–no-prune | false | 不移除该镜像的过程镜像,默认移除 |
例1:删除指定名称的镜像。
docker rmi hello-world
表示删除hello-world这个镜像。
例2:删除所有镜像。
docker rmi -f $(docker images)
-f参数表示强制删除。
保存镜像
使用docker save 即可保存镜像。
命令格式:
docker save [OPTIONS] IMAGE [IMAGE...]
参数:
Name, shorthand | Default | Description |
---|---|---|
–output, -o | Write to a file, instead of STDOUT |
例1:
docker save busybox > busybox.tar
docker save --output busybox.tar busybox
加载镜像
使用docer load 命令即可加载镜像。
命令格式:
docker load [OPTIONS]
参数:
Name, shorthand | Default | Description |
---|---|---|
–input, -i | 从文件加载而非STDIN | |
–quiet, -q | false | 静默加载 |
构建镜像[重要]
通过Dockerfile构建镜像。
命令格式:
docker build [OPTIONS] PATH | URL | -
参数:
http://www.itmuch.com/docker/04-docker-command-images/
容器常用命令
新建并启动容器[重要]
使用以下docker run 命令即可新建并启动一个容器。
① -d选项:表示后台运行
② -P选项:随机端口映射
③ -p选项:指定端口映射,有以下四种格式。
ip:hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort
④ –network选项:指定网络模式,该选项有以下可选参数:
–network=bridge: 默认选项,表示连接到默认的网桥。
–network=host:容器使用宿主机的网络。
–network=container:NAME_or_ID:告诉Docker让新建的容器使用已有容器的网络配置。
–network=none:不配置该容器的网络,用户可自定义网络配置。
示例1:
docker run java /bin/echo 'Hello World'
示例:
docker run -d -p 91:80 nginx
列出容器[重要]
使用docker ps 命令即可列出运行中的容器。执行该命令后,可看到类似于如下的表格。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
784fd3b294d7 nginx "nginx -g 'daemon off" 20 minutes ago Up 2 seconds 443/tcp, 0.0.0.0:91->80/tcp backstabbing_archimedes
该表格包含了七列,含义如下:
① CONTAINER_ID:表示容器ID。
② IMAGE:表示镜像名称。
③ COMMAND:表示启动容器时运行的命令。
④ CREATED:表示容器的创建时间。
⑤ STATUS:表示容器运行的状态。Up表示运行中,Exited表示已停止。
⑥ PORTS:表示容器对外的端口号。
⑦ NAMES:表示容器名称。该名称默认由Docker自动生成,也可使用docker run命令的–name选项自行指定。
命令格式:
docker ps [OPTIONS]
参数:
Name, shorthand | Default | Description |
---|---|---|
–all, -a | false | 列出所有容器,包括未运行的容器,默认只展示运行的容器 |
–filter, -f | 根据条件过滤显示内容 | |
–format | 通过Go语言模板文件展示镜像 | |
–last, -n | -1 | 显示最近创建n个容器(包含所有状态) |
–latest, | -l false | 显示最近创建的容器(包含所有状态) |
–no-trunc | false | 不截断输出 |
–quiet, -q | false | 静默模式,只展示容器的编号 |
–size, -s | false | 显示总文件大小 |
停止容器[重要]
使用docker stop 命令,即可停止容器。
命令格式:
docker stop [OPTIONS] CONTAINER [CONTAINER...]
参数:
Name, shorthand | Default | Description |
---|---|---|
–time, -t | 10 | 强制杀死容器前等待的时间,单位是秒 |
强制停止容器[重要]
可使用docker kill 命令停止一个或更多运行着的容器。
命令格式:
docker kill [OPTIONS] CONTAINER [CONTAINER...]
参数:
|Name, shorthand| Default| Description|
|–signal, -s| KILL| 向容器发送一个信号|
启动已停止的容器[重要]
使用docker run 命令,即可新建并启动一个容器。对于已停止的容器,可使用docker start 命令来启动。
命令格式:
docker start [OPTIONS] CONTAINER [CONTAINER...]
参数:
Name, shorthand | Default | Description |
---|---|---|
–attach, -a | false | 连接STDOUT/STDERR并转发信号 |
–checkpoint | 从该检查点还原 | |
–checkpoint-dir | 使用自定义的检查点存储目录 | |
–detach-keys | 覆盖断开容器的关键顺序 | |
–interactive, -i | false | 连接容器的STDIN |
重启容器[重要]
可使用docker restart 命令来重启容器。该命令实际上是先执行了docker stop 命令,然后执行了docker start 命令。
命令格式:
docker restart [OPTIONS] CONTAINER [CONTAINER...]
参数:
Name, shorthand | Default | Description |
---|---|---|
–time, -t 10 | 关闭容器前等待的时间,单位是秒 |
示例:
docker restart --time=10 08dc7fe747f6
```
#### 进入容器[重要]
某场景下,我们可能需要进入运行中的容器。
① 使用`docker attach` 命令进入容器。
例如:
```
docker attach 784fd3b294d7
很多场景下,使用docker attach 命令并不方便。当多个窗口同时attach到同一个容器时,所有窗口都会同步显示。同理,如果某个窗口发生阻塞,其他窗口也无法执行操作。
② 使用nsenter 进入容器
nsenter工具包含在util-linux 2.23或更高版本中。为了连接到容器,我们需要找到容器第一个进程的PID,可通过以下命令获取:
docker inspect --format "{{.State.Pid}}" $CONTAINER_ID
获得PID后,就可使用nsenter命令进入容器了:
nsenter --target "$PID" --mount --uts --ipc --net --pid
下面给出一个完整的例子:
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
784fd3b294d7 nginx "nginx -g 'daemon off" 55 minutes ago Up 3 minutes 443/tcp, 0.0.0.0:91->80/tcp backstabbing_archimedes
[root@localhost ~]# docker inspect --format "{{.State.Pid}}" 784fd3b294d7
95492
[root@localhost ~]# nsenter --target 95492 --mount --uts --ipc --net --pid
root@784fd3b294d7:/#
读者也可将以上两条命令封装成一个Shell,从而简化进入容器的过程。
③ docker exec
docker exec -it 容器id /bin/bash
退出容器[重要]
ctl+d 退出容器
删除容器[重要]
使用docker rm 命令即可删除指定容器。
命令格式
docker rm [OPTIONS] CONTAINER [CONTAINER...]
参数:
Name, shorthand | Default | Description |
---|---|---|
–force, -f | false | 通过SIGKILL信号强制删除正在运行中的容器 |
–link, -l | false | 删除容器间的网络连接 |
–volumes, -v | false | 删除与容器关联的卷 |
例1:删除指定容器。
docker rm 784fd3b294d7
该命令只能删除已停止的容器,如需删除正在运行的容器,可使用-f参数。
例2:删除所有的容器。
docker rm -f $(docker ps -a -q)
导出容器
将容器导出成一个压缩包文件。
命令格式:
docker export [OPTIONS] CONTAINER
参数:
Name, shorthand | Default | Description |
---|---|---|
–output, -o | 将内容写到文件而非STDOUT |
示例:
docker export red_panda > latest.tar
docker export --output="latest.tar" red_panda
导入容器
使用docker import 命令即可从归档文件导入内容并创建镜像。
命令格式:
docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
参数:
|Name, shorthand |Default |Description|
|–change, -c| |将Dockerfile指令应用到创建的镜像|
|–message, -m| |为导入的镜像设置提交信息|
示例:
docker import nginx2.tar nginx
访问nginx
https://blog.csdn.net/ShelleyLittlehero/article/details/104794738
Dockerfile指令详解
什么是 Dockerfile?
Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。
ADD 复制文件
DD指令用于复制文件,格式为:
ADD <src>... <dest>
ADD ["<src>",... "<dest>"]
注意 :
① src必须在构建的上下文内,不能使用例如:ADD …/somethine /something 这样的命令,因为docker build 命令首先会将上下文路径和其子目录发送到docker daemon。
② 如果src是一个URL,同时dest不以斜杠结尾,dest将会被视为文件,src对应内容文件将会被下载到dest。
③ 如果src是一个URL,同时dest以斜杠结尾,dest将被视为目录,src对应内容将会被下载到dest目录。
④ 如果src是一个目录,那么整个目录下的内容将会被拷贝,包括文件系统元数据。
⑤ 如果文件是可识别的压缩包格式,则docker会自动解压。
示例:
ADD microservice-discovery-eureka-0.0.1-SNAPSHOT.jar app.jar
ARG 设置构建参数
ARG指令用于设置构建参数,类似于ENV。和ARG不同的是,ARG设置的是构建时的环境变量,在容器运行时是不会存在这些变量的。
格式为:
ARG <name>[=<default value>]
示例:
ARG user1=someuser
详细介绍文档:https://www.centos.bz/2016/12/dockerfile-arg-instruction/
CMD 容器启动命令
CMD指令用于为执行容器提供默认值。每个Dockerfile只有一个CMD命令,如果指定了多个CMD命令,那么只有最后一条会被执行,如果启动容器的时候指定了运行的命令,则会覆盖掉CMD指定的命令。
支持三种格式:
CMD ["executable","param1","param2"] (推荐使用)
CMD ["param1","param2"] (为ENTRYPOINT指令提供预设参数)
CMD command param1 param2 (在shell中执行)
示例:
CMD echo "This is a test." | wc -
COPY 复制文件
复制文件,格式为:
COPY <src>... <dest>
COPY ["<src>",... "<dest>"]
复制本地端的src到容器的dest。COPY指令和ADD指令类似,COPY不支持URL和压缩包。
ENTRYPOINT 入口点
格式为:
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
ENTRYPOINT和CMD指令的目的一样,都是指定Docker容器启动时执行的命令,可多次设置,但只有最后一个有效。ENTRYPOINT不可被重写覆盖。
ENTRYPOINT、CMD区别:http://blog.csdn.net/newjueqi/article/details/51355510
ENV 设置环境变量
ENV指令用于设置环境变量,格式为:
ENV <key> <value>
ENV <key>=<value> ...
示例:
ENV JAVA_HOME /path/to/java
EXPOSE 声明暴露的端口
EXPOSE指令用于声明在运行时容器提供服务的端口,格式为:
EXPOSE <port> [<port>...]
需要注意的是,这只是一个声明,运行时并不会因为该声明就打开相应端口。该指令的作用主要是帮助镜像使用者理解该镜像服务的守护端口;其次是当运行时使用随机映射时,会自动映射EXPOSE的端口。示例:
# 声明暴露一个端口示例
EXPOSE port1
# 相应的运行容器使用的命令
docker run -p port1 image
# 也可使用-P选项启动
docker run -P image
# 声明暴露多个端口示例
EXPOSE port1 port2 port3
# 相应的运行容器使用的命令
docker run -p port1 -p port2 -p port3 image
# 也可指定需要映射到宿主机器上的端口号
docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image
FROM 指定基础镜像
使用FROM指令指定基础镜像,FROM指令有点像Java里面的“extends”关键字。需要注意的是,FROM指令必须指定且需要写在其他指令之前。FROM指令后的所有指令都依赖于该指令所指定的镜像。
支持三种格式:
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
LABEL 为镜像添加元数据
LABEL指令用于为镜像添加元数据。
格式为:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
使用 ””“和”“转换命令行,示例:
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates
that label-values can span multiple lines."
MAINTAINER 指定维护者的信息(已过时)
注:该指令已过时,建议使用如下形式:
LABEL maintainer="SvenDowideit@home.org.au"
RUN 执行命令
该指令支持两种格式:
RUN <command>
RUN ["executable", "param1", "param2"]
RUN <command> 在shell终端中运行,在Linux中默认是/bin/sh -c ,在Windows中是 cmd /s /c ,使用这种格式,就像直接在命令行中输入命令一样。
RUN ["executable", "param1", "param2"] 使用exec执行,这种方式类似于函数调用。指定其他终端可以通过该方式操作,例如:RUN ["/bin/bash", "-c", "echo hello"] ,该方式必须使用双引号[“]而不能使用单引号[‘],因为该方式会被转换成一个JSON 数组。
USER 设置用户
该指令用于设置启动镜像时的用户或者UID,写在该指令后的RUN、CMD以及ENTRYPOINT指令都将使用该用户执行命令。
格式为:
USER 用户名
示例:
USER daemon
VOLUME 指定挂载点
该指令使容器中的一个目录具有持久化存储的功能,该目录可被容器本身使用,也可共享给其他容器。当容器中的应用有持久化数据的需求时可以在Dockerfile中使用该指令。格式为:
VOLUME ["/data"]
示例:
VOLUME /data
使用示例:
FROM nginx
VOLUME /tmp
当该Dockerfile被构建成镜像后,/tmp目录中的数据即使容器关闭也依然存在。如果另一个容器也有持久化的需求,并且想使用以上容器/tmp目录中的内容,则可使用如下命令启动容器:
docker run -volume-from 容器ID 镜像名称 # 容器ID是di一个容器的ID,镜像是第二个容器所使用的镜像。
WORKDIR 指定工作目录
格式为:
WORKDIR /path/to/workdir
切换目录指令,类似于cd命令,写在该指令后的RUN,CMD以及ENTRYPOINT指令都将该目录作为当前目录,并执行相应的命令。
使用Docker Registry管理镜像
可使用docker-registry项目或者Docker Registry 2.0来搭建私有仓库,但docker-registry已被官方标记为过时,并且已有2年不维护了,不建议使用。
我们先用Docker Registry 2.0搭建一个私有仓库,然后将Docker镜像推送到私有仓库。
搭建Docker Registry 2.0
Docker Registry 2.0的搭建非常简单,只需执行以下命令即可新建并启动一个Docker Registry 2.0。
docker run -d -p 5000:5000 --restart=always --name registry2 registry:2
将镜像推送到Docker Registry 2.0
前文我们使用docker push 命令将镜像推送到了Docker Hub,现在我们将前文构建的itmuch/microservice-discovery-eureka:0.0.1推送到私有仓库。
只需指定私有仓库的地址,即可将镜像推送到私有仓库。
docker push localhost:5000/itmuch/microservice-discovery-eureka:0.0.1
执行以上命令,我们发现推送并没有成功,且提示以下内容:
The push refers to a repository [localhost:5000/itmuch/microservice-discovery-eureka]
An image does not exist locally with the tag: localhost:5000/itmuch/microservice-discovery-eureka
我们知道,Docker Hub是默认的Docker Registry,因此,itmuch/microservice-discovery-eureka:0.0.1相当于docker.io/itmuch/microservice-discovery-eureka:0.0.1。因此,要想将镜像推送到私有仓库,需要修改镜像标签,命令如下:
docker tag itmuch/microservice-discovery-eureka:0.0.1 localhost:5000/itmuch/microservice-discovery-eureka:0.0.1
修改镜像标签后,再次执行以下命令,即可将镜像推送到私有仓库。
docker push localhost:5000/itmuch/microservice-discovery-eureka:0.0.1
文章主要参考:
http://www.itmuch.com/docker/00-docker-lession-index/