一、docker的产生和概述
docker技术主要是为程序部署和运维而产生的,对部署来说它提供了一个能让程序正常运行的封装环境,它避免了不同环境配置导致的程序无法运行的尴尬,它的思想理念是镜像封装,达到一次封装多处运行的目的。其次对高并发、高可用程序来说,是实现服务集群的基石。Docker技术是在Linux容器技术的基础上发展而来,所以说docker实质上就是一项容器虚拟化技术。
提到容器就不得不提到虚拟机,容器和虚拟机的本质是一样的,虚拟机虚拟的是一套带软件和硬件的完整解决方案,其缺点有占用资源、步骤冗余、启动慢等,而容器是在虚拟机之上对进程进行隔离,形成一个个独立的容器,这些容器只包含程序运行必须的软件环境,因此具有启动快、占用硬件资源少等特点,容器实质上可看作是一个基础镜像系统+应用程序的简版系统。
docker技术包含三个部分,即仓库、镜像、容器,容器是运行程序的最小单元,它是镜像的实例;镜像是容器的模板,容器运行需要借助镜像来装载环境;仓库用于存储镜像文件,通常分为中央仓库、私有仓库、本地仓库; 三者之间的关系类似于java面向对象中的包、类、对象的关系。
目前最大仓库是Docker Hub,国内公开仓库有阿里云仓库、网易云等。
二、docker运行原理
docker是一个client-server结构的系统,使用远程API来管理和创建Docker容器,docker守护进程运行在主机上,通过socket连接从客户端,守护进程会从客户端接收命令并管理运行在主机上的容器。
docker的详细命令请参考帮助命令(docker --help)输出的内容( 命令语法格式: docker [OPTIONS] COMMAND [ARG...] ),OPTIONS为可选项,参考options选项说明,COMMAND为命令,包括管理命令和普通命令,参考managerCommands和commands说明, ARG为参数(容器ID、镜像名等表示命令要操作的对象)。参考常见命令有docker version、docker info、docker images、docker ps、docker rm 、docker search、docker run、docker logs、docker inspect。
docker的镜像实际上是由一层一层的文件系统构成,这种层级的文件系统UnionFS。Union文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,Union文件系统是Dokcer镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的镜像。一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统加载起来,这样最终的文件系统会包含所有的底层文件和目录。
UnionFS主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的linux/unix系统是一样的,包含boot加载器内核。当boot加载完之后整个内核就都在内存中了,此时内存的使用权已经由bootfs交给内核了,此时系统也会卸载bootfs。对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就行,因为底层直接用host和kernel,自己只需要提供rootfs就行。由此可见对于不同的Linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。
在下载镜像的过程中我们可以看到docker的镜像好像是在一层一层的下载,这些层其实都是文件系统,使用分层思想主要是为了实现文件系统的共享,比如多个镜像都从相同的base镜像构建而来,那么宿主机只需要在磁盘上保存一份base镜像,同时内存中也需要加载一份base镜像,就可以为所有上层文件系统提供服务了。而且镜像的每一层都可以被共享。
Docker 支持通过扩展现有镜像,创建新的镜像。实际上,Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的。新镜像是从 base 镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层,其构建过程 如下:
当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下都叫“镜像层”,可写层可以改动,镜像层则为只读的,其容器的结构如下图:
Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来, 那么当容器删除后,数据自然也就没有了,为此我们使用数据卷来持久化数据。卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷,无主的数据卷可能会占据很多空间,所以要及时删除。使用数据卷可以实现多个容器和宿主机之间数据共享,数据卷类似于局域网的共享文件或文件,特点如下:
- 数据卷存在于宿主机的文件系统中,独立于容器,和容器的生命周期是分离的。
- 数据卷可以是目录也可以是文件,容器可以利用数据卷与宿主机进行数据共享。
- 容器启动初始化时,如果容器使用的镜像包含了数据,这些数据会拷贝到数据卷中。
- 容器对数据卷的修改是实时进行的。
- 数据卷的变化不会影响镜像的更新。数据卷是独立于联合文件系统,镜像是基于联合文件系统。镜像与数据卷之间不会相互影响。
镜像本身是不可描述的,Docker提供了镜像文件Dockerfile机制,Dockerfile是一个文本文件,内容包含了一条条构建镜像所需的指令和说明, 它可以用来构建镜像,我们还可以通过它了解镜像的信息和功能。因此镜像的产生有仓库拉取、commit、dockerfile构建等几种方式,如图所示:
三、docker的安装和使用
1、docker安装参考https://www.w3cschool.cn/docker/,还可以参考docker官网,该教程包含了不同系统的安装方式,此处省略,国外下载镜像慢,推荐使用阿里云的镜像加速器下载镜像。镜像加速器的使用和配置方式请参考阿里云镜像加速器操作文档。
2、下载和运行镜像:运行容器需要先从镜像仓库下载镜像到本地后运行,其下载命令为docker pull imagesname:tagname,运行命令为docker run imagesName:tagname,运行命令会先从本地查找,如果镜像不存在,则会从仓库下载。
3、常用的docker命令和参数说明:
Docker环境信息 — docker [info|version]
容器生命周期管理 — docker [create|exec|run|start|stop|restart|kill|rm|pause|unpause]
容器操作运维 — docker [ps|inspect|top|attach|wait|export|port|rename|stat]
容器rootfs命令 — docker [commit|cp|diff]
镜像仓库 — docker [login|pull|push|search]
本地镜像管理 — docker [build|images|rmi|tag|save|import|load]
容器资源管理 — docker [volume|network]
系统日志信息 — docker [events|history|logs]
管理命令:
container 管理容器
image 管理镜像
network 管理网络
命令:
attach 介入到一个正在运行的容器
build 根据 Dockerfile 构建一个镜像
commit 根据容器的更改创建一个新的镜像
cp 在本地文件系统与容器中复制 文件/文件夹
create 创建一个新容器
exec 在容器中执行一条命令
images 列出镜像
kill 杀死一个或多个正在运行的容器
logs 取得容器的日志
pause 暂停一个或多个容器的所有进程
ps 列出所有容器
pull 拉取一个镜像或仓库到 registry
push 推送一个镜像或仓库到 registry
rename 重命名一个容器
restart 重新启动一个或多个容器
rm 删除一个或多个容器
rmi 删除一个或多个镜像
run 在一个新的容器中执行一条命令
search 在 Docker Hub 中搜索镜像
start 启动一个或多个已经停止运行的容器
stats 显示一个容器的实时资源占用
stop 停止一个或多个正在运行的容器
tag 为镜像创建一个新的标签
top 显示一个容器内的所有进程
unpause 恢复一个或多个容器内所有被暂停的进程
docker run 命令常用参数:
--name:为容器指定名称
-it:启动一个交互型容器,此参数为我们和容器提供了一个交互shell
-d:创建后台型容器
-restart=always:容器退出后自动重启
-restart=on-failure:x:容器退出时如果返回值是非0,就会尝试重启x次
-p x:y :主机端口:容器端口
-P:随机分配一个49000到49900的端口
-v:创建数据卷
-n :指定dns
-h : 指定容器的hostname
-e :设置环境变量
-m :设置容器使用内存最大值
--net: 指定容器的网络连接类型,支持 bridge/host/none/container
--link=x: 添加链接到另一个容器x
--expose=x: 开放端口x
docker ps 命令常用参数:
-a:查看所有容器
-l:只列出最近创建的
-n=x:只列出最后创建的x个
-q:只列出容器id
docker rm 命令常用参数:
-f:强制删除运行中的容器
docker rm `docker ps -aq`:删除所有容器
docker logs 命令常用参数:
-f:实时查看日志
--tail=x:查看最后x行
-t:查看日志产生的时间
4、数据卷的添加方式:
a.使用docker命令的 -v 选项配置,格式为 “ docker run -it -v /宿主机绝对路径目录 :/容器内目录 镜像名”。
b.使用dockerfile文件配置,在donckerfile文件中使用VOLUME命令指定数据卷。
5、数据卷容器的使用:数据卷可以通过容器来实现继承,达到数据卷共享的目的,提供数据卷的容器称为数据卷容器(父容器),例如以下命令创建了1个父容器和2个子容器,这三个容器都共享同一个数据卷。
docker run -it --parentcentos centos //创建父容器
docker run -it --child1 --volumes-from parentcentos centos //数据卷来自父容器
docker run -it --child2 --volumes-from parentcentos centos //数据卷来自父容器
//经过继承,三者都使用同一个数据卷,达到容器之间共享数据卷的目的
6、dockerfile文件的使用:要使用dockerfile构建镜像首先是编写dockerfile文件,然后调用" docker build -f dockefikename -t imagesname:tag "命令即可构建。其dockerfile文件内容格式要求和说明:
a.每条指令必须大写且必须跟参数;
b.指令按顺序执行;
c.#表示注释;
d.每条指令都会创建一个新的镜像层,并对镜像进行提交,当所有命令执行完成后形成一个新的镜像;
其内容描述模板参考如下:
# Base images 基础镜像
FROM centos
#MAINTAINER 作者姓名和邮箱
MAINTAINER zqf<92973322@qq.com>
#ENV 设置环境变量,可通过 $变量名 引用
ENV PATH /usr/local/nginx/sbin:$PATH
#ADD 文件放在当前目录下,拷过去会自动解压,这与COPY命令差不多,区别是COPY不会自动解压
ADD nginx-1.8.0.tar.gz /usr/local/
ADD epel-release-latest-7.noarch.rpm /usr/local/
#RUN 执行以下命令
RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpm
RUN yum install -y wget lftp gcc gcc-c++ make openssl-devel pcre-devel pcre && yum clean all
RUN useradd -s /sbin/nologin -M www
#WORKDIR 相当于cd,登录时切换到的目录
WORKDIR /usr/local/nginx-1.8.0
RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-pcre && make && make install
RUN echo "daemon off;" >> /etc/nginx.conf
#挂在数据卷
VOLUME /data : /usr
#镜像被子镜像继承后构建时,运行的命令
ONBUILD ["nginx"]
#EXPOSE 映射端口
EXPOSE 80
#CMD 容器启动时要运行的命令,如果有多个CMD则前面的会被覆盖,也会被dockr run 后面的脚本参数替换
CMD ["nginx"]
#容器启动时要运行的命令,有多个时会追加执行命令,而不会CMD那样被覆盖
ENTRYPOINT ["nginx"]
四、镜像发布到仓库
通常镜像打包后需要送到云镜像仓库,首先需要在阿里云、腾讯云等平台开通镜像仓库功能,或者自己搭建仓库,再按照平台操作文档使用账号密码登录到仓库,后使用“docker push 仓库地址/imagesname:[tag]”命令执行推送。