Docker之路

作者: alonwang | 来源:发表于2017-03-12 00:26 被阅读421次

    每天晚上回到寝室都没事做,一直对Docker很好奇,正好学一下《Docker--从入门到实践》做此笔记。

    镜像操作

    docker images -f dangling=true

    显示虚悬镜像,所谓虚悬镜像是当拉去了一个新版本的镜像后,原来的镜像就没有标签名,称之为虚悬镜像。

    docker rmi $(docker images -q -f dangling=true)

    删除虚悬镜像

    docker images tag_name

    显示符合tag_name条件的所有镜像

    docker run --name webserver -d -p 80:80 nginx

    生成一个名字为webserver的容器,以nginx镜像生成,端口映射到本机的80端口,这样可以在http://localhost访问

    • -p <宿主端口>: <容器端口>:端口映射,将容器内端口(右)映射到主机(左)。

    docker diff container_name

    查看容器的文件具体的改动(相对于镜像)

    docker commit [选项] <容器ID或容器名> [<仓库名> [:<标签>]]

    docker commit  \
    > --author "wangweilong1996@gmail.com" \
    > --message "modify default index" \
    > webserver \
    > nginx:v2
    sha256:f3fbd32761750b4b23e509085db2639d0651b1e88ff27a9b5a697a6c03d8a1f2
    
    

    保存修改到新镜像中,其中nginx:v2 v2为新镜像的标签,但是会造成较多垃圾,使镜像极为臃肿。

    使用Dockerfile定制镜像

    行尾\表示换行,#注释

    # Dockerfile
    From nginx
    Run echo "<p>233</p>" > /usr/share/nginx/html/index.html
    

    From 指定基础镜像,必须为第一条指令,其中 scratch为虚拟镜像,表示从零开始构建;Run执行命令,

    • shell格式 如上
    • exec格式 Run ["可执行文件","参数1","参数2"],类似函数调用

    Dockerfile中每条指令新建一层,Union FS最大层数127

    docker build -t nginx:v3 .

    使用当前文件夹中的Dockerfile定制镜像(不要忽视最后的.,它用来指定上下文目录,表示将当前目录下所有文件发送到服务端)

    上下文 上下文
    docker build 构建镜像并非在本地而是在服务端,上下文概念就是为了让服务端获取本地文件,会将上下文目录下所有文件打包发送到服务端
    ➜  docker docker build -t nginx:v3 . # 或 ./Dockerfile
    Sending build context to Docker daemon 2.048 kB
    Step 1/2 : FROM nginx
     ---> 6b914bbcb89e
    Step 2/2 : RUN echo "<p>23333</p>" > /usr/share/nginx/html/index.html
     ---> Running in 04b53f187929
     ---> eb25b3b9aca7
    Removing intermediate container 04b53f187929
    Successfully built eb25b3b9aca7
    
    

    如果在上下文目录下增加文件,相应的发送数据也会变大

    ➜  docker docker build -t nginx:v3 .  
    Sending build context to Docker daemon 11.78 kB
    Step 1/2 : FROM nginx
     ---> 6b914bbcb89e
    Step 2/2 : RUN echo "<p>23333</p>" > /usr/share/nginx/html/index.html
     ---> Using cache
     ---> eb25b3b9aca7
    Successfully built eb25b3b9aca7
    
    

    可以看到文件由2.048kB变到了11.78kB

    docker build [选项] <上下文路径>

    • -f file_name 指定此文件为Dockerfile
    ➜  docker docker build -t nginx:v3 -f ./config .  # 将上面的Dockerfile重命名为config
    Sending build context to Docker daemon 2.048 kB
    Step 1/2 : FROM nginx
     ---> 6b914bbcb89e
    Step 2/2 : RUN echo "<p>23333</p>" > /usr/share/nginx/html/index.html
     ---> Running in 04dd44d844d1
     ---> 17e8d87be6c3
    Removing intermediate container 04dd44d844d1
    Successfully built 17e8d87be6c3
    
    

    docker build还支持

    1. docker build URL

    从给出的URL构建,一般是从github

    1. docker build context.tar.gz

    从给定的压缩包构建

    1. docker build - < Dockerfile

    从标准输入读取Dockerfile构建

    1. docker build - < context.tar.gz

    从标准输入读取压缩包构建

    Dockerfile 命令

    COPY <源路径> <目标路径>

    将文件config从上下文目录中源路径的文件复制到新的一层目标路径中,源文件的元数据都会被保留如读写权限支持通配符

    ADD <源路径> <目标路径>

    源文件的元数据不会被保留,且会自动解压压缩文件。根据官方准则,只在需要自动解压时使用ADD

    CMD

    • shell 格式:CMD <命令>
    • 参数列表格式:CMD ["参数1"...]。在指定了ENTRYPOINT指令后用CMD指定具体的参数
    • exec格式:CMD ["可执行文件","参数1"...]
      实际运行时 shell格式会被变更成exec格式,如
      CMD echo $HOME
      会被变更为
      CMD ["sh","-c","echo $HOME"]
      Docker是进程,需要在前台运行
    Docker是进程

    ENTRYPOINT入口点

    它的格式和CMD相同。当指定了 ENTRYPOINT 后, CMD 的含义就发生了改变,不再是直接的运行其命
    令,而是将 CMD 的内容作为参数传给 ENTRYPOINT 指令,换句话说实际执行时,将变为:

    <ENTRYPOINT> "<CMD>"
    

    使用场景1:像命令一样使用镜像

    #Dockerfile
    FROM ubuntu:16.04
    RUN apt-get update \
    && apt-get install -y curl \
    && rm -rf /var/lib/apt/lists/*
    ENTRYPOINT [ "curl", "-s", "http://ip.cn" ]
    

    使用上面的配置文件构建镜像

     docker build -t myip . 
    

    使用时

    $ docker run myip (-i)
    当前 IP:61.148.226.66 来自:北京市 联通
    

    可以增加参数(如果是使用CMD是不行的)

    ENV设置环境变量

    ENV <key> <value>
    ENV <key1>=<value1> <key2>=<value2>

    一次定义多层使用

    ARG 构建参数

    ARGM<参数名>[=<默认值>]
    ARG设置的是构建环境的环境变量

    VOLUME定义匿名卷

    VOLUME ["<路径1>","<路径2>"]
    VOLUME <路径>

    容器运行时应该保持容器存储层不发生写操作,对于数据库类需要动态保存数据的应用,它的数据文件应该保存在卷(Volume)中,为了防止运行时用户忘记将动态文件所保存目录挂载为卷,在 Dockerfile 中,我们可以事先指定某些目录挂载为匿名卷,这样在运行时如果用户不指定挂载,其应用也可以正常运行,不会向容器存储层写入大量数据。

    VOLUME /data
    

    运行时/data会自动挂载为匿名卷,任何向 /data 中写入的信息都不会记录进容器存储层。

    docker run -d -v mydata:/data xxxx
    

    在这行命令中,就使用了 mydata 这个命名卷挂载到了 /data 这个位置,替代
    了 Dockerfile 中定义的匿名卷的挂载配置。

    WORKDIR 指定工作目录

    WORKDIR <工作目录路径>

    要注意Dockerfile中执行的命令都不在同一个进程执行环境

    RUN  cd /root
    RUN touch text.txt
    

    这里第一个RUN命令它的工作目录是/root,执行第二个命令时它的工作目录是默认目录而不是/root

    USER 指定当前用户

    USER <用户名>
    更改以后层的运行用户,类似于WORKDIR

    HEALTHCHECK健康检查

    HEALTHCHECK [选项] CMD <命令> :设置检查容器健康状况的命令
    HEALTHCHECK NONE :如果基础镜像有健康检查指令,使用这行可以屏蔽掉
    其健康检查指令

    • --interval=<间隔> :两次健康检查的间隔,默认为 30 秒;
    • --timeout=<时长> :健康检查命令运行超时时间,如果超过这个时间,本次
      健康检查就被视为失败,默认 30 秒;
    • --retries=<次数> :当连续失败指定次数后,则将容器状态视为
      unhealthy ,默认 3 次。
    #Dockerfile
    FROM nginx
    RUN apt-get update && apt-get install -y curl && rm -rf /var/lib
    /apt/lists/*
    HEALTHCHECK --interval=5s --timeout=3s \
    CMD curl -fs http://localhost/ || exit 1
    

    五秒检查一次容器运行情况,如果三秒没有回应报错

    运行后

    docker ps
    

    显示运行状态

    ONBUILD 为他人做嫁衣裳

    ONBUILD <其它指令>

    ONBUILD 是一个特殊的指令,它后面跟的是其它指令,比如 RUN , COPY 等,
    而这些指令,在当前镜像构建时并不会被执行。只有当以当前镜像为基础镜像,去
    构建下一级镜像的时候才会被执行。

    docker 删除镜像

    docker rmi [选项] <镜像1> [<镜像2>...]

    •  docker rmi **短ID**
      
    • docekr rmi <镜像名:标签>

    Docker 镜像部分结束


    docker run

    docker run -it --rm ubuntu:14.04 bash

    运行容器,启动镜像中的bash进行交互式操作并在退出时删除这个容器

    • i : 交互式操作,启动的行为完成后进程不会立即结束
    • t :terminal,启动终端,这里指定为bash

    在执行docker run这个命令时Docker在后台进行的标准操作有:

    • 检查本地是否存在指定的镜像,不存在就从公有仓库下载
    • 利用镜像创建并启动一个容器
    • 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
    • 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
    • 从地址池配置一个 ip 地址给容器
    • 执行用户指定的应用程序
    • 执行完毕后容器被终止

    docker run -d ubuntu:14.04 ××××××

    在后台执行容器,执行后会返回容器ID可以使用docker logs ID/name查看输出信息,如果没注意id,可以使用docker ps查看正在运行中的容器ID

    • docker stop 查看终止状态的容器可以使用docker ps -a
    • docker restart 重启正在运行的容器
    • docker attach 进入正在运行的容器,不适合多人协作,nsenter是更好的选择.

    docker的导入和导出

    docker export ID/name >XXXX.tar

    导出容器到文件

    docker import XXXX.tar name/ubuntu:tag

    从文件导入容器
    注:用户既可以使用 docker load 来导入镜像存储文件到本地镜像库,也可以
    使用 docker import 来导入一个容器快照到本地镜像库。这两者的区别在于容
    器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状
    态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入
    时可以重新指定标签等元数据信息。

    docker rm

    删除一个终止状态的容器,要删除正在运行的容器,加上-f参数,会发送终止命令给容器继而删除

    docker rm $(docker ps -a -q)清除所有终止容器

    docker hub

    • docker login输入账号信息
    • 无需登录就可用docker search 查找Docker hub的镜像

    略过了docker 私有仓库,用到了再看。明天更新docker 数据管理

    数据卷

    数据卷是可供一个或多个容器使用的特殊目录,绕过了UFS

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

    *数据卷的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定
    为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的数据卷 *

    docker run -v /myvol ubuntu

    挂在一个数据卷到容器的/myvol目录

    docker run -v /home/dvwang/docker/test:/home ubuntu

    挂载主机的 /home.../test到容器的/home。目录和文件都可以必须是绝对路径 Dockerfile因为移植不能使用这个功能

    docker run -v /home/dvwang/docker/test:/home:ro ubuntu

    同上,只是挂载为只读

    docker inspect ID/name

    查看数据卷的具体信息

    docker run -d -v /dbdate --name dbdata mongo

    创建一个以MongoDB镜像为基础名字为dbdata的容器,在其他容器中使用 --volume-from(可使用多个)来挂载dbdata中的数据卷

    利用数据卷来备份和恢复暂时略过

    Docker网络功能

    -P|-p端口映射功能

    • -p 指定要映射的端口
    • -P 随机映射一个49000~49900的端口到容器开放的网络端口
    ➜  ~ docker run -d -P nginx
    ➜  ~ docker ps -l
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                           NAMES
    fe84de5fe039        nginx               "nginx -g 'daemon ..."   17 seconds ago      Up 16 seconds       0.0.0.0:32769->80/tcp, 0.0.0.0:32768->443/tcp   gifted_darwin
    

    可以看到主机的32769端口被映射到容器的80端口

    映射到指定地址的端口

    ➜  ~ docker run -d -p 127.0.0.1:5000:5000 nginx
    ➜  ~ docker ps                                                            
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                           NAMES
    473d9de29644        nginx               "nginx -g 'daemon ..."   23 seconds ago      Up 23 seconds       80/tcp, 443/tcp, 127.0.0.1:5000->5000/tcp       laughing_keller
    fe84de5fe039        nginx               "nginx -g 'daemon ..."   29 minutes ago      Up 29 minutes       0.0.0.0:32769->80/tcp, 0.0.0.0:32768->443/tcp   gifted_darwin
    

    映射到指定地址的任意端口

    ➜  ~ docker run -d -p 127.0.0.1::2000 nginx
    9463fc6a4c92e87d9118259c986d282c2bd478ec7b6d551e47622c4465643029
    ➜  ~ docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                           NAMES
    9463fc6a4c92        nginx               "nginx -g 'daemon ..."   3 seconds ago       Up 3 seconds        80/tcp, 443/tcp, 127.0.0.1:32770->2000/tcp      goofy_kalam
    473d9de29644        nginx               "nginx -g 'daemon ..."   7 minutes ago       Up 7 minutes        80/tcp, 443/tcp, 127.0.0.1:5000->5000/tcp       laughing_keller
    fe84de5fe039        nginx               "nginx -g 'daemon ..."   36 minutes ago      Up 36 minutes       0.0.0.0:32769->80/tcp, 0.0.0.0:32768->443/tcp   gifted_darwin
    
    

    docker port ID

    查看端口使用情况
    注意

    • 容器有自己的内部网络和 ip 地址(使用 docker inspect 可以获取所有的
      变量,Docker 还可以有一个可变的网络配置。)
    • -p 标记可以多次使用来绑定多个端口

    容器互联

    复习一下docker run

    docker run --name myimage image

    使用images创建容器并命名为myimage

    --link可以让容器之间安全的通信

    下面的因为目前实在用不到并且看不懂。暂时不看

    相关文章

      网友评论

        本文标题:Docker之路

        本文链接:https://www.haomeiwen.com/subject/xsazgttx.html