zoukankan      html  css  js  c++  java
  • Docker系列-(2) 镜像制作与发布

    目前已经更新完《Java并发编程》,《Docker教程》和《JVM性能优化》,欢迎关注【后端精进之路】,轻松阅读全部文章。

    Java并发编程:

    Docker教程:

    JVM性能优化:

    上篇文章引入了Docker的基本原理和操作,本节文章主要介绍如何制作Docker镜像和发布。

    镜像文件结构

    Docker镜像的本质是一系列文件的集合,这些文件依次叠加,形成了最后的镜像文件,类似于下图所示的结构,

    Screen Shot 2019-11-24 at 11.42.39 AM.png

    从底层往上,依次是文件系统层,操作系统层,专有镜像层,读写层。

    • 启动文件层:Docker启动时的用到的文件系统,启动完成后会自动脱离,用户不会与这一层直接打交道。

    • 操作系统层:这一层主要是操作系统相关的一些文件,根据发行版本的不同,可能有CentsOS、Ubuntu等等。文件包含dev,/proc,/bin,/etc 等目录, 是一个最小化的操作系统,很多工具都没有提供,包括vi、wget、curl等。注意这一层不包含linux内核,只是可在任何满足要求的linux内核上运行。

    • 专有镜像层:一般各大软件都会基于上面两层制作专有的镜像,比如nginx、tomcat等,都有专门的官方镜像,可以直接在docker hub上下载。

    • 读写层:这是我们制作自己的镜像时需要操作的层,是一个动态的运行环境,在后续镜像制作中的比如ENV, Volume,cmd等操作最终落实到此运行环境中。

    制作镜像的实质就是修改读写层。当需要修改镜像内的某个文件时,只对处于最上方的读写层进行了变动,不复写下层已有文件系统的内容,已有文件在只读层中的原始版本仍然存在,但会被读写层中的新版本文件所隐藏,当 docker commit 这个修改过的容器文件系统为一个新的镜像时,保存的内容仅为最上层读写文件系统中被更新过的文件。

    可以通过history命令查看镜像层,

    Screen Shot 2019-11-24 at 3.05.19 PM.png

    制作镜像

    制作镜像有两种通用的方法,第一种是直接通过配置好的Container来生成镜像;另外一种是通过Dockerfile的方式,基于已有的镜像来生成新的镜像,这种方法更为常用。

    配置Container制作镜像

    这里以制作nginx的镜像为例,介绍整个制作流程。

    1)下载基础镜像,这里以Ubuntu作为基础镜像。由于本地没有镜像可以先利用docker search获取官方镜像的名称,然后docker pull将镜像下载到本地。

    Screen Shot 2019-11-24 at 3.18.12 PM.png

    2)以交互方式启动镜像,方便在容器中安装软件。-it表示交互方式,/bin/bash为指定启动的终端。下图可以看到已经成功进入到容器内部了。

    docker run -it ubuntu:latest /bin/bash
    

    Screen Shot 2019-11-24 at 3.21.23 PM.png

    3)现在按照Nginx正常的安装流程安装即可,由于Ubuntu镜像只是一个最小化的系统,可能你需要通过apt-get install来安装一些需要的软件。

    4)退出容器,使用commit指令生成新的镜像。

    注意退出容器的时候,也有两种方法,通常直接exit就可以,但是这样容器也会关闭。如果不想关闭容器,只是退出终端,可以使用Ctrl+P+Q快捷键,此时退出后,容器依然在后台运行。

    直接运行docker commit同时指定容器id或者name,以及镜像名就可以了,新的镜像制作完成了。

    docker commit e0c618df0979 ubuntu-nginx
    

    Screen Shot 2019-11-24 at 3.32.46 PM.png

    接下来可以通过正常的方式启动镜像了。

    使用Dockerfile制作

    上面介绍了手动进入容器内部,制作Docker镜像的方式,一般比较繁琐。通常我们会使用Dockerfile的方式制作镜像,这种方式下我们需要编写Dockerfile文件。

    Dockerfile文件

    Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile快速创建自定义镜像。

    下面是一个简单的Dockerfile文件,先将编译生成的jar文件复制到容器,然后声明容器暴露的端口,最后指定在启动容器时需要运行的指令。

    FROM openjdk:8
    ADD ["target/bazaar-1.0.0.jar", "bazaar.jar"]
    EXPOSE 1234
    ENTRYPOINT ["java", "-jar", "/bazaar.jar"]
    

    Dockerfile中常用的指令集有:

    Picture1.png

    • FROM: 第一条指令必须为FROM指令,用于指定基础镜像。
    • MAINTAINER: 指定维护者信息。
    • RUN: 会在shell终端运行命令。
    • EXPOSE: 格式为 EXPOSE [ ...],声明容器需要暴露的端口号。镜像启动可以通过 –P 或 -p 进行端口映射的绑定。
    • ENV: 指定一个环境变量,可以被后续的RUN引用,并且在容器中记录该环境变量。
    • ADD: 该命令将复制指定的到容器中的。其中可以是Dockerfile所在目录的一个相对路径;也可以是tar文件(自动解压)。
    • VOLUME: 格式为 VOLUME [path]。创建一个可以从本地主机或其他容器挂载点,一般用来存放需要保持的数据。
    • USER: 指定运行容器时的用户名,后续的RUN也会指定该用户。
    • WORKDIR: 指定工作空间,后续命令都在此目录下执行。

    比较复杂的是CMD与ENTRYPOINT的对比,两者都可以运行指令,但是稍有不同。

    • CMD给出的是一个容器的默认的可执行体,可以被覆盖。
    • ENTRYPOINT才是正统地用于定义容器启动以后的执行体,这个执行体一定会被执行。

    (1) CMD单独使用

    FROM debian:wheezy
    CMD ["/bin/ping", "localhost"]
    

    启动后不指定任何参数,将会ping localhost,

    $ docker run -it test
    PING localhost (127.0.0.1): 48 data bytes
    56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.076 ms
    56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.087 ms
    56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.090 ms
    ^C--- localhost ping statistics ---
    3 packets transmitted, 3 packets received, 0% packet loss
    round-trip min/avg/max/stddev = 0.076/0.084/0.090/0.000 ms
    

    但是如果启动容器的同时带有新的指令,则原有的CMD会被新的指令覆盖

    docker run -it test bash
    root@e8bb7249b843:/#
    

    (2)CMD和ENTRYPOINT同时使用

    CMD通常用作传递参数给ENTRYPOINT,如下例子所示:

    FROM debian:wheezy
    ENTRYPOINT ["/bin/ping"]
    CMD ["localhost"]
    

    直接运行镜像并不指定任何参数,将会一直ping localhost

    $ docker run -it test
    PING localhost (127.0.0.1): 48 data bytes
    56 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.096 ms
    56 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.088 ms
    56 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.088 ms
    ^C--- localhost ping statistics ---
    3 packets transmitted, 3 packets received, 0% packet loss
    round-trip min/avg/max/stddev = 0.088/0.091/0.096/0.000 ms
    

    如果直接运行的同时,指定一个参数,将会ping对应的参数,此时CMD被覆盖。

    $ docker run -it test google.com
    PING google.com (173.194.45.70): 48 data bytes
    56 bytes from 173.194.45.70: icmp_seq=0 ttl=55 time=32.583 ms
    56 bytes from 173.194.45.70: icmp_seq=2 ttl=55 time=30.327 ms
    56 bytes from 173.194.45.70: icmp_seq=4 ttl=55 time=46.379 ms
    ^C--- google.com ping statistics ---
    5 packets transmitted, 3 packets received, 40% packet loss
    round-trip min/avg/max/stddev = 30.327/36.430/46.379/7.095 ms
    

    如果你想要制作的容器更加通用一些,可以在Dockerfile中使用CMD ["/path/dedicated_command"],这样你可以在运行容器的同时,根据需求来覆盖已有的指令。

    利用Dockerfile制作容器

    上面介绍了Dockerfile中常用的指令,一般我们写好Dockerfile之后,直接进入到Dockerfile所在的目录,运行docker build即可,Docker会根据Dockerfile中指定的步骤来生成我们的镜像。

    $ docker build -t your_image_name .
    

    以上就是制作镜像的所有流程,接下来介绍镜像的发布。

    镜像发布

    镜像发布有两种选择,可以直接push到官方的docker hub,你只需要注册一个docker账号即可;也可以自己在本地创建私有仓库,将镜像push这里。

    Docker Hub

    打开 https://hub.docker.com/ 注册好账户后,记住好自己的账户名,待会需要将本地的镜像打tag带上用户名,然后进行push。

    首先使用如下的指令就给本地镜像打tag,

    docker tag myImage:v1 your_user_name/myImage:v1
    

    接下来直接push就行,会自动push到官方仓库,注意可能会需要docker login一下,这里直接输入用户名密码即可。

    docker push your_user_name/myImage:v1
    

    这样官方仓库就有你的Image了, 以后直接docker pull就行了。

    本地私有仓库

    (1) 首先下载registry镜像:docker pull registry.

    (2) 接着在5000端口启动,docker run -d --name reg -p 5000:5000 registry.

    (3) 配置http传输,私服默认只能使用https,需要配置开放http.

    以centos上的配置为例,

    Picture1.png

    注意图中的ip根据实际registry的ip来进行设置,可以通过docker inspect reg来找到。

    配置完毕重启下docker服务

    systemctl daemon-reload 
    systemctl restart docker
    

    以上就完成了私有仓库的创建。

    接下来直接push Image到仓库即可,流程和push到官方仓库类似,只是打tag的用户名改成私有仓库的地址。

    (1)打tag

    docker tag hello-world http://192.168.244.7:5000/hello-world 
    

    (2)push镜像

    docker push 192.168.244.7:5000/hello-world
    

    (3)查询镜像:

    Picture1.png

    (4)查询镜像版本:

    Picture1.png

    以上就是镜像制作和发布的全部内容,下节会介绍实际部署中,docker-compose的使用以及docker的网络通信。

    参考链接:


    本文由『后端精进之路』原创,首发于博客 http://teckee.github.io/ , 转载请注明出处

    搜索『后端精进之路』关注公众号,立刻获取最新文章和价值2000元的BATJ精品面试课程

    后端精进之路.png

  • 相关阅读:
    POJ 1426 Find The Multiple(数论——中国同余定理)
    POJ 2253 Frogger(Dijkstra变形——最短路径最大权值)
    POJ 3790 最短路径问题(Dijkstra变形——最短路径双重最小权值)
    POJ 3278 Catch That Cow(模板——BFS)
    HDU 1071 The area
    HDU 1213 How Many Tables(模板——并查集)
    POJ 1611 The Suspects
    light oj 1214 Large Division
    POJ 1258 Agri-Net(Prim算法求解MST)
    POJ 2387 Til the Cows Come Home(模板——Dijkstra算法)
  • 原文地址:https://www.cnblogs.com/way2backend/p/11992661.html
Copyright © 2011-2022 走看看