Docker
Posted zhaohaiyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker相关的知识,希望对你有一定的参考价值。
一、简介
1.1 为什么出现docker
1.2什么是docker
- 打包应用程序及程序运行所依赖的环境, 产出叫做Docker 镜像
- 启动多个镜像到服务器中
- 是一个CS架构的软件产品
概念:Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上 ,是一种轻量级的虚拟化技术。
1.3发展史
- Docker 公司位于旧金山,原名dotCloud,底层利用了Linux容器技术(在操作系统中实现资源隔离与限制)。为了方便创建和管理这些容器,dotCloud 开发了一套内部工具,之后被命名为“Docker”。Docker就是这样诞生的!
- 2013年,dotCloud 的 PaaS 业务并不景气,公司需要寻求新的突破。于是他们聘请了 Ben Golub 作为新的 CEO,将公司重命名为Docker,放弃dotCloud PaaS 平台,怀揣着"将 Docker 和容器技术推向全世界"的使命,开启了一段新的征程。
- "Docker"一词来自英国口语,意为码头工人(Dock Worker),即从船上装卸货物的人。
- 如今 Docker 公司被普遍认为是一家创新型科技公司,据说其市场价值约为 10 亿美元。Docker 公司已经通过多轮融资,吸纳了来自硅谷的几家风投公司的累计超过 2.4 亿美元的投资,几乎所有的融资都发生在公司更名为“Docker”之后。
1.4版本规划
- Docker 引擎主要有两个版本:企业版(EE)和社区版(CE)。
- 每个季度(1-3,4-6,7-9,10-12),企业版和社区版都会发布一个稳定版本(Stable)。社区版本会提供 4 个月的支持,而企业版本会提供 12 个月的支持。
- 每个月社区版还会通过 Edge 方式发布月度版。
- 从 2017 年第一季度开始,Docker 版本号遵循 YY.MM-xx 格式,类似于 Ubuntu 等项目。例如,2018 年 6 月第一次发布的社区版本为 18.06.0-ce。
二、安装
wget http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
mv docker-ce.repo /etc/yum.repos.d
yum install -y docker-ce
wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-17.09.0.ce-1.el7.centos.x86_64.rpm
yum localinstall docker-ce-17.09.0.ce-1.el7.centos.x86_64.rpm
三、核心三要素
2.1Docker镜像
??镜像是容器构建的基石,是基于联合文件系统的一种层式结构。由一系列指令构建,是一种轻量级、可执行的独立软件包,用于打包软件运行环境和基于运行环境开发的软件(代码、运行时、库、环境变量和配置文件)。
??联合文件系统(UnionFS)是一种分层、轻量级、高性能的文件系统。它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一虚拟文件系统下。Union文件系统是Docker镜像的基础。
??典型的Linux文件系统由bootfs和rootfs两部分组成,bootfs(boot file system)主要包含 bootloader和kernel,bootloader主要是引导加载kernel,当kernel被加载到内存中后 bootfs就被umount了。 rootfs (root file system) 包含的就是典型 Linux 系统中的/dev,/proc,/bin,/etc等标准目录和文件,rootfs就是不同操作系统的发行版。
??Docker容器的文件系统类似于Linux虚拟化栈。Docker镜像是由文件系统叠加而成。最底端是一个引导文件系统,即bootfs, 很像典型的Linux/Unix的引导文件系统。当一个容器启动时,首先加载bootfs用于引导重要文件,当容器启动后,bootfs引导文件系统会被卸载(unmount)。
??传统的Linux引导过程中,root文件系统会最先以只读的方式加载,当引导结束并完成了完整性检查之后,rootfs将会从read-only改为read-write。
Docker的镜像加载时,在bootfs自检完毕之后并不会把rootfs的read-only改为read-write。而是利用联合加载union mount(UnionFS的一种挂载机制)将一个或多个read-only的rootfs加载到之前的read-only的rootfs层之上。在加载了这么多层的rootfs之后,仍然让它看起来只像是一个文件系统,在Docker的体系里把union mount的这些read-only的rootfs叫做Docker的镜像。
??一个镜像可以放到另一个镜像的顶部。位于下面的镜像称为父镜像(parent image), 依次类推,直到镜像栈的最底部,最底部的镜像称为基础镜像( base image)。最后,当从一个镜像启动容器时,Docker会在该镜像的最顶层加载一个读写文件系统。镜像可以通过分层来进行继承,基于基础镜像可以制作各种具体的应用镜像。
??此时的每一层rootfs都是read-only的,在镜像启动容器的最后阶段,Docker会在该镜像的最顶层加载一个读写read-write的rootfs文件系统,我们想在Docker中运行的程序就是在这个读写层中执行的。
??当Docker第一次启动一个容器时,初始的读写层是空的。当文件系统发生变化时,这些变化都会应用到这一层上。比如,如果想修改一个文件,这个文件首先会从该读写层下面的只读层复制到该读写层。该文件的只读版本依然存在,但是已经被读写层中的该文件副本所隐藏。
这种机制被称为写时复制C copy on write), 这也是使Docker如此强大的技术之一。 每个只读镜像层都是只读的,以后永远不会变化。当创建一个新容器时,Docker会构建出一个镜像栈,并在栈的最顶端添加一个读写层。这个读写层再加上其下面的镜像层以及一些配置数据,就构成了一个容器。容器的这种特点加上镜像分层框架( image-layering framework), 使我们可以快速构建镜像并运行包我们自己的应用程序和服务的容器。
docker本地镜像保存在 /var/lib/docker ,容器保存在 /var/lib/docker/containers 。
??总结:Docker镜像(image)就是一个只读的模板。 镜像可以用来创建Docker容器,一个镜像可以创建很多容器。
镜像分层优势:
??共享资源:通过引入分层技术,可以增加镜像复用度,减少磁盘占用;同时可以实现差分上传下载,加快镜像pull、push性能。
2.2Docker容器
??Docker利用容器(container)独立运行的一个或者一组应用。容器是利用镜像创建的运行实例(相对于Java中的类和对象的概念)。容器可以被启动、开始、停止、删除。每个容器都是互相隔离的,保证安全的平台。可以把容器看做是一个简易版的Linux环境 (包括root用户名权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
??容器的定义和镜像几乎是一模一样的,也是一堆层的统一视角, 唯一区别的是容器的最上面那一层是可读可写的。
??容器是镜像启动或执行阶段。Docker中的每个容器都包含了一个软件镜像,该镜像可以被创建、启动、关闭、重启和销毁。
2.3Docker仓库Registry
??仓库(repository)是集中存放镜像文件的场所 。最大的公开仓库是docker hub( https://hub.docker.com/), 存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云、网易云等。
??Docker Hub中有两种类型的仓库:用户仓库(user repository)和顶层仓库(top-level repository)。用户仓库的镜像都是由Docker用户创建的,而顶层仓库则是由Docker内部的人来管理的。
用户仓库的命名由用户名和仓库名两部分组成,如:jamtur01/puppet。用户名:jamtur01,仓库名:puppet。
顶层仓库只包含仓库名部分,如ubuntu仓库。顶层仓库由Docker公司和由选定的能提供优质基础镜像的厂商(如Fedora团队提供了fedora镜像)管理,用户可以基于这些基础镜像构建自己的镜像。
??仓库(repository)和仓库注册服务器(registry)是有区别的。仓库注册服务器上往往放着很多个仓库,每个仓库中又包含了很多个镜像,每个镜像有不同的标签(tag)。使用示例:仓库名:TAG号。
总结:
??Docker本身是一个容器运行载体或者称之为管理引擎。我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个打包好的运行环境就叫image镜像文件。 只有通过这个镜像文件才能生成docker容器。image文件可以看做是容器的模板。 Docker根据image文件生成容器的实例。 同一个image文件,可以生成多个同时运行的容器实例。
??a)image文件生成的容器实例,本身也是一个文件,称为镜像文件;
??b)一个容器运行一种服务,当我们需要的时候,就可以通过docker客户端创建一个对应的运行实例,也就是我们的容器;
??c)至于仓库,就是放了一堆镜像的地方,我们可以把镜像发布到仓库中,需要的时候从仓库中拉下来就可以了。
四、HelloWorld
$ docker run hello-world
镜像加速
$ "registry-mirrors": ["https://i1el1i0w.mirror.aliyuncs.com"]
五、常用命令
docker ps
查看容器列表docker images
查看镜像列表docker run
启动容器,-d|-p|--namedocker pull
从仓库拉取镜像docker push
本地镜像推送到仓库中docker tag
为镜像做标记docker search
搜索镜像docker rm
删除容器docker rmi
删除镜像docker cp
在容器与宿主机之间拷贝文件docker exec -ti
进入容器docker build
构建镜像- docker inspect 查看镜像或者容器详细信息
六、制作自己的镜像
6.1构建镜像
docker build . -f ./Dockerfile -t my-helloworld:20191110
6.2Dockerfile
一堆指令,在docker build的时候,按照该指令进行操作,最终生成我们期望的镜像
FROM 指定基础镜像,必须为第一个命令
格式: FROM <image> FROM <image>:<tag> 示例: FROM mysql:5.6 注意: tag是可选的,如果不使用tag时,会使用latest版本的基础镜像
MAINTAINER 镜像维护者的信息
格式: MAINTAINER <name> 示例: MAINTAINER Yongxin Li MAINTAINER inspur_lyx@hotmail.com MAINTAINER Yongxin Li <inspur_lyx@hotmail.com>
COPY|ADD 添加本地文件到镜像中
格式: COPY <src>... <dest> 示例: ADD hom* /mydir/ # 添加所有以"hom"开头的文件 ADD test relativeDir/ # 添加 "test" 到 `WORKDIR`/relativeDir/ ADD test /absoluteDir/ # 添加 "test" 到 /absoluteDir/
WORKDIR 工作目录
格式: WORKDIR /path/to/workdir 示例: WORKDIR /a (这时工作目录为/a) 注意: 通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行
RUN 构建镜像过程中执行命令
格式: RUN <command> 示例: RUN yum install nginx RUN pip install django RUN mkdir test && rm -rf /var/lib/unusedfiles 注意: RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache
CMD 构建容器后调用,也就是在容器启动时才进行调用
格式: CMD ["executable","param1","param2"] (执行可执行文件,优先) CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数) CMD command param1 param2 (执行shell内部命令) 示例: CMD ["/usr/bin/wc","--help"] CMD ping www.baidu.com 注意: CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
ENTRYPOINT 设置容器初始化命令,使其可执行化
格式: ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先) ENTRYPOINT command param1 param2 (shell内部命令) 示例: ENTRYPOINT ["/usr/bin/wc","--help"] 注意: ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数,都会被当做参数再次传递给ENTRYPOINT。Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,而只执行最后的ENTRYPOINT指令
ENV
格式: ENV <key> <value> ENV <key>=<value> 示例: ENV myName John ENV myCat=fluffy
EXPOSE
格式: EXPOSE <port> [<port>...] 示例: EXPOSE 80 443 EXPOSE 8080 EXPOSE 11211/tcp 11211/udp 注意: EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口
VOLUME
格式: VOLUME ["/path/to/dir"] 示例: VOLUME ["/data"] VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"] 注意: EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口
示例
# This my first django Dockerfile
# Version 1.0
# Base images 基础镜像
FROM centos:centos7.5.1804
#MAINTAINER 维护者信息
LABEL maintainer="inspur_lyx@hotmail.com"
#ENV 设置环境变量
ENV VERSION v1.0
#RUN 执行以下命令
RUN yum install -y wget
RUN wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/Centos-7.repo
RUN yum install -y python36 python3-devel gcc
#工作目录
WORKDIR /opt
#拷贝文件至工作目录
COPY . /opt
RUN pip3 install -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com Django==2.1.8
RUN rm -rf ~/.cache/pip
#EXPOSE 映射端口
EXPOSE 8000
#容器启动时执行命令
CMD ["python3", "manage.py", "runserver", "0.0.0.0:8000"]
6.3推送镜像
$ docker build . -f Dockerfile -t my-helloworld:20191110
$ docker tag my-helloworld:20191110 liyongxin5288/my-helloworld:20191110
$ docker push liyongxin5288/my-helloworld:20191110
$ docker run --name helloworld -d -p 8000:8000 my-helloworld:20191110
以上是关于Docker的主要内容,如果未能解决你的问题,请参考以下文章