Docker:入门



    • Docker可以认为是vmware或者virtualbox

    • 镜像可以认为是 xxx.iso

    • 容器可以认为是 virtualbox运行xxx.iso后的系统

    • 镜像是容器的基础

      $ docker run --name webserver -d -p 80:80 nginx
      这条命令会用nginx镜像启动一个容器,命名为webserver,并且映射到80 端口,这样我们可以用浏览器去访问这个 nginx 服务器。

    • 可以使用docker exec命令进入容器,修改其内容。
      $ docker exec -it webserver bash

    • 做的任何文件修改都会被记录于容器存储层里。而 Docker 提供了一个docker commit命令,可以将容器的存储层保存下来成为镜像
      docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]

      docker commit的坏处:黑箱操作,docker diff只能提供一些线索,除了制作者本人外其他人都不知道这个镜像的详细情况

    • Dockerfile 是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

    • dockerfile所在文件夹和镜像容器的关系?


    Dockerfile详解

    FROM 指定基础镜像

    服务类镜像:nginx、redis、mongo、mysql、httpd、php、tomcat 
    语言应用镜像:node、openjdk、python、ruby、golang 
    空白镜像:scratch
    指定版本时自动安装latest

    RUN 执行命令

    每一个 RUN 的行为,就和刚才我们手工建立镜像的过程一样:新建立一层,在其上执行这些命令,执行结束后,commit 这一层的修改,构成新的镜像。
    正确的写法应该是这样:

    FROM debian:jessie
    
    RUN buildDeps='gcc libc6-dev make' \
    
      && apt-get update \
    
      && apt-get install -y $buildDeps \
    
      && wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \
    
      && mkdir -p /usr/src/redis \
    
      && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
    
      && make -C /usr/src/redis \
    
      && make -C /usr/src/redis install \
    
      && rm -rf /var/lib/apt/lists/* \
    
      && rm redis.tar.gz \
    
      && rm -r /usr/src/redis \
    
      && apt-get purge -y --auto-remove $buildDeps
    
    

    rm用来清理无关的东西

    COPY 复制文件

    COPY [--chown=<user>:<group>] <源路径>... <目标路径>

    目标路径可以是容器内的绝对路径,也可以是相对于工作目录的相对路径(工作目录可以用 WORKDIR 指令来指定)。目标路径不需要事先创建,如果目录不存在会在复制文件前先行创建缺失目录。

    VOLUME 定义匿名卷

    容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷(volume)中,后面的章节我们会进一步介绍 Docker 卷的概念。为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在 Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。
    VOLUME /data
    这里的 /data 目录就会在运行时自动挂载为匿名卷,任何向 /data 中写入的信息都不会记录进容器存储层,从而保证了容器存储层的无状态化。当然,运行时可以覆盖这个挂载设置。

    EXPOSE 声明端口

    • 在容器中使用端口不需要特殊声明
    • 若需要这个端口暴露出来,需要在Dockerfile中声明
    • 若需要容器的端口指定映射到宿主的端口,需要在启动一个镜像为容器时,用 -p 参数来进行端口映射

    构建镜像

    • docker build [选项] <上下文路径/URL/->

    $ docker build -t nginx:v3 .
    这里的 . ,指的是上下文的目录,docker build命令会将该目录下的内容打包交给Docker引擎以构建镜像,一般来说,应该会将 Dockerfile 置于一个空目录下,或者项目根目录下。如果该目录下没有所需文件,那么应该把所需文件复制一份过来。如果目录下有些东西确实不希望构建时传给 Docker 引擎,那么可以用 .gitignore 一样的语法写一个 .dockerignore

    • $ docker build - < context.tar.gz

    如果发现标准输入的文件格式是 gzip、bzip2 以及 xz 的话,将会使其为上下文压缩包,直接将其展开,将里面视为上下文,并开始构建。

    进入容器

    -i -t参数一起使用时,则可以看到我们熟悉的 Linux 命令提示符。

    $ docker exec -it 69d1 bash
    
    root@69d137adef7a:/#
    
    

    数据管理

    • 数据卷

      数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:

      • 数据卷 可以在容器之间共享和重用
      • 对 数据卷 的修改会立马生效
      • 对 数据卷 的更新,不会影响镜像
      • 数据卷 默认会一直存在,即使容器被删除

    Dockerfile最佳实践

    • 容器只运行单个应用

      若在一个容器中运行多个进程

      • 非常长的构建时间(修改前端之后,整个后端也需要重新构建)
      • 非常大的镜像大小
      • 多个应用的日志难以处理(不能直接使用stdout,否则多个应用的日志会混合到一起)
      • 横向扩展时非常浪费资源(不同的应用需要运行的容器数并不相同)
      • 僵尸进程问题 - 你需要选择合适的init进程


  • 顶,docker应该是利器



  • 此回复已被删除!


  • @zdw yep~用来线上部署或者获得一个隔离的环境再好不过了~


 

Copyright © 2018 bbs.dian.org.cn All rights reserved.

与 Dian 的连接断开,我们正在尝试重连,请耐心等待