Docker 安装入门及命令行工具介绍
1.什么是 Docker?
Docker 是基于 Go 语言实现的云开源项目。Docker 的主要目标是 Build,Ship and Run Any App,Anywhere,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的 APP(可以是一个 WEB 应用或者数据库应用等等)及其运行环境能够做到 一次封装,到处运行。
Docker 引擎的基础是 Linux 自带的容器(Linux Containers,LXC)技术。IBM 对于容器技术的准确描述如下:
容器有效的将单个操作系统管理的资源划分到孤立的组中,以便更好的在孤立的组之间平衡有冲突的资源使用需求。与虚拟化相比,这样既不需要指令级模拟,也不需要即时编译。容器可以在核心 CPU 本地运行指令,而不需要任何专门的解释机制。此外,也避免了准虚拟化(paravirtualization)和系统调用替换中的复杂性。
我们可以将容器理解为一种沙盒。每个容器内运行一个应用,不同的容器相互隔离,容器之间可以建立通信机制。容器的创建和停止都十分快速(秒级),容器自身对资源的需求十分有限,远比虚拟机本身占用的资源少。
2. Docker 给 DevOps 带来的好处
更快速的交付和部署:开发人员可以使用镜像快速的构建标准开发环境;开发完成后,测试和运维人员可以使用开发人员提供的 docker 镜像快速部署应用,可以避免开发和测试运维人员之间的环境差异导致的部署问题。
更高效的资源利用:Docker 容器的运行不需要额外的虚拟化管理程序支持,它是内核级的虚拟化,在占用更少资源的情况实现更高的性能。
更方便的迁移和扩展:Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、服务器等。这种兼容使得用户可以在不同的平台之间很方便的完成应用迁移。
更简单的更新管理:使用 Dockerfile,只需要小小的配置修改,就可以替代以往大量的更新工作,并且所有修改都以增量方式进行分发和更新。
3. 虚拟化与 Docker
虚拟化的核心是对资源进行抽象,目标往往是为了在同一个机器上运行多个系统或应用,从而提高系统资源的利用率。虚拟化分为很多类型,比如常见的硬件辅助虚拟化(VMware workstation、 KVM等)。
Docker 所代表的容器虚拟化技术属于操作系统级虚拟化:内核通过创建多个虚拟的操作系统实例(内核和库)来隔离不同的进程。#
传统虚拟化和容器技术结构比较:传统虚拟化技术是在硬件层面实现虚拟化,增加了系统调用链路的环节,有性能损耗;容器虚拟化技术以共享 Kernel 的方式实现,几乎没有性能损耗。
4. Docker 怎么实现的?
Docker 是 Client/Server 的架构,Docker 客户端与 Docker daemon 进行交互,daemon负责构建、运行和发布 Docker 容器。客户端可以和服务端运行在同一个系统中,也可以连接远程的 daemon。Docker 的客户端的 daemon 通过 RESTful API 进行 socket 通信。
Docker 守护进程(daemon)在主机上运行,用户不能直接和守护进程打交道,但是可以通过 Docker 客户端与其进行交互;Client 是 Docker 的初始用户界面,它接收用户的命令并反馈,并且与 Docker 的守护进行交互。
Docker 基于 Linux 容器技术(LXC),Namespace,Cgroup,UnionFS(联合文件系统)等技术实现:
namespace(命名空间)
命名空间是 Linux 内核一个强大的特性。每个容器都有自己单独的命名空间,运行在其中的应用都像是在独立的操作系统中运行一样。命名空间保证了容器之间彼此互不影响。docker 实际上一个进程容器,它通过namespace实现了进程和进程所使用的资源的隔离。使不同的进程之间彼此不可见。
Docker 用到的一些命名空间有:
- pid 命名空间:用于隔离进程,容器都有自己独立的进程表和1号进程;
- net 命名空间:用于管理网络,容器有自己独立的 networkinfo;
- ipc 命名空间:用于访问 IPC 资源(IPC:InterProcess Communication);
- mnt 命名空间:用于管理挂载点,每个容器都有自己唯一的目录挂载;
- uts 命名空间:用于隔离内核和版本标识(UTS:UnixTimeProcess System),每个容器都有独立的 hostname 和 domain。
cgroup(控制组):
是 Linux 内核的一个特性,主要用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,才能避免当多个容器同时运行时的对系统资源的竞争。控制组技术最早是由 Google 的程序员 2006 年起提出,Linux 内核自 2.6.24 开始支持。控制组可以提供对容器的内存、CPU、磁盘 IO 等资源的限制和审计管理。
UnionFS(联合文件系统):
Union 文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对 文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。另外,不同 Docker 容器就可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率。Docker 中使用的 AUFS(AnotherUnionFS)就是一种 Union FS。 AUFS 支持为每一个成员目录(类似 Git 的分支)设定只读(readonly)、读写(readwrite)和写出(whiteout-able)权限, 同时 AUFS 里有一个类似分层的概念, 对只读权限的分支可以逻辑上进行增量地修改(不影响只读部分的)。Docker 目前支持的 Union 文件系统种类包括 AUFS, btrfs, vfs 和 DeviceMapper。
5. Docker 核心概念
5.1 image
Docker 镜像类似于虚拟机镜像,是一个只读模板,并且包含了文件系统。一个镜像可以只包含一个操作系统环境(比如SUSE镜像),也可以安装了用户程序及其运行环境(比如eBackup镜像)。镜像其实就是一个文件,任何用户程序都可以成为镜像的一部分。
镜像 = 操作系统 + 软件运行环境 + 用户程序
一个 layer 就是一个 image,多个 image 又可以打包成一个 image。Image 类似一个单链表系统,每个 image 包含一个指向 parent image 的指针,没有 parent image 的 image 是 baseimage(image 的指针靠 sqlite 数据库来保存)。
最上面的一层(不属于image)是可写的,上面的内容依赖于下面的内容,如果要修改下面的内容,先将下面的内容复制到上面再进行修改。Image 是创建 container 的基础。
关于 image 的一些命令:
docker pull //从网络上下载镜像
docker images //查看本地主机已经存在的镜像
5.2 Container
容器是从镜像创建的运行实例,可以将其启动、开始。停止、删除,而这些容器都是相互隔离(独立进程),互不可见的。
5.3 Repository
我们对 Docker 有了认识和了解,docker 还有非常重要的一块,那就是 docker 镜像。提到docker镜像必不可少的一个文件是 Dockerfile
docker 可以通过 build 命令自动从 Dockerfile 文件中读取并执行命令,最终生成 docker 镜像。使用 Dockerfile 非常简单,且重要!
Dockerfile 命令详解
写文章时 docker 版本号为:1.8.2 目前 Dockerfile 中共包含14个命令,文章内容详细介绍每个一个命令的含义和用法
Dockerfile
格式:INSTRUCTION arguments
instruction 不区分大小写,推荐用大写,以免和其他参数冲突
FROM
格式:
FROM \<image\>
FROM \<image\>:\<tag\>
FROM \<image\>@\<digest\>
Dockerfile中的第一条指令必须是FROM,FROM指令指定了构建镜像的base镜像
MAINTAINER
格式:MAINTAINER \<name\> \<Email\>
编写维护 Dockerfile 的作者信息
ENV
格式:
ENV \<key\>\<value\>
ENV \<key\>=\<value\>
为容器声明环境变量,环境变量在子镜像中也可以使用。可以直接使用环境变量$variable_name
运行容器指定环境变量:docker run --env <key>=<value>
RUN
格式:
RUN \<command\>
(类似/bin/sh -c
shell 格式)RUN ["executable", "param1", "param2"]
(exec 格式)
第一种 使用 shell 格式时,命令通过 /bin/sh -c
执行;
第二种 使用exec
格式时,命令直接执行,容器不调用shell,并且 exec
格式中的参数会看作是JSON
数组被Docker解析,所以要用(")双引号,不能用单引号(')。
举例:
RUN [ "echo", "$HOME" ]
HOME变量不会被替换,如果你想运行shell程序,使用:`RUN [ "sh", "-c", "echo", "HOME变量不会被替换,如果你想运行shell程序,使用:‘RUN["sh","−c","echo","HOME" ]`
COPY
格式:COPY \<src\>\<dest\>
拷贝本地<src>目录下的文件到容器中<dest>目录。
ADD
格式:
- ADD <src><dest>
- ADD ["",... ""]
ADD hom* /mydir/
从<src>目录下拷贝文件,目录或网络文件到容器的<dest>目录。和COPY非常相似,但比COPY功能多,拷贝的文件可以是一个网络文件,并且ADD有解压文件得功能。
CMD
格式:
CMD \<commadn\> param1 param2
(shell格式)CMD ["executable", "param1", "param2"]
(exex格式)CMD ["param1", "param2"]
(为ENTRYPOINT命令提供参数)
虽然有三种格式,但在Dockerfile中如果有多个CMD命令,只有最后一个生效。
CMD
命令主要是提供容器运行时得默认值。默认值,可以是一条指令,也可以是参数(ENTRYPOINT),CMD
命令参数是一个动态值,信息会保存到镜像的JSON文件中。
举例:
ENTRYPOINT ["executable"]
CMD ["param1", "param2"]
启动容器执行:["executable", "param1", "param2"]
注意: 如果在命令行后面运行docker run
时指定了命令参数,则会把Dockerfile
中定义的CMD
命令参数覆盖
ENTRYPOINT
格式:
ENTRYPOINT \<command\>
(shell 格式)ENTRYPOINT ["executable", "param1", "param2"]
(exec 格式)
ENTRYPOINT
和CMD
命令类似,也是提供容器运行时得默认值,但它们有不同之处。同样一个Dockerfile中有多个ENTRYPOINT命令,只有最后一个生效。
当
ENTRYPOINT
命令使用<commmand>格式,ENTRYPOINT
会忽略任何CMD
指令和docker run
传来的参数,直接运行在/bin/sh -c
中;也就是说ENTRYPOINT
执行的进程会是/bin/sh -c
的子进程。所以进程的PID不会是1,而且也不能接受Unix信号。(执行docker stop $container_id的时候,进程接收不到SIGTERM信号)使用
exec
格式,docker run
传入的命令参数会覆盖CMD
命令,并附加到ENTRYPOINT
命令的参数中。推荐使用exec
方式
ONBUILD
格式:ONBUILD [INSTRUCTION]
ONBUILD
指令的功能是添加一个将来执行触发器指令到镜像中。当Dockerfile中FROM
的镜像中包含ONBUILD
指令,在构建此镜像的时候会触发ONBUILD
指令。但如果当前Dockerfile中存在ONBUID
指令,不会执行就。ONBUILD
指令在生成应用镜像时用处非常大。
ONBUILD
如何工作
1.构建过程中,ONBUILD
指令会添加到触发器指令镜像元数据中。触发器指令不会在当前构建过程中生效
2.构建完后,触发器指令会被保存到镜像的详情中,主键是OnBuild
,可以使用docker inspect
命令查看到
3.之后此镜像可能是构建其他镜像的父镜像,在构建过程中,FROM
指令会查找ONBUILD
触发器指令,并按照之前定义的顺序执行;如果触发器指令执行失败,则构建新镜像失败并退出;如果触发器指令执行成功,则继续往下执行。
4.构建成功后ONBUILD
指令清除,固不会被孙子辈镜像继承。
VOLUME
格式:VOLUME ["/data"]
为docker主机和容器做目录映射,volume目录信息会保存到镜像的JSON文件中,在运行docker run
命令时指定$HOST_DIR
LABEL
格式:LABEL <key>=<value> <key>=<value> <key>=<value> ...
LABEL指令,添加一个元数据到镜像中。一个镜像中可以有多个标签,建议写一个(因为没多个LABEL指令镜像会多一个layer
)LABEL
是一个键值对<key><value>,在一个标签值,包括空间使用引号和反斜杠作为您在命令行解析。
举例:LABEL multi.label1="value1" multi.label2="value2" other="value3"
EXPOSE
格式:EXPOSE <port> [<port>...]
在Dockerfile中定义端口,默认是不往外暴露,在运行docker run
-p
or -P
暴露
USER
格式:USER daemon
设定一个用户或者用户ID,在执行RUN``CMD``ENTRYPOINT
等指令时指定以那个用户得身份去执行
WORKDIR
格式:WORKDIR /path/to/workdir
当执行RUN``CMD``ENTRYPOINT``ADD``CMD
等命令,设置工作目录
.dockerignore
如果在Dockerfile文件目录下有.dockerignore文件,docker在构建镜像的时候会把在.dockerignore文件中定义的文件排除出去
*/temp*
*/*/temp*
temp?
*.md
!LICENSE.md
Docker 安装 (基于17.06.2-ce,Centos7)
系统要求
正在维护的 Centos 7 以上版本, centos-extras 被启用(默认是启用状态)启用 centos-extras
卸载旧版本 docker
旧版本被称为docker或者docker-engine,如果之前装有旧版本,需要卸载旧版本,相关依赖一同卸载。
>$ sudo yum remove docker \\
docker-common \\
docker-selinux \\
docker-engine
/var/lib/docker/
路径下的内容将被保留,现在 Docker-CE 包统称 docker-ce
安装 Docker-CE
- 使用 repository 安装,这种方式免除了安装和升级的任务,官方推荐的安装方式
- 下载 RPM 包手动安装和升级,适用于无外网的隔离环境
- 使用自动化的便捷脚本安装,适用于测试和开发环境
使用 repository 安装
如果是第一次在一台新的机器上安装,则需要安装 repository,之后就可以通过 repository 进行安装和升级
安装 repository
- 安装依赖包,yum-utils 包为 yum-config-manager 包提供了可用性,devicemapper 的存储驱动则需要 device-mapper-persistent-data 和 lvm2
>$ sudo yum install -y yum-utils \\
device-mapper-persistent-data \\
lvm2
- 安装 stable repository,即使要使用 edge 或者 test repository,也需要stable repository 的支持(docker-ce有两个更新通道 stablet 提供可靠的版本,每个季度会更新一次,edge 提供新版本,每个月更新一次)
$ sudo yum-config-manager \\
--add-repo \\
https://download.docker.com/linux/centos/docker-ce.repo
- (可选) 开启 edge 或者 test repository,默认是未启用的
$ sudo yum-config-manager --enable docker-ce-edge
$ sudo yum-config-manager --enable docker-ce-test
禁用 edge 或者 test repository 可以使用如下命令:
$ sudo yum-config-manager --disable docker-ce-edge
$ sudo yum-config-manager --disable docker-ce-test
安装 DOCKER CE
- 安装最新版本的 docker ce
$ sudo yum install docker-ce
Note:如果启用了多个 docker repository,则在使用 yum install 或者 yum update 没有指定版本时,总是会安装最高的版本,可能最高的版本并不是很稳定。
- 在生产环境,应该使用指定版本的 docker,而不是使用最新的版本,查看可用版本
$ yum list docker-ce --showduplicates | sort -r
docker-ce.x86_64 17.09.ce-1.el7.centos docker-ce-stable
安装指定版本的 docker ce
sudo yum install \<FULLY-QUALIFIED-PACKAGE-NAME\>
example:上面列表中的全称版本 docker-ce-17.06.1.ce
- 启动 docker
$ sudo systemctl start docker
- 运行 hello-world 镜像检查 docker 是否正确安装
$ sudo docker run hello-world
这个命令会下载测试镜像,并且运行一个容器,当容器运行成功,会打印信息然后退出。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

上一篇: 红黑树介绍和操作方法
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论