全网最详细Docker的基础知识(从入门到实例)

    科技2022-08-15  103

    Docker详细基础

    一、Docker简介二、Docker三要素:仓库、镜像、容器三、docker底层原理3.1 docker为什么比VM快?(docker与虚拟化技术的特点) 四、Docker常用命令4.1 帮助命令:docker (-help、version、info)4.2 镜像命令:4.3 容器命令: 五、容器重要命令启动就退出问题? 六、Docker镜像原理6.1 UnionFile(联合文件系统),6.2 Docker镜像加载原理6.3 为什么docker采用分层结构? 七、Docker容器数据卷7.1 使用-v(一对一进行宿主机和容器之间的数据共享)7.2 使用DockerFile 八、Docker数据卷容器九、DockerFile解析9.1 Docker执行Dockerfile的大致流程:9.2 Dockerfile、Docker镜像、Docker容器的关系9.3 Docker体系结构-保留字指令 十、Dockerfile案例10.1 案例一:自定义镜像mycentos10.2 案例二:CMD/ENTRYPOINT镜像案例10.3 案例三:ONBUILD10.4 案例四:自定义镜像Tomcat9 十一、Docker常用的安装安装redis 十二、参考资料

    一、Docker简介

    解决了运行环境和配置问题的软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术。

    1.1 Docker包含两方面技术:

    1.镜像技术,打破“代码即应用”的概念,透过镜像将运作应用程式所需要的系统环境,自底向上打包应用,达到应用程式跨平台间的无缝运作。即一次封装,到处运行。2.容器虚拟化技术,基于容器的虚拟化,仅包含业务运行所需的runtime环境。

    1.2 Docker的优势(DevOps):

    1.更快速的应用交付和部署2.更快捷的升级和扩缩容3.更简单的系统运维4.更高效的计算资源利用

    二、Docker三要素:仓库、镜像、容器

    从远程仓库pull的镜像,就是一个只读的模版,用来创建Docker容器,并且一个镜像可以创建很多容器。

    1.容器,Docker利用容器独立运行一个或一组应用,容器是用镜像创建的运行实例(runtime环境)。它可以被启动、开始、停止、删除,每个容器都是相互隔离的、保证安全的平台。可以把容器看作是一个简易版的Linux环境和运行在其中的应用程序。容器的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。2.仓库,集中存放镜像文件的场所。3.镜像,Docker本身是一个容器运行载体或称之为管理引擎(daemon)。我们将应用程序和配置依赖打包好形成一个可交付的运行环境,这个打包好的运行环境就是image镜像文件。一个容器运行一种服务,当我们需要的时候,就可以通过Docker客户端创建一个对应的容器。

    如何配置阿里云镜像加速器?

    三、docker底层原理

    Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上,然后通过Socket连接从客户端访问,守护进程从客户端接收命令并管理运行在主机上的容器。

    3.1 docker为什么比VM快?(docker与虚拟化技术的特点)

    1.docker有着比虚拟机更少的抽象层。运行在docker容器上的程序直接使用实际物理机的硬件资源,不需要实现硬件资源虚拟化。2.docker通过Docker Engine利用的是宿主机的内核,而不需要Guest OS。

    四、Docker常用命令

    4.1 帮助命令:docker (-help、version、info)

    4.2 镜像命令:

    1.docker images,查看本地镜像。包含多个options: -a,列出本地所有的镜像(镜像分层,含中间映像层)。-q,只显示镜像id(-qa组合options)。–digests,现实摘要信息。– no-trunc,显示完整的镜像信息(–digests --no-trunc组合options)。 2.docker search 镜像名,options: –no-trunc,显示完整的镜像描述。-s,列出收藏数不小于指定值的镜像。–automated,只列出automated build类型的镜像。 3.docker pull 镜像名(镜像名可以:版本号,不指定版本号默认latest)4.docker rmi 镜像名id,删除镜像。options: -f,删除单个镜像id。空格分割,删除多个镜像。3.-f $(docker images -q),删除全部镜像。 5.docker commit6.docker push

    4.3 容器命令:

    1.docker run 镜像id,新建并启动容器。options: –name,为容器指定名字。-d,后台运行容器,并返回容器id,即启动守护式容器。-i,以交互模式运行容器,通常与-t同时使用。-t,为容器重新分配一个伪输入终端。-P,随机端口映射。-p,指定端口映射,有以下四种格式: ip:hostPort:containerPortip::containerPorthostPort:containerPortcontainerPort 2.docker ps,列出当前所有正在运行的容器。options: -a,列出所有正在运行的容器+历史上运行过的。-l,显示最近创建的容器。-n,显示最近n个创建的容器。-q,静默模式,只显示容器编号(-lq可组合使用)。–no-trunc,不截断输出。 3.退出容器有两种方式: exit,容器停止退出。ctrl+P+Q,容器不停止退出。 4.docker start 容器id或容器名,启动容器。5.docker restart 容器id,重启容器。6.docker stop 容器id或容器名,停止容器。7.docker kill 容器id或容器名,强制停止容器。8.docker rm 容器id,删除已经停止的容器。options: -f $(docker ps -a -q),删除全部。直接全部删除,docker ps -a -q | xargs docker rm

    五、容器重要命令

    1.启动守护式容器,docker run -d 容器名2.查看容器日志,docker logs -f -t --tail 容器id: -t,加入时间数-f,跟随最新的日志打印–tail,数字显示最后多少条 3.查看容器内运行的进程,docker top 容器id4.查看容器内部细节以json格式,docker inspect 容器id5.进入正在运行的容器并以命令行交互 1.docker exec -it 容器id /bin/bash,在容器中打开新的终端,并且可以启动新的进程;并且在宿主机外可以执行docker容器运行的命令,docker exec -t 容器id ls /tmp,直接返回结果到宿主机。2.重新进入,docker attach 容器id,直接进入容器命令的终端,不会启动新的进程。 6.从容器内拷贝文件到主机上,docker cp 容器id:容器内路径 目的主机路径。(可对容器内数据进行持久化)。7.提交容器副本使之成为一个新的镜像,docker commit -m=“提交的描述信息” -a=“作者” 容器id 要创建的目标镜像名:[标签名]

    启动就退出问题?

    1.Docker容器后台运行就必须有一个前台进程。

    2.容器运行的命令如果不是那些一直挂起的命令(top、tail等),就会自动退出。

    3.这个是docker的机制问题,容器为后台进程模式运行,就导致docker前台没有运行的应用,容器就会立即停止。

    4.最佳的解决方案,将要运行的程序以前台进程的形式运行。

    5.后台运行某一个程序,容器就会一直运行,例如:

    docker run -d centos /bin/sh -c 'while trues; do echo hello-world; sleep 2; done' #可用查看容器日志命令,后台一直在打印‘hello-world’

    六、Docker镜像原理

    镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、库、环境变量和配置文件。 特点:Docker镜像都是只读的,当容器启动时每一个新的可写层被加载到镜像的顶部。这一层通常被称为“容器层”,“容器层”之下的都叫“镜像层”。

    6.1 UnionFile(联合文件系统),

    Union文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交,来一层层的额叠加,同时可以将不同目录挂载到同一个虚拟文件系统。Union文件系统是Docker镜像的基础,镜像可以通过分层来进行继承,基于镜像,可以制作各种具体的应用镜像。

    特性,一次同时加载多个文件系统,但是从外部看,只能看到一个文件系统,联合加载会把各层文件系统叠加,这样最终的文件系统会包含所有底层的文件和目录。Docker镜像的底层原理,docker的镜像实际上是由一层一层的文件系统组成,即联合文件系统。

    6.2 Docker镜像加载原理

    bootfs(boot file system)主要包含bootloader和kernel。bootloader主要是引导加载kernel,linux刚启动时就会加载bootfs文件系统,在docker镜像的最底层就是bootfs,当boot加载完成之后整个内核就都存在内存中,此时内存的使用权有bootfs转交给内核,系统卸载bootfs。rootfs(root file system),在bootfs之上。包含的就是典型linux系统中的 /dev, /proc, /bin, /etc等标准目录和文件。对docker容器,rootfs只需包括最基本的命令、工具和程序库就行。因为底层直接使用Host的kernel,自己只需要rootfs。因此docker容器中的centos这么小。

    6.3 为什么docker采用分层结构?

    最大的好处就是,共享资源。

    有多个镜像都从相同的base镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,同时在内存中也只需加载一份base镜像,就可以为所有容器服务,而且镜像的每一层都可以被共享。例如,下载镜像的时候第一次很慢,但接着下载就会很快。因为,docker将base镜像进行了缓存。基于base镜像,只需要下载各种具体的应用镜像。

    七、Docker容器数据卷

    数据卷即数据持久化。为了能够保存容器中数据,我们可以使用容器数据卷,类似于Redis里的RDB和AOF文件,相当于活动硬盘。

    目的:

    1.将应用和环境打包形成容器运行,运行可以伴随着容器,但是我们有时需要将数据进行持久化。2.容器间继承和容器之间有时需要共享数据。

    7.1 使用-v(一对一进行宿主机和容器之间的数据共享)

    1.docker run -it -v /宿主机Data文件夹:/容器Data文件夹 镜像名

    此命令相当于在容器与宿主机之间Data文件建立了数据共享的连接,可以使用上述的docker -inspect 容器id命令查看详细信息,可以看到宿主机和容器之间Data文件夹的绑定。

    docker run -it -v /myDataVolume:/dataVolumeContainer centos

    注意:容器停止退出后,主机修改后数据同步。类似于redis的持久化,因为redis是运行在内存中,当redis停止再次启动,会读取持久化的数据进行回写。

    2.docker run -it -v /宿主机Data文件夹:/容器Data文件夹:ro 镜像名

    此命令加上ro,表示容器对与宿主机Data文件夹only read权限,只能读取宿主机传过来的数据。

    docker run -it -v /myDataVolume:/dataVolumeContainer:ro centos

    7.2 使用DockerFile

    1.宿主机目录下新建mydocker文件夹进入。

    2.File构建,在DockerFile中使用VOLUME指令给镜像添加一个或多个数据卷。

    From centos VOLUME ["dataVolumeContainer1","dataVolumeContainer2","dataVolumeContainer3"] CMD echo "finished,--------------succeess" CMD /bin/bash

    3.File进行build生成镜像,使用docker images命令可查看生成的镜像。

    docker build -f /mydocker/dockerfile -t mm/centos . #-f表示dockerFile文件 -t表示镜像名称 .表示当前文件夹

    4.run 镜像生成容器。

    docker run -it mm/centos

    宿主机中的容器卷默认位置,快使用docker inspect 容器id,进行查看。

    VOLUME指令

    VOLUME ["/dataVolumeContainer","/dataVolumeContainer2","/dataVolumeContainer3"]

    说明:

    1.考虑到可移植和分享的考虑,用-v命令这种方法不能直接在DockerFile中实现。2.由于宿主机目录是依赖于特定宿主机,并不能够保证所有的宿主机都存在这样的特定目录。

    八、Docker数据卷容器

    命名的容器挂载数据卷,其他容器通过挂载这个(父容器)实现数据共享。挂载数据卷的容器,称之为数据容器卷。

    上一步新建的镜像mm/centos为模版并运行容器dc01、dc02/dc03,这三个数据卷容器都包含三个数据卷 “dataVolumeContainer1”, “dataVolumeContainer2”,“dataVolumeContainer3”。以该两个父容器为继承对象实现容器间传递共享(–volumes-from)。

    docker run -it --name dc02 --volumes-from doc1 mm/centos docker run -it --name dc03 --volumes-from doc2 mm/centos

    数据卷容器之间的关系为继承和共享关系,容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止。

    九、DockerFile解析

    Dockerfile是用来构建Docker镜像的文件,是由一系列命令和参数构成的脚本。构建三步骤为:create、build、run。

    1.scratch是所有镜像文件的主键类,类似于java里的Objext类,FROM scratch引用。2.每条保留指令都必须为大写字母且后面必须跟随至少一个参数。3.指令按照从上到下,顺序执行。4.每条指令都会创建一个新的镜像层,并对镜像进行提交。

    9.1 Docker执行Dockerfile的大致流程:

    1.docker从基础镜像运行一个容器。2.执行一条指令并对容器作出修改。3.执行类似docker commit的操作提交一个新的镜像层。4.docker再基于刚提交的镜像运行一个新的容器。5.执行dockerfile中的下一条指令直到所有指令都执行完成。

    9.2 Dockerfile、Docker镜像、Docker容器的关系

    1.dockerfile是构成镜像的基础,面向开发。

    dockerfile定义了进程所需要的一切东西,包括执行代码(文件)、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程。

    2.docker镜像,成为交付标准。

    用Dockerfile定义一个文件后,docker build时会产生一个Docker镜像,当运行Docker镜像时,会真正开始提供服务。

    3.docker容器是docker镜像的运行态,涉及部署和运维。

    容器是直接提供服务的。

    9.3 Docker体系结构-保留字指令

    1.FROM,基础镜像,当前新镜像是基于哪个镜像的。

    2.MAINTAINER,镜像维护者的姓名和邮箱。

    3.RUN,容器构建时需要运行的具体命令(例如,run redis镜像时,需要创建的用户组)。

    4.EXPOSE,当前容器对外暴露的端口号。

    5.WORKDIR,指定在创建容器后,终端默认登录进来的工作目录。

    6.ENV,用来在构建镜像过程中设置环境变量。

    7.ADD,将宿主机目录下的文件拷贝进镜像且自动处理URL和解压tar压缩包。

    8.COPY,类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中的文件或目录复制到新的一层的镜像内。

    9.VOLUME,容器数据卷,用于数据保存和持久化工作。

    10.CMD,指定一个容器启动时需要的命令。Dockerfile中可以有多个CMD指令,但是只有最后一个生效,CMD会被docker run 之后的参数替换。

    CMD指令的格式和RUN相似,也是两种格式:

    1.shell格式:CMD<命令>2.exec格式:CMD[“可执行文件”,“参数1”,“参数2”,……]参数列表格式:CMD[“参数1”,“参数2”,……],在指定了ENTRYPOINT指令后,用CMD指定具体的参数。

    11.ENTRYPOINT,指定一个容器启动时需要的命令。ENTRYPOINT的目的和CMD一样,都是指定容器启动程序及参数。区别在于:CMD会覆盖掉前面的CMD指令,只有最后一个生效;ENTRYPOINT是追加命令。

    12.ONBUILD,当构建一个被继承的Dockfile时运行命令,父镜像在被子镜像继承后,父镜像的onbuild被触发。

    十、Dockerfile案例

    Docker Hub中99%的镜像都是通过在base镜像中安装和配置需要的软件构建出来的。

    1.自定义镜像mycentos2.CMD/ENTRYPOINT镜像案例3.ONBUILD使用4.自定义镜像Tomcat9

    10.1 案例一:自定义镜像mycentos

    目的: 自定义mycentos使我们自己的镜像具备,登录后的指定路径、有vim编辑器、能查看网络配置ifconfig支持。

    流程:

    1.编写

    Hub默认Centos镜像编写DockerFile文件 FROM centos MAINTAINER mm<1806483840@qq.com> ENV MYPATH /usr/local WORKDIR $MYPATH RUN yum -y install vim RUN yum -y install net-tools EXPOSE 80 CMD echo $MYPATH CMD echo "success---------ok" CMD /bin/bash

    2.构建

    Docker build -f dockerfile路径名 -t 新镜像名:TAG .

    docker build -f /mydocker/dockerfile2 -t mycentos:1.0 .

    3.运行

    docker run -it 新镜像名:TAG

    4.列出镜像的变更历史

    docker history 镜像名

    10.2 案例二:CMD/ENTRYPOINT镜像案例

    目的: CMD和ENTRYPOINT的区别

    1.CMD

    CMD会被docker run 之后的参数替换,只有最后一个生效,。

    2.ENTRYPOINT

    docker run 之后的参数传递给ENTRYPOINT,之后形成新的命令组合。

    流程:

    1.构建用CMD的dockerfile。

    FROM centos RUN yum -y curl CMD ["curl","-s",http://ip.cn]

    2.构建用ENTRYPOINT的dockerfile。

    FROM centos RUN yum -y curl ENTRYPOINT ["curl","-s",http://ip.cn]

    3.具体步骤同案例一,只是run的时候,一个不可以加-i(会被覆盖为CMD -i),另一个可以加参数-i。

    10.3 案例三:ONBUILD

    目的:

    父镜像的dockerfile文件中加上ONBUILD,当有其他的镜像通过dockerfile里的FROM命令继承该父镜像时,会触发ONBUILD并打印信息。

    流程:

    1.新建dockerfile文件

    FROM centos MAINTAINER mm<1806483840@qq.com> ENV MYPATH /usr/local WORKDIR $MYPATH RUN yum -y install vim RUN yum -y install net-tools EXPOSE 80 CMD echo $MYPATH CMD echo "success---------ok" CMD /bin/bash ONBUILD RUN echo"father is mycentos1"

    2.将上述dockerfile 进行build命令,生成镜像mycentos1。

    3.构建子镜像的dockerfile文件

    FROM mycentos1 MAINTAINER mm<1806483840@qq.com> ENV MYPATH /usr/local WORKDIR $MYPATH RUN yum -y install vim EXPOSE 80 CMD echo $MYPATH

    4.build第三步的dockerfile,会打印父镜像dockerfile里的ONBUILD命令的语句,也就是进行了回调。

    10.4 案例四:自定义镜像Tomcat9

    目的:

    构建属于自己特有的Tomcat

    流程:

    1.构建dockerfile

    FROM centos MAINTAINER mm<1806483840@qq.com> #把宿主机当前上下文的c.txt拷贝到容器/usr/local路径下 COPY c.txt /usr/local/cincontainer.txt #将java和tomcat添加到容器内,进行解压缩 ADD jdk1.8.0_101.tar.gz /usr/local ADD apache-tomcat-9.0.26.tar.gz /usr/local #安装vim编辑器 RUN yum -y install vim #设置工作访问时候的WORKDIR路径 ENV MYPATH /usr/local WORKDIR $MYPATH #配置java与tomcat环境变量 ENV JAVA_HOME /usr/local/jdk1.8.0_101 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.26 ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.26 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin #容器运行时监听的端口 EXPOSE 8080 #启动时运行tomcat #ENTRYPOINT ["usr/local//bin/startup.sh"] CMD /usr/local/apache-tomcat-9.0.26/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.26/bin/logs/catalina.out

    2.build dockerfile

    docker build -t mmtomcat9 .

    3.run dockerfile

    docker run -it -p 9080:8080 --name mtomcat9 -v /myDataVolume/mtomcat9/test:/usr/local/apache-tomcat-9.0.26/webapps/test -v /myDataVolume/mtomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.26/logs --privileged=true mmtomcat9

    4.验证

    5.发布

    1.将容器进行commit

    docker commit -a mm -m "mycentos first push " 44910358112d mycentos:1.1

    2.进入阿里云开发者平台

    docker login --username=账户名 registry.cn-hangzhou.aliyuncs.comdocker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/xmm_666/mmdocker:[镜像版本号]docker push registry.cn-hangzhou.aliyuncs.com/xmm_666/mmdocker:[镜像版本号]

    十一、Docker常用的安装

    1.搜索镜像2.拉取镜像3.查看镜像4.启动镜像5.停止镜像6.移除镜像

    安装redis

    1.docker pull redis:3.2 ,拉取redis官方镜像。

    2.docker run redis镜像(docker容器的端口号可以指定任意未被占用端口,redis如果需要使用其他端口,需要修改redis.conf配置文件)。

    docker run -p 6389:6379 -v /mydocker/myredis/data:/data -v /mydocker/myredis/conf/redis.conf:/usr/local/etc/redis/redis.conf -d redis:3.2 redis-server /usr/local/etc/redis/redis.conf --appendonly yes

    3.使用容器

    在宿主机redis.conf目录下新建redis.conf文件,并使用vim编辑,可以保存并共享到容器内。

    4.开启redis服务,redis-cli

    docker exec -it f79c16d34035 redis-cli

    5.redis持久化。

    cd /mydocker/myredis/data,进入到宿主机data目录。vim appendonly.aof ,查看redis的持久化数据。

    十二、参考资料

    Linux资料Docker Hub: 运行环境的打包,上传下载的是镜像尚硅谷资料

    最后修改于日期:2020年9月15日

    Processed: 0.023, SQL: 8