一、Docker镜像原理
1.1 Docker镜像的运行原理
当一个容器启动后,它将会被移到内存中,而引导文件系统则会被卸载,以留出更多的内存供initrd磁盘镜像使用。
2、什么是Docker镜像
(1)Docker镜像是由文件系统叠加而成,最低端是一个引导文件系统,即bootfs,典型的为Linux/Unix 的引导文件系统。
Docker镜像的第二层是root文件系统rootfs,位于引导文件系统之上,rootfs可以是一种或多种操作系统如ubuntu文件系统。
Docker镜像是由多个文件系统(只读层)叠加而成。当我们启动一个容器的时候,Docker会加载只读镜像层并在其上(即镜像栈顶部)添加一个读写层。如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏。当删除Docker容器,并通过该镜像重新启动时,之前的更改将会丢失。在Docker中,只读层及在顶部的读写层的组合被称为Union File System(联合文件系统)。
联合文件系统是一种轻量级的高性能分层文件系统,它支持将文件系统中的修改信息作为一次提交,并层层叠加,同时可以将不同目录挂载在同一个虚拟文件系统下,应用看到的是挂载的最终结果。
1.2 Docker数据管理
在生成环境中使用Docker,往往需要对数据进行持久化,或需要多个容器之间进行数据共享,这涉及到容器的数据管理操作。
容器中管理数据主要方式有两种:
- 数据卷:容器内数据直接映射到本地主机环境;
- 数据卷容器:使用特性容器维护数据卷。
1.2.1 数据卷
数据卷是一个可供容器使用的特殊目录,它将数据操作系统目录直接映射进容器,类型linux mount。
- 数据卷可在容器之间共享和重用,容器器传递数据变得高效方便;
- 对数据卷内数据的修改会立马生效,无论是容器内操作还是本地操作;
- 对数据卷的更新不会影响到镜像;
- 卷会一直存在,直到没有容器使用它,可以安全地卸载它。
1、创建数据卷
docker volume create -d local test
创建并查看数据卷test
Volume可以将容器以及容器产生的数据分离开
2、绑定数据卷
该方法为创建容器时,将主机本地的任意路径挂载到容器内作为数据卷,这种形式创建的数据卷称为绑定数据卷。
在docker run 时,用-mount 选项挂载数据卷:
数据卷的类型:
- volume:普通数据卷 映射到主机 /var/lib/docker/volumes 目录下
- bind: 绑定数据卷,映射到主机指定路径下;
- tmpfs:临时数据卷,只存在于内存中
本地目录的路径必须是绝对路径,容器内的路径可以为相对路径,如果目录不存在,Docker会自动创建。
挂载数据卷:
格式:
docker run -it -v /宿主机绝对目录:/容器内目录 镜像名
应用举例;
docker run -it -v /myDataVolume:/dataVolumerContainer centos
绑定数据卷,并在容器内的centos下创建一个test1目录,查看宿主机的目录
若容器中不存在指定的路径,该目录中会创建/data 数据卷
1.2.2 数据卷容器
如果用户需要在多个容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器。数据卷容器也是一个容器,但是它的目的是专门提供数据卷给其他容器挂载。
1、创建一个数据卷容器dbdata,并在其中创建一个数据卷挂载到 /dbdata
docker run -it -v /dbdata --name dbdata ubuntu
在其他容器中使用 --volumes-from 来挂载dbdata容器中的数据卷,多个容器可以挂载同一个数据卷容器
将容器db1挂载到dbdata 容器中的数据卷
docker run -it --volumes-from dbdata --name db1 ubuntu
删除了 db1 和dbdata容器,数据卷并不会被自动删除。删除一个数据卷,必须在删除最后一个还挂载它的容器使用docker rm -v 命令,指定同时删除关联的容器。
二、构建Docker镜像
构建docker镜像有两种方法:
- 使用docker commit 命令
- 使用docker build 命令和Dockerfile文件
2.1 使用docker commit 命令构建镜像
1、注册Docker Hub账号
安装docker 教程参考:怎样注册Docker Hub账号 - 此生不换Yang - 博客园
注册完成账号,邮件激活,测试登录
2、docker commit 格式
docker commit 容器id 仓库名/镜像名
(1)创建一个要进行修改的定制容器
docker run -i -t ubuntu /bin/bash
通过以上指令进行ubuntu容器 执行apdate指令时会出现如下错误:
执行 apt-get -yqq update 解决如下问题传递
正确进入容器的指令:通过--net=host参数改变容器网络模式解决
docker run -it --name test --net=host ubuntu /bin/bash
通过该链接解决该问题:我的ubuntu连vi都没有??那在命令行怎么编辑文件??_dianguan0598的博客-CSDN博客
(2)安装apache2
主要是更新软件源
apt-get -yqq update
apt-get -y install apache2apt-get -y install apache2
ubuntu容器中安装了apache,为了不必每次创建一个ubuntu容器时,都要在里面安装Apache,使用docker commit 指令创建镜像
(3)提交定制容器
退出ubuntu容器
exit
docker commit 用法:
docker commit 容器id 目标镜像仓库/镜像名
docker commit 只会提交创建容器的镜像与容器的当前状态之间有差异的部分。
查看ubuntu 容器id
执行commit
docker commit f9a8e6a0e8ec aoct/apache2
(3)查看新创建的镜像
docker images aoct/apache2
也可附带 上传信息,镜像作者信息,镜像标签
docker commit -m "a new custom image" -a "herry" f9a8e6a0e8ec aoct/apache2:webserver
查看详细上传信息
docker inspect aoct/apache2:webserver
(4)运行新建的容器
docker run -t -i aoct/apache2:webserver /bin/bash
2.2 使用Dockerfile 构建镜像
2.2.1 Dockerfile 简介
Dockerfile 用来构建镜像,是一个命令参数脚本。有了Dockerfile 可以使用docker build 命令基于该Dockerfile 中的指令构建一个新的镜像。
(1)Dockerfile构建步骤:
(2)Dockerfile 基本要点:
- 每个Dockerfile 的第一条指令必须是FROM,FROM 指令指定一个已经存在的镜像,后续指令都将基于该镜像进行。这个镜像被称为基础镜像。
- MAINTAINER指令,告诉Docker该镜像的作者是谁。
- 每条RUN指令都会创建一个新的镜像层。
- EXPOSE指令来向外部公开端口。
Dockerfile 主体内容分为四部分:基础镜像信息,维护者信息,镜像操作指令和启动时执行指令。
RUN:用于执行后面跟着的命令行命令。有以下俩种格式:
shell 格式:
RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。
exec 格式:
RUN ["可执行文件", "参数1", "参数2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline
2.2.2 Docker构建镜像
(1)搭建构建环境,创建Dockerfile文件
mkdir docker_test
mkdir docker static_web
cd static_web
touch Dockerfile
vim Dockerfile
static_web目录用来保存Dockerfile,该目录被称为构建环境(build environment),Docker则称此环境为上下文(context)或构建环境(build context),Docker 会在构建镜像时,将构建上下文和上下文中的文件和目录上传到Docker守护进程。
(2)编辑Dockerfile文件
FROM ubuntu:14.04 #基础镜像
MAINTAINER Herry "你的邮箱@qq.com" #标识镜像的所有者和联系方式
RUN apt-get update && apt-get install -y nginx #RUN 指令创建一个新的镜像层
Run echo 'Hi,I am in your container' >/usr/share/nginx/html/index.html
EXPOSE 80 #指定容器的应用程序使用容器指定端口
Dockerfile 每一条指令都会创建一个新的镜像层并对镜像进行提交。
语句含义:
- Docker 从基础镜像运行一个容器,Dockerfile 的第一条指令必须是FROM,FROM指令指定一个已经存在的镜像,后续指令都将基于该进行运行。
- 执行一条指令,对容器做出修改,并创建一个新的镜像层,如果该指令执行成功,就会将此镜像层提交。(每运行一条RUN 指令,镜像添加新的一层,并提交)
(3)执行Docker build命令构建新镜像
在构建环境目录中执行,注意不要缺少“.”,指的是当前目录,执行docker build 后,Dockerfile 中所有指令都会被执行并且提交,并且在该命令成功结束后返回一个新镜像。
docker build -t="jamtur01/static_web:v1" .
-t 为新镜像设置了仓库和名称,也可设置标签。
以上会报错误,容器无法访问宿主机网络,设置host网络模式:
docker build -t="jamtur01/static_web:v1" --network=host .
镜像构建成功。
运行创建的镜像
docker run -it d46ea90d394d /bin/bash
参考:https://segmentfault.com/a/1190000002567459
解决docker ubuntu 镜像无法执行update命令问题
三、Docker 端口映射与容器互联
3.1 端口映射实现容器访问
在启动容器的时候,如果不指定对应参数,在容器外部是无法通过网络来访问容器内的网络应用和服务。
当容器中运行需要一些网络应用时,可以通过-P或-p 参数来指定端口映射。-P ,Docker会随机映射一个 49000-49900 的端口到内部容器开发的网络端口。
-p 可以指定要映射的端口。
3.2 容器的互联
容器的互联是一种让多个容器中的应用进行快速交互的方式,它会在源和接收容器之间创建连接关系,接收容器可以通过容器名快速访问到源容器,而不用指定具体的ip地址。
容器互联相当于两个互联的容器之间创建了一个虚拟通道。