前言:
第一次接触docker是在两年前,那时候感觉云里雾里,只知道有很多类似于linux的命令,做着和linux操作系统类似的事情。最近在工作中又重新接触到了docker,前一段时间也看了一些教学视频,本来是看过就过了,现在觉得还是要留下点什么,才能印象深刻。
官网地址:
https://docs.docker.com/
(最全以及最权威的信息往往在官网中,其他地方的信息都是围绕官网而衍生~)
首先对docker进行一个简单的介绍,docker是基于Go语言实现的开源项目,主要是为了是实现轻量级的操作系统虚拟化解决方案(虚拟化的本质:复用主机的原有内核+自己定制的文件系统),相当于一个mini版本的Linux(只包含Linux中最基础的命令)。
云计算和微服务的兴起,服务器硬件扩展便利,软件服务部署成为瓶颈。
(1)镜像(Image):类似于一个只读的模板文件,可以用来创建docker容器。
(2)容器(container):从镜像创建的运行实例,用来运行应用。可以被启动、开始、停止、删除。每个容器都是互相隔离的,以保证容器中应用的安全。可以看作是一个简易版的Linux环境和运行在其中的应用程序。
(3)仓库:存放镜像文件的地方。分为私有仓库和共有仓库(最大公共仓库:Docker Hub),可以使用push命令将镜像上传到仓库,使用pull命令将镜像从仓库中下载到本地。另外,仓库注册服务器上往往存放多个仓库,每个仓库包含多个镜像,每个镜像有不同的标签。
Docker使用客户端-服务器架构。Docker 客户端与Docker 守护进程进行对话,该守护进程完成了构建,运行和分发Docker容器的繁重工作。Docker客户端和守护程序可以 在同一系统上运行,也可以将Docker客户端连接到远程Docker守护程序。Docker客户端和守护程序在UNIX套接字或网络接口上使用REST API进行通信。
(1)Docker守护程序
Docker守护程序(dockerd)侦听Docker API请求并管理Docker对象,例如图像,容器,网络和卷。守护程序还可以与其他守护程序通信以管理Docker服务。
(2)Docker客户端
Docker客户端(docker)是许多Docker用户与Docker交互的主要方式。当您使用诸如之类的命令时docker run,客户端会将这些命令发送到dockerd,以执行这些命令。该docker命令使用Docker API。Docker客户端可以与多个守护程序通信。
(3)Docker注册表(仓库)
Docker 注册表存储Docker镜像。Docker Hub是任何人都可以使用的公共注册表,并且Docker配置为默认在Docker Hub上查找镜像。您甚至可以运行自己的私人注册表。 使用docker pull或docker run命令时,所需的镜像将从配置的注册表中提取。使用该docker push命令时,会将镜像推送到配置的注册表。
(4)Docker对象
使用Docker时,您正在创建和使用映像,容器,网络,卷,插件和其他对象。本节是其中一些对象的简要概述。
容器在Linux上本机运行,并与其他容器共享主机的内核。它运行一个独立的进程,不占用比任何其他可执行文件更多的内存,这使得它是轻量级的。相比之下,虚拟机(VM)运行成熟的“第三方”操作系统,通过管理程序虚拟访问主机资源。通常,虚拟机会产生比应用程序逻辑所消耗的更多的开销。
(1)交互式创建容器并进入(前台进程):
docker run -it --name (容器名) (镜像名) /bin/bash
使用exit退出也关闭容器;Ctrl+P+Q退出不关闭容器。
(2)后台启动容器(后台进程):
docker run -d --name (容器名) (镜像名)
(3)进入已运行的容器:
docker exec -it ( 容器名) /bin/bash
(4)查看容器元数据:
docker inspect nginx
(5)绑定容器端口到主机:
docker run -d -p 主机ip:容器ip --name (容器名) (镜像名)
(6)挂载主机文件目录到容器内:
docker run -dit -v 主机目录:容器目录 --name (容器名) (镜像名)
(7)复制主机文件到容器内:
docker cp (主机文件目录)(容器名):(容器目录)
(1)由容器commit镜像
镜像与容器由一层层的layer 文件组装而成。
a、当用镜像模板创建容器时,是直接在镜像的文件层级上,加一层容器读写层。
b、反过来,如果想要创建一个新的镜像,直接把容器对应的所有文件层,转为只读层即可(commit)。
(2)dockerfile方式创建
dockerfile的基本要素:
FROM {base 镜像}必须放在Dockerfile 的第一行,表示从哪个baseimage 开始构建
可选的,用来标识image 作者的地方
RUN 都是启动一个容器、执行命令、然后提交存储层文件变更。第一层RUN command1 的执行仅仅是当前进程,一个内存上的变化而已,其结果不会造成任何文件。而到第二层的时候,启动的是一个全新的容器,跟第一层的容器更完全没关系,自然不可能继承前一层构建过程中的内存变化。而如果需要将两条命令或者多条命令联合起来执行需要加上&&。如:cd /usr/local/src && wget xxxxxxx
CMD 的作用是作为执行container 时候的默认行为(容器默认的启动命令)当运行container 的时候声明了command,则不用image 中的CMD 默认所定义的命令一个Dockerfile 中只能有一个有效的CMD,当定义多个CMD 的时候,只有最后一个才会起作用
EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是docker run -P 时,会自动随机映射EXPOSE 的端口。
entrypoint 的作用是,把整个container 变成可执行的文件,且不能够通过替换CMD 的方法来改变创建container 的方式。但是可以通过参数传递的方法影响到container 内部每个Dockerfile 只能够包含一个entrypoint,多个entrypoint 只有最后一个有效当定义了entrypoint 以后,CMD 只能够作为参数进行传递
把host 上的文件或者目录复制到image 中(能够进行自动解压压缩包)
用来设置环境变量,后续的RUN 可以使用它所创建的环境变量
用来指定当前工作目录(或者称为当前目录)
运行RUN 指令的用户
用来创建一个在image 之外的mount point
docker 容器运行,产生一些数据/文件/等等持久化的东西,不应该放在容器内部。应当以挂载的形式存在主机文件系统中。
(1)docker 的文件系统
(2)volume 参数创建容器数据卷
eg:docker run --name (容器名) -v (主机目录) -it (镜像名)/bin/bash
(3)volumes-from 引用数据卷
新启一容器,引入上一步的容器目录。得到同一个目录,内容于原有容器的挂载一样。
eg:docker run -it --rm --volumes-form (原有容器名) --name (新容器名)(镜像名) /bin/bash
(4)删除数据卷
docker rm -v data