Docker初级使用指南
目录
什么是Docker
Docker开源项目
Docker是基于Go语言实现的云开源项目,诞生于2013年初,最初的发起者是dotCloud公司。dotCloud公司后来改名为Docker Inc,专注于Docker相关技术和产品的开发。
Docker的主要目标是“Build, Ship and Run Any App, Anywhere”,即通过对应用组件的封装(Packaging)、分发(Distribution)、部署(Deployment)、运行(Runtime)等设备能生命周期的管理,达到应用组件级别的“一次封装,到处运行”。这里的应用组件,既可以是一个web应用,也可以是一套数据库服务,甚至是一个操作系统或编译器。
Docker基于Linux的多项开源技术提供了高效、敏捷和轻量级的容器方案,并且支持在多种主流云平台(PaaS)和本地系统上部署。可以说Docker为应用的开发和部署提供了“一站式”的解决方案。
Linux容器技术
Docker 引擎的基础是Linux容器(Linux Containers,LXC)技术。
LXC被集成到了主流Linux内核中,进而成为Linux系统轻量级容器技术的事实标准。
从Linux容器到Docker
在LXC的基础上,Docker进一步优化了容器的使用体验。Docker提供了各种容器管理工具(如分发、版本、移植等)让用户无需关注底层的操作,可以简单明了地管理和使用容器。用户操作Docker容器就像操作一个轻量级的虚拟机那样简单。
可以简单地将Docker容器理解为一种沙盒(SandBox),每个容器内运行一个应用,不同的容器相互隔离,容器之间也可以建立通信机制。容器的创建和停止都十分快速,容器自身对资源的需求也十分有限,远低于虚拟机。
为什么要使用Docker
Docker容器虚拟化的好处
高效地构建应用。Docker通过容器打包应用,节约时间,降低部署过程出现问题的风险。
Docker在开发和运维中的优势
- 更快速的交付和部署。使用Docker,开发人员可以使用镜像来快速构建一套标准的开发环境;开发完成后,测试和运维人员可以直接使用相同环境来部署代码。Docker可以快速创建和删除容器,实现快速迭代,大量节约开发、测试、部署的时间。并且,各个步骤都有明确的配置和操作,整个过程全程可见,使团队更容易理解应用的创建和工作过程。
- 更高效的资源利用。Docker容器的运行不需要额外的虚拟化管理程序(Virtual Machine Manager,VMM,以及Hypervisor)支持,它是内核级的虚拟化,可以实现更高的性能,同时对资源的额外要求很低。
- 更轻松的迁移和扩展。Docker容器几乎可以在任意平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。这种兼容性让用户可以在不同平台之间轻松地迁移应用。
- 更简单的更新管理。使用Dockerfile,只需要小小的配置修改,就可以代替以往大量的更新工作。并且所有的修改都以增量的方式进行分发和更新,从而实现自动化并且高效的容器管理。
Docker与虚拟机比较
Docker在运行应用上相比传统虚拟机方式具有显著的优势:
- Docker容器很快,启动和停止可以在秒级实现。
- Docker容器对系统资源需求很少,一台主机可以同时运行数千个Docker容器。
- Docker通过类似Git的操作来方便用户获取、分发和更新应用镜像,指令简明,学习成本低。
- Docker通过Dockerfile配置文件来支持灵活的自动化创建和部署机制,提高工作效率。
特性 | 容器 | 虚拟机 |
---|---|---|
启动速度 | 秒级 | 分钟级 |
硬盘使用 | 一般为MB | 一般为GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 一般几十个 |
隔离性 | 安全隔离 | 完全隔离 |
虚拟化与Docker
虚拟化技术,在计算机领域,一般指的是计算机虚拟化(Computing Virtualization),或通常说的服务器虚拟化。
从大类上分,虚拟化技术可以分为基于硬件的虚拟化和基于软件的虚拟化。其中,真正意义上的基于硬件的虚拟化技术不多见,少数如网卡中的单根多IO虚拟化(Single Root I/O Virtualization and Sharing Specificatio,SR-IOV)等技术。
基于软件的虚拟化从对象所在的层次,又可以分为应用虚拟化和平台虚拟化(通常说的虚拟化技术即属于这个范畴)。其中,前者一般指的一些模拟设备或Wine这样的软件。后者又可以详细分为:
Virtualization* 完全虚拟化。虚拟机模拟完整的底层硬件环境和特权指令的执行过程,客户机操作系统无需进行修改。例如VMware Workstation、VirtualBox、QEMU等。
- 硬件辅助虚拟化。利用硬件(主要是CPU)辅助支持(目前x86体系结构上可用的硬件辅助虚拟化技术包括Intel-VT和AMD-V)处理敏感指令来实现完全虚拟化的功能,客户机操作系统无需修改,例如VMware WorkStation、Xen、KVM。
- 部分虚拟化。只针对部分硬件资源进行虚拟化,客户端操作系统需要进行修改。现在有些虚拟化技术的早期版本仅支持部分虚拟化。
- 超虚拟化(paravirtualization)。部分硬件接口以软件的形式提供给客户机操作系统,客户机操作系统需要进行修改,例如早期的Xen。
- 操作系统级虚拟化。内核通过创建多个虚拟的操作系统(内核和库)来隔离不同的进程。容器相关技术即在这个范畴。
Docker和常见的虚拟机方式的不同之处。
传统方式是在硬件层面实现虚拟化,需要有额外的虚拟机管理应用和虚拟机操作系统层。
Docker容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,因而更加轻量级。
核心概念
Docker镜像
Docker镜像(Image)类似于虚拟机镜像,可以将它理解为一个面向Docker引起的只读模板,包含了文件系统。
镜像是创建Docker容器的基础。通过版本管理和增量的文件系统,Docker提供了一套十分简单的机制来创建和更新现有的镜像,用户甚至可以从网上下载一个已经做好的应用镜像,并通过简单的命令就可以直接使用。
Docker容器
Docker容器(Container)类似于一个轻量级的沙箱,Docker利用容器来运行和隔离应用。
容器是从镜像创建的应用运行实例,可以将其启动、开始、停止、删除,而这些容器都是相互隔离、互不可见的。
镜像自身是只读的。容器从镜像启动的时候,Docker会在镜像的最上层创建一个可写层,镜像本身将保持不变。
Docker仓库
Docker仓库(Repository)类似于代码仓库,是Docker集中存放镜像文件的场所。
Docker注册服务器(Registry)是存放仓库的地方。每个仓库中存放某一类镜像,往往包括多个镜像文件,通过不同的标签(tag)来进行区分。
当用户创建了自己的镜像后,就可以使用push命令将它上传到指定的仓库中。这样下一次用户在另外一台机器上使用该镜像时,只需将其从仓库上pull下来就可以了。
安装Docker
Docker镜像
镜像是Docker的三大核心概念之一。
Docker运行容器前需要本地存在对应的镜像,如果不存在本地,Docker会尝试先从默认镜像仓库下载(Docker Hub),用户也可以通过配置,使用自定义的镜像仓库。
获取镜像
命令的格式。
1 | docker pull NAME[:TAG] |
从Docker Hub的Ubuntu仓库下载最新的Ubuntu操作系统的镜像。
1 | sudo docker pull ubuntu |
下载过程中,镜像文件一般由若干层组成,行首的afde35469481字符串代表了各层的ID。
指定标签下载指定版本的镜像
1 | sudo docker pull ubuntu:16.04 |
查看镜像信息
使用docker images命令可以查看本地主机上已有的镜像。
1 | sudo docker images |
使用docker inspect获取镜像的详细信息
1 | sudo docker inspect [image id] |
docker inspect命令返回的是一个Json格式的消息,获取其中一项内容可以使用-f参数指定。获取镜像的Created信息。
1 | sudo docker inspect [image id] -f {{".Created"}} |
搜寻镜像
使用docker search命令可以搜寻远端仓库中共享的镜像。
1 | sudo docker search [item] |
删除镜像
1 | sudo docker images rm [image id|tag] |
或者
1 | sudo docker rmi [image id|tag] |
1 | sudo docker images rm [image id tag] -f |
创建镜像
创建镜像的方法有三种:基于已有镜像的容器创建、基于本地模板导入、基于Dockerfile创建。
基于已有镜像的容器创建
主要使用docker commit命令。
1 | sudo docker commit [options] container [repository[:tag]] |
演示。首先,启动一个镜像,并且在其中进行修改操作,创建test文件,之后退出。
1 | king@ubuntu ~ sudo docker run -it ubuntu /bin/bash |
提交镜像。
1 | king@ubuntu ~ sudo docker commit -m "Added a new file" -a "Docker Newbee" d12bc42d52bc test |
此时查看本地镜像列表,可以看到新创建的镜像。
基于本地模板导入
从一个操作系统模板文件导入一个镜像。这里使用的是OpenVZ提供的模板来创建。
下载地址
1 | sudo docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]] |
基于Dockerfile创建
[下节讲]
存储和载入镜像
存储镜像
1 | sudo docker save [OPTIONS] IMAGE [IMAGE...] |
载入镜像
1 | sudo docker load [OPTIONS] |
上传镜像
可以使用docker push命令上传镜像到仓库,默认上传到DockerHub官方仓库(需要登录)。
1 | sudo docker push [OPTIONS] NAME[:TAG] |
Docker容器
容器是Docker的另一核心概念。容器是镜像的一个运行实例,不同的是,容器带有额外的可写文件层。
创建容器
新建容器
可以使用docker create命令新建一个容器。
1 | sudo docker create [OPTIONS] IMAGE [COMMAND] [ARG...] |
使用docker create命令创建的容器处于停止状态,可以使用docker start命令来启动它。
1 | sudo docker start [OPTIONS] CONTAINER [CONTAINER...] |
新建并启动容器
启动容器有两种方式:一种是基于镜像新建一个容器并启动,另一个是将在终止的状态(stopped)的容器重新启动。使用命令docker run,等价于先执行docker create命令,再执行docker start命令。
1 | sudo docker run [OPTIONS] IMAGE [COMMAND] [ARG...] |
当利用docker run来创建并启动容器是,Docker在后台运行的标准包括:
- 检查本地是否存在指定的镜像,不存在就从公有仓库下载。
- 利用镜像创建并启动一个容器。
- 分配一个文件系统,并在只读的镜像层外面挂在一层可读写层。
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中。
- 从地址池配置一个IP地址给容器。
- 执行用户指定的应用程序。
- 执行完毕后容器就被终止。
下面的命令将启动一个bash终端,允许用户进行交互。
1 | sudo docker run -t -i ubuntu /bin/bash |
守护态运行
更多时候,需要docker容器在后台以守护态(Daemonized)形式运行。用户可以添加-d参数来实现。
1 | sudo docker run -d ubuntu /bin/sh -c "while ture; do echo hello world; sleep 1; done" |
1 | sudo docker logs [OPTIONS] CONTAINER |
终止容器
1 | sudo docker stop [OPTIONS] CONTAINER [CONTAINER...] |
进入容器
在使用-d参数时,容器启动后会进入后台,用户需要进入容器进行相关操作。
attach命令
docker attach是docker自带的命令。
1 | sudo docker attach [OPTIONS] CONTAINER |
exec命令
docker自1.3版本起,提供一个更加方便的工具exec,可以直接在容器内运行命令。
1 | sudo docker exec [OPTIONS] CONTAINER COMMAND [ARG...] |
nsenter工具
这里不做讨论。
删除容器
1 | sudo docker rm [OPTIONS] CONTAINER [CONTAINER...] |
导入和导出容器
导出容器
导出容器是指导出一个已经创建的容器到一个文件中。
1 | sudo docker export [OPTIONS] CONTAINER |
导入容器
导出的文件又可以使用docker import命令导入,成为镜像。
1 | sudo docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]] |
Docker仓库
仓库(Repository)是集中存放镜像的地方。注册服务器是存放仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下有多个镜像。对于仓库地址dl.dockerpool.com/ubuntu来说,dl.dockerpool.com是注册服务器地址,ubuntu是仓库名。
Docker Hub
创建和使用私有仓库
使用registry镜像创建私有仓库
可以使用官方提供的registry镜像来搭建本地私有仓库环境。
1 | sudo docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry |
此时本地将启动一个私有仓库服务,监听端口为5000。
管理私有仓库镜像
使用docker tag将ubuntu镜像标记为10.211.55.11:5000/test(格式为docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG])
1 | sudo docker tag ubuntu 10.211.55.11:5000/king |
使用docker push上传标记的镜像。
1 | sudo docker push 10.211.55.11:5000/king |
现在可以在任意连接到10.211.55.11的机器下载这个镜像。
1 | sudo docker pull 10.211.55.11:5000/king |
出现错误
1 | king@ubuntu: sudo docker push 10.211.55.11:5000/king |
在/etc/docker下,创建daemon.json文件。
1 | { "insecure-registries":["10.211.55.11:5000"]} |
重启docker
1 | systemctl restart docker.service |
重新启动registry
1 | sudo docker ps -a # 找到registry的CONTAINER ID |