• Docker 使用手册


    一、Docker 核心概念

    安装Docker

    Mac下载地址

    Docker Desktop - Docker

    核心概念

    镜像:类似于虚拟机的镜像,可以理解为面向Docker的只读文件,包含了文件系统

    容器:容器为镜像运行后的实体,可以将其启动 ,运行,停止,删除,而这些容器之间都是相互隔离的,互不可见的。

    仓库:类似于代码仓库,是Docker存放镜像文件的场所。这里要将注册服务器和仓库这两个概念区分开来。注册服务器是存放仓库的地方。

    大小 : 注册服务器 > 仓库 > 镜像

    Docker 为什么比VM快

     

    配置

    Docker for Mac

    配置 阿里云镜像

    {
      "features": {
        "buildkit": true
      },
      "experimental": false,
      "registry-mirrors": [ //配置阿里云镜像
        "https://cz48ekii.mirror.aliyuncs.com"
      ]
    }

    如下就能看到阿里云镜像配置成功,但是现在用的是Docker for Mac ,输入命令后查不到

     

    二、镜像

    联合文件系统

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

    特性:一次性同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样文件系统会包含所有底层的文件和目录。

    Docker镜像的加载原理

    Docker镜像实际上是由一层一层的文件系统组成。Linux启动是会加载bootfs,bootfs包含bootloader和kernel,当bootloader 加载完毕之后,内核kernel也就存在在内存中了,此时bootfs 会把内存的使用权移交给内核,然后系统会卸载掉bootfs。rootfs 在bootfs之上,包含Linux的各种标准文件和目录,如/etc,/usr,/var,/dev等,rootfs就是各种不同操作系统的发行版,如ubuntu, centos等。

    对于一个精简的os ,rootfs可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用host的kernel,自己只需要提供rootfs就可以了。由此可见,对于不同发行版本的Linux,bootfs基本是一致的,而根据不同的版本的rootfs会有差别。

    Docker为什么采用这种分层结构呢

    最大的好处就是资源共享

    有多个镜像都是从相同的base镜像那里构建而来,那么宿主机只需要在磁盘上保存一份base镜像,同时内存中也只需要加载一分base镜像,就可以为所有容器服务了,而且镜像的每一层都可以被共享。

    Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到顶部,这一层通常被称为“容器层”,容器之下的都被称为“镜像层”。

    获取镜像

    docker pull NAME[:TAG]

    如果不显示的指定TAG,则会默认选择latest标签。

    docker pull ubuntu

    此命令相当于docker pull register.hub.docker.com/ubuntu:latest 即从默认的注册服务器上registry.hub.docker.com 中的ubuntu仓库中下载标记为latest的镜像。

    此时用户也可以选择从其他注册服务器上下载,如:dl.dockerpool.com 下载,这是DockerPool的地址,这是国内的注册服务器。

    docker pull dl.dockerpool.com:5000/ubuntu:latest

    运行容器

    docker run -ti ubuntu /bin/bash

    这种方式运行的容器,当exit退出后运行的容器也将停止。

     

     

    Run 命令做了什么?

     

    运行Tomcat 容器

    docker run -it -p 8888:8080 tomcat

    -p : 指定映射端口

    冒号前面的8888为映射端口,即外接访问Docker中的Tomcat的端口,暴露给外界进行访问的端口。

    冒号后面的是容器中的Tomcat启动后的真实端口。

    dcoker run -it -P tomcat

    -P : 随机分配端口

    此时Tomcat的访问端口就编程32768了

    提交修改好的容器生成镜像

    提交容器的副本生成一个新镜像

    ➜  ~ docker commit -a="chenbt" -m="tomcat without docs" ef51d55268c5 chenbt/tomcat:1.0

    容器ID,镜像名称:tag

    -a : 作者

    -m : 描述

    查看镜像信息 docker images

     

    REPOSITORY :来自哪个仓库

    TAG :镜像的标签信息,比如14.04

    IMAGE ID :镜像的ID号(唯一)

    CREATED:镜像创建时间

    SIZE:镜像大小

    获取到容器中的镜像信息

    options :

    -a : 显示所有镜像

    ➜  ~ docker images -a
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    ubuntu              20.10               d80d9d9b3dc3        6 weeks ago         79.5MB
    ubuntu              20.04               9140108b62dc        6 weeks ago         72.9MB
    centos              centos7             7e6257c9f8d8        2 months ago        203MB
    centos              latest              0d120b6ccaa8        2 months ago        215MB
    harisekhon/hbase    1.3                 cadb170e663b        7 months ago        236MB
    harisekhon/hbase    latest              c2f78e407322        8 months ago        413MB

    -q: 显示镜像的镜像ID

    ➜  ~ docker images -q
    d80d9d9b3dc3
    9140108b62dc
    7e6257c9f8d8
    0d120b6ccaa8
    cadb170e663b
    c2f78e407322

    --digests: 显示镜像的摘要信息

     

    --no-trunc: 显示镜像的完整信息,这里展示出镜像ID没有被截取的ID

    docker inspect [image id] 查看镜像的详细信息

    用 -f 来指定参数

    docker inspect 9140108b62dc -f {{".Architecture"}}

     

    搜寻镜像

    docker search

    搜索远端仓库中共享的镜像,默认搜索的Docker Hub 官方仓库的中镜像。

    -- automated=false 仅显示自动创建的镜像

    --no-trunc=false 输出信息不截断显示

    --s, --stars=0 指定仅显示评价为指定星级以上的镜像

    1. ➜ ~ docker search mysql --automated=false
    2. Flag --automated has been deprecated, use --filter=is-automated=true instead
    3. NAME                             DESCRIPTION                                     STARS               OFFICIAL           AUTOMATED
    4. mysql                             MySQL is a widely used, open-source relation…   10040               [OK]
    5. mariadb                           MariaDB is a community-developed fork of MyS…   3678               [OK]
    6. mysql/mysql-server               Optimized MySQL Server Docker images. Create…   735                                     [OK]
    7. percona                           Percona Server is a fork of the MySQL relati…   511                 [OK]
    8. centos/mysql-57-centos7           MySQL 5.7 SQL database server                   83
    9. mysql/mysql-cluster               Experimental MySQL Cluster Docker images. Cr…   77
    10. centurylink/mysql                 Image containing mysql. Optimized to be link…   60                                     [OK]
    11. bitnami/mysql                     Bitnami MySQL Docker Image                      45                                     [OK]
    12. deitch/mysql-backup               REPLACED! Please use http://hub.docker.com/r…   41                                     [OK]
    13. tutum/mysql                       Base docker image to run a MySQL database se…   35
    14. prom/mysqld-exporter                                                              31                                     [OK]
    15. schickling/mysql-backup-s3       Backup MySQL to S3 (supports periodic backup…   30                                     [OK]
    16. databack/mysql-backup             Back up mysql databases to... anywhere!         30
    17. linuxserver/mysql                 A Mysql container, brought to you by LinuxSe…   26
    18. centos/mysql-56-centos7           MySQL 5.6 SQL database server                   20
    19. circleci/mysql                   MySQL is a widely used, open-source relation…   19
    20. mysql/mysql-router               MySQL Router provides transparent routing be…   17
    21. arey/mysql-client                 Run a MySQL client from a docker container      15                                     [OK]
    22. fradelg/mysql-cron-backup         MySQL/MariaDB database backup using cron tas…   9                                       [OK]
    23. yloeffler/mysql-backup           This image runs mysqldump to backup data usi…   7                                       [OK]
    24. openshift/mysql-55-centos7       DEPRECATED: A Centos7 based MySQL v5.5 image…   6
    25. devilbox/mysql                   Retagged MySQL, MariaDB and PerconaDB offici…   3
    26. ansibleplaybookbundle/mysql-apb   An APB which deploys RHSCL MySQL                2                                       [OK]
    27. jelastic/mysql                   An image of the MySQL database server mainta…   1
    28. widdpim/mysql-client             Dockerized MySQL Client (5.7) including Curl…   1                                       [OK]
    1. ➜ ~ docker search mysql -s=10000
    2. Flag --stars has been deprecated, use --filter=stars=3 instead
    3. NAME               DESCRIPTION                                     STARS               OFFICIAL           AUTOMATED
    4. mysql               MySQL is a widely used, open-source relation…   10040               [OK]
    5. ➜ ~
     
    
    1. ➜ ~ docker search mysql --stars=10000
    2. Flag --stars has been deprecated, use --filter=stars=3 instead
    3. NAME               DESCRIPTION                                     STARS               OFFICIAL           AUTOMATED
    4. mysql               MySQL is a widely used, open-source relation…   10040               [OK]
    5. ➜ ~

    查看镜像版本

    1. curl https://registry.hub.docker.com/v1/repositories/centos/tags | tr -d '[\{\,\[\]" ]' | tr '}' '\n' | awk -F: '{if(NF!=NR){printf("%s:%s\n",$2,$3) }}'
    2. 1tr -d '[\{\,\[\]" ]'
    3. \{\,\[\]"   删除{ , [ ] 这几个符号
    4. (2)tr '}' '\n' 将 } 替换成换行
    5. (3)awk -F: '{if(NF!=NR){printf("%s:%s\n",$2,$3) }}'
    6. -F: 按照指定的分隔符进行切分
    7. 'pattern1{action1} pattern2{action2}...'
    8. NF 浏览记录域的个数
    9. NR 已经浏览的个数

    删除镜像

    docker rmi IMAGE[IMAGE...]

    docker rmi dl.dockerpool.com:5000/ubuntu:latest

    1. ➜ ~ docker ps -a
    2. CONTAINER ID       IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
    3. 8dbec7f9de55       hello-world         "/hello"            5 seconds ago       Exited (0) 4 seconds ago                       gallant_khorana
    4. 85324d49a1a6       ubuntu              "/bin/bash"         4 days ago         Exited (127) 4 days ago                       keen_hertz
    5. b7e7078a2282       centos:latest       "/bin/bash"         4 days ago         Exited (0) 4 days ago                         confident_turing
    6. ➜ ~ docker images
    7. REPOSITORY         TAG                 IMAGE ID           CREATED             SIZE
    8. ubuntu             latest             9140108b62dc        2 weeks ago         72.9MB
    9. centos             latest             0d120b6ccaa8        2 months ago       215MB
    10. hello-world         latest             bf756fb1ae65        9 months ago        13.3kB
    11. ➜ ~ docker rmi bf756fb1ae65
    12. Error response from daemon: conflict: unable to delete bf756fb1ae65 (must be forced) - image is being used by stopped container 8dbec7f9de55
    13. ➜ ~
    14. 此时hello-world 这个景象是删除不了的,因为有该镜像创建的容器存在时,镜像文件默认是删除不了的。
    15. 使用 docker rm [CONTAINER ID] 将这个容器停止掉,然后就可以执行删除镜像文件的操作了
    1. ➜ ~ docker images
    2. REPOSITORY         TAG                 IMAGE ID           CREATED             SIZE
    3. ubuntu             20.10               d80d9d9b3dc3       2 weeks ago         79.5MB
    4. ubuntu             20.04               9140108b62dc       2 weeks ago         72.9MB
    5. ubuntu             latest             9140108b62dc       2 weeks ago         72.9MB
    6. centos             latest             0d120b6ccaa8       2 months ago       215MB
    7. ➜ ~ docker ps -a
    8. CONTAINER ID       IMAGE               COMMAND             CREATED             STATUS                   PORTS               NAMES
    9. 8dbec7f9de55       bf756fb1ae65       "/hello"           6 hours ago         Exited (0) 6 hours ago                       gallant_khorana
    10. 85324d49a1a6       ubuntu             "/bin/bash"         5 days ago         Exited (127) 5 days ago                       keen_hertz
    11. b7e7078a2282       centos:latest       "/bin/bash"         5 days ago         Exited (0) 5 days ago                         confident_turing
    12. ➜ ~ docker rmi ubuntu:latest
    13. Untagged: ubuntu:latest
    14. ➜ ~

    此处需要注意的是,ubuntu的两个镜像,image ID 是一样的,这个不是说他有两份,而是两个不同的tag,指向了同一个镜像文件。根据以上操作,删除ubuntu:latest,也只是删除了该镜像的多个标签中的一个。当该镜像只有一个tag指向该镜像的时候,通过tag删除的时候就直接删除了该镜像。

    docker rmi -f 镜像ID

    此种删除方式为强制删除。如果是没有 -f 的删除方式,该镜像有正在运行的容器,是无法删除的,同样也会提示添加 -f 后再进行删除。添加 -f 后是强制删除,既是是该镜像有生成的容器在运行,也是会把该镜像删除的。

    docker rmi -f 镜像名1:tag1 镜像名2:tag2

    删除多个,删除多个镜像中间用空格隔开。

    docker rmi -f $(docker images -qa)

    docker images -aq 是查询出所有镜像的镜像ID,再配上前面的删除命令,则这条命令的作用就是本地库中所有的镜像。

    三、Docker 基本命令

    帮助命令

    Docker info

    docker version

    docker --help

    容器命令

    启动并创建容器

    docker run [options] imageID

    --name="容器名称" : 容器新名字,为容器指定一个名字;

    -d : 后台运行容器,返回容器ID,也即启动守护式容器;

    -i : 以交互模式运行容器,通常与-t 一起使用;

    -t : 为容器重新分配一个伪终端,通常与-i 同时使用;

    -P : 随机端口映射;

    -p : 指定端口映射,有以下四种格式:

    ip:hostPort:containerPort

    ip::containerPort

    hostPort:containerPort

    ontainerPort

    -d 后台守护进程的模式运行容器

     

    从途中看出,虽然是运行了容器,但是ps的时候,却看不到。

    使用镜像以后台模式运行一个容器,用ps进行查看,容器已经退出。这是因为,Docker 容器后台运行,就必须要有一个前台进程。容器的命令如果不是那些一直挂起的命令(如:top,tail),就会自动退出。这个是docker 的机制问题。例如nginx 后天运行后,没有与之匹配的前台进程,这样的容器启动后会觉得自己没有事做,就会立即自杀。那么解决办法就是将运行的容器以前台的形式运行。

    docker ps [options]

    -a : 列出当前正在运行的容器+ 历史上运行过的

    -l : 显示最近创建的容器,上一个运行的容器

    -n : 显示最近n个创建的容器,前n个运行的容器

    -q : 静默模式,只显示容器编号

    --no-trunc : 不截断输出

    1. # 设置容器名称
    2. ➜ ~ docker run -ti --name cbt01 centos:centos7
    3. [root@dbf1ffdfd79d /]#
    4. ➜ ~ docker ps
    5. CONTAINER ID       IMAGE               COMMAND             CREATED             STATUS             PORTS               NAMES
    6. dbf1ffdfd79d       centos:centos7      "/bin/bash"         21 seconds ago     Up 20 seconds                         cbt01

    exit : 停止容器退出

    ctrl+p+q : 不停止容器退出,同样也适用于Mac

    启动容器

    docker start ContainerID

     

    关闭容器

    正常关闭:docker stop 容器ID

    强制关闭:docker kill 容器ID

    删除已停止的容器

    docker rm 容器ID

    -f : 强制删除

    一次性删除多个容器

    docker rm -f ${docker ps -a -q}

    docker ps -a -q |xargs docker rm

    xargs 可变参数 将前面的结果作为参数传递给后面的命令

    查看容器日志

    docker logs -f -t --tail

    -t : 加入时间戳

    -f : 跟随最新的日志打印

    --tail : 数字显示最后多少条

    docker run -d centos:centons7 /bin/bash -c "while true; do echo chenbotao; sleep 2 ; done"

    此时容器在后台一直运行

     

    显示前10条

     

    docker top 容器ID

     

    重新进入容器

    docker attach 容器ID

    attach 进入容器命令终端后进行操作

    exec 是执行命令,将执行明后的结果返回到宿主机

     

    执行如下命令行和attach是同样的结果

     

    从容器中拷贝文件到宿主机

    docker cp 容器ID:容器内路径 宿主机路径

     

    四、容器数据卷

    概念

    对运行的容器中的部分数据希望能够持久化或者实现容器间数据的共享。

    Docker 容器产生的数据如果不通过commit 生成新的镜像,将数据作为镜像的一部分保存下来,那么当容器删除后,数据也就没了。

    数据卷可以使得容器中产生的数据保存在Docker中。

    作用

    卷的设计目的就是数据持久化,完全独立于容器的生命周期,因此Docker不会在删除容器时删除其挂载的数据卷。

    特点:

    1、数据卷可以在容器之间共享或者重用数据

    2、卷中的更改可以直接生效

    3、数据卷中的更改不会包含在容器的更新中

    4、数据卷的生命周期一直持续到没有容器使用它为止

    注:如果是在mac上操作,这里需要做的一个操作是检查机器的SIP状态,如果是enable的,那么在/ 根目录下建不了文件夹,就导致后面的一些操作是没办法验证的。也就是可以操作,但是宿主机没有生成文件夹,看不到效果。

    1. ➜ ~ csrutil status
    2. System Integrity Protection status: disabled.

    若不是disabled状态的话,先关闭SIP

    关闭SIP的方法

    1、重启Mac
    2、在OS X启动之前,按住 Command+R 并保持不动,
    直到看到Apple图标和进度条。发布。这将引导你进入恢复。
    3、从 “实用工具” 菜单中选择 “终端”。
    4、在提示符处输入以下内容,然后按回车键:
    csrutil disable
    5、终端应显示SIP被禁用的消息。
    6、从菜单中选择 重新启动。

    然后执行

    sudo mount -uw /

    此时应该可以创建目录了,执行创建命令尝试以下

    sudo mkdir /home

    命令形式添加

    1. docker run -it -v /宿主机的绝对路径:/容器内目录 镜像名
    2. docker run -it -v /Users/chenbotao12440/dockerDataVolumes:/dockerVolumeContainer centos:centos7
    3. # 此时,容器中就有了相应的dockerVolumeContainer文件夹,而映射到主机的就是/Users/chenbotao12440/dockerDataVolumes文件夹
    4. # 值得注意的是,如果mac 安装的是Docker for mac 是桌面版的,当前主机需要映射到容器中的数据卷文件夹是需要先创建好指定的文件夹或者是配置一个路径,然后点击图标Docker -> Preferences... -> Resources -> File Sharing 下进行配置,那么指定的需要映射的文件夹也就在执行路径的下。

    以上方式创建的数据卷,容器中的数据也会同步更新到宿主机当中,那么在通过Docker inspect 镜像id 就会有这样的一个配置:

     

    从图中看出有绑定的信息和RW:true 的配置,这表示当前配置的数据卷是可读可写的。

    1. docker run -ti -v /Users/chenbotao12440/dockerDataVolume:/dataVolumeContainer:ro centos:centos7
    2. # 此种方式运行起来的是容器内数据卷只读的,也就是说,此种方式只能单向的支持宿主机是可以写数据后同步到容器中,容器是只读的,不能够对其做任何的增删改操作。

    此时的状态就变了

     

    DockerFile形式创建数据卷

    VOLUME["dataVolumeContainer1","dataVolumeContainer2","dataVolumeContainer3"]

    出于可移植和分享的考虑,用-v 主机目录:容器目录 这种方式不能再DockerFile中直接实现。

    由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的目录。

    1. # Test Volume
    2. FROM centos
    3. VOLUME ["dataVolumeContainerDockerFile1","dataVolumeContainerDockerFile2","dataVolumeContainerDockerFile3"]
    4. CMD echo "Finished create Container"
    5. CMD /bin/bash
    6. # 运行如上脚本 -f 为指定Dockerfile 的路径,-t 为指定tag
    7. ➜ myDocker docker build -f /Users/chenbotao12440/docker/myDocker/Dockerfile -t cbtdockerfile/centos .
    8. [+] Building 0.2s (5/5) FINISHED
    9. => [internal] load build definition from Dockerfile                                                                                                                         0.1s
    10. => => transferring dockerfile: 232B                                                                                                                                         0.0s
    11. => [internal] load .dockerignore                                                                                                                                            0.1s
    12. => => transferring context: 2B                                                                                                                                              0.0s
    13. => [internal] load metadata for docker.io/library/centos:latest                                                                                                             0.0s
    14. => [1/1] FROM docker.io/library/centos                                                                                                                                      0.0s
    15. => => resolve docker.io/library/centos:latest                                                                                                                               0.0s
    16. => exporting to image                                                                                                                                                       0.0s
    17. => => exporting layers                                                                                                                                                      0.0s
    18. => => writing image sha256:eb60f768d60f046a605c0de0e89fc9533fc799ac2f2868fe4a22df425a21fba3                                                                                 0.0s
    19. => => naming to docker.io/cbtdockerfile/centos

    运行成功后如图所示:

     

    生成了cbtdockerfile/centos 的一个新的镜像文件,而镜像ID即为上面所示的sha256 编码值的前12位。

    运行刚才生成的镜像:

     

    由于生成镜像的时候,最后一行指定运行命令/bin/bash,所以在运行镜像的时候也就不用写最后的 /bin/bash 了,同样,图中可以看出,有了Dockerfile 文件中所指定的三个数据卷目录。

    此种方式生成的数据卷是没有指定宿主机与之对应的目录的,所以Docker会生成一写默认的路径与之对应。如下图所示,会生成一些目录与之对应。

     

    Docker 挂载主机目录出现 cannt open directory : Permission denoed

    挂载目录后面多加一个 --privileged=true 即可

    docker run -it -v /Users/chenbotao12440/dockerDataVolumes:/dockerVolumeContainer --privileged=true centos:centos7

    数据卷容器

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

    # 以此种方式实现容器见的数据共享
    run -it --name dc02 --volumes-from dc01 cbtdockerfile/centos

     

     

    此处如果再以同样的方式创建一个dc03容器,继承dc01,那么此时三个容器之间实现了数据共享。如果把dc01删了,也不会影响dc02和dc03之间的数据共享。数据卷的生命周期一直持续到没有容器使用它为止。

    五、DockerFile

    是什么

    Dockerfile是用来构建Docker镜像的文件,是由一系列参数和文件构成的脚本。

    构建三步骤:

    1、编写DockerFile文件

    2、docker build

    3、docker run

    Dockerfile:

    1. FROM scratch
    2. ADD centos-8-x86_64.tar.xz /
    3. LABEL org.label-schema.schema-version="1.0"     org.label-schema.name="CentOS Base Image"     org.label-schema.vendor="CentOS"     org.label-schema.license="GPLv2"     org.label-schema.build-date="20200809"
    4. CMD ["/bin/bash"]

    这是一个centos的Dockerfile 文件,平常运行镜像的时候,docker run -it centos 后面有时候会加一句 /bin/bash,那其实这个对于这个镜像而言是多余的一句,因为在Dockerfile文件中最后已经表明了最后是要运行这个容器的。但是加上也无妨,其作用也就是如在这个文件的后面再写一句CMD ["/bin/bash"] 效果是一样的。

    DockerFile 解析构建过程

    DockerFile内容基础知识

    1:每条保留字指令都必须大写且后面都要跟至少一个参数

    2:指令都是从上到下按照顺序执行

    3:# 表示注释

    4:每条指令都会创建一个新的镜像层,并对镜像进行提交

    DockerFile 执行大致流程

    1:从基础镜像运行一个容器

    2:执行一条指令并对容器做出修改

    3:执行类似Docker commit 操作提交一个新的镜像层

    4:Docker 在基于刚提交的进项运行一个新容器

    5:执行DockerFile中的下一条指令,直到所有指令都执行完成

    DockerFile 体系结构(保留字指令)

    FROM 基础镜像,当前镜像是基于那个镜像的

    MAINTAINER 镜像维护者的姓名和邮箱地址

    RUN 容器构建时需要运行的命令

    EXPOSE 当前容器对外暴露的端口号

    WORKDIR 登录后指定的目录,也就是登陆后就到这个指定的目录

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

    ADD 将宿主机目录下的文件拷贝进镜像且add命令会处理URL 和解压缩压缩包

    COPY 类似add,把宿主机的目录下的文件拷贝到复制的新一层的镜像内

    COPY scr dest

    COPY ["scr","dest"]

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

    CMD 指定一个容器启动时要运行的命令

    DockerFile中可以有多个CMD命令,但只有最后一个生效,CMD会被docker run 之后的参数替换

    ENTRYOINT 指定一个容器启动时要运行的命令

    ENTRYOINT 和 CMD 的目的一样,都是在指定容器启动程序和参数,而这个是追加,不会被覆盖。

    ONBUILD 当构建一个被继承的DockerFile时运行命令,父镜像再被子镜像继承后父镜像的onbuild触发

    案例

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

    案例一:登陆后的Centos 指定到一个目录,有VIM编辑器,有ifconfig net工具

    1. FROM centos
    2. ENV MYPATH /usr/local
    3. WORKDIR $MYPATH
    4. RUN yum -y update && yum -y install vim
    5. RUN yum -y install net-tools
    6. EXPOSE 80
    7. CMD echo $MYPATH
    8. CMD echo "Build Success"
    9. CMD /bin/bash

    执行DockerFile 后生成镜像

    运行构建命令:docker build -f /Users/chenbotao12440/docker/myDocker/Dockerfile2 -t centos:1.0 .

     

    然后运行进行,进去后就在/usr/local目录下

    当然,里面vim编辑器和ifconfig 工具都是能可以用的。

    对于以上命令需要作出的几点说明:

    1:-f 后面的是指定dockerfile 路径

    2:-t 后是指定生成的镜像的镜像名称和标签。

    3:这条命令最后还有个点,这个点和前面的内容之间还有一个空格。这个点代表的是镜像构建过程中的上下文环境的目录。Docker运行时分为Docker引擎(服务端守护进程)以及客户端工具,日常所用的各种docker命令都是使用客户端工具与Docker引擎进行交互。使用docker build 构建镜像时,构建过程是在Docker 引擎中进行的。如果DockerFile中有些COPY的指令需要拷贝文件时就有了镜像构建上下文的概念。当构建的时候,由用户指定构建的上下文路径,而Docker build 会将这个路径下的所有文件打包上传到Docker 引擎,引擎将这些内容展开后,就能后去到所有指定的上下文中的文件了。所以,docker build 最后的 . 是指构建镜像过程中的上下文环境的目录。

    案例二:获取当前机器的IP

    1. FROM centos
    2. RUN yum update -y && yum -y install curl
    3. CMD [ "curl","-s","https://ip.cn/api/index?ip=&type=0" ]

    执行结果:

     

    由以上可以。在运行容器的命令后面加了一个需要现实报文头信息的-i 命令,就报错了。其原因是加了 -i 就相当于与把Dockerfile 文件的最后一样的 CMD [ "curl","-s","https://ip.cn/api/index?ip=&type=0" ] 给替换掉了,命令不全,就不会报错。此时就需要使用ENTRYPOINT 来实现。

    FROM centos
    RUN yum update -y && yum -y install curl
    ENTRYPOINT [ "curl","-s","https://ip.cn/api/index?ip=&type=0" ]

    以此种方式生成后的容器时是可以追加命令的。

     

    案例三:ONBUILD

    修改DockerFile4文件

    FROM centos
    RUN yum update -y && yum -y install curl
    ENTRYPOINT [ "curl","-s","https://ip.cn/api/index?ip=&type=0" ]
    OBBUILD RUN echo "Father images onbuild success !"

    复制Dockerfile3位Dockerfile5 并做如下修改:

    # 继承镜像修改为centos-myip-father
    FROM centos-myip-father
    RUN yum update -y && yum -y install curl
    CMD [ "curl","-s","https://ip.cn/api/index?ip=&type=0" ]

     

    案例四:自定义Tomcat

    DockerFile文件

    FROM centos
    MAINTAINER  chenbt<2298800303@qq.com>
    # 把宿主机当前上下文目录的c.txt文件拷贝到容器的/usr/local下
    COPY c.txt /usr/local/container.txt
    #把jdk 和Tomcat 添加到容器中
    ADD apache-tomcat-8.5.60.tar.gz /usr/local/
    ADD jdk-8u271-linux-x64.tar.gz /usr/local/
    # 安装vim 编辑器
    RUN yum update -y && yum -y install vim
    
    # 设置登陆落脚点
    ENV MYPATH /usr/local
    WORKDIR $MYPATH
    
    #配置Java与Tomcat 环境变量
    ENV JAVA_HOME /usr/local/jdk1.8.0_271
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.60
    ENV CATALINA_BASE /usr/local/apache-tomcat-8.5.60
    ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
    
    # 容器暴露的端口
    EXPOSE 8080
    
    # 容器启动是运行Tomcat
    #ENTRYPOINT ["/usr/local/apache-tomcat-8.5.60/bin/startup.sh"]
    #CMD ["/usr/local/apache-tomcat-8.5.60/bin/catalina.sh","run"]
    CMD /usr/local/apache-tomcat-8.5.60/bin/startup.sh && tail -f /usr/local/apache-tomcat-8.5.60/logs/catalina.out

    docker build -t chenbt/tomcat .

    此时当前目录下有一个名为Dockerfile的文件,所以就不用使用-f 指定 Dockerfile 文件了

    运行命令启动容器:

    docker run -d -p 9080:8080 --name chenbt-tomcat -v /Users/chenbotao12440/docker/tomcat8.5/test:/usr/local/apache-tomcat-8.5.60/webapps/test -v /Users/chenbotao12440/docker/tomcat8.5/logs:/usr/local/apache-tomcat-8.5.60/logs --privileged=true chenbt/tomcat

    指定两个数据卷,运行容器,运行成功后再宿主机就可以访问到Tomcat主页

    宿主机对应数据卷

     

    案例四:安装运行MySQL

    # 以下命令使用的时候,需要去除掉换行,这个命令时一行。
    docker run -d -p 3307:3306 
    	--name mysql 
    	-v /Users/chenbotao12440/mysql/conf:/etc/mysql/conf.d 
    	-v /mysql/logs:/logs 
    	-v /Users/chenbotao12440/mysql/data:/var/lib/mysql 
    	-e MYSQL_ROOT_PASSWORD=123456 mysql:5.7

    案例五:安装运行Redis

    docker run -p 6379:6379 
    -v /Users/chenbotao1244/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf 
    -v /Users/chenbotao1244/redis/data:/data 
    -d redis:5.0 redis-server /usr/local/etc/redis/redis.conf 
    --appendonly yes # 开启AOF持久化

    托管镜像到阿里云上

    1、在阿里云上新建镜像仓库

    2、进入仓库后执行页面提示操作,将镜像推送到云上

    $ sudo docker login --username=cbt0030 registry.cn-hangzhou.aliyuncs.com
    $ sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/chenbt-centos/basic-centos:[镜像版本号]
    $ sudo docker push registry.cn-hangzhou.aliyuncs.com/chenbt-centos/basic-centos:[镜像版本号]

    如下图所示:

     

  • 相关阅读:
    谨慎使用多线程中的 fork !!!!
    Android进行字符串替换
    谷粒学院16万字笔记+1600张配图(五)——讲师管理前端
    共同富裕-三大维度-各省份、城市、农村基尼系数-附带多种计算方法
    linux中使用ps查看进程的所有线程
    Golang基础 基础数据类型之值类型
    每日一题AC
    matlab创建矩阵、理解三维矩阵
    Linux 的 grep
    二叉搜索树--查询节点-力扣 700 题
  • 原文地址:https://blog.csdn.net/qq_38481805/article/details/126391968