docker介绍
什么是docker?我们先看一下官方文档对docker的定义。翻译一下就是:Docker是一个集开发,发布和运行应用程序的开放平台。Docker能够分离应用和基础架构,从而可以使得用户可以快速交付软件。借助于Docker,用户可以以管理应用的方式管理基础架构。通过利用Docker快读交付,测试和部署代码的能力,用户可以大大地减少编写代码和在生产环境中运行代码的延迟。
Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production.
Docker提供了在一个松散隔离的环境中打包和运行应用的功能,这个环境被称为容器。容器是轻巧的,它们不需要其他额外的管理程序就可以直接运行在宿主机的内核上,同时环境的隔离性和安全性特性允许在一个给定的主机上可以运行多个容器,而且多个容器相互独立,互不干扰。
Docker架构
Docker的基础架构是客户端-服务器(client-server)模式。在Docker中的主要组件有守护程序进程(daemon process)[服务器(service),一种长期运行的程序],命令行界面客户端(command line interface client, CLI client)和指定程序与守护进程通信并指示其操作的接口REST API。CLI 使用接口docker REST API通过脚本或者直接CLI命令控制docker守护进程或者与docker守护进程进行交互。守护进程(daemon)创建和管理docker对象,比如镜像(images),容器(contains),网络(network)和数据卷(data volumes)。
Docker客户端和Docker守护进程可以在同一系统上运行,也可以将Docker客户端连接到远程的Docker守护进程。Docker客户端和Docker守护进程在UNIX套接字或者网络接口上使用REST API进行通话,Docker守护进程用来完成docker容器的构建,运行和分发等工作。
- docker守护进程侦听docker API的并且管理docker对象,例如图像,容器,网路和数据卷。守护进程也可以与其他的守护进程进行通信来管理docker服务
- docker客户端是docker用户与Docker交互的主要方式。客户端将命令发送到守护进程,守护进程执行相应的命令。Docker客户端可以与多个守护进程进行通信。
- docker仓库用来储存docker仓库。Docker hub是一个任何人都能够使用的公共仓库。
- docker对象
- 镜像是一个带有创建Docker容器的说明的只读模板。用户可以docker仓库中他人已经创建好的镜像,也可以创建Dockerfile文件来编写创建镜像的指令。Dockerfile中的每条指令都会在镜像中创建一层。当用户更改Dockerfile并且重新创建镜像的时候,只有更改的层需要重建,其它层保持不变。通常情况下,一个镜像可以基于另一个镜像进行构建。假设用户现在拥有一个GPU版本的pytorch环境基础镜像,然而项目还需要一些额外的库文件,比如opencv库文件,那么就可以基于基础镜像,再安装相应的opencv库文件 ,就可以构造项目所需要的镜像了。
- 容器是一个镜像的可运行实例。用户可以通过API或者命令行界面创建,启动,停止,移除和删除一个容器。默认情况下,容器与容器以及宿主机之间的隔离度相对较好,用户可以控制容器的网络,存储和其他基础子系统与宿主机的隔离程度。
docker 和虚拟机
dokcer和虚拟机docker可直接运行在宿主机上,与宿主机共享内核。
虚拟机是指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。创建虚拟机时,需要将实体机的部分硬盘黑盒内存容量作为虚拟机的硬盘和内存容量。每个虚拟机都有独立的CMOS、硬盘黑盒操作系统。 -----<虚拟机>百度百科编写
命名空间namespaces
docker使用命名空间namespaces技术提供独立的工作区间。当用户运行一个容器的时候,Docker就为这个容器创建一系列的命名空间。这些命令空间提供了层的隔离性。
- pid命令空间:进程隔离(PID:进程ID)
- net命名空间:网络接口管理
- ipc命名空间:管理进程间通信资源的访问
- mnt命名空间:管理文件系统挂载点
- uts命名空间:隔离内核和版本标识符
联合文件系统
联合文件系统(Union File System)通过创建层来实现联合挂载。Docker使用联合文件挂载和copy-on-write技术为容器提供组成容器的块,这也是容器轻巧和快速的原因。
copy-on-write是一种共享和复制文件能够达到最大效率的技术。如果一个文件或者一个文件夹存在于镜像的最底层,其它层(包括可写层)需要对其进行读访问,那么就可以使用这个存在的文件。如果其他层首次需要修改这个文件(当构建镜像时或者运行容器时),那么这个文件被复制到此层并被修改。这样能够最小化I/O和后续每层的大小。
当使用docker pull 从仓库中拉取一个镜像时,或者当你从一个当地并不存在的镜像中创建容器时,每一层单独地被拉取,存储在Docker的当地存储区域,在linux主机上,则是/var/lib/docker。
从上图可以看出,拉取镜像时,是分层拉取,ubuntu18.04总共有三层。docker inspect 查看其镜像信息,在Layers属性中,包含三层的sha256信息。
镜像和容器
一个docker镜像从一系列层中构建,在Dockerfile中,每一层表示一条指令。除了最后一层,其它层都仅仅是可读的。这些层按照栈的格式堆叠,每一层互不相同。当用户创建容器的时候,用户仅仅在最高层添加一个可写的层,这一层被称为“容器层”。在运行的容器中进行的改变,例如对文件的增删改查,都仅仅写入这个可写的容器层。
镜像和容器的最主要区别在于最顶层的可写层。添加新文件,更改存储可写成的数据等等都被写入到这个容器中。当容器被删除,那么这个可写层也随之被删除。这个容器基于的镜像保持不变。 基于此,基于一个镜像就可以构造多个容器,并且每个容器都有自己的数据区域。
Docker常用命令
# 镜像有关命令
docker image pull # 拉取镜像
docker images # 查看镜像
docker rmi image-id/镜像名字 # 删除某个镜像
docker rmi $(docker images | grep -v RESPOSITORY | awk '{print $3}') # 删除所有镜像
docker search 镜像名字 # 搜索某个镜像
docker build -t 镜像名称:版本 . # 构建镜像,注意后面的 .# docker命令
docker -v # 查看docker版本
docker info # 查看docker系统信息# 容器有关命令
docker ps -a # 查看所有容器列表
docker ps -a -n=10 # 查看10个容器
docker inspect 容器ID # 查看某个容器的信息
docker rm 容器ID # 删除某个容器
docker rm $(docker ps -a) # 删除所有容器
docker stop 容器ID # 关闭运行中的某个容器
docker start 容器ID # 启动某个容器但是不进入
docker start -i 容器ID # 启动并进入某个容器
docker restart 容器ID # 重启某个容器
docker attach 容器ID # 进入一个运行中的容器
docker run -it 镜像名称:版本 # 启动容器并且以交互式进入容器