2.使用docker镜像和仓库

第四章 使用docker镜像和仓库

  1. docker 镜像:
    docker 镜像是由文件系统叠加而成,最低端是一个引导文件系统即bootfs
    当容器启动后镜像被移动到内存当中,而引导文件系统由于完成了使命,将被卸载
    以留出更多内存供initrd磁盘使用
    实际上docker镜像的第二层是root文件系统rootfs,它位于引导文件系统之上,
    rootfs可以是一种或多种操作系统
    在传统的linux引导过程中,root文件系统最先以只读的方式加载,当引导结束
    并完成完整性检查后,它才被切换为读写模式,但docker里,root文件系统永远处于
    只读状态
    docker 利用联合加载技术又会在root文件系统上加载更多的只读文件系统,
    联合加载指的是一次同时加载多个文件系统,但外面只能看到一个文件系统。联合加载
    会将各层文件系统叠加到一起,这样最终的文件系统会包含所有底层文件和目录,docker
    将这样的文件系统称为镜像
    docker 架构大致流程:
    内核 -> 引导文件系统 -> 基础镜像(centos/ubuntu) -> 镜像1(cmacs) ->
    镜像2(Apache) -> 可写容器

  2. 列出镜像:
    docker images

  3. 拉取镜像(下载)
    docker pull ubuntu:18.0.4

    为了区分同一个仓库中的不同版本的镜像,Docker提供了标签功能,每个镜像在列出

    时都有一个标签如18.0.4,我们在拉去镜像是可以在仓库名后加:来获取不同镜像

    虽然拉取的镜像比如ubuntu18.0.4称其为操作系统,但是这个是剪裁版,只包含

    最低限度的支持系统运行的组件

  4. 查找镜像:
    docker search centos
    这条命令会列出docker hub 中所有的有关centos的镜像

  5. 构建镜像:
    构建镜像有两种方式:第一种 docker commit命令, 第二种: docker build 命令和
    Dockerfile 文件

    5.1 第一种方式: docker commit
    1. docker run --name flask -i -t centos /bin/bash //创建centos容器
    2. 对容器进行定制: yum -y install vim //将vim 安到centos 以后用的时候
    直接运行容器便会有相应的配置和软件等所需要的环境
    3. docker commit 638704b0eaea centos/flask
    这里 638704b0eaea 是指容器ID,centos是指仓库名,flask是镜像名
    需要注意的是docker commit 提交的只是创建容器的镜像和容器当前状态之间的
    差异部分,换句话就是说,提交的只是你对镜像的改动
    docker ps -l -q 可以得到刚才创建的容器的ID
    4. 提交镜像时还可以带更多的参数, -m 指定镜像的备注信息,-a 指定镜像的作者信息
    同时还可以指定容器ID, 镜像名后面可跟:标签名

    1. 第二种方式: 用dockerfile构建镜像

      1. mkdir docker_test //创建Dockerfile 所在的目录

        1. touch Dockerfile // 创建Dockerfile 文件

        2. vim Dockerfile :
          FROM centos/flask
          MAINTAINER Mr Li "[email protected]"
          ENV REFRESHED_AT 2019-05-09
          RUN yum -y install vim
          EXPOSE 5000

          注意事项: 1. 所有的开头关键词必须大写, 2. FROM 指定了基础镜像必须放在
          第一行, 3. MAINTAINER 是对作者说明, 4. ENV设置环境变量这里通过
          REFRESHED_AT 来设置镜像最后更新的时间 5. RUN 运行的指令,可以有无数条
          RUN指令,每条指令执行成功都会对镜像进行叠加 6. EXPOSE 指定容器暴露的
          端口号

        3. 执行 docker build -t="centos/flask:tag1" . 构建镜像
          其中centos/flask 指的是仓库名/镜像名 tag1是标签明 "."代表当前目录下的
          Dockerfile

        4. 如果上面的某条命令执行失败,那么会创造一个到目前已经成功执行的指令的容器
          然后可以运行容, docker run -i -t ID /bin/bash 进去进行调试
          此时的镜像应为没有完整创建所以没有镜像名和标签名,这两个参数都是none
          并且会有一个非正常的容器直接创建,此时只有先将容器移除才能将镜像移除

        5. 也可以指定一个Git仓库的源地址来指定Dockerfile位置
          docker build -t="centos/flask:tag1" [email protected]:centos/flask

        6. docker 有一个非常聪明的设计就是,将镜像进行缓存,比如存在已经构建好的镜像
          而再次构建一个镜像里面包含之前构建镜像层,那么再次构建的时候会忽略掉这些
          镜像层直接拿过来用

          如果不需要使用缓存那么需要在构建竟像是加 --no-cache 参数
          docker build --no-cache -t="centos/flask:tag1"

        7. 查看docker新镜像:
          docker images centos/flask
          如果想要知道这个镜像是如何构建出来的可以使用:
          docker history ID

        8. 从新镜像启动一个容器:
          docker run -d -p 5000 --name flask centos nginx -g "daemon off"
          -d 告诉容器以分离的方式在在后台运行,nginx -g 告诉容器运行的命令, "daemon off"以前台方式启动, -p 告诉告诉docker 在运行时公开哪些端口

        9. docker 可以通过两种方式来在宿主机上分配端口号:
          11.1 docker可以在宿主机上随机选择一个位于62768-61000的一个比较大的端口
          号来映射到容器的80端口
          11.2 可以在docker 宿主机中指定一个具体的端口号来映射到容器中的80端口上
          docker run 命令将在docker宿主机上随机打开一个端口号,这个端口号会链接到
          容器的80端口上

        10. 使用docker ps 命令来看容器的端口分配情况

        11. 使用docker port 命令来看容器端口到宿主机端口的映射情况:
          docker port ID port // ID为容器ID, 端口号为创建容器时指定的端口
          号如果未指定默认为80

        12. 使用-p 选项映射到宿主机特定端口:
          14.1 docker run -d -p 5000:80 --name flask centos nginx -g "daemon off"

              这会将容器的80端口绑定到宿主机的5000端口
          14.2 绑定到特定网络接口:
              docker run -d -p 127.0.0.1:5000:80 --name flask centos nginx -g "daemon off"
          
              这条命令将本地80端口绑定到宿主机指定IP上
          
              docker run -d -p 127.0.0.1::80 --name flask centos nginx -g "daemon off"
          
              这条命令将绑定到指定IP的随机端口
          
              docker run -d -p --name flask centos nginx -g "daemon off"
          
              这条命令将容器内的80端口对本地宿主机公开,并且绑定到宿主机一个
              随机端口上,该命令会将用来构建该镜像的Dockerfile中的EXPOSE
              指令的其他端口号也一并公开
        13. Dockerfile 指令:
          15.1 CMD:
          CMD指令用于指定一个容器启动时需要运行的命令,类似于构建镜像时的RUN
          指令,不同的是CMD是容器运行时需要运行的命令,这和docker run 命令启动
          容器时指定要运行的命令非常类似:
          docker run -i -t centos /bin/bash
          等效于在Dockerfile指定的CMD命令:
          CMD ["/bin/bash"]
          当然也可以为CMD命令指定参数:
          CMD ["/bin/bash", "-l"]
          注意: docker run 命令会覆盖掉CMD命令,而且Dockerfile中只允许有一条
          CMD命令,如果有多条命令那么只会执行最后一条命令
          CMD /bin/bash && service mysql start //CMD 可以用这种方式实现
          多条命令同时执行

          15.2 ENTRYPOINT:
          该命令类似于CMD命令不同的是,docker run 命令不会覆盖掉ENTRYPOINT
          命令内容,而且会和ENTRYPOINT协同工作比如:
          ENTRYPOINT ["/usr/sbin/nginx"]
          CMD ["-h"]
          docker run -i -t centos -g "daemon off;"

              解释:
                  当docker run 指定了-g 参数那么会覆盖掉CMD 所以此时
                  nginx 运行方式是 /usr/sbin/nginx -g
                  如果docker run 没有指定-g 那么就是ENTRYPOINT + CMD组合
                  即 /usr/sbin/nginx -h
          
          如果需要用户可以通过--entrypoint 来覆盖掉ENTRYPOINT

          15.3 WORKDIR
          该命令用来从镜像创建一个容器时,在容器内部设置一个工作目录,ENTRYPOINT,CMD指定的程序会在这个目录下执行
          我们可以使用该指令,为Dockerfile中后续的一系列指令设置工作目录,也可以为最终的容器设置工作目录:
          eg:
          WORKDIR /opt/webapp/db
          RUN bundle install
          WORKDIR /opt/webapp
          ENTRYPOINT ["rackup"]

              解释:
                  1.首先将工作目录切换为/opt/webapp/db
                  2. 在db目录下执行RUN
                  3.切换为webapp目录
                  4. 在webapp目录下执行ENTRYPOINT

          15.4 ENV
          ENV指令用来在镜像构建过程中设置环境变量,可以一次构造多个环境变量
          以空格隔开
          1.文件中设置环境变量:
          ENV RVM_PATH /home/test/
          镜像中的任何部分都可以用这个环境变量来切换目录
          WORKDIR $RVM_PATH 就会切换到这个目录
          2. 这些环境变量会被持久化到我们的镜像创建的任何容器中,所以
          我们在使用带有环境变量创建的容器的时候可以运行env命令
          来显示当前的环境变量
          3. 我们也可以在创建容器时使用-e 来添加环境变量
          sudo docker run -it -e "BASE_DIR=/home/" tt /bin/bash
          这样创建的环境变量只能对当前容器有效
          15.5 USER
          USER 指令用来指定该镜像以什么样的用户去运行:
          我们可以指定用户名或UID以及组或GID,甚至两者的组合:
          USER user
          USER user:group
          USER uid
          USER uid:gid
          USER user:gid
          USER uid:group

              我们也可以在docker run 时通过-u 标志来覆盖指令指定的值
              如果USER不指定值默认为root

          15.6 VOLUME
          VOLUME 指令用于像基于镜像创建的容器添加卷。一个卷可以存在于一个或
          多个容器内特定的目录,这个目录可以绕过联合文件系统,并提供如下共享
          数据或者对数据进行持久化的功能
          卷可以在容器间共享和重用
          一个容器可以不是必须和其他容器共享卷
          对卷的修改是立即生效的
          卷会一直存在直到没有任何容器使用它
          卷功能让我们可以将数据(如源代码),数据库,或者其他内容添加到镜像中而
          不是将这些内容提交到镜像中,并且允许我们在多个容器间共享这些内容,我
          们可以利用此功能来测试容器和内部的应用程序代码,管理日志,或者处理内部的数据库
          eg:
          VOLUME ["/opt/tt", "/home/tt"] //挂在两个卷

          15.7 ADD
          ADD 用来将构建环境下的文件和目录复制到镜像中,比如在安装应用程序时
          ADD 指令需要源文件位置和目的文件位置两个参数
          ADD test.txt /opt/test.txt //将构建目录下的test.txt 复制
          到容器opt下
          15.7.1 ADD 文件源也可以是url格式:
          ADD http:www.test/test.zip /home/kwd.zip
          这一步将url中的zip 文件添加到home中并重命名为kwd.zip
          15.7.2 ADD 小技巧:
          如果将一个归档文件指定为源文件,docker会自动将归档文件解开
          (gzip, bzip2, xz)而目标则需要指定一个目的目录
          ADD test.zip /home/test/
          注意:1.使用ADD 命令时如果目标是目录必须是以"/"结尾,否则docker
          人为这是一个文件
          2. 目前ADD 还不只是url 模式下的归档文件解压
          3. 如果目的目录不存在那么docker 会自动新建需要的目录结构
          新创建的目录模式为0755,并且UID和GID都是0
          4. ADD 指令会使得构建缓存无效,这点非常重要,如果在ADD
          指令那么ADD指令下的后续指令无法继续使用之前的缓存
          15.8 COPY
          COPY 功能和ADD类似,可以实现文件或者目录的拷贝,只不过不支持文件提取
          和解压,所拷贝的源文件也必须在镜像构造文件同目录:
          COPY test/ /opt/test/
          15.9 LABEL
          LABEL 指令可以为镜像添加元数据,元数据以键值对的形式展现:
          LABEL version="1.0"
          LABEL name="test" location="NewYork"

              可以同时指定一条或者多条元数据,以空格隔开,推荐一次指定多条
              以降低镜像层厚度

          15.10 STOPSIGNAL
          STOPSIGNAL 指令用来设置停止容器时发送什么系统调用的信号给容器,
          这个信号必须是内核系统调用合法的数,如9,SIGKILL

          15.11 ARG
          ARG 指令用于定义docker build 命令运行时传递给构建运行时的变量,
          我们只需要在构建时使用--build-arg标志即可
          ARG build
          ARG webapp_build=user

              sudo docker build --build-arg build=1234 -t centos
          这里构建镜像是build将变成1234,而webapp_build会用默认值user

          15.12 ONBUILD
          ONBUILD 指令为镜像添加触发器,当一个镜像被用作其他镜像的基础竟像时
          该镜像中的触发器将被执行
          ONBUILD 后面可以跟任何Dockerfile指令除了FROM,MAINTAINER,
          ONBUILD自身
          如:
          ONBUILD RUN yum -y install vim
          ONBUILD 构造镜像时本镜像不会执行ONBUILD中的内容,只有引用
          该镜像为基镜像的Dockerfile创造的镜像文件会执行ONBUILD中的命令
          而且除了FROM 拉取镜像外,ONBUILD中的命令会首先执行,而后执行
          其他命令

              注意:ONBUILD的镜像只会影响一代,也就是说如果有镜像间接引用这个
              镜像的话ONBUILD中的内容不会执行。

        16 将镜像推送到 Docker Hub
        docker push imagesname

            需要注意的是镜像名必须是docker hub 用户名开头加/镜像名形式
            如:  pglmc88/centos
        
            如果需要更改镜像名可使用命令:
                docker tag ID imagesname

        17 删除镜像:
        docker rmi imagesname/ID // 同时删除多个用空格隔开

猜你喜欢

转载自www.cnblogs.com/limengchun/p/11942724.html
今日推荐